如何在加载时设置 d3 笔刷范围

How to set d3 brush extent on load

我在这里尝试绘制一个可刷的条形图。以下是我使用的代码行。

var barchart = function(width,height,id,data,d3){

var focusGraph;


var margin = {top: 10, right: 10, bottom: (height*.2), left: 40},
margin2 = {top: (height*.86), right: 10, bottom: 20, left: 40},
width = width - margin.left - margin.right,
height2 = height - margin2.top - margin2.bottom,
height = height - margin.top - margin.bottom;

var max1 = d3.max(data, function(d) { return d.Metric1; });
var max2 = d3.max(data, function(d) { return d.Metric2; });
var maxValue = d3.max([max1, max2]);


var x = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.1, 0.2);
var x2 = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.1, 0.2);

var y = d3.scale.linear()
.range([height,0]);


var y2 = d3.scale.linear()
.range([height2,0]);


var dimensions = data.map(function(d){
    return d.Dim1;
});


var barWidth = x.rangeBand();

x.domain(data.map(function(d) { return d.Dim1; }));
y.domain([0, d3.max(data.map(function(d) { return d.Metric1; }))]);
x2.domain(x.domain());
y2.domain(y.domain());


var xAxis = d3.svg.axis().scale(x).orient("bottom"),
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left").tickFormat(d3.format("s"));



var svg = d3.select("#"+id).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)

var brush = d3.svg.brush()
.x(x2)
.extent([0,50])
.on("brush", brushed);

var area = d3.svg.area()
.x(function(d) { return x(d.Dim1); })
.y0(height)
.y1(function(d) { return y(d.Metric1); });


svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);

var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var barsGroup = focus.append("g")
.attr('clip-path', 'url(#clip)');

var context = svg.append("g")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");



var barWidth = x.rangeBand();

focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);

focus.append("g")
.attr("class", "y axis")
.call(yAxis);

focusGraph = barsGroup.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d, i) { return x(d.Dim1); })
.attr("y", function(d) { return y(d.Metric1); })
.attr("width", barWidth)
.attr("height", function(d) { return height-y(d.Metric1); });


context.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d, i) { return x2(d.Dim1); })
.attr("y", function(d) { return y2(d.Metric1); })
.attr("width", barWidth)
.attr("height", function(d) { return height2-y2(d.Metric1); });

// context.append("g")
// .attr("class", "x axis")
// .attr("transform", "translate(0," + height2 + ")")
// .call(xAxis2);

context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2);

var test = 0;

function brushed() {


var selected =  x2.domain().filter(function(d){return (brush.extent()[0] <= x2(d)) && (x2(d) <= brush.extent()[1])});
x.domain(selected);
var b =0;
var w =0;
if(selected.length < 2){
    b=barWidth;
    w=b*2;
}
else{
    b = x(selected[1])-x(selected[0]);
    var w = b/2;
}


var j = 0;





focusGraph.attr("width", w);
focusGraph.attr("id",function(d, i) { return d.Index;});
focusGraph.attr("height", function(d,i) { 
for(j=0;j<selected.length;j++)
    {
        if(d.Dim1 == selected[j]){
            console.log(d.Dim1 +"=="+selected[j])
                return d.Metric1;
        }
    }
});
console.log(j);
focusGraph.attr("x", function(d,i) {
    for(j=0;j<selected.length;j++)
    {
        if(d.Dim1 == selected[j]){
            console.log(d.Dim1 +"=="+selected[j])
                return (x(selected[j]))+(barWidth/2);
        }
    }
});
focus.select(".x.axis").call(xAxis);

svg.append("g")



}

};

输出:

这里我想把条形图显示到一个固定的笔刷范围。如下图所示:

我已经尝试将默认范围值应用为 brush.extent([0,50]) 它设置了范围宽度,但默认情况下它不会裁剪条形图。 我试过使用 brush.on("start",brushstart)。但它不工作 非常感谢任何帮助。

添加一行代码成功解决问题brush.call(brush.event)

var barchart = function(width,height,id,data,d3){

var focusGraph;


var margin = {top: 10, right: 10, bottom: (height*.2), left: 40},
margin2 = {top: (height*.86), right: 10, bottom: 20, left: 40},
width = width - margin.left - margin.right,
height2 = height - margin2.top - margin2.bottom,
height = height - margin.top - margin.bottom;

var max1 = d3.max(data, function(d) { return d.Metric1; });
var max2 = d3.max(data, function(d) { return d.Metric2; });
var maxValue = d3.max([max1, max2]);


var x = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.1, 0.2);
var x2 = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.1, 0.2);

var y = d3.scale.linear()
.range([height,0]);


var y2 = d3.scale.linear()
.range([height2,0]);


var dimensions = data.map(function(d){
    return d.Dim1;
});


var barWidth = x.rangeBand();

x.domain(data.map(function(d) { return d.Dim1; }));
y.domain([0, d3.max(data.map(function(d) { return d.Metric1; }))]);
x2.domain(x.domain());
y2.domain(y.domain());


var xAxis = d3.svg.axis().scale(x).orient("bottom"),
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left").tickFormat(d3.format("s"));



var svg = d3.select("#"+id).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)

var brush = d3.svg.brush()
.x(x2)
.extent([0,50])
.on("brush", brushed);

var area = d3.svg.area()
.x(function(d) { return x(d.Dim1); })
.y0(height)
.y1(function(d) { return y(d.Metric1); });


svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);

var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var barsGroup = focus.append("g")
.attr('clip-path', 'url(#clip)');

var context = svg.append("g")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");



var barWidth = x.rangeBand();

focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);

focus.append("g")
.attr("class", "y axis")
.call(yAxis);

focusGraph = barsGroup.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d, i) { return x(d.Dim1); })
.attr("y", function(d) { return y(d.Metric1); })
.attr("width", barWidth)
.attr("height", function(d) { return height-y(d.Metric1); });


context.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d, i) { return x2(d.Dim1); })
.attr("y", function(d) { return y2(d.Metric1); })
.attr("width", barWidth)
.attr("height", function(d) { return height2-y2(d.Metric1); });

// context.append("g")
// .attr("class", "x axis")
// .attr("transform", "translate(0," + height2 + ")")
// .call(xAxis2);

context.append("g")
.attr("class", "x brush")
.call(brush)
.call(brush.event)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2);

var test = 0;

function brushed() {


var selected =  x2.domain().filter(function(d){return (brush.extent()[0] <= x2(d)) && (x2(d) <= brush.extent()[1])});
x.domain(selected);
var b =0;
var w =0;
if(selected.length < 2){
    b=barWidth;
    w=b*2;
}
else{
    b = x(selected[1])-x(selected[0]);
    var w = b/2;
}


var j = 0;





focusGraph.attr("width", w);
focusGraph.attr("id",function(d, i) { return d.Index;});
focusGraph.attr("height", function(d,i) { 
for(j=0;j<selected.length;j++)
    {
        if(d.Dim1 == selected[j]){
            console.log(d.Dim1 +"=="+selected[j])
                return d.Metric1;
        }
    }
});
console.log(j);
focusGraph.attr("x", function(d,i) {
    for(j=0;j<selected.length;j++)
    {
        if(d.Dim1 == selected[j]){
            console.log(d.Dim1 +"=="+selected[j])
                return (x(selected[j]))+(barWidth/2);
        }
    }
});
focus.select(".x.axis").call(xAxis);

svg.append("g")



}

};