Как изменить порядок рисования элементов в зависимости от индекса точки данных? - PullRequest
1 голос
/ 18 января 2020

Я рисую несколько элементов для каждого элемента данных, которые я использую в своем d3. js datavizualization. Это создает простой список элементов, основанный на данных. Он выводит следующее:

<div>
  <p>[Title of datapoint 1]</p>
  <svg>[SVG using datapoint 1]</svg>
</div>
<div>
  <p>[Title of datapoint 2]</p>
  <svg>[SVG using datapoint 2]</svg>
</div>
<div>
  <p>[Title of datapoint 3]</p>
  <svg>[SVG using datapoint 3]</svg>
</div>
<div>
  <p>[Title of datapoint 4]</p>
  <svg>[SVG using datapoint 4]</svg>
</div>
<div>
  <p>[Title of datapoint 5]</p>
  <svg>[SVG using datapoint 5]</svg>
</div>

Для большинства людей это именно то, что они хотят.

Однако я пытаюсь добиться того, чтобы иметь возможность изменить порядок рисования, например, каждый четный объект данных должен начинаться с тега SVG и заканчиваться тегом p. Что будет выглядеть так:

<div>
  <p>[Title of datapoint 1]</p>
  <svg>[SVG using datapoint 1]</svg>
</div>
<div>
  <svg>[SVG using datapoint 2]</svg>
  <p>[Title of datapoint 2]</p>
</div>
<div>
  <p>[Title of datapoint 3]</p>
  <svg>[SVG using datapoint 3]</svg>
</div>
<div>
  <svg>[SVG using datapoint 4]</svg>
  <p>[Title of datapoint 4]</p>
</div>
<div>
  <p>[Title of datapoint 5]</p>
  <svg>[SVG using datapoint 5]</svg>
</div>

Обратите внимание, что порядок черчения изменился как для точки данных 2, так и для 4

Может кто-нибудь сказать мне, если d3. js предлагает способ достичь этого или вы можете сказать мне, как бы вы решили эту проблему самостоятельно?

1 Ответ

0 голосов
/ 19 января 2020

К сожалению, вы не поделились своим кодом, поэтому мы не можем его реорганизовать.

Поэтому я напишу ответ, используя selection.each, что, возможно, является идиоматическим решением c D3 в вашем случае. , Единственная важная вещь здесь - это передача индексов оператору остатка, как i % 2, который возвращает true (1) для нечетных индексов и false (0) для четных индексов. Затем, используя if, мы можем выбрать, какие элементы будут добавлены. Например:

.each(function(_, i) {
    if (i % 2) {
        appendSvg(d3.select(this))
        appendParagraph(d3.select(this))
    } else {
        appendParagraph(d3.select(this))
        appendSvg(d3.select(this))
    }
});

В этом случае я использую две разные функции, которым я передаю текущий выбор, но вы можете просто использовать имеющиеся у вас блоки (хотя и более повторяющийся код).

Вот демоверсия:

const body = d3.select("body");

const divs = body.selectAll(null)
  .data(d3.range(5))
  .enter()
  .append("div")
  .each(function(_, i) {
    if (i % 2) {
      appendSvg(d3.select(this))
      appendParagraph(d3.select(this))
    } else {
      appendParagraph(d3.select(this))
      appendSvg(d3.select(this))
    }
  });

function appendSvg(sel) {
  sel.append("svg")
    .attr("width", 80)
    .attr("height", 20);
};

function appendParagraph(sel) {
  sel.append("p")
    .html("This is a p element")
};
div {
  display: inline-block;
  margin-right: 10px;
  border: 1px solid gray;
  padding: 2px;
}

svg {
  background-color: tan;
}

p {
  font-size: 12px;
  margin-bottom: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...