'Why axisBottom result wrong position if my data contain date minute?
I found that my point circle and axis bottom positions don't match if the timesamp contains minutes like "2021-11-23T15:20:54,000Z". But if I use the time without the minutes the bottom axis is in the right position for example " '2022-02-01T00:00:00.000Z'.
const chartRef = useRef<SVGSVGElement | null>(null);
const margin = {
top: 5,
right: 20,
bottom: 20,
left: 30,
};
const parseTime = timeParse('%Y-%m-%dT%H:%M:%S.%LZ');
let values: ChartData[] = [];
const parsedData: ParsedData[] = [];
const obj: any = new Object();
dataLineChart.forEach((d) => {
values.push(d);
});
obj.values = values;
parsedData.push(obj);
const width = widthSVG - margin.left - margin.right;
const height = heightSVG - margin.top - margin.bottom;
const minDate = min(parsedData[0].values, (d) => parseTime(d.timestamp));
const maxDate = max(parsedData[0].values, (d) => parseTime(d.timestamp));
const minValue = min(parsedData[0].values, (v) => v.value);
const maxValue = max(parsedData[0].values, (v) => v.value);
let xScale, yScale;
if (minDate && maxDate) {
xScale = scaleTime().domain([minDate, maxDate]).range([0, width]);
}
if (minValue && maxValue) {
yScale = scaleLinear().domain([minValue, maxValue]).range([height, 0]);
}
const lineGenerator = line<ChartData>()
.x((d) => xScale(parseTime(d.timestamp)))
.y((d) => yScale(d.value))
.curve(curveCatmullRom.alpha(0.5));
useEffect(() => {
const svg = select(chartRef.current)
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.attr('fill', '#d5d5d5');
svg.append('defs');
svg.call(createGradient, [chartColor]);
svg.call(createGlowFilter);
svg
.selectAll('line')
.data(parsedData)
.enter()
.append('path')
.attr('d', (d) => {
const v = d.values as ChartData[];
const lineValues = lineGenerator(v)?.slice(1);
const splitedValues = lineValues?.split(',') as string[];
let path: string = '';
if (splitedValues.length > 0) {
path = `M0,${height},${lineValues},l0,${
height - parseInt(splitedValues[splitedValues.length - 1])
}`;
}
return path;
})
.style('fill', `url(${chartColor})`)
.attr('y2', `-${height}px`);
svg
.selectAll('line')
.data(parsedData)
.enter()
.append('path')
.attr('d', lineGenerator(parsedData[0].values))
.attr('stroke-width', 1)
.style('fill', 'none')
.style('filter', 'url(#glow)')
.attr('stroke', chartColor);
const tick = svg
.append('g')
.attr('transform', `translate(0, ${height})`)
.call(axisBottom(xScale).ticks(timeHour.every(1), '%H'))
.selectAll('.tick')
.style('transition', '.2s');
tick.selectAll('text').attr('fill', '#A1A1A1');
tick.selectAll('line').remove();
tick
.append('circle')
.attr('r', '1.5')
.style('fill', '#A1A1A1')
.attr('cy', '0');
svg
.selectAll('.tick')
.append('circle')
.attr('r', 2)
.style('fill', chartColor)
.attr('cy', (x, i) => -height + yScale(parsedData[0].values[i].value));
const setFade = (selection, opacity) => {
selection.style('opacity', opacity);
};
const mouseover = (event, elements) => {
selectAll(elements).filter(':not(:hover)').call(setFade, 2);
};
tick.on('mouseover', mouseover);
const tickHorizontal = svg
.append('g')
.attr('transform', `translate(0, 0)`)
.call(axisLeft(yScale).ticks(4))
.selectAll('.tick')
.style('transition', '.2s');
tickHorizontal.selectAll('text').attr('fill', '#A1A1A1');
tickHorizontal.selectAll('line').remove();
svg.selectAll('.domain').style('stroke', '#A1A1A1');
if (
indexPoint !== undefined &&
indexPoint <= dataLineChart.length &&
indexPoint >= 1
) {
const lastData = dataLineChart[dataLineChart.length - indexPoint];
if (onSelectedDate) {
onSelectedDate({
timestamp: lastData.timestamp,
value: lastData.value,
});
}
const y = yScale(lastData.value);
const x = xScale(parseTime(lastData.timestamp));
svg
.append('line')
.attr('x1', x)
.attr('x2', x)
.attr('y1', y)
.attr('y2', height)
.attr('stroke', chartColor)
.attr('stroke-width', '0.15rem');
svg
.append('circle')
.attr('cy', y)
.attr('cx', x)
.style('fill', chartColor)
.attr('r', '0.3rem');
}
return () => {
svg.selectAll('*').remove();
};
}, [dataLineChart, indexPoint]);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|


