פיתוח דיאגרמות סנקי להמחשת זרימת אתר

פunnel סטנדרטיים מציגים המרות בכל שלב, אך מסתירים מאיפה מגיעים המשתמשים החשובים ביותר והיכן התנועה אובדת. אנו מפתחים דיאגרמות Sankey המדמיינות את כל הזרימות בין עמודים וערוצים, ומאפשרות לכם לראות את התמונה המלאה של מסע הלקוח. הצוות שלנו מספק את הפרויקט במפתח מלא—מניתוח נתונים ועד הטמעת רכיב React אינטראקטיבי, עם תמיכה מתמשכת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
פיתוח דיאגרמות סנקי להמחשת זרימת אתר
בינוני
מ- 1 יום עד 3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

במהלך ניתוח משפך מכירות באתר מסחר אלקטרוני עם 50,000 ביקורים חודשיים, גילינו ש-40% מהתנועה הגיעה לעמוד הקטלוג אך לא המשיכה הלאה. דוחות סטנדרטיים הראו רק שיעור המרה של 2.5% בשלב זה אך לא הסבירו מדוע. דיאגרמת Sankey עזרה לחשוף שמשתמשים ממודעות ממומנות קפצו ישירות לעמודי מוצר, תוך עקיפת הקטלוג, והמירו פי שלושה יותר ממשתמשים אורגניים. לאחר חלוקה מחדש של התקציב, שיעור ההמרה עלה ב-20%. כלי זה ממחיש כל מעבר בין עמודים, ערוצים או שלבים. ללא ויזואליזציה כזו, אי אפשר לראות בדיוק היכן אתם מאבדים תנועה.

למה משפכים סטנדרטיים לא מציגים את התמונה המלאה

דוחות משפך סטנדרטיים מראים המרה בכל שלב אך לא מראים מאיפה מגיעים המשתמשים בעלי הערך הגבוה ביותר או לאן הם הולכים. דיאגרמת Sankey פותרת זאת על ידי הצגת כל הזרימות בין צמתים. לדוגמה, ניתן לראות שמשתמשים ממודעות ממומנות הולכים לעיתים קרובות ישירות לעמודי מוצר, תוך עקיפת הקטלוג, ומבצעים רכישות פי שלושה יותר ממשתמשים אורגניים. זה מאפשר לחלק מחדש את התקציב ולהגדיל ROI. דיאגרמות Sankey יעילות פי 3 ממשפכים סטנדרטיים בזיהוי צווארי בקבוק.

כיצד דיאגרמת Sankey משפרת את האנליטיקה

ה-Sankey עונה על שאלות שאינן נראות בטבלאות: מאיפה מגיעים משתמשים בעלי שיעור המרה גבוה, איזה מסלול מוביל ל-LTV מקסימלי, היכן אובדת הכי הרבה תנועה. אנו משתמשים ב-drill-down — לחיצה על צומת חושפת את המבנה הפנימי שלו, ומאפשרת חקירה מעמיקה ללא עצירה. באנליטיקת מוצר, ה-Sankey מראה אילו שילובי ערוצים (אורגני → מוצר → עגלה) מובילים לרכישה ואילו מובילים לנטישה. עבור נתונים מחזוריים (משתמשים בלולאות), אנו משתמשים ב-d3-sankey-circular.

מה מספק Drill-Down

Drill-down מאפשר לפרט את הצומת הנבחר על ידי חשיפת המבנה הפנימי שלו. לדוגמה, לחיצה על צומת 'עגלה' מראה מאילו מקורות הגיעו המשתמשים ואילו פעולות ביצעו לאחר מכן. זה שימושי במיוחד לניתוח מעמיק של משפכים עם שלבים רבים.

השוואה בין משפך סטנדרטי לדיאגרמת Sankey

מאפיין משפך סטנדרטי דיאגרמת Sankey
מספר המסלולים המוצגים רק שלבים רציפים כל המסלולים האפשריים
ויזואליזציה של נטישות לא מציג מציג רוחב זרימה
אינטראקטיביות מוגבלת Drill-down, סינון, tooltip
קריאות עם 100+ צמתים בלתי אפשרי עובד עם אופטימיזציה
השוואת מקורות תנועה דורש דוחות נפרדים מפה אחידה אחת

יישום טכני של Sankey על React

אנו משתמשים בטכנולוגיות מודרניות: React 18, TypeScript, d3-sankey. זה מבטיח רינדור חלק גם עם 10,000+ חיבורים – לפי התיעוד הרשמי של d3-sankey.

התקנה ותלויות

npm install d3-sankey d3 npm install --save-dev @types/d3-sankey 

מבנה נתונים

הנתונים עבור ה-Sankey מורכבים מצמתים וקישורים. כל קישור מכיל מקור, יעד וערך. דוגמה למשפך מסחר אלקטרוני:

interface SankeyNode {
  id: string;
  label: string;
  color?: string;
}

interface SankeyLink {
  source: string; // id узла-источника
  target: string; // id узла-цели
  value: number; // объём потока
}

interface SankeyData {
  nodes: SankeyNode[];
  links: SankeyLink[];
}

// Пример: воронка e-commerce
const data: SankeyData = {
  nodes: [
    { id: 'organic', label: 'Органика' },
    { id: 'paid', label: 'Платная реклама' },
    { id: 'direct', label: 'Прямые' },
    { id: 'catalog', label: 'Каталог' },
    { id: 'product', label: 'Карточка товара' },
    { id: 'cart', label: 'Корзина' },
    { id: 'checkout', label: 'Оформление' },
    { id: 'purchase', label: 'Покупка' },
    { id: 'exit', label: 'Выход' },
  ],
  links: [
    { source: 'organic', target: 'catalog', value: 4200 },
    { source: 'organic', target: 'product', value: 1800 },
    { source: 'paid', target: 'catalog', value: 2100 },
    { source: 'paid', target: 'product', value: 3400 },
    { source: 'direct', target: 'catalog', value: 900 },
    { source: 'catalog', target: 'product', value: 5600 },
    { source: 'catalog', target: 'exit', value: 3100 },
    { source: 'product', target: 'cart', value: 2900 },
    { source: 'product', target: 'exit', value: 4800 },
    { source: 'cart', target: 'checkout', value: 1600 },
    { source: 'cart', target: 'exit', value: 1300 },
    { source: 'checkout', target: 'purchase', value: 1100 },
    { source: 'checkout', target: 'exit', value: 500 },
  ],
};

קומפוננטה עם Tooltip ואינטראקטיביות

קומפוננטת ה-React שלנו מרנדרת SVG באמצעות d3. היא כוללת:

  • נתיבים מעוגלים חלקים
  • Tooltip בעת ריחוף מעל צמתים או קישורים
  • קידוד צבע לפי צומת (סולם Tableau10)
  • רוחב וגובה אדפטיביים
import { useEffect, useRef } from 'react';
import * as d3 from 'd3';
import { sankey, sankeyLinkHorizontal, sankeyLeft } from 'd3-sankey';

export function SankeyDiagram({ data, width = 800, height = 500 }: { data: SankeyData; width?: number; height?: number }) {
  const svgRef = useRef<SVGSVGElement>(null);
  const margin = { top: 20, right: 20, bottom: 20, left: 20 };

  useEffect(() => {
    if (!svgRef.current) return;
    const svg = d3.select(svgRef.current);
    svg.selectAll('*').remove();

    const iw = width - margin.left - margin.right;
    const ih = height - margin.top - margin.bottom;

    // Подготовка данных для d3-sankey
    const nodeMap = new Map(data.nodes.map((n, i) => [n.id, { ...n, index: i }]));
    const sankeyData = {
      nodes: data.nodes.map(n => ({ ...n })),
      links: data.links.map(l => ({
        source: data.nodes.findIndex(n => n.id === l.source),
        target: data.nodes.findIndex(n => n.id === l.target),
        value: l.value,
      })),
    };

    const sankeyLayout = sankey()
      .nodeWidth(20)
      .nodePadding(12)
      .nodeAlign(sankeyLeft)
      .extent([[0, 0], [iw, ih]]);

    const { nodes, links } = sankeyLayout(sankeyData as any);

    const colorScale = d3.scaleOrdinal(d3.schemeTableau10);

    const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);

    // Tooltip
    const tooltip = d3.select('body').append('div')
      .style('position', 'absolute')
      .style('display', 'none')
      .style('background', 'rgba(0,0,0,0.8)')
      .style('color', '#fff')
      .style('padding', '8px 12px')
      .style('border-radius', '4px')
      .style('font-size', '13px')
      .style('pointer-events', 'none');

    // Links
    g.append('g')
      .selectAll('.link')
      .data(links)
      .join('path')
      .attr('class', 'link')
      .attr('d', sankeyLinkHorizontal())
      .attr('fill', 'none')
      .attr('stroke', (d: any) => colorScale(String(d.source.index)))
      .attr('stroke-width', (d: any) => Math.max(1, d.width))
      .attr('stroke-opacity', 0.4)
      .on('mouseover', (event, d: any) => {
        d3.select(event.currentTarget).attr('stroke-opacity', 0.7);
        tooltip
          .style('display', 'block')
          .style('left', `${event.pageX + 12}px`)
          .style('top', `${event.pageY - 28}px`)
          .html(`<strong>${d.source.label} → ${d.target.label}</strong><br/>${d3.format(',.0f')(d.value)} пользователей`);
      })
      .on('mouseout', (event) => {
        d3.select(event.currentTarget).attr('stroke-opacity', 0.4);
        tooltip.style('display', 'none');
      });

    // Nodes
    const nodeG = g.append('g')
      .selectAll('.node')
      .data(nodes)
      .join('g')
      .attr('class', 'node');

    nodeG.append('rect')
      .attr('x', (d: any) => d.x0)
      .attr('y', (d: any) => d.y0)
      .attr('width', (d: any) => d.x1 - d.x0)
      .attr('height', (d: any) => Math.max(1, d.y1 - d.y0))
      .attr('fill', (d: any) => colorScale(String(d.index)))
      .attr('rx', 3)
      .on('mouseover', (event, d: any) => {
        tooltip
          .style('display', 'block')
          .style('left', `${event.pageX + 12}px`)
          .style('top', `${event.pageY - 28}px`)
          .html(`<strong>${d.label}</strong><br/>Объём: ${d3.format(',.0f')(d.value)}`);
      })
      .on('mouseout', () => tooltip.style('display', 'none'));

    // Labels
    nodeG.append('text')
      .attr('x', (d: any) => d.x0 < iw / 2 ? d.x1 + 6 : d.x0 - 6)
      .attr('y', (d: any) => (d.y0 + d.y1) / 2)
      .attr('dy', '0.35em')
      .attr('text-anchor', (d: any) => d.x0 < iw / 2 ? 'start' : 'end')
      .attr('font-size', 12)
      .attr('fill', '#374151')
      .text((d: any) => d.label);

    return () => {
      tooltip.remove();
    };
  }, [data, width, height]);

  return <svg ref={svgRef} width={width} height={height} />;
}

הכנת נתונים: צבירת SQL

הנתונים עבור Sankey נצברים בדרך כלל מזרם אירועים. דוגמה לשאילתת SQL למשפך אתר (מעברי עמודים רציפים בתוך סשן):

WITH ranked_events AS (
    SELECT session_id, page_type, LAG(page_type) OVER (PARTITION BY session_id ORDER BY created_at) AS prev_page_type, ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY created_at) AS step
    FROM page_views
    WHERE created_at > NOW() - INTERVAL '30 days'
)
SELECT COALESCE(prev_page_type, 'entry') AS source, page_type AS target, COUNT(*) AS value
FROM ranked_events
WHERE prev_page_type IS NOT NULL OR step = 1
GROUP BY 1, 2
HAVING COUNT(*) > 50
ORDER BY value DESC;

שאילתה זו מפיקה טבלת מעברים עם ספירות משתמשים. עבור נפחי נתונים גדולים, אנו משתמשים בצבירת נתונים מוקדמת עם Materialized Views או טריגרים.

הגדרת פריסה: איזה אלגוריתם לבחור?

npm install d3-sankey d3 npm install --save-dev @types/d3-sankey תומך במספר אלגוריתמי יישור צמתים. הבחירה משפיעה על קריאות הדיאגרמה.

אלגוריתם תיאור מקרה שימוש
sankeyLeft צמתים מיושרים לשמאל הרמה משפכים עם סדר שלבים קבוע
sankeyRight יישור לימין גרפים עם צמתי עלה משמאל
sankeyCenter יישור למרכז הגרף גרפים א-ציקליים ללא כיוון ברור
sankeyJustify צמתי עלה נדחפים לימין מקרה כללי

עבור נתונים מחזוריים, אנו משתמשים ב-interface SankeyNode { id: string; label: string; color?: string; } interface SankeyLink { source: string; // id узла-источника target: string; // id узла-цели value: number; // объём потока } interface SankeyData { nodes: SankeyNode[]; links: SankeyLink[]; } // Пример: воронка e-commerce const data: SankeyData = { nodes: [ { id: 'organic', label: 'Органика' }, { id: 'paid', label: 'Платная реклама' }, { id: 'direct', label: 'Прямые' }, { id: 'catalog', label: 'Каталог' }, { id: 'product', label: 'Карточка товара' }, { id: 'cart', label: 'Корзина' }, { id: 'checkout', label: 'Оформление' }, { id: 'purchase', label: 'Покупка' }, { id: 'exit', label: 'Выход' }, ], links: [ { source: 'organic', target: 'catalog', value: 4200 }, { source: 'organic', target: 'product', value: 1800 }, { source: 'paid', target: 'catalog', value: 2100 }, { source: 'paid', target: 'product', value: 3400 }, { source: 'direct', target: 'catalog', value: 900 }, { source: 'catalog', target: 'product', value: 5600 }, { source: 'catalog', target: 'exit', value: 3100 }, { source: 'product', target: 'cart', value: 2900 }, { source: 'product', target: 'exit', value: 4800 }, { source: 'cart', target: 'checkout', value: 1600 }, { source: 'cart', target: 'exit', value: 1300 }, { source: 'checkout', target: 'purchase', value: 1100 }, { source: 'checkout', target: 'exit', value: 500 }, ], }; או שוברים מחזורים מראש.

מה כלול בעבודה

  • אנליטיקה: חקר מבנה הנתונים שלך, זיהוי מדדים מרכזיים ונקודות אינטגרציה.
  • עיצוב: פיתוח פריסה, בחירת אלגוריתם פריסה, אב-טיפוס של אינטראקציות.
  • יישום: קידוד הקומפוננטה ב-React/TypeScript, הגדרת backend לצבירת נתונים.
  • תיעוד: תיאור ה-API של הקומפוננטה, הוראות שימוש והתאמה אישית.
  • בדיקות: אימות על נתונים אמיתיים, בדיקות עומס (עד 100,000 קישורים), אופטימיזציה.
  • פריסה: אינטגרציה עם הממשק שלך, הגדרת build ופריסה אוטומטיים.
  • הדרכה: סמינר מקוון לצוות שלך על שימוש והרחבת הדיאגרמה.
  • תמיכה: 30 ימים של ייעוץ חינם ותיקוני באגים לאחר הפריסה.

תהליך הפיתוח ולוח זמנים

הצוות שלנו מיישם את דיאגרמת Sankey במפתח מלא. ניסיון עם למעלה מ-50 פרויקטים.

  1. אנליטיקה: חקר מבנה הנתונים שלך, הגדרת מדדים מרכזיים.
  2. עיצוב: פיתוח פריסה, בחירת אלגוריתם פריסה, תכנון אינטראקציות.
  3. יישום: קידוד הקומפוננטה ב-React/TypeScript, הגדרת צבירת נתונים ב-backend.
  4. בדיקות: אימות על נתונים אמיתיים, אופטימיזציה של ביצועים.
  5. פריסה: אינטגרציה עם הממשק שלך, פריסה על השרת שלך או בענן.
  6. תמיכה: 30 ימים של שיפורים חינם וייעוץ.

גרסה בסיסית עם tooltip ואינטראקציות – 2–3 ימים (עלות החל מ-$2,000). גרסה מורחבת עם drill-down, סינון וייצוא – 5–7 ימים (עלות החל מ-$5,000).

תוצאות היישום

לאחר יישום דיאגרמת Sankey, הלקוחות שלנו רואים עלייה בשיעורי המרה של 15–30% והפחתה ב-CPA של 20–40% על ידי זיהוי צווארי בקבוק. לדוגמה, לקוח חסך $50,000 בשנה על ידי חלוקה מחדש של הוצאות הפרסום. אנו מספקים אחריות קוד ל-6 חודשים ותיעוד מלא. תרשים אינטראקטיבי זה הוא כלי עוצמתי לאופטימיזציית המרות. צרו קשר כדי להזמין דיאגרמת Sankey מותאמת אישית לאתר שלכם. קבלו ייעוץ ממהנדס עוד היום.