d3.js - 动态更新可缩放区域图的 y 轴
问题描述
在缩放和平移时,y 轴不会更新为可见缩放数据集中的最大值,例如,当最大值为 3500 时,y 轴仍然有 3500、4000、4500、5000 和 5500 的刻度,这会限制显示。可以更准确地更新过滤数据的新最大值吗?
const height = 400,
width = 800;
const margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
};
const parser = d3.timeParse("%Y-%m-%d");
const url = "https://static.observableusercontent.com/files/4e532df03705fa504e8f95c1ab1c114ca9e89546bf14d697c73a10f72028aafd9eb3d6ea2d87bb6b421d9707781b8ac70c2bf905ccd60664f9e452a775fe50ed?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27Book1%25401.csv";
d3.csv(url, function(d) {
return {
date: parser(d.date),
value: +d.value
};
}).then(function(data) {
const x = d3.scaleUtc()
.domain(d3.extent(data, d => d.date))
.range([margin.left, width - margin.right]),
y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([height - margin.bottom, margin.top]),
xAxis = (g, x) => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0)),
yAxis = (g, y) => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).ticks(5))
.call(g => g.select(".domain").remove())
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", 3)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text(data.y)),
area = (data, x) => d3.area()
.curve(d3.curveStepAfter)
.x(d => x(d.date))
.y0(y(0))
.y1(d => y(d.value))
(data)
const zoom = d3.zoom()
.scaleExtent([1, 32])
.extent([
[margin.left, 0],
[width - margin.right, height]
])
.translateExtent([
[margin.left, -Infinity],
[width - margin.right, Infinity]
])
.on("zoom", zoomed);
const svg = d3.select("svg")
.attr("width", width)
.attr("height", height);
svg.append("clipPath")
.attr("id", "myclip")
.append("rect")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom);
const path = svg.append("path")
.attr("clip-path", "url('#myclip')")
.attr("fill", "steelblue")
.attr("d", area(data, x));
const gx = svg.append("g")
.call(xAxis, x);
const gy = svg.append("g")
.call(yAxis, y);
svg.call(zoom)
.transition()
.duration(750)
.call(zoom.scaleTo, 1, [x(Date.UTC(2020, 8, 1)), 0]);
function zoomed(event) {
const xz = event.transform.rescaleX(x);
const yz = event.transform.rescaleY(y);
path.attr("d", area(data, xz));
gx.call(xAxis, xz);
gy.call(yAxis, yz);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.js"></script>
<svg></svg>
解决方案
感谢指导: https ://observablehq.com/@steve-pegg/zoomable-area-chart
下面的更改已经奏效。
function zoomed(event) {
var xz = event.transform.rescaleX(x);
var startDate = xz.domain()[0];
var endDate = xz.domain()[1];
var fData = data.filter(function (d) {
var date = new Date(d.date);
return (date >= startDate && date <= endDate);});
y.domain([0, d3.max(fData, function (d) { return d.value; })]);
path.attr("d", area(data, xz));
gx.call(xAxis, xz);
gy.call(yAxis, y);
}
推荐阅读
- javascript - React - Typescript interfaces - errors when get props from union types
- outlook-redemption - 将 Outlook 消息另存为 eml 不完整(正文丢失,附件未打开,...)
- git - 如何更新已经提出拉取请求的分支
- javascript - 如何导出需要其他模块的模块
- c++ - Strange "No instance of constructor matches the argument list" error (Solved)
- ios - ios - UITableViewCell does not fill the entire width of the table
- angular - 在 Angular 中使用带有数组的输出指令
- reactjs - 使用 React Router 将表单数据从一个组件发送到另一个
- javascript - 节点脚本中的异步等待
- networkx - 无需在内存中加载图形的最短路径算法