Kevin Py
Kevin Py

Reputation: 2468

Code doesn't work when upgrading from v3 to v5

when I upgrade d3.js from v3.5 to 5.9.2 (the latest actually), my graph display correctly, but the legend items doesn't display. In my code, the data exist, but I have only <div class="legend"></div> without inner <div data-id="DATA">DATA</div>. I don't know if the code below is correct for v5. Thank you for your help.

d3.select(".segLegend")
  .insert("div", ".chart")
  .attr("class", "legend")
  .selectAll("div")
  .data(names)
  .sort()
  .enter()
  .append("div")
  .attr("data-id", function(id) {
  return id;
})
  .each(function(id) {
  d3.select(this)
    .append("span")
    .style(
    "background-color",
    $scope.openGraphModal.chart.color(id)
  );
  d3.select(this)
    .append("span")
    .html(id);
  if (id !== findSupplier.commodity.supplier.name) {
    $(this).toggleClass('c3-legend-item-hidden');
  }
})

The DOM with V3 enter image description here The DOM with V5 enter image description here

Upvotes: 2

Views: 279

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102194

At a first and quick look this is a strange problem, hard to identify, because in a D3 code we don't use the sort method at the position you did: at that position, that sort is worthless. Have a look (using v3):

const data = [1,3,5,4,2];
const divs = d3.select("body")
  .selectAll(null)
  .data(data)
  .sort()
  .enter()
  .append("div")
  .html(Number)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>

As you can see, nothing is sorted. The sort method should be used after appending the real DOM elements (again, v3):

const data = [1, 3, 5, 4, 2];
const divs = d3.select("body")
  .selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .sort()
  .html(Number)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>

Finally, sort at this correct position works with v5 as well:

const data = [1, 3, 5, 4, 2];
const divs = d3.select("body")
  .selectAll(null)
  .data(data)
  .enter()
  .append("div")
  .sort()
  .html(Number)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Your problem

When you put sort in that strange (and useless) position in the enter selection in a code that uses D3 v4/5, not only it doesn't sort anything but, the most important, it avoids the DOM elements being appended:

const data = [1, 3, 5, 4, 2];
const divs = d3.select("body")
  .selectAll(null)
  .data(data)
  .sort()
  .enter()
  .append("div")
  .html(Number)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

The snippet remains blank.

The solution is moving the sort to the correct position, not only because of the problem you're facing but also because, where it is right now, it's useless in v3 as well.

Upvotes: 2

Related Questions