我有一些数据,范围从2003年到2007年,使用以下代码绘制为折线图:
var x = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]);
var area = d3.svg.area()
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
以后我将数据提取到了:
x.domain(d3.extent(data.map(function(d) { return d.date; })));
y.domain([0, d3.max(data.map(function(d) { return d.price; }))]);
context.append("path")
.datum(data)
.attr("d", area);
我已经实现了一个刷子来过滤数据。它的工作原理如下:
http://bl.ocks.org/mbostock/4349545
但是我没有散点图,而是有一个折线图。我想选择图形区域的任意部分,并根据画笔选择重新着色。就像这张雅虎图上的第二张图:
我有一个在brushmove上触发的画笔功能:
function brushmove() {
var s = brush.extent();
console.log(s);
}
正确记录所选范围。我只是不确定如何根据从brushmove函数返回的范围选择我的图形区域的一部分。
完整代码在这里:
//specify some margins
var margin = {top: 500, right: 10, bottom: 20, left: 40},
width = 960,
height = 100;
var bigMargin = {top: 20, right: 10, bottom: 20, left: 40},
bigWidth = 960,
bigHeight = 400;
//parse the date
var parseDate = d3.time.format("%b %Y").parse;
//create scales
var x = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]);
//create scales
var bigX = d3.time.scale().range([0, bigWidth]),
bigY = d3.scale.linear().range([bigHeight, 0]);
//create axis
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left");
var bigXAxis = d3.svg.axis().scale(bigX).orient("bottom"),
bigYAxis = d3.svg.axis().scale(bigY).orient("left");
//create a brush area accessor function
var brush = d3.svg.brush()
.x(x)
.on("brush", brushmove);
//create an area accessor function
var area = d3.svg.area()
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
var bigArea = d3.svg.area()
.x(function(d) { return bigX(d.date); })
.y0(bigHeight)
.y1(function(d) { return bigY(d.price); });
//append the svg container
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", bigWidth)
.attr("height", bigHeight);
//append a container
var context = svg.append("g")
.attr('class','container')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var bigContext = svg.append("g")
.attr('class','bigContainer')
.attr("transform", "translate(" + bigMargin.left + "," + bigMargin.top + ")");
//loop over the data
d3.csv("data.csv", function(error, data) {
//coerce the data a little because values from .CSv are always strings
data.forEach(function(d) {
d.date = parseDate(d.date);
d.price = +d.price;
});
//set the scale domains based on the data
x.domain(d3.extent(data.map(function(d) { return d.date; })));
y.domain([0, d3.max(data.map(function(d) { return d.price; }))]);
bigContext.append("path")
.datum(data)
.attr("clip-path", "url(#clip)")
.attr("fill","red")
.attr("d", bigArea);
//set the scale domains based on the data
bigX.domain(d3.extent(data.map(function(d) { return d.date; })));
bigY.domain([0, d3.max(data.map(function(d) { return d.price; }))]);
var t = new Date(2003, 0, 1);
//append the graph as an area
context.append("path")
.datum(data)
.attr("d", area).
attr("fill",function(d) {
//if the data is at a certain range then give it a particular fill
return (new Date(d.date) > t ? "orange" : "yellow"); });
//append the x axis
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
//append the x axis
context.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,0)")
.call(yAxis);
//append the x axis
bigContext.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + bigHeight + ")")
.call(bigXAxis);
//append the x axis
bigContext.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,0)")
.call(bigYAxis);
//append the brush
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height + 7)
});
function brushstart() {
svg.classed("selecting", true);
}
function brushmove() {
bigX.domain(brush.extent());
bigContext.select("path").attr("d", bigArea);
bigContext.select(".x.axis").call(bigXAxis);
}