0

I have a method in React, drawChart(), which should generate a pie chart SVG. However React is throwing a TypeError of "d is undefined" and highlighting my "svg" line (see below)

const drawChart = () => {
    const data = {'protein': 16, 'fat': 36, 'carbs':45} // sample data

    const width = 80;
    const height = 80;

    const colorScale = d3.scaleOrdinal()
                          .domain(data)
                          .range(d3.schemeCategory10);

    const svg = d3.select("#graph")
      .append("svg")
        .attr("width", width)
        .attr("height", height)
      .append("g")
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


    const arcs = d3.pie()
                    .value(d => d.value)(data);
    const path = d3.arc()
                    .innerRadius(0)
                    .outerRadius(width / 2);

    svg  // this is getting highlighted in the React error output
      .selectAll('.arc')
      .data(arcs)
      .enter()
      .append('path')
        .classed('arc', true)
        .attr('fill', d => {
          if (d.properties) {
            colorScale(d.data.key)
          }
        })
        .attr('stroke', 'black')
        .attr('d', path);
  }
0

1 Answer 1

1

That is because of the following issues:

1) The data structure of the data object you have provided do not match the format on your data joins. I would recommend you to use an array of objects, instead of a dictionary.

2) You are filling the colours wrongly. This is your original code.

.attr('fill', d => {
  if (d.properties) {
    colorScale(d.data.key)
  }
});

properties is not a valid key of d. If you want to check for the presence of a valid key and value, you should be using the data property instead(d.data). In addition, you are not returning any colour values from thecolourScale` anonymous function.

To fix it, this is what you should be doing instead:

.attr('fill', d => {
  if (d.data) {
    return colorScale(d.data.value);
  }
})

The full code is available below:

const data = [{
    name: 'protein',
    value: 16,
  },
  {
    name: 'fat',
    value: 36,
  },
  {
    name: 'carbs',
    value: 45,
  }
];

const width = 80;
const height = 80;

const colorScale = d3.scaleOrdinal()
  .domain(data)
  .range(d3.schemeCategory10);

const svg = d3.select("#graph")
  .append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


const arcs = d3.pie()
  .value(d => d.value)(data);
const path = d3.arc()
  .innerRadius(0)
  .outerRadius(width / 2);

svg
  .selectAll("path")
  .data(arcs)
  .enter()
  .append('path')
  .classed('arc', true)
  .attr('fill', d => {
    if (d.data) {
      return colorScale(d.data.value);
    }
  })
  .attr('stroke', 'black')
  .attr('d', path);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.min.js"></script>

<div id="graph"></div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.