D3 笔刷事件——移动了哪个笔刷?左边那个还是右边那个?
D3 Brush events - which brush was moved? The left one or the right one?
希望标题说明了一切。
我正在处理 D3 笔刷移动事件。我想知道用户是移动了左画笔还是右画笔...?
我真的很想避免将鼠标位置存储在某处。
是否有相对简单的方法来解决这个问题..?
我能看到的最简单的方法:
// bind to at least start and end events
var brush = d3.brushX()
.extent([[0, 0], [width, height]])
.on("start brush end", brushmoved);
// handle it
var bs = "";
function brushmoved() {
var s = d3.event.selection;
if (d3.event.type === "start"){
bs = d3.event.selection;
} else if (d3.event.type === "end"){
if (bs[0] !== s[0] && bs[1] !== s[1]) {
console.log('moved both');
} else if (bs[0] !== s[0]) {
console.log('moved left');
} else {
console.log('moved right');
}
}
}
完整示例:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
circle {
fill-opacity: 0.2;
transition: fill-opacity 250ms linear;
}
circle.active {
stroke: #f00;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var data = d3.range(800).map(Math.random);
var svg = d3.select("svg"),
margin = {top: 194, right: 50, bottom: 214, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scaleLinear().range([0, width]),
y = d3.randomNormal(height / 2, height / 8);
var brush = d3.brushX()
.extent([[0, 0], [width, height]])
.on("start brush end", brushmoved);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
var circle = g.append("g")
.attr("class", "circle")
.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("transform", function(d) { return "translate(" + x(d) + "," + y() + ")"; })
.attr("r", 3.5);
var gBrush = g.append("g")
.attr("class", "brush")
.call(brush);
var handle = gBrush.selectAll(".handle--custom")
.data([{type: "w"}, {type: "e"}])
.enter().append("path")
.attr("class", "handle--custom")
.attr("fill", "#666")
.attr("fill-opacity", 0.8)
.attr("stroke", "#000")
.attr("stroke-width", 1.5)
.attr("cursor", "ew-resize")
.attr("d", d3.arc()
.innerRadius(0)
.outerRadius(height / 2)
.startAngle(0)
.endAngle(function(d, i) { return i ? Math.PI : -Math.PI; }));
gBrush.call(brush.move, [0.3, 0.5].map(x));
var bs = "";
function brushmoved() {
var s = d3.event.selection;
if (d3.event.type === "start"){
bs = d3.event.selection;
} else if (d3.event.type === "end"){
if (bs[0] !== s[0] && bs[1] !== s[1]) {
console.log('moved both');
} else if (bs[0] !== s[0]) {
console.log('moved left');
} else {
console.log('moved right');
}
}
if (s == null) {
handle.attr("display", "none");
circle.classed("active", false);
} else {
var sx = s.map(x.invert);
circle.classed("active", function(d) { return sx[0] <= d && d <= sx[1]; });
handle.attr("display", null).attr("transform", function(d, i) { return "translate(" + s[i] + "," + height / 2 + ")"; });
}
}
</script>
希望标题说明了一切。
我正在处理 D3 笔刷移动事件。我想知道用户是移动了左画笔还是右画笔...?
我真的很想避免将鼠标位置存储在某处。
是否有相对简单的方法来解决这个问题..?
我能看到的最简单的方法:
// bind to at least start and end events
var brush = d3.brushX()
.extent([[0, 0], [width, height]])
.on("start brush end", brushmoved);
// handle it
var bs = "";
function brushmoved() {
var s = d3.event.selection;
if (d3.event.type === "start"){
bs = d3.event.selection;
} else if (d3.event.type === "end"){
if (bs[0] !== s[0] && bs[1] !== s[1]) {
console.log('moved both');
} else if (bs[0] !== s[0]) {
console.log('moved left');
} else {
console.log('moved right');
}
}
}
完整示例:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
circle {
fill-opacity: 0.2;
transition: fill-opacity 250ms linear;
}
circle.active {
stroke: #f00;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var data = d3.range(800).map(Math.random);
var svg = d3.select("svg"),
margin = {top: 194, right: 50, bottom: 214, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scaleLinear().range([0, width]),
y = d3.randomNormal(height / 2, height / 8);
var brush = d3.brushX()
.extent([[0, 0], [width, height]])
.on("start brush end", brushmoved);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
var circle = g.append("g")
.attr("class", "circle")
.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("transform", function(d) { return "translate(" + x(d) + "," + y() + ")"; })
.attr("r", 3.5);
var gBrush = g.append("g")
.attr("class", "brush")
.call(brush);
var handle = gBrush.selectAll(".handle--custom")
.data([{type: "w"}, {type: "e"}])
.enter().append("path")
.attr("class", "handle--custom")
.attr("fill", "#666")
.attr("fill-opacity", 0.8)
.attr("stroke", "#000")
.attr("stroke-width", 1.5)
.attr("cursor", "ew-resize")
.attr("d", d3.arc()
.innerRadius(0)
.outerRadius(height / 2)
.startAngle(0)
.endAngle(function(d, i) { return i ? Math.PI : -Math.PI; }));
gBrush.call(brush.move, [0.3, 0.5].map(x));
var bs = "";
function brushmoved() {
var s = d3.event.selection;
if (d3.event.type === "start"){
bs = d3.event.selection;
} else if (d3.event.type === "end"){
if (bs[0] !== s[0] && bs[1] !== s[1]) {
console.log('moved both');
} else if (bs[0] !== s[0]) {
console.log('moved left');
} else {
console.log('moved right');
}
}
if (s == null) {
handle.attr("display", "none");
circle.classed("active", false);
} else {
var sx = s.map(x.invert);
circle.classed("active", function(d) { return sx[0] <= d && d <= sx[1]; });
handle.attr("display", null).attr("transform", function(d, i) { return "translate(" + s[i] + "," + height / 2 + ")"; });
}
}
</script>