【发布时间】:2019-10-10 10:30:38
【问题描述】:
我已经为我的图表实现了缩放功能,可以通过拖动并释放该区域来放大图表的某个区域。我的小提琴可以访问here。
蓝线的缩放功能正常工作,因为蓝线和左轴都在更新。但是,当红线放大时,右轴没有被更新。我已经为右轴硬编码了一个从 0 到 200 的域,所以每当我放大域时,域都会从 0 变为 200,而不是正确的放大域。右侧轴的域代码应该是什么,以便在缩放期间更新?非常感谢任何帮助!
var data = [ {x: 0, y: 0, y1: 0}, {x: 1, y: 30, y1: 100}, {x: 2, y: 40, y1: 200},
{x: 3, y: 60, y1: 300}, {x: 4, y: 70, y1: 400}, {x: 5, y: 90, y1: 500} ];
const margin = {
left: 20,
right: 20,
top: 20,
bottom: 80
};
const svg = d3.select('svg');
svg.selectAll("*").remove();
const width = 200 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;
const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);
var x = d3.scaleLinear()
.domain([0, d3.max(data, function(d){ return d.x; })])
.range([0,width])
.nice();
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d){ return d.y; })])
.range([0,height])
.nice();
var y1 = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d.y1; })])
.range([0, height])
.nice();
const xAxis = d3.axisTop()
.scale(x)
.ticks(5)
.tickPadding(3)
.tickSize(-height)
const yAxis = d3.axisLeft()
.scale(y)
.ticks(5)
.tickPadding(3)
.tickSize(-width);
const yAxis1 = d3.axisRight()
.scale(y1)
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(20,20)")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,20)")
.call(yAxis);
svg.append("g")
.attr("class", "y1 axis")
.attr("transform", "translate(185,20)")
.call(yAxis1);
var lineFunction = d3.line()
.x(function(d) {return x(d.x); })
.y(function(d) {return y(d.y); })
.curve(d3.curveLinear);
var lineFunctionOne = d3.line()
.x(function(d) {return x(d.x); })
.y(function(d) {return y1(d.y1); })
.curve(d3.curveLinear);
//defining and plotting the lines
var path = g.append("path")
.attr("class", "path1")
.attr("id", "blueLine")
.attr("d", lineFunction(data))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none")
.attr("clip-path", "url(#clip)");
var path1 = g.append("path")
.attr("class", "path2")
.attr("id", "redLine")
.attr("d", lineFunctionOne(data))
.attr("stroke", "red")
.attr("stroke-width", 2)
.attr("fill", "none")
.attr("clip-path", "url(#clip)");
//************* Zoom ***************
//add brushing
var brush = d3.brush().extent([[0, 0], [width, height]]).on("end", brushended),
idleTimeout,
idleDelay = 350;
g.append("g")
.attr("class", "brush")
.call(brush);
// Add a clipPath: everything out of this area won't be drawn when chart is zoomed in
var clip = svg.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("width", width)
.attr("height", height)
.attr("x", 0)
.attr("y", 0);
function brushended() {
var s = d3.event.selection;
//If no selection, re-initialize chart on double click. Otherwise, update x-axis and y-axis domain
if (!s) {
// This allows to wait a little bit
if (!idleTimeout) return idleTimeout = setTimeout(idled, 350);
x.domain(d3.extent(data, function (d) { return d.x; })).nice();
y.domain(d3.extent(data, function (d) { return d.y; })).nice();
y1.domain(d3.extent(data, function (d) { return d.y1; })).nice();
} else {
x.domain([s[0][0], s[1][0]].map(x.invert, x));
y.domain([s[0][1], s[1][1]].map(y.invert, y));
y1.domain([0, 200]); //hardcoded domain
//This removes the grey brush area as soon as the selection has been done
g.select(".brush").call(brush.move, null)
}
zoom();
}
function idled() {
idleTimeout = null;
}
function zoom() {
var t = svg.transition().duration(750);
svg.select(".x.axis").transition(t).call(xAxis);
svg.select(".y.axis").transition(t).call(yAxis);
svg.select(".y1.axis").transition(t).call(yAxis1);
svg.select(".path1").transition(t).attr("d", lineFunction(data));
svg.select(".path2").transition(t).attr("d", lineFunctionOne(data));
}
【问题讨论】:
标签: javascript d3.js