Mit D3 Version 4 scheint das Pinselkonzept deutlich überarbeitet zu sein. Um irgendeinen anderen Code zu aktualisieren, versuche ich ein sehr einfaches Beispiel für das Putzen zu schreiben, um sicherzugehen, dass ich das neue Paradigma verstehe. Mein aktueller Code ist unten. Der Pinsel wird erstellt und dem richtigen Element zugeordnet, ist aber für den Benutzer nicht sichtbar oder aktiv. Der Aufruf brush.move
führt jedoch wie erwartet zu einem Bericht an die Konsole. Ich möchte, dass die Pinselaktion auf das obere Datenfeld angewendet wird, und das neue Paradigma macht deutlich, dass der Pinselumfang aus dem enthaltenden Element gezogen wird (1. paragraph here). Schließlich wird der gebürstete Bereich im unteren Bereich angezeigt. Was vermisse ich?D3 Version 4: Pinsel nicht sichtbar/zugänglich, aber im Hintergrund aktiv
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src = "http://d3js.org/d3.v4.min.js"> </script>
</body>
<script>
// Using version 4 of d3!!!
// Demonstrate the simplest possible brush in version 4
var margin = {top: 20, right: 20, bottom: 20, left: 20},
width = 600 - margin.left - margin.right,
height = width/2 - margin.top - margin.bottom,
offset = 20; // offset between original and brushed data
var xdata = d3.range(0, 20);
var ydata = [1, 4, 5, 9, 10, 14, 15, 15, 11, 10, 5, 5, 4, 8, 7, 5, 5, 5, 8, 10];
var xy = []; // start empty, add each element one at a time
for(var i = 0; i < xdata.length; i++) {
xy.push({x: xdata[i], y: ydata[i]});
}
var xscl = d3.scaleLinear()
.domain(d3.extent(xy, function(d) {return d.x;})) //use just the x part
.range([margin.left, width + margin.left])
var yscl = d3.scaleLinear()
.domain(d3.extent(xy, function(d) {return d.y;})) // use just the y part
.range([height + margin.top, margin.top])
var myline = d3.line()
.x(function(d) { return xscl(d.x);}) // apply the x scale to the x data
.y(function(d) { return yscl(d.y);}) // apply the y scale to the y data
var brush = d3.brush()
// .extent([[margin.left, margin.top],[margin.right, margin.bottom]])
.on("end", brushed);
function brushed() {
if (!d3.event.selection) return; // ignore empty selections
var s = d3.event.selection,
x0 = s[0][0],
y0 = s[0][1],
x1 = s[1][0],
y1 = s[1][1];
console.log("brush coords:", s)
}
var svg = d3.select("body")
.append("svg")
.attr("width",window.innerWidth)
.attr("height",window.innerHeight)
var data1 = svg.append("rect") // outline original data region
.attr("id", "orig_data")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("stroke", "black")
.style("stroke-width", 0.5);
var data2 = svg.append("rect") // outline brushed data region
.attr("x", margin.left)
.attr("y", margin.top + offset + height)
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("stroke", "black")
.style("stroke-width", 0.5);
svg.append("path") // draw original data
.attr("class", "line")
.attr("d", myline(xy)) // use the value of myline(xy) as the data, 'd'
.style("fill", "none")
.style("stroke", "red")
.style("stroke-width", 2);
var brush_region = d3.select("#orig_data")
.append("g")
.attr("class", "brush")
.call(brush)
.call(brush.move, [[100, 100,],[200, 200,]]);
</script>
Dank Mark. Allerdings kann der Pinsel, wie Sie ihn haben, überall hingehen, da er an den Haupt-Svg-Container "angehängt" ist. Ich möchte es nur auf die Region "data1" beschränken (d. H. Im oberen Bereich). Und ich möchte dieses umreißende Rechteck behalten (kann das in einem späteren Schritt hinzugefügt werden?). –