简体   繁体   中英

How to fix a multiple brush chart in d3

I am so close this is killing me. I've generated a simple brush for one column and it's generating the limits it's set to perfectly. The thing is I'd like multiple brushes for multiple columns ['A', 'B', 'C', 'D']. I could write this out four times, but I've put it in a function that doesn't appear to work. Please see the working code below, I've commented out the part that doesn't work. I know I need to somehow bind the data and loop through, but how do I do this efficiently?

 var margin = { top: 20, right: 20, bottom: 30, left: 50 }, width = 960 - margin.left - margin.right, height = 180 - margin.top - margin.bottom; var x = d3.scale.ordinal() .domain(["A", "B", "C", "D"]) .rangeBands([0, 200]) var y = d3.scale.linear() .range([height, 0]) .domain([0, 100]) var xAxis = d3.svg.axis() .scale(x) var svg = d3.select("#timeline").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // define brush control element and its events var brush = d3.svg.brush().y(y) .on("brushend", () => console.log('A Extent: ', brush.extent())) // create svg group with class brush and call brush on it var brushg = svg.append("g") .attr("class", "brush") .call(brush); // set brush extent to rect and define objects height brushg.selectAll("rect") .attr("x", x("A")) .attr("width", 20); /* var brush = (d) => { var brush = d3.svg.brush().y(y) .on("brushend", () => console.log(d, ' Extent: ', brush.extent())) var brushg = svg.append("g") .attr("class", "brush") .call(brush1); brushg.selectAll("rect") .attr("x", x("A")) .attr("width", 20); } */
 .brush { fill: lightgray; fill-opacity: .75; shape-rendering: crispEdges; }
 <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.6/d3.min.js'></script> <div class="container"> <div id="timeline"></div> </div>

Treat the brushes as data, as they map to each ordinal value on the x axis. Create the brushes with .enter and append all the necessary functionality. The .each function is similar to call, but runs on each element separately. This is very useful to contain the generation of the brushes.

 xData = ["A", "B", "C", "D"]; var margin = { top: 20, right: 20, bottom: 30, left: 50 }, width = 960 - margin.left - margin.right, height = 180 - margin.top - margin.bottom; var x = d3.scale.ordinal() .domain(xData) .rangeBands([0, 200]) var y = d3.scale.linear() .range([height, 0]) .domain([0, 100]) var xAxis = d3.svg.axis() .scale(x) var svg = d3.select("#timeline").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); const brushes = svg.selectAll('g.brush') .data(xData) .enter() .append('g') .attr('class', 'brush') .each(function(d) { const el = d3.select(this); const brush = d3.svg.brush().y(y).on("brushend", () => console.log(d, ' Extent: ', brush.extent())); el.call(brush); el.selectAll("rect") .attr("x", x(d)) .attr("width", 20); });
 .brush { fill: lightgray; fill-opacity: .75; shape-rendering: crispEdges; }
 <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.6/d3.min.js'></script> <div class="container"> <div id="timeline"></div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM