I am trying to make a rectangle svg inside a wrapper svg div but somehow I am getting two or sometimes multiple svg wrapper div. I am guessing that one is created when data isn't available and another when useEffect refresh component when data loads but I might be wrong. I don't know why its happening there might be a silly mistake or logical mistake I am new in learning D3 so forgive me and guide me. Please help. below is the code. Thank You
import React, { useState, useEffect } from 'react';
import * as d3 from 'd3';
const LineChart = () => {
const weatherDataUrl =
'https://gist.githubusercontent.com/anujshaanmydash/17687a309a87105ab8991a3dcfd8c7e3/raw/weatherData.json';
const [data, setData] = useState(null);
useEffect(() => {
d3.json(weatherDataUrl).then(setData);
}, []);
if (!data) {
return <pre>Loading....</pre>;
}
console.log(data);
const yAccessor = (d) => d.temperatureMax;
const dateParser = d3.timeParse('%Y-%m-%d');
const xAccessor = (d) => dateParser(d.date);
let dimensions = {
width: 1200,
height: 500,
margins: {
top: 15,
right: 15,
bottom: 30,
left: 50,
},
};
dimensions.boundedWidth =
dimensions.width - dimensions.margins.left - dimensions.margins.right;
dimensions.boundedHeight =
dimensions.height - dimensions.margins.top - dimensions.margins.bottom;
const wrapper = d3
.select('#Wrapper')
.append('svg')
.attr('width', dimensions.width)
.attr('height', dimensions.height);
const bounds = wrapper
.append('g')
.style(
'transform',
`translate(${dimensions.margins.left}px,${dimensions.margins.top}px)`
);
//Create Scales
const yScale = d3
.scaleLinear()
.domain(d3.extent(data, yAccessor))
.range([dimensions.boundedHeight, 0]);
const freezingTempArea = yScale(32);
const freezingTemp = bounds
.append('rect')
.attr('x', 0)
.attr('width', dimensions.boundedWidth)
.attr('y', freezingTempArea)
.attr('height', dimensions.boundedHeight - freezingTempArea)
.attr('fill', '#e0f3f3');
const xScale = d3
.scaleTime()
.domain(d3.extent(data, xAccessor))
.range(0, dimensions.boundedWidth);
return <div id='Wrapper'></div>;
};
export default LineChart;
Most probably its a <StrictMode> issue (index.js). Some functions like useEffect are double-invoked in development mode.
You can see that data is logged twice on console due to this.
How to avoid this? @Dan Abramov
useEffect(() => {
let ignore = false;
fetchStuff().then(res => {
if (!ignore) setResult(res)
})
return () => { ignore = true }
}, [])
Read more here - https://github.com/facebook/react/issues/24502