При создании графиков мне нужно установить данные. Эти данные (массив объектов) у меня уже есть в 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 есть данные для отображения в собственном атрибуте данных.
Или мой подход неправильный, и я буду использовать другой подход?
Спасибо за ваши ответы.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Невозможно просто указать 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.
Использование 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>
Обновление 2019, см. Ответ для современных браузеров и использования JSON на
data-stuff.