Javascript d3js v4:独立多轴缩放和平移
我正在尝试实现一个图表框架,它能够为每个方向创建多轴的线图和面积图,即左2-y轴、右1-YAX轴和底部1-x轴 我得去工作。我的下一个任务是实现图表的缩放行为。我缩进以获得全局缩放行为,如果用户在绘图区域内使用鼠标,就会触发该行为。显示的序列将被重新缩放,并且可以平移绘图。这个我也得去工作 此外,我希望每个轴都有独立的缩放。我得到了缩放,但是我仍然有全局缩放和平移的问题。如果缩放一个轴,打印区域中的关联系列将重新缩放,但平移不起作用。在轴的独立缩放之后,如果我使用全局重缩放,缩放会重置,然后通过全局缩放行为进行缩放 在d3.js页面上,我发现了一个简单的用于独立和全局缩放和平移的方法,但它是用d3v3编写的 我以这种方式更改了示例,以便它显示我的问题。在轴上和打印区域中使用鼠标Javascript d3js v4:独立多轴缩放和平移,javascript,d3.js,Javascript,D3.js,我正在尝试实现一个图表框架,它能够为每个方向创建多轴的线图和面积图,即左2-y轴、右1-YAX轴和底部1-x轴 我得去工作。我的下一个任务是实现图表的缩放行为。我缩进以获得全局缩放行为,如果用户在绘图区域内使用鼠标,就会触发该行为。显示的序列将被重新缩放,并且可以平移绘图。这个我也得去工作 此外,我希望每个轴都有独立的缩放。我得到了缩放,但是我仍然有全局缩放和平移的问题。如果缩放一个轴,打印区域中的关联系列将重新缩放,但平移不起作用。在轴的独立缩放之后,如果我使用全局重缩放,缩放会重置,然后通过
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Independent Axis Zooms on x, y, or xy</title>
<script src="//d3js.org/d3.v4.min.js"></script>
<style>
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<div id="chart"></div>
<script>
var data = [];
for (var i = 0; i < 100; i++) {
data.push([Math.random(), Math.random()]);
}
var svg = d3.select('#chart')
.append("svg")
.attr("width", window.innerWidth).attr("height", window.innerHeight);
function example(svg, data) {
var svg;
var margin = {
top: 60,
bottom: 80,
left: 60,
right: 0
};
var width = 500;
var height = 400;
var xaxis = d3.axisBottom();
var yaxis = d3.axisLeft();
var xscale = d3.scaleLinear();
var yscale = d3.scaleLinear();
var xcopyScale, ycopyScale;
var xyzoom, xzoom, yzoom;
updateZooms();
function update() {
var gs = svg.select("g.scatter");
var circle = gs.selectAll("circle")
.data(data);
circle.enter().append("svg:circle")
.attr("class", "points")
.style("fill", "steelblue")
.attr("cx", function (d) {
return X(d);
})
.attr("cy", function (d) {
return Y(d);
})
.attr("r", 4);
circle.attr("cx", function (d) {
return X(d);
})
.attr("cy", function (d) {
return Y(d);
});
circle.exit().remove();
}
function updateZooms() {
xyzoom = d3.zoom()
.on("zoom", function () {
xaxis.scale(d3.event.transform.rescaleX(xscale));
yaxis.scale(d3.event.transform.rescaleY(yscale));
draw();
});
xzoom = d3.zoom()
.on("zoom", function () {
xaxis.scale(d3.event.transform.rescaleX(xscale));
draw();
});
yzoom = d3.zoom()
.on("zoom", function () {
yaxis.scale(d3.event.transform.rescaleY(yscale));
draw();
});
}
function draw() {
svg.select('g.x.axis').call(xaxis);
svg.select('g.y.axis').call(yaxis);
update();
// After every draw, we reinitialize zoom. After every zoom, we reexecute draw, which will reinitialize zoom.
// This is how we can apply multiple independent zoom behaviors to the scales.
// (Note that the zoom behaviors will always end up with zoom at around 1.0, and translate at around [0,0])
svg.select('rect.zoom.xy.box').call(xyzoom);
svg.select('rect.zoom.x.box').call(xzoom);
svg.select('rect.zoom.y.box').call(yzoom);
}
// X value to scale
function X(d) {
return xaxis.scale() !== undefined && xaxis.scale() !== null
? xaxis.scale()(d[0])
: xscale(d[0]);
}
// Y value to scale
function Y(d) {
return yaxis.scale() !== undefined && yaxis.scale() !== null
? yaxis.scale()(d[1])
: yscale(d[1]);
}
var g = svg.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom);
g.append("svg:rect")
.attr("class", "border")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.style("stroke", "black")
.style("fill", "none");
g.append("g").attr("class", "x axis")
.attr("transform", "translate(" + 0 + "," + (height - margin.top - margin.bottom) + ")");
g.append("g").attr("class", "y axis");
g.append("g")
.attr("class", "scatter")
.attr("clip-path", "url(#clip)");
g
.append("svg:rect")
.attr("class", "zoom xy box")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.style("visibility", "hidden")
.attr("pointer-events", "all")
.call(xyzoom);
g
.append("svg:rect")
.attr("class", "zoom x box")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.attr("transform", "translate(" + 0 + "," + (height - margin.top - margin.bottom) + ")")
.style("visibility", "hidden")
.attr("pointer-events", "all")
.call(xzoom);
g
.append("svg:rect")
.attr("class", "zoom y box")
.attr("width", margin.left)
.attr("height", height - margin.top - margin.bottom)
.attr("transform", "translate(" + -margin.left + "," + 0 + ")")
.style("visibility", "hidden")
.attr("pointer-events", "all")
.call(yzoom);
// Update the x-axis
xscale.domain(d3.extent(data, function (d) {
return d[0];
})).range([0, width - margin.left - margin.right]);
xaxis.scale(xscale)
.tickPadding(10);
svg.select('g.x.axis').call(xaxis);
// Update the y-scale.
yscale.domain(d3.extent(data, function (d) {
return d[1];
})).range([height - margin.top - margin.bottom, 0]);
yaxis.scale(yscale)
.tickPadding(10);
svg.select('g.y.axis').call(yaxis);
draw();
}
var exampleChart = example(svg, data);
</script>
</body>
</html>
提供头衔
简单独立轴在x、y或xy上缩放
.轴路径,.轴线{
填充:无;
行程:#000;
形状渲染:边缘清晰;
}
var数据=[];
对于(变量i=0;i<100;i++){
data.push([Math.random(),Math.random()]);
}
var svg=d3。选择(“#图表”)
.append(“svg”)
.attr(“宽度”,window.innerWidth).attr(“高度”,window.innerHeight);
功能示例(svg、数据){
var-svg;
var保证金={
排名:60,
底部:80,
左:60,,
右:0
};
var宽度=500;
var高度=400;
var xaxis=d3.axisBottom();
var yaxis=d3.axisLeft();
var xscale=d3.scaleLinear();
var yscale=d3.scaleLinear();
var xcopyScale,ycopyScale;
变量xyzoom、xzoom、yzoom;
updateZooms();
函数更新(){
var gs=svg.select(“g.scatter”);
变量循环=gs。选择全部(“循环”)
.数据(数据);
circle.enter().append(“svg:circle”)
.attr(“类”、“点”)
.样式(“填充”、“钢蓝”)
.attr(“cx”,功能(d){
返回X(d);
})
.attr(“cy”,函数(d){
返回Y(d);
})
.attr(“r”,4);
圆属性(“cx”,函数(d){
返回X(d);
})
.attr(“cy”,函数(d){
返回Y(d);
});
circle.exit().remove();
}
函数updateZooms(){
xyzoom=d3.zoom()
.on(“缩放”,函数(){
scale(d3.event.transform.rescaleX(xscale));
yaxis.scale(d3.event.transform.rescaleY(yscale));
draw();
});
xzoom=d3.zoom()
.on(“缩放”,函数(){
scale(d3.event.transform.rescaleX(xscale));
draw();
});
yzoom=d3.zoom()
.on(“缩放”,函数(){
yaxis.scale(d3.event.transform.rescaleY(yscale));
draw();
});
}
函数绘图(){
svg.select('g.x.axis').call(xaxis);
svg.select('g.y.axis').call(yaxis);
更新();
//在每次绘图之后,我们重新初始化缩放。在每次缩放之后,我们重新执行绘图,这将重新初始化缩放。
//这就是我们如何将多个独立缩放行为应用于缩放的方法。
//(请注意,缩放行为将始终以1.0左右的缩放和[0,0]左右的平移结束)
选择('rect.zoom.xy.box')。调用(xyzoom);
选择('rect.zoom.x.box')。调用(xzoom);
svg.select('rect.zoom.y.box').call(yzoom);
}
//缩放的X值
函数X(d){
返回xaxis.scale()!==undefined&&xaxis.scale()!==null
?xaxis.scale()(d[0])
:xscale(d[0]);
}
//比例Y值
函数Y(d){
返回yaxis.scale()!==undefined&&yaxis.scale()!==null
?yaxis.scale()(d[1])
:yscale(d[1]);
}
var g=svg.append('g')
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
g、 附加(“defs”)。附加(“clipPath”)
.attr(“id”、“剪辑”)
.append(“rect”)
.attr(“宽度”,宽度-边距。左侧-边距。右侧)
.attr(“高度”,高度-边距。顶部-边距。底部);
g、 追加(“svg:rect”)
.attr(“类”、“边界”)
.attr(“宽度”,宽度-边距。左侧-边距。右侧)
.attr(“高度”,高度-边距.顶部-边距.底部)
.style(“笔划”、“黑色”)
.样式(“填充”、“无”);
g、 附加(“g”).attr(“类”、“x轴”)
.attr(“转换”、“平移”(+0+),“+(高度-边距.顶部-边距.底部)+”);