Поведение синтаксиса цепочки при генерации осей - PullRequest
2 голосов
/ 12 апреля 2019

Я пишу код d3.js (d3 v4) для генерации простой гистограммы, что мне удалось сделать, но я запутался в поведении кода при генерации осей.

Итак, по сути, я инкапсулировал код диаграммы в функцию, содержащую основные методы доступа.

Вот код, показывающий ядро ​​моей функции диаграммы.

function chart(selection){
      selection.each(function(data){

        var x = d3.scale.ordinal().rangeRoundBands([0, width], 0.5);
        var y = d3.scale.linear().range([height, 0]);

        var xAxis = d3.svg.axis()
          .scale(x)
          .orient("bottom");

        var yAxis = d3.svg.axis()
          .scale(y)
          .orient("left")
          .ticks(10);

        x.domain(data.map(function(d) { return d.name; }));
        y.domain([0, d3.max(data, function(d) { return d.value; })]);

        var div = d3.select(this)
        var svg = div.selectAll("svg")
          .data([data]).enter()
          .append("svg")
          .attr("width", width + margin.left + margin.right)
          .attr("height", height + margin.top + margin.bottom)
          .append("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        svg.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis)
          .selectAll("text")
          .style("text-anchor", "end")
          .attr("dx", "-.8em")
          .attr("dy", "-.55em")
          .attr("transform", "rotate(-90)" );

        svg.append("g")
          .attr("class", "y axis")
          .call(yAxis)
          .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 5)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Frequency");

        svg.selectAll(".bar")
          .data(data)
          .enter().append("rect")
          .attr("class", "bar")
          .attr("fill", "#1CE6FF")
          .attr("x", function(d) { return x(d.name); })
          .attr("width", x.rangeBand())
          .attr("y", function(d) { return y(d.value); })
          .attr("height", function(d) { return height - y(d.value); });
      });

Итак, у меня два вопроса: 1) Можно ли использовать несколько блоков кода, вызывая svg.append ("g"), как показано выше в коде? 2) Когда я заменяю следующий код:

var svg = div.selectAll("svg")
          .data([data]).enter()
          .append("svg")
          .attr("width", width + margin.left + margin.right)
          .attr("height", height + margin.top + margin.bottom)
          .append("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        svg.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis)
          .selectAll("text")
          .style("text-anchor", "end")
          .attr("dx", "-.8em")
          .attr("dy", "-.55em")
          .attr("transform", "rotate(-90)" );

При этом (который в основном объединяет два блока в один фрагмент кода цепочки):

var svg = div.selectAll("svg")
          .data([data]).enter()
          .append("svg")
          .attr("width", width + margin.left + margin.right)
          .attr("height", height + margin.top + margin.bottom)
          .append("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")").append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis)
          .selectAll("text")
          .style("text-anchor", "end")
          .attr("dx", "-.8em")
          .attr("dy", "-.55em")
          .attr("transform", "rotate(-90)" );

... почему моя ось y не отображается в нужном месте? Тег <g class="y axis">...</g> кажется вложенным в сам тег <text>, вложенный в тег оси x. Почему двухблочный код и одноблочный код не ведут себя одинаково?

1 Ответ

2 голосов
/ 12 апреля 2019

Структура кода определяет структуру результирующего SVG. В функции chart() переменная svg содержит ссылку на последний добавленный <g>, а не на сам ранее добавленный <svg>. Обратите внимание, как все операторы после первого создания добавляются к той же внешней группе svg. Это один прекрасный способ сделать это.

Однако, если вы объедините операторы, как вы делали в последнем фрагменте, значение svg изменится, потому что меняется правая часть, то есть возвращаемое значение выражения. Поскольку вы в последний раз выбирали все текстовые элементы добавленной оси X *, 1009 * содержит именно эти тексты. Учитывая это, довольно легко понять, что это нарушает остальную часть кода, который теперь добавит другое содержимое к текстовым элементам. Даже если бы он был синтаксически верным, а это не так, он, скорее всего, все равно нарушил бы макет.

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

...