Преди да започнем тази публикация в блога, нека научим малко повече за визуализацията на данни. Ако сте запознати с анализа на данни, тогава трябва да сте срещали визуализация на данни. Това е ключова част от анализа на данни. С прости думи, визуализацията на данни е, когато вземете необработени данни и ги представите визуално с помощта на графики, диаграми и карти. Той позволява на хората да откриват тенденции и модели в големи набори от данни, без да губят време, а също така придава смисъл на сложните набори от данни и помага на бизнеса да идентифицира областите, които изискват подобрение и внимание. С нарастването на големите данни, ние трябва да можем да интерпретираме все по-големи пакети от данни по по-бърз и по-интерактивен начин. Можем да използваме BI инструменти като Tableau, PowerBi, Superset и т.н. или можем да използваме свободно достъпни библиотеки за визуализация на данни като D3.js, Highcharts и т.н. D3.js е стандартът по подразбиране в данните библиотеки за визуализация. В тази публикация в блога ще обсъждам повече относно интерактивността в D3.js, по-специално събитията с мишката и как можете да се абонирате и да използвате тези събития в D3.

Този блог е продължение на предишната ми публикация в блог, ако все още не сте го проверили, горещо препоръчвам да прегледате по-долу споменатата публикация в блога, преди да приложите тази концепция.

СЪЗДАВАНЕ НА ПРОСТИ ЛИНЕЙНИ ГРАФИ С ИЗПОЛЗВАНЕ НА D3.JS — ЧАСТ 01

Тази статия ще ви помогне да проучите следните основни концепции на D3:

  • Как да добавите етикет на ос към диаграма с помощта на D3.js?
  • Как да покажа данни при Mouseover в d3.js?
  • Как да начертаете вертикална линия при преместване на мишката с помощта на d3.js?
  • Добавяне на интерактивност към визуализацията с помощта на Dynamic Tooltip?

СТЪПКА 1: СЪБИТИЯ В D3

D3 поддържа вградени събития и персонализирани събития. DOM събития се задействат, за да уведомят кода за интересни промени, които могат да повлияят на изпълнението на кода. Те могат да възникнат от потребителски взаимодействия като използване на мишка или преоразмеряване на прозорец, промени в състоянието на основната среда и други причини. Всяко събитие е представено от обект, който е базиран на интерфейса Event и може да има допълнителни потребителски полета и/или функции за предоставяне на информация за случилото се

d3.selection.on(type[, listener[, capture]]);

Слушателите на събития слушат за конкретни събития, които се задействат върху конкретни DOM елементи. Можем да свържем слушател на събития към всеки DOM елемент, като използваме метода d3.selection.on(). Методът on()добавя слушател на събития към всички избрани DOM елементи. Първият параметър е тип събитие като низ като „щракване“, „преминаване с мишката“ и т.н. Вторият параметър е функция за обратно извикване, която ще бъде изпълнена при възникване на събитие, а третият незадължителен параметър флаг за улавяне може да бъде указано, което съответства на флага на W3C useCapture.

СТЪПКА 2: D3.JS СЪБИТИЯ НА МИШКАТА

Нека се потопим в повече подробности за събитията, които се случват, когато мишката се движи между елементите. За да добавим тези интерактивни функции към нашите визуализации, ще трябва да използваме events. Когато добавяме събитие към всеки елемент или възел, трябва да зададем две неща: типа на събитието и функцията слушател.

Типът събитие е това, за какъв сценарий проверява елементът, като например когато мишката дойде или излезе от елемента (onmouseenter и onmouseout съответно). Слушателят е функцията, която се извиква всеки път, когато се задейства събитие. Например, нашата функция слушател може да промени размера и цвета на елемент всеки път, когато мишката премине върху елемента.

Можете да намерите интересна демонстрация на събития в уебсайта W3Schools.

  • Събитието mouseover се задейства, когато показалецът на мишката влезе в елемента div и неговите дъщерни елементи.
  • Събитието mouseenter се задейства само когато показалецът на мишката влезе в елемента div.
  • Събитието onmousemove се задейства всеки път, когато показалецът на мишката се премести върху елемента div.

Имаме достатъчно разговори за събития и слушатели, нека се съсредоточим върху нашата цел сега.

СТЪПКА 3: ДОБАВЯНЕ НА ЕТИКЕТ НА Y-ОСА

Когато показваме нашите визуализации на уеб страница, това може да помогне на нашите читатели, ако нашите визуализации са интерактивни. Вече създадохме линейна диаграма в предишната ни статия, така че просто трябва да покажем подсказка при задържане или щракване. Но преди да добавим подсказка, трябва да променим съществуващия код и да добавим етикет на оста за нашата Y-ос — Използване на интернет (GB)

const yAxisGenerator = d3.axisLeft().scale(yScale);
  const yAxis = bounds.append("g").call(yAxisGenerator);
  const yAxisLabel = yAxis
    .append("text")
    .attr("class", "y-axis-label")
    .attr("x", -dimensions.boundedHeight / 2)
    .attr("y", -dimensions.margin.left + 110)
    .html("Internet Usage (GB)");

СТЪПКА 4: НАСТРОЙТЕ ВЗАИМОДЕЙСТВИЕ

Нека създадем подсказка за нашата линия. Ще използваме ефекти на мишката, за да добавим интерактивност към SVG. Първото нещо, което трябва да знаем къде е задействано дадено събитие. Можем да използваме d3.event, който съдържа полетата event.pathXи event.pathYкоето ни казва позицията на мишката, когато събитието е било задействано, но тази позиция е по отношение на целия HTML документ. Така че, въпреки че може да ни помогне в някои ситуации, няма да ни помогне да разберем къде е мишката в нашите визуализации.

Вместо да улавяме събития при задържане на курсора на мишката за отделни елементи, ние искаме да показваме подсказка, когато потребителят задържа курсора на мишката някъде върху диаграмата. Следователно ще искаме елемент, който обхваща всичките ни граници. За да настроим взаимодействията, нека създадем правоъгълник, който покрива нашите граници и да добавим нашите слушатели на събития на мишката към него. Тук не е необходимо да дефинираме нашите x или y атрибути, защото и двата са с 0.

const listeningRect = bounds
    .append("rect")
    .attr("class", "listening-rect")
    .attr("width", dimensions.boundedWidth)
    .attr("height", dimensions.boundedHeight)
    .on("mousemove", onMouseMove)
    .on("mouseleave", onMouseLeave);

Това определено не е това, което искахме, но можем да го поправим, като създадем styles.css лист. Cascading Style Sheets (CSS) е език за маркиране, отговорен за това как ще изглеждат вашите уеб страници. Той контролира цветовете, шрифтовете и оформлението на вашите елементи. Основната идея зад CSS е да се отдели структурата на документа от представянето на документа. HTML е предназначен за структура. Никога не е бил предназначен за нещо друго. Всички онези атрибути, които добавяте, за да стилизирате страниците си, бяха добавени по-късно. Нека създадем друг файл в папката Same Blog 1 и го кръстим Styles.css и добавим кода по-долу. Сега папката Blog 1 трябва да показва три файла 1. Chart.js 2. Index.html 3. Styles.css. Най-добрият начин да направите процеса възможно най-лесен е да планирате предварително. Знам, че е много да искам, но наистина ще се изплати по-късно.

Ето как можете да използвате външен CSS. Външни таблици със стилове изисква да добавите маркер ‹link› в секцията ‹head› на вашия HTML документ. Целият смисъл на такова писане е да ви позволи да създадете универсална структура за вашите документи.

  1. Отворете вашата HTML страница и намерете отварящия таг ‹head›.
  2. Поставете следния код (маркиран в червено) точно след тага ‹head›

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
        <link rel="stylesheet" href="/bg./styles.css"></link>
    <title>My Line Chart</title>
</head>
<body>
        <div id="wrapper" class="wrapper">
            <div id="tooltip" class="tooltip">
                <div class="tooltip-date">
                    <span id="date"></span>
                </div>
                <div class="tooltip-Internet">
                    Internet Usage: <span id="internet"></span>
                </div>
            </div>
        
        </div>
    <script src="./../../d3.v5.js"></script>
    <script src="./chart.js"></script>
</body>
</html>

По време на нашата стъпка на изграждане, компилаторът ще търси този styles.css файл, който сме създали

Styles.css

Външен лист със стилове е самостоятелен .css файл, към който има връзка от уеб страница. Предимството на външните таблици със стилове е, че могат да бъдат създадени веднъж и правилата да се прилагат към множество уеб страници. Ако трябва да направите широко разпространени промени в дизайна на вашата диаграма, можете да направите една промяна в таблицата със стилове и тя ще бъде приложена към всички свързани страници, спестявайки време и усилия.

Забележка: В CSS селекторът на клас е име, предшествано от точка (“.”), а селекторът на ID е име, предшествано от хеш символ(“#”).

.listening-rect {
  fill: transparent;
}

Без целия допълнителен HTML за стилизиране, структурата на вашия документ е много по-четима, което улеснява актуализирането, без да нарушава документа. Целият ви CSS може да бъде преместен в отделен файл, което улеснява и актуализирането на вашите стилове.

СТЪПКА 5: ПУСКАНЕ НА ЛИНИЯ ЗА ВЗАИМОДЕЙСТВИЕ С ПОТРЕБИТЕЛЯ

Добавяне на вертикална линия към диаграма D3, която следва показалеца на мишката. Като първа стъпка ще добавим линия, така че всеки път, когато някой задържи курсора, да може да пусне вертикална линия.

const xAxisLine = bounds
    .append("g")
    .append("rect")
    .attr("class", "dotted")
    .attr("stroke-width", "1px")
    .attr("width", ".5px")
    .attr("height", dimensions.boundedHeight);

СТЪПКА 6: НАСТРОЙТЕ НАШАТА ПРОМЕНЛИВА НА ИНСТРУМЕНТА

Вече сме създали три отделни Div на нашия Index.html за съхраняване на нашата информация за подсказки.

  • Div ID — подсказка — Правоъгълник, който показва подсказката
  • Div ID — tooltip-date — Правоъгълник, който показва информацията за датата
  • Div ID — tooltip-internet — Правоъгълник, който показва използването на интернет

За да покажем подсказката до действителна точка от данни, трябва да знаем до коя точка сме най-близо. Първо ще трябва да разберем над коя дата се намираме - как да конвертираме x позиция в дата? Досега сме използвали нашите скали само за преобразуване от пространството на данните (в този случай обекти с дата на JavaScript) в пространството на пикселите.

За щастие, скалите d3 правят това много лесно! Можем да използваме същия xScale(), който използвахме преди, който имаметод .invert(). .invert() ще конвертира нашите единици назад, от диапазона към домейна.

Нека предадем x позицията на нашата мишка (mousePosition[0]) към метода .invert() на нашия xScale().

Откъс от: Нейт Мъри. „Пълна визуализация на данни с D3“

function onMouseMove() {
    const mousePosition = d3.mouse(this);
    const hoveredDate = xScale.invert(mousePosition[0]);

Когато извикаме d3.mouse(container), ние предаваме възела, с който искаме да бъде свързана нашата позиция на събитието. d3.mouse ще върне обратно масив от позициите x и y, където е задействано текущото събитие.

  • d3.mouse(container) — Връща местоположението на текущото събитие спрямо посочения container. Контейнер е HTML възел. Използва същото събитие, което е в d3.event, така че събитието трябва да е регистрирано от selection.on.

СТЪПКА 7: НАМЕРЕТЕ НАЙ-БЛИЗКАТА ТОЧКА

Функцията d3.scan() е вградена функция в D3.js, която сканира линейно масива и връща индекса на минималния елемент според посочения компаратор. Функцията връща undefined, когато в масива няма сравними елементи.

Синтаксис:

d3.scan(array, comparator)

Параметри: Тази функция приема два параметъра, които са споменати по-горе и описани по-долу:

  • масив: Този задължителен параметър съдържа масив от елементи, чиято минимална стойност трябва да бъде изчислена и съответният индекс трябва да бъде върнат.
  • компаратор: Този параметър е незадължителен параметър, който указва как трябва да се получи минималният елемент.

Върната стойност: Функцията връща една цяло число, обозначаваща индекса на минималния елемент в масива въз основа на посочения компаратор.

Нека да го изпробваме. Създайте функция за намиране на разстоянието между задържаната точка и точка с данни. Не ни интересува дали точката е преди или след датата, върху която е поставен курсора, така че ще използваме Math.abs(), за да преобразуваме това разстояние в абсолютно разстояние.

const getDistanceFromHoveredDate = (d) =>
    Math.abs(xAccessor(d) - hoveredDate);
    const closestIndex = d3.scan(dataset,(a, b) =>
    getDistanceFromHoveredDate(a) - getDistanceFromHoveredDate(b));
    
    //Grab the data point at that index
    const closestDataPoint = dataset[closestIndex];
    const closestXValue = xAccessor(closestDataPoint);
    const closestYValue = yAccessor(closestDataPoint);

СТЪПКА 8: ПОЯВКА ЗА ФОРМАТИРАНЕ

Свършихме трудната част. Следващата задача е да коригираме показването на Tooltip въз основа на нашите нужди. Решението е ефективно да създадем подсказка div в нашия код, след което да прикрепим подходящите mouseover и mousemove функции за събития към всяка от нашите лентови диаграми divs, за да покажем/скрием по подходящ начин нашата персонализирана подсказка div. Когато се покаже подсказката, можем лесно да вземем данните, които искаме да покажем като текст.

Форматирането на числа е едно от онези неща, за които обикновено не мислите, докато на етикетите на осите ви не се появи грозно „0,300004“. Освен това може би искате да групирате хиляди, за да подобрите четливостта и да използвате фиксирана точност, като например „$1,240.10“. Или може би искате да покажете само значимите цифри на определено число. D3 прави това лесно с помощта на стандартен числов формат. Функцията format() в D3.js се използва за форматиране на числата в различни стилове, налични в D3. Това е псевдонимът за locale.format. Можете да се обърнете към връзката по-долу за по-голяма яснота
1. https://observablehq.com/@d3/d3-format
2. http://bl.ocks.org/zanarmstrong /05c1e95bf7aa16c4768e
3. https://bl.ocks.org/zanarmstrong/raw/ca0adb7e426c12c06a95/
4. https://www.ibm.com/docs/en/cmofz/ 10.1.0?topic=SSQHWE_10.1.0/com.ibm.ondemand.mp.doc/arsa0257.htm

const formatDate = d3.timeFormat("%B %A %-d, %Y");
    tooltip.select("#date").text(formatDate(closestXValue));
    const formatInternetUsage = (d) => `${d3.format(".1f")(d)} GB`;
    tooltip.select("#internet").html(formatInternetUsage(closestYValue));
    const x = xScale(closestXValue) + dimensions.margin.left;
    const y = yScale(closestYValue) + dimensions.margin.top;
     //Grab the x and y position of our closest point, 
    //shift our tooltip, and hide/show our tooltip appropriately
    tooltip.style(
      "transform",
      `translate(` + `calc( -50% + ${x}px),` + `calc(-100% + ${y}px)` + `)`
    );
    tooltip.style("opacity", 1);
    tooltipCircle
      .attr("cx", xScale(closestXValue))
      .attr("cy", yScale(closestYValue))
      .style("opacity", 1);
    xAxisLine.attr("x", xScale(closestXValue));
  }
  function onMouseLeave() {
    tooltip.style("opacity", 0);
    tooltipCircle.style("opacity", 0);
  }
  // Add a circle under our tooltip, right over the “hovered” point
 
  const tooltip = d3.select("#tooltip"); 
  const tooltipCircle = bounds
    .append("circle")
    .attr("class", "tooltip-circle")
    .attr("r", 4)
    .attr("stroke", "#af9358")
    .attr("fill", "white")
    .attr("stroke-width", 2)
    .style("opacity", 0);

Забележка: Искаме да използваме .html() тук, за да гарантираме, че нашият символ за градуси ще бъде анализиран правилно.

В много случаи и където е възможно, наистина е най-добрата практика да се манипулират динамично класове чрез свойството className, тъй като крайният външен вид на всички куки за стилизиране може да се контролира в един лист със стилове. Критичните допълнения са блокът Const tooltip = …, където създаваме нашата подсказка, която е просто div, скрит по подразбиране и позициониран „абсолютно“ на всички елементи на страницата (използвайки висока стойност на z-индекс). Специални благодарности на Amelia Wattenberger за всичките й насоки

styles.css
.wrapper {
  position: relative;
}
.y-axis-label {
  fill: black;
  font-size: 1.4em;
  text-anchor: middle;
  transform: rotate(-90deg);
}
.listening-rect {
  fill: transparent;
}
body {
  display: flex;
  justify-content: center;
  padding: 5em 1em;
  font-family: sans-serif;
}
.dotted {
  stroke: #5c5c5c;
  stroke-dasharray: 1 1;
  fill: none;
}
.tooltip {
  opacity: 0;
  position: absolute;
  top: -14px;
  left: 0;
  padding: 0.6em 1em;
  background: #fff;
  text-align: center;
  line-height: 1.4em;
  font-size: 0.9em;
  border: 1px solid #ddd;
  z-index: 10;
  transition: all 0.1s ease-out;
  pointer-events: none;
}
.tooltip:before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 12px;
  height: 12px;
  background: white;
  border: 1px solid #ddd;
  border-top-color: transparent;
  border-left-color: transparent;
  transform: translate(-50%, 50%) rotate(45deg);
  transform-origin: center center;
  z-index: 10;
}
.tooltip-date {
  margin-bottom: 0.2em;
  font-weight: 600;
  font-size: 1.1em;
  line-height: 1.4em;
}
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
        <link rel="stylesheet" href="/bg./styles.css"></link>
    <title>My Line Chart</title>
</head>
<body>
        <div id="wrapper" class="wrapper">
        
            <div id="tooltip" class="tooltip">
                <div class="tooltip-date">
                    <span id="date"></span>
                </div>
                <div class="tooltip-Internet">
                    Internet Usage: <span id="internet"></span>
                </div>
            </div>
        
        </div>
    <script src="./../../d3.v5.js"></script>
    <script src="./chart.js"></script>
</body>
</html>
Chart.js
async function drawLineChart() {
  //1. Load your Dataset
  const dataset = await d3.csv("./../../Internet Usage.csv");
  //Check the sample values available in the dataset
  //console.table(dataset[0]);
  const yAccessor = (d) => d.InternetUsage;
  const dateParser = d3.timeParse("%d/%m/%Y");
  const xAccessor = (d) => dateParser(d["Bill Date"]);
  // Note : Unlike "natural language" date parsers (including JavaScript's built-in parse),
  // this method is strict: if the specified string does not exactly match the
  // associated format specifier, this method returns null.
  // For example, if the associated format is the full ISO 8601
  // string "%Y-%m-%dT%H:%M:%SZ", then the string "2011-07-01T19:15:28Z"
  // will be parsed correctly, but "2011-07-01T19:15:28", "2011-07-01 19:15:28"
  // and "2011-07-01" will return null, despite being valid 8601 dates.
  //Check the value of xAccessor function now
  //console.log(xAccessor(dataset[0]));
  // 2. Create a chart dimension by defining the size of the Wrapper and Margin
  let dimensions = {
    width: window.innerWidth * 0.8,
    height: 600,
    margin: {
      top: 115,
      right: 20,
      bottom: 40,
      left: 160,
    },
  };
  dimensions.boundedWidth =
    dimensions.width - dimensions.margin.left - dimensions.margin.right;
  dimensions.boundedHeight =
    dimensions.height - dimensions.margin.top - dimensions.margin.bottom;
  // 3. Draw Canvas
  const wrapper = d3
    .select("#wrapper")
    .append("svg")
    .attr("width", dimensions.width)
    .attr("height", dimensions.height);
  //Log our new Wrapper Variable to the console to see what it looks like
  //console.log(wrapper);
  // 4. Create a Bounding Box
  const bounds = wrapper
    .append("g")
    .style(
      "transform",
      `translate(${dimensions.margin.left}px,${dimensions.margin.top}px)`
    );
  // 5. Define Domain and Range for Scales
  const yScale = d3
    .scaleLinear()
    .domain(d3.extent(dataset, yAccessor))
    .range([dimensions.boundedHeight, 0]);
  // console.log(yScale(100));
  const referenceBandPlacement = yScale(100);
  const referenceBand = bounds
    .append("rect")
    .attr("x", 0)
    .attr("width", dimensions.boundedWidth)
    .attr("y", referenceBandPlacement)
    .attr("height", dimensions.boundedHeight - referenceBandPlacement)
    .attr("fill", "#ffece6");
  const xScale = d3
    .scaleTime()
    .domain(d3.extent(dataset, xAccessor))
    .range([0, dimensions.boundedWidth]);
  //6. Convert a datapoints into X and Y value
  // Note : d3.line() method will create a generator that converts
  // a data points into a d string
  // This will transform our datapoints with both the Accessor function
  // and the scale to get the Scaled value in Pixel Space
  const lineGenerator = d3
    .line()
    .x((d) => xScale(xAccessor(d)))
    .y((d) => yScale(yAccessor(d)));
  //.curve(d3.curveBasis);
  // 7. Convert X and Y into Path
  const line = bounds
    .append("path")
    .attr("d", lineGenerator(dataset))
    .attr("fill", "none")
    .attr("stroke", "Red")
    .attr("stroke-width", 2);
  //8. Create X axis and Y axis
  // Generate Y Axis
  const yAxisGenerator = d3.axisLeft().scale(yScale);
  const yAxis = bounds.append("g").call(yAxisGenerator);
  const yAxisLabel = yAxis
    .append("text")
    .attr("class", "y-axis-label")
    .attr("x", -dimensions.boundedHeight / 2)
    .attr("y", -dimensions.margin.left + 110)
    .html("Internet Usage (GB)");
  //9. Generate X Axis
  const xAxisGenerator = d3.axisBottom().scale(xScale);
  const xAxis = bounds
    .append("g")
    .call(xAxisGenerator.tickFormat(d3.timeFormat("%b,%y")))
    .style("transform", `translateY(${dimensions.boundedHeight}px)`);
  //10. Add a Chart Header
  wrapper
    .append("g")
    .style("transform", `translate(${50}px,${15}px)`)
    .append("text")
    .attr("class", "title")
    .attr("x", dimensions.width / 2)
    .attr("y", dimensions.margin.top / 2)
    .attr("text-anchor", "middle")
    .text("My 2020 Internet Usage(in GB)")
    .style("font-size", "36px")
    .style("text-decoration", "underline");
  // 11. Set up interactions
  const listeningRect = bounds
    .append("rect")
    .attr("class", "listening-rect")
    .attr("width", dimensions.boundedWidth)
    .attr("height", dimensions.boundedHeight)
    .on("mousemove", onMouseMove)
    .on("mouseleave", onMouseLeave);
  const xAxisLine = bounds
    .append("g")
    .append("rect")
    .attr("class", "dotted")
    .attr("stroke-width", "1px")
    .attr("width", ".5px")
    .attr("height", dimensions.boundedHeight);
  //.style("transform", `translate(${0}px,${-5}px)`);
  function onMouseMove() {
    const mousePosition = d3.mouse(this);
    const hoveredDate = xScale.invert(mousePosition[0]);
    const getDistanceFromHoveredDate = (d) =>
      Math.abs(xAccessor(d) - hoveredDate);
    const closestIndex = d3.scan(
      dataset,
      (a, b) => getDistanceFromHoveredDate(a) - getDistanceFromHoveredDate(b)
    );
    const closestDataPoint = dataset[closestIndex];
    console.table(closestDataPoint);
    const closestXValue = xAccessor(closestDataPoint);
    const closestYValue = yAccessor(closestDataPoint);
    const formatDate = d3.timeFormat("%B %A %-d, %Y");
    tooltip.select("#date").text(formatDate(closestXValue));
    const formatInternetUsage = (d) => `${d3.format(".1f")(d)} GB`;
    tooltip.select("#internet").html(formatInternetUsage(closestYValue));
    const x = xScale(closestXValue) + dimensions.margin.left;
    const y = yScale(closestYValue) + dimensions.margin.top;
    //Grab the x and y position of our closest point,
    //shift our tooltip, and hide/show our tooltip appropriately
    tooltip.style(
      "transform",
      `translate(` + `calc( -50% + ${x}px),` + `calc(-100% + ${y}px)` + `)`
    );
    tooltip.style("opacity", 1);
    tooltipCircle
      .attr("cx", xScale(closestXValue))
      .attr("cy", yScale(closestYValue))
      .style("opacity", 1);
    xAxisLine.attr("x", xScale(closestXValue));
  }
  function onMouseLeave() {
    tooltip.style("opacity", 0);
    tooltipCircle.style("opacity", 0);
  }
  // Add a circle under our tooltip, right over the “hovered” point
  const tooltip = d3.select("#tooltip");
  const tooltipCircle = bounds
    .append("circle")
    .attr("class", "tooltip-circle")
    .attr("r", 4)
    .attr("stroke", "#af9358")
    .attr("fill", "white")
    .attr("stroke-width", 2)
    .style("opacity", 0);
}
drawLineChart();

ЗАКЛЮЧЕНИЕ

В този урок се запознахте със събитията на мишката, които можете да използвате в D3 визуализации. Събитията с мишката се предизвикват/задействат в резултат на различни потребителски взаимодействия. Препоръчително е да се запознаете с различните налични събития на мишката и тяхното предназначение, така че да можете да добавите допълнително измерение към вашите визуализации на данни.

Тук разгледахме много, но основните принципи са относително прости. В следващата си публикация в блога ще разгледам как да създам няколко линейни диаграми и да добавя легенда. След като преодолеете първоначалния дискомфорт от изучаването на основата на D3, можете да избирате измежду хиляди типове диаграми в D3 от примерни галерии на D3 и да ги модифицирате според собствените си нужди.

Опитахме се да покрием колкото се може повече, за да може един начинаещ да започне с D3.js. Надявам се да ви хареса. Както винаги, приветстваме отзивите и градивната критика. Ако ви е харесал този блог, ще се радваме да натиснете бутона за споделяне, така че други да могат да се натъкнат на него. Моля, натиснете и бутона за абониране, ако искате да бъдете добавени към моя списък с имейли веднъж седмично и не забравяйте да следвате Vizartpandey в Instagram!

Също така, ето няколко ръчно подбрани статии, които да прочетете по-нататък: