我有一个多线 D3 图表。我已经实现了缩放,
but when I zoom, I'm not able to zoom to a specific data point on xy location
。这是我开发的代码要点
let xScale = d3
.scaleUtc()
.domain([
d3.min(formattedChartsData, (c) => d3.min(c.values, (v) => v?.x)),
d3.max(formattedChartsData, (c) => d3.max(c.values, (v) => v?.x)),
])
.nice()
.range([0, width]);
let yScale = d3
.scaleLinear()
.domain([
d3.min(formattedChartsData, (c) => d3.min(c.values, (v) => v.y)),
d3.max(formattedChartsData, (c) => d3.max(c.values, (v) => v.y)),
])
.nice()
.range([height, 0]);
const xAxis = d3
.axisBottom(xScale)
.tickFormat(formatTime)
.tickValues(tickValues);
const yAxis = d3
.axisLeft(yScale)
.tickSize(-boundsWidth)
.tickValues(yAxisTicks)
.tickFormat((d) => d3.format(",.2f")(d));
const identifyZoomLevel = async (min, max) => {
let data = originalTimedilationData.filter((d) => {
return d.updateTime >= min && d.updateTime <= max;
});
};
const zoomed = async (event) => {
const transform = event.transform;
const rex = transform.rescaleX(xScale);
const rey = transform.rescaleY(yScale);
let min = rex.domain()[0];
let max = rex.domain()[1];
if (
compareDates(min, max) === -1 &&
compareDates(min, latestSettlement.updateTime) === -1
) {
setActiveDateRange(CUSTOMDATERANGE);
await triggerFilterDataByDateInterval(min, max);
await identifyZoomLevel(min, max);
timedilationLines
.selectAll("path.line")
.transition()
.duration(2000)
.attr("d", (d) => {
return setupLines(rex, rey)(d.values);
});
g.selectAll("circle.dot")
.transition()
.duration(2000)
.attr("transform", transform);
timedilationLines
.selectAll("line")
.attr("x1", (d) => rex(d.date))
.attr("y1", (d) => rey(d.loss))
.attr("x2", (d) => rex(d.date))
.attr("y2", (d) => rey(d.gain));
xAxisCaller.transition().duration(2000).call(xAxisGenerator.scale(rex));
yAxisCaller.transition().duration(2000).call(yAxisGenerator.scale(rey));
}
};
const debouncedZoomed = debounce(zoomed, 5);
svg
.attr("width", width)
.attr("height", height)
.attr("viewBox", `0 0 ${width} ${height}`)
.attr(
"style",
"max-width: 100%; height: auto; overflow: visible; font: 10px sans-serif;"
)
.append("g")
.attr("transform", `translate(0,${MARGIN.top})`);
svg
.append("g")
.attr("class", "x axis")
.style("color", "#A0A9B8")
.style("font-size", "14px")
.attr("transform", `translate(0,${height})`)
.call(xAxis);
svg
.append("g")
.attr("class", "y axis")
.style("color", "#A0A9B8")
.style("font-size", "14px")
.call(yAxis);
d3.line()
.x((d) => xScale(d.x))
.y((d) => yScale(d.y))
.curve(d3.curveMonotoneX);
g.selectAll(".timedilation")
.data(formattedChartsData)
.enter()
.append("svg")
.attr("class", "timedilation")
.attr("width", width - MARGIN.right)
.attr("id", (d, i) => `chart-${i}-${d.name}`)
.append("path")
.attr("class", "line")
.attr("d", (d) => line(d.values))
.style("stroke", (d) => CHARTCOLORMAP[d?.name]);
const zoom = d3
.zoom()
.scaleExtent([-0.5, 8])
.extent([
[0, 0],
[width.current, height],
])
.translateExtent([
[0, 0],
[width.current, height],
])
.on("zoom", (event) => debouncedZoomed(event));
svg.call(zoom).transition().duration(100);
有人可以帮助我吗?
如果缩放未按预期运行,请在缩放函数内记录新域(rex.domain() 和 rey.domain()),以验证它们是否已正确更新。另外,请确保依赖于这些比例的所有图形元素都在此函数内正确更新:)