2

I'm trying to create a d3 area chart but nothing is being displayed. My guess is something wrong with xScale. I can see a path being added to the DOM, however d attribute is absent. What am I doing wrong?

// Area chart width and height
const width = 500,
  height = 100;

//Define x and y scale for area chart
const xScale = d3.scaleLinear().range([0, width]);
const yScale = d3.scaleLinear().range([height, 0]);

// Add SVG to #areachart
const svg = d3
  .select('#areachart')
  .append('svg')
  .attr('width', width)
  .attr('height', height);

const g = svg.append('g');

// Fetch data
d3.json('https://data.london.gov.uk/api/table/s8c9t_j4fs2?$offset=7600')
  .then(function(data) {

    //Define xScale & yScale domain after data loaded
    yScale.domain([
      0,
      d3.max(data, function(d) {
        return +d.total_cases;
      }),
    ]);

    xScale.domain(
      d3.extent(data, function(d) {
        return +d.new_cases;
      })
    );
    // Area  generator
    const area = d3
      .area()
      .curve(d3.curveBasis)
      .x((d) => xScale1(+d.new_cases))
      .y0((d) => yScale1(d.y0))
      .y1((d) => yScale1(d.y0 + d.y));

    console.log('data:', data.rows);

    g.selectAll('g')
      .data(data)
      .enter()
      .append('g')
      .append('path')
      .classed('line', true)
      .attr('d', area)
      .style('fill', 'red');
  })
  // if there's an error, log it
  .catch((error) => console.log(error));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.2/d3.min.js"></script>
<section id="map">
  <div id="visualisation-container">
    <div id="visualisation"></div>
    <div id="areachart"></div>
  </div>
</section>
Ruben Helsloot
  • 12,582
  • 6
  • 26
  • 49
Alina Khachatrian
  • 757
  • 1
  • 6
  • 19

1 Answers1

2

Your major problems were these:

  • You used d3.max(data, but data was not an array. I took data.rows in a previous .then(, which fixed this;
  • You used selectAll, creating one path per data point. For an area chart, you actually need only one path, or at least one per area. I changed that from .data().enter() to .datum();
  • You used the values d.y0 and d.y, which do not exist on the data object;
  • You didn't provide the area with a stroke, only with a fill. If the area has no filling, that doesn't work.

I'm not saying that this is better, because the data is not ordered, but at least you now see something.

// Area chart width and height
const width = 500,
  height = 100;

//Define x and y scale for area chart
const xScale = d3.scaleLinear().range([0, width]);
const yScale = d3.scaleLinear().range([height, 0]);

// Add SVG to #areachart
const svg = d3
  .select('#areachart')
  .append('svg')
  .attr('width', width)
  .attr('height', height);

const g = svg.append('g');

// Fetch data
d3.json('https://data.london.gov.uk/api/table/s8c9t_j4fs2?$offset=7600')
  .then(response => response.rows)
  .then(function(data) {

    //Define xScale & yScale domain after data loaded
    yScale.domain([
      0,
      d3.max(data, function(d) {
        return +d.total_cases;
      }),
    ]);

    xScale.domain(
      d3.extent(data, function(d) {
        return +d.new_cases;
      })
    );

    // Area  generator
    const area = d3
      .area()
      .curve(d3.curveBasis)
      .x((d) => xScale(+d.new_cases))
      .y((d) => yScale(+d.total_cases));

    g.append('g')
      .datum(data)
      .append('path')
      .classed('line', true)
      .attr('d', area)
      .style('stroke', 'red')
      .style('fill', 'red');
  })
  // if there's an error, log it
  .catch((error) => console.log(error));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.2/d3.min.js"></script>
<section id="map">
  <div id="visualisation-container">
    <div id="visualisation"></div>
    <div id="areachart"></div>
  </div>
</section>
Ruben Helsloot
  • 12,582
  • 6
  • 26
  • 49
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222858/discussion-between-ruben-helsloot-and-alina-khachatrian). – Ruben Helsloot Oct 11 '20 at 13:33