我使用d3折线图并创建了带有值的十字线。 放大时面临问题。 十字线未使用新的缩放值更新。它具有旧值并且首先显示值。 我如何解决这个问题,并使用缩放值制作十字线
这是我的代码:
var self = this;
this.margin = { top: 0, right: 45, bottom: 20, left: 0 };
this.size = {
width: $('#realtimechart').width() - 40,
height: 300
};
$('#realtimechart').empty();
this.x = d3.time.scale.utc()
.domain(d3.extent(self.plots, function (d) {
return d.date;
}))
.range([0, this.size.width])
.clamp(true);
this.y = d3.scale.linear()
.domain([0, d3.max(self.plots, function (d) {
return d.close;
})])
.range([this.size.height, 0])
.clamp(true);
this.line = d3.svg.line()
.x(function (d) {
return self.x(d.date);
})
.y(function (d) {
return self.y(d.close);
});
this.xAxis = d3.svg.axis().scale(this.x).ticks(12).orient('bottom');
this.yAxis = d3.svg.axis().scale(this.y).ticks(8).orient('right');
this.zoom = d3.behavior.zoom().x(this.x).scaleExtent([1,10]).on('zoom', this.redraw());
this.zoom.scale(currentZoom).translate([0, 0]);
this.svg = d3.select('#realtimechart').append('svg')
.attr('width', this.size.width + this.margin.left + this.margin.right)
.attr('height', this.size.height + this.margin.top + this.margin.bottom)
.append('g')
.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')')
.call(this.zoom);
this.makeX = function () {
return d3.svg.axis()
.scale(self.x)
.orient('bottom')
.ticks(12);
};
this.makeY = function () {
return d3.svg.axis()
.scale(self.y)
.orient('left')
.ticks(8);
};
this.svg.append('rect')
.attr('width', this.size.width)
.attr('height', this.size.height);
var focus = this.svg.append("g")
.attr("class","focus")
.style("display", "none");
focus.append("line")
.attr({
"x1": -this.size.width,
"y1": 0,
"x2": this.size.width,
"y2": 0
});
focus.append("line")
.attr({
"x1": 0,
"y1": -this.size.height,
"x2": 0,
"y2": this.size.height
});
var tipValue = this.svg.append("g")
.attr("class","focus")
.style("display", "none");
tipValue.append("text")
.attr("x", -10);
var bisectDate = d3.bisector(function(d) { return d.date; }).left;
var formatValue = d3.format(",.2f");
var formatCurrency = function(d) { return "$" + formatValue(d); };
var xDomain = d3.extent(self.chartData, function (d, i){ return d.date; });
var yMin = d3.min(self.chartData, function(d){ return Math.min(d.close); });
var yMax = d3.max(self.chartData, function(d){ return Math.max(d.close); });
var x = d3.time.scale()
.range([0, this.size.width]);
var y = d3.scale.linear()
.range([this.size.height, 0]);
x.domain([self.chartData[0].date, self.chartData[self.chartData.length - 1].date]);
y.domain(d3.extent(self.chartData, function(d) { return d.close; }));
function mousemove() {
var x0 = x.invert(d3.mouse(this)[0]),
i = bisectDate(self.chartData, x0, 1),
d0 = self.chartData[i - 1],
d1 = self.chartData[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
focus.attr("transform", "translate(" + x(d.date) + "," + y(d.close) + ")");
tipValue.attr("transform", "translate(10, 10)");
tipValue.select("text").text(formatCurrency(d.close));
}
this.svg.on('mouseover', function() {
focus.style("display", null);
tipValue.style("display", null);
}).on('mouseout', function() {
focus.style("display", "none");
tipValue.style("display", "none");
}).on('mousemove', mousemove);
this.svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + this.size.height + ')')
.call(this.xAxis);
this.svg.append('g')
.attr('class', 'y axis')
.attr('transform', 'translate(' + this.size.width + ', 0)')
.call(this.yAxis);
this.svg.append('g')
.attr('class', 'x grid')
.attr('transform', 'translate(0,' + this.size.height + ')')
.call(this.makeX()
.tickSize(-this.size.height, 0, 0)
.tickFormat(''));
this.svg.append('g')
.attr('class', 'y grid')
.call(this.makeY()
.tickSize(-this.size.width, 0, 0)
.tickFormat(''));
this.clip = this.svg.append('svg:clipPath')
.attr('id', 'clip')
.append('svg:rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', this.size.width)
.attr('height', this.size.height);
this.chartBody = this.svg.append('g')
.attr('clip-path', 'url(#clip)')
.append('svg:path')
.datum(self.plots)
.attr('class', 'line')
.attr('d', this.line);
}
Chart.prototype.redraw = function() {
var self = this;
return function() {
currentZoom = d3.event.scale;
self.svg.select('.x.axis').call(self.xAxis);
self.svg.select('.y.axis').call(self.yAxis);
self.svg.select('.x.grid')
.call(self.makeX()
.tickSize(-self.size.height, 0, 0)
.tickFormat(''));
self.svg.select('.y.grid')
.call(self.makeY()
.tickSize(-self.size.width, 0, 0)
.tickFormat(''));
self.svg.select('.line')
.attr('class', 'line')
.attr('d', self.line);
};