d3v4 - 缩放(相当于 d3.zoom.x)
Posted
技术标签:
【中文标题】d3v4 - 缩放(相当于 d3.zoom.x)【英文标题】:d3v4 - zooming (Equivalent to d3.zoom.x) 【发布时间】:2017-01-16 04:43:36 【问题描述】:我正在将我的 d3 代码从 v3 迁移到 v4,但在查找 d3.zoom.x、d3.zoom.y 属性的等效项时遇到问题。
下面是一小段代码,包括最重要的元素:
this.init = function(obj, def)
/* X-axis */
x = d3.scaleTime()
.range([0, width]);
xAxis = d3.axisBottom(x)
.ticks(ticks);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")");
/* Y-axis */
for (var i = 0; i < 1; i++)
// Returns the y and yAxis as arrays
createYAxis(i);
initZoom();
;
// Zoom trigger
var drawUpdXY = function()
setPause(true);
drawUpd();
zoomY.y(y[0]);
zoomX.x(x);
zoom = d3.zoom()
.on("zoom", drawUpdXY);
zoomX = d3.zoom()
.on("zoom", drawUpdX);
zoomY = d3.zoom()
.on("zoom", drawUpdY);
;
我尝试用它来替换“zoom.x(x); zoom.y(y[0])”
xAxis.scale(d3.event.transform.rescaleX(x));
yAxis[0].scale(d3.event.transform.rescaleY(y[0]));
但是,这些只会重新缩放轴,而不会缩放数据。
【问题讨论】:
既然这个比较老了,你有没有找到解决办法?我遇到了同样的问题。 今天还没有找到解决方案 - 我决定等到有更大的 v4 社区。span> tl;dr:这可能有助于重组你的重构,查看链接了解原因和方式,以及它的工作示例 b> 我正在做一个类似的项目,试图在 d3v4 和 React 中实现平移/缩放坐标网格系统。在此过程中,我使用了article explaining how the new zooming/panning works,这让我意识到我必须重新考虑如何构建我的重构。然后,我在纯 d3 中创建了这个 codepen of what I was trying to make。仍在 React 方面工作。 【参考方案1】:我无法谈论 d3 v3 是如何处理缩放的,因为我最近才开始使用 D3,但下面的代码应该可以让您找到正确的方向。我会尽力描述发生了什么。我邀请更正、改进和更好的解释。
首先,MCVE
<html>
<head>
<meta charset="UTF-8">
<title>Energy Visualizer</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<style>
body
background-color: #4e5965;
</style>
</svg>
</head>
<body>
<div class="chart" />
<script>
var svg = d3.select(".chart").append("svg")
.attr("width", 200)
.attr("height", 200);
var data = [
"x": 2,
"y": 8,
"color": "green"
,
"x": 4,
"y": 6,
"color": "red"
];
var width = svg.attr("width");
var height = svg.attr("height");
x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]);
y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]);
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d)
return x_scale(d.x);
)
.attr("cy", function(d)
return y_scale(d.y);
)
.attr("r", 5)
.attr("fill", function(d)
return d.color
);
var xAxis = d3.axisBottom(x_scale);
var yAxis = d3.axisRight(y_scale);
var x_axis = svg.append("g").call(xAxis);
var y_axis = svg.append("g").call(yAxis);
</script>
</body>
</html>
这只是一个带有红色和绿色圆圈的简单散点图。您可以看到我是如何分解 x 和 y 轴的组件的。这与d3.zoom()
一起发挥作用。
接下来,让我们添加一个缩放组件。
<html>
<head>
<meta charset="UTF-8">
<title>Energy Visualizer</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<style>
body
background-color: #4e5965;
</style>
</svg>
</head>
<body>
<div class="chart" />
<script>
var svg = d3.select(".chart").append("svg")
.attr("width", 200)
.attr("height", 200);
var zoom = d3.zoom()
.on("zoom", zoomed);
svg.call(zoom);
var data = [
"x": 2,
"y": 8,
"color": "green"
,
"x": 4,
"y": 6,
"color": "red"
];
var width = svg.attr("width");
var height = svg.attr("height");
x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]);
y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]);
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d)
return x_scale(d.x);
)
.attr("cy", function(d)
return y_scale(d.y);
)
.attr("r", 5)
.attr("fill", function(d)
return d.color
);
var xAxis = d3.axisBottom(x_scale);
var yAxis = d3.axisRight(y_scale);
var x_axis = svg.append("g").call(xAxis);
var y_axis = svg.append("g").call(yAxis);
function zoomed()
var new_x_scale = d3.event.transform.rescaleX(x_scale);
var new_y_scale = d3.event.transform.rescaleY(y_scale);
x_axis.transition()
.duration(0)
.call(xAxis.scale(new_x_scale));
y_axis.transition()
.duration(0)
.call(yAxis.scale(new_y_scale));
circles
.attr("cx", function(d)
return new_x_scale(d.x)
)
.attr("cy", function(d)
return new_y_scale(d.y)
);
</script>
</body>
</html>
在这里,您可以看到图表允许在两个轴上放大、缩小和拖动。我相信你只想要一个单轴缩放,所以在这种情况下,只需要重新缩放 x 轴和每个圆圈位置的 x 分量。
最后一个 sn-p 做我认为你想做的事。
<html>
<head>
<meta charset="UTF-8">
<title>Energy Visualizer</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<style>
body
background-color: #4e5965;
</style>
</svg>
</head>
<body>
<div class="chart" />
<script>
var svg = d3.select(".chart").append("svg")
.attr("width", 200)
.attr("height", 200);
var zoom = d3.zoom()
.on("zoom", zoomed);
svg.call(zoom);
var data = [
"x": 2,
"y": 8,
"color": "green"
,
"x": 4,
"y": 6,
"color": "red"
];
var width = svg.attr("width");
var height = svg.attr("height");
x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]);
y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]);
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d)
return x_scale(d.x);
)
.attr("cy", function(d)
return y_scale(d.y);
)
.attr("r", 5)
.attr("fill", function(d)
return d.color
);
var xAxis = d3.axisBottom(x_scale);
var yAxis = d3.axisRight(y_scale);
var x_axis = svg.append("g").call(xAxis);
var y_axis = svg.append("g").call(yAxis);
function zoomed()
var new_x_scale = d3.event.transform.rescaleX(x_scale);
x_axis.transition()
.duration(0)
.call(xAxis.scale(new_x_scale));
circles
.attr("cx", function(d)
return new_x_scale(d.x)
);
</script>
</body>
</html>
【讨论】:
以上是关于d3v4 - 缩放(相当于 d3.zoom.x)的主要内容,如果未能解决你的问题,请参考以下文章
在 D3 中放大和缩小时如何更改平移和缩放的速度(使用 zoom.on 和 d3.event.translate,d3.event.zoom)?