Friday, 16 July 2021

How to create line chart with JSON data using D3

I am working with D3.js and react-hooks to create charts, So I tried creating one Line chart by searching around and got one.

  • But the one I am working with is using Sample data, here in my case I have JSON data.
  • I have made the charts responsive as well using resize-observer-polyfill this library.
  • Now I am struggling to implement it with JSON data, to renders it with dynamic data.

What I did

const svgRef = useRef();
const wrapperRef = useRef();
const dimensions = useResizeObserver(wrapperRef); // for responsive

// will be called initially and on every data change
useEffect(() => {
    const svg = select(svgRef.current);
    const { width, height } =
        dimensions || wrapperRef.current.getBoundingClientRect();

    // scales + line generator
    const xScale = scaleLinear()
        .domain([0, data.length - 1]) // here I need to pass the data
        .range([0, width]);

    const yScale = scaleLinear()
        .domain([0, max(data)])
        .range([height, 0]);

    const lineGenerator = line()
        .x((d, index) => xScale(index))
        .y((d) => yScale(d))
        .curve(curveCardinal);

    // render the line
    svg
        .selectAll('.myLine')
        .data([data])
        .join('path')
        .attr('class', 'myLine')
        .attr('stroke', 'black')
        .attr('fill', 'none')
        .attr('d', lineGenerator);

    svg
        .selectAll('.myDot')
        .data(data)
        .join('circle')
        .attr('class', 'myDot')
        .attr('stroke', 'black')
        .attr('r', (value, index) => 4)
        .attr('fill', (value, index) => 'red')
        .attr('cx', (value, index) => xScale(index))
        .attr('cy', yScale);

    // axes
    const xAxis = axisBottom(xScale);
    svg
        .select('.x-axis')
        .attr('transform', `translate(0, ${height})`)
        .call(xAxis);

    const yAxis = axisLeft(yScale);
    svg.select('.y-axis').call(yAxis);
}, [data, dimensions]);

    <React.Fragment>
        <div ref={wrapperRef} style=>
            <svg ref={svgRef}>
                <g className="x-axis" />
                <g className="y-axis" />
            </svg>
        </div>
    </React.Fragment>

Here I am not able to pass the data, my data is below

[
  { anno: 2014, consumo: 300, color: "#ff99e6" },
  { anno: 2015, consumo: 290, color: "blue" },
  { anno: 2016, consumo: 295, color: "green" },
  { anno: 2017, consumo: 287, color: "yellow" },
  { anno: 2018, consumo: 282, color: "red" },
  { anno: 2019, consumo: 195, color: "white" }
]

Here in my data I have color for each data, which I want to show in each dot generated.

working code sandbox of line chart

Similarly I tried doing bar chart and it is working fine

I did some dynamic rendering to labels, when we resize the window the labels gets adjusted automatically.

Here is the full working bar chart what I am trying to implement to line chart

I have also commented the lines where I am doing what.



from How to create line chart with JSON data using D3

No comments:

Post a Comment