D3 js устанавливает данные из атрибута данных

При создании графиков мне нужно установить данные. Эти данные (массив объектов) у меня уже есть в HTML, например:

<svg  class = "graph-n" data-stuff = "{simplified data}"></svg>

Затем с помощью Javascript и D3 JS я инициализирую и настраиваю графики с помощью следующего кода:

<script>
    var margin = { top: 20, right: 20, bottom: 30, left: 50},
        width = 1500 - margin.left - margin.right,
        height = 350 - margin.top - margin.bottom;

    var x = d3.scaleTime().range([0, width]);
    var y = d3.scaleLinear().range([height, 0]);


    var valueline = d3.line()
        .x(function(d) { return x(new Date(d.t)); })
        .y(function(d) { return y(d.y); });

    var svg = d3.selectAll(".graph-n")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


        x.domain(d3.extent(data, function(d) { return new Date(d.t); }));
        y.domain([0, d3.max(data, function(d) { return d.y; })]);

        svg.append("path")
            .attr("class", "line")
            .attr("d", valueline);

        svg.append("g")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x));

        svg.append("g")
            .call(d3.axisLeft(y));
</script>

Вопрос в том, как я могу сказать, что данные находятся внутри каждого элемента во время выбора в атрибуте данных data-stuff? У каждого SVG есть данные для отображения в собственном атрибуте данных.

Или мой подход неправильный, и я буду использовать другой подход?

Спасибо за ваши ответы.

Обновление 2019, см. Ответ для современных браузеров и использования JSON на data-stuff.

Peter Krauss 17.08.2019 23:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
3 387
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Невозможно просто указать d3 явно «брать данные из этого атрибута». Однако вы можете установить данные программно, загрузив их из выбранного вами атрибута. Есть несколько способов достижения этого, как показано на этих примерах выбора (они используют <ul> и <li> для простоты, <svg> используется аналогично):

// the pure D3 way
d3.selectAll("ul.d3-pure")                // select the element
    .datum(function() { return this.getAttribute("data-list").split(",")}) // set selection's data based on its data attribute
    .selectAll("li")                      // create new selection
        .data((d) => d)                   // set the data from the parent element
        .enter().append("li")             // create missing elements
            .text((content) => content);  // set elements' contents

// the DOM way      
var domUls = document.querySelectorAll("ul.dom");     // select elements
for(var i = 0; i < domUls.length; i++) {              // iterate over those elements
    const ul = domUls[i];
    const d3_ul = d3.select(ul);                      // create D3 object from the node
    const data = ul.getAttribute("data-list").split(",");
    d3_ul.selectAll("li").data(data)                  // create new selection and assign its data
        .enter().append("li")                         // create missing elements
            .text((content) => content)               // set elements' content
}

// the hybrid D3-DOM way
d3.selectAll("ul.d3-hybrid")                // select elements
    .each(function() {                      // iterate over each node of the selection
        const ul = d3.select(this);         // "this" is the "ul" HTML node
        const data = ul.attr("data-list").split(",");
        ul.selectAll("li").data(data)       // create new selection, assign its data
            .enter().append("li")           // create missing elements
                .text((content) => content) // set elements' content
        });
<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<ul class = "d3-pure" data-list = "1,2,3">
</ul>
<ul class = "dom" data-list = "a,b,c">
</ul>
<ul class = "d3-hybrid" data-list = "I,II,III">
</ul>

Хороший ответ! Вы также можете рассмотреть возможность использования для этого малоизвестного свойства набор данных, которое обеспечивает легкий доступ к настраиваемые атрибуты данныхdata-* элемента. Вместо this.getAttribute("data-list") вы можете использовать this.dataset.list.

altocumulus 17.05.2018 20:30

Современные браузеры принимают набор данных node ().

Использование D3_selection.node() и чистое свойство DOM-узла Javascript набор данных, как ранее комментировал @altocumulus.

Это старый стандарт Javascript для элементов HTML (начиная с Chorme 8 и Firefox 6), но новое для SVG (начиная с Chorme 55 и Firefox 51).

Значения ключей и значений набора данных являются чистыми строками, но Хорошая практика - принять строковый формат JSON для нестроковых типов данных, чтобы анализировать их с помощью JSON.parse().

Используй это

Фрагмент кода для наборов данных "ключ-значение" получать и набор в HTML и SVG.

console.info("-- GET values --")
var x = d3.select("#html_example").node().dataset;
console.info("s:", x.s );
for (var i of JSON.parse(x.list)) console.info("list_i:",i)

var y = d3.select("#svg_example g").node().dataset;
console.info("s:", y.s );
for (var i of JSON.parse(y.list)) console.info("list_i:",i)

console.info("-- SET values --");
y.s = "BYE!"; y.list = "null";
console.info( d3.select("#svg_example").node().innerHTML )
<script src = "https://d3js.org/d3.v5.min.js"></script>
<p id = "html_example" data-list = "[1,2,3]" data-s = "Hello123">Hello dataset!</p>
<svg id = "svg_example">
  <g data-list = "[4,5,6]" data-s = "Hello456 SVG"></g>
</svg>

Другие вопросы по теме