d3js: порядковая шкала с уникальными метками [duplicate]

Как отметил @FelixKling, наиболее вероятным сценарием является то, что узлы, которые вы ищете, еще не существуют.

Однако современные методы разработки часто могут манипулировать элементами документа за пределами дерева документов либо с DocumentFragments, либо просто отсоединением / повторным подключением текущих элементов напрямую. Такие методы могут использоваться как часть шаблонов JavaScript или для предотвращения чрезмерных операций перерисовки / переплавки, в то время как элементы, о которых идет речь, сильно изменяются.

Аналогично, новая функциональность «Теневой DOM» развертывается в современных браузерах позволяет элементам быть частью документа, но не обрабатываться запросом document.getElementById и всеми его методами sibling (querySelector и т. д.). Это делается для инкапсуляции функциональных возможностей и, в частности, скрыть его.

Опять же, скорее всего, элемент, который вы ищете, просто (пока) в документе, и вы должны сделать, как предлагает Феликс , Тем не менее, вы также должны знать, что это все чаще является не единственной причиной того, что элемент может быть необоснованным (временно или постоянно).

3
задан OriWei 24 July 2013 в 18:58
поделиться

2 ответа

Проблема с вашим кодом заключается в том, что вы пытаетесь использовать значения из вашего массива data для создания диапазонов диапазонов в порядковой шкале. Поскольку одно и то же входное значение всегда будет сопоставлено с тем же выходным значением, что означает, что оба входа 16 отображаются в один диапазон диапазона 72.

Если вы хотите, чтобы каждое входное значение отображалось на его собственный «бар», тогда вам нужно использовать индексы массива вместо значений массива.

Сначала вы готовите индексы

var indices = d3.range(0, data.length);    // [0, 1, 2, ..., data.length-1]

Затем вы используете их для определения шкалы y domain

var y = d3.scale.ordinal()
    .domain(indices)
    // use rangeRoundBands instead of rangeBands when your output units
    // are pixels (or integers) if you want to avoid empty line artifacts
    .rangeRoundBands([0, chartHeight]);  

Наконец, вместо использования значений массива в качестве входных данных используются индексы массивов при сопоставлении с y

chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("y", function (value, index) { 
        // use the index as input instead of value; y(index) instead of y(value)
        return y(index); 
    })
    .attr("width", x)
    .attr("height", y.rangeBand());

. В качестве дополнительного бонуса этот код автоматически изменит масштаб диаграммы если количество данных изменяется или вы решите изменить ширину или высоту диаграммы.

Вот демон jsFiddle: http://jsfiddle.net/q8SBN/1/

Полный код:

var data = [4, 8, 15, 16, 23, 16];
var indices = d3.range(0, data.length);

var chartWidth = 420;
var chartHeight = 120;

var chart = d3.select("body").append("svg")
     .attr("class", "chart")
     .attr("width", chartWidth)
     .attr("height", chartHeight);

var x = d3.scale.linear()
     .domain([0, d3.max(data)])
     .range([0, chartWidth])

var y = d3.scale.ordinal()
     .domain(indices)
     .rangeRoundBands([0, chartHeight]);

chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("y", function (value, index) { return y(index); })
    .attr("width", x)
    .attr("height", y.rangeBand());
9
ответ дан Ma3x 18 August 2018 в 22:50
поделиться
  • 1
    теперь это работает, спасибо! – OriWei 24 July 2013 в 22:28
  • 2
    @OriWei: Если какой-либо из представленных здесь ответов будет работать для вас, вы должны перенести их и принять один из них. – Ma3x 24 July 2013 в 22:30

Способ установки атрибута y для прямоугольников будет использовать одинаковое значение для всех повторяющихся элементов. Вы можете использовать некоторые смещения так:

chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("y", function (d, i) {
       return (i * y.rangeBand()) + y.rangeBand();})
    .attr("width", x)
    .attr("height", y.rangeBand());

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

0
ответ дан Satyajit 18 August 2018 в 22:50
поделиться