2016-12-22 6 views
0

Wenn Sie sich dieses einfache Balkendiagramm http://codepen.io/ksh/pen/BQEGRK ansehen, und wenn Sie rote gestrichelte Bereiche nach oben oder unten ziehen und verschieben, sehen Sie eine umgekehrte Pinselbewegung. Was soll ich tun, um es richtig zu machen? Die zweite Frage, die ich habe, wie kann ich meine gestrichelten Bereiche immer sichtbar machen und das gleiche Element wieder ziehen. Standardmäßig verschwinden sie, wenn die Balkenhöhe Null ist, und es ist nicht möglich, den Balken zu einer höheren Position zu verschieben.d3js Balkendiagramm über Kopf und gleitende Bürsten

var margin = {top: 20, right: 20, bottom: 50, left: 70}, 
    width = 400 - margin.left - margin.right, 
    height = 400 - margin.top - margin.bottom, 
    delim = 4; 

var scale = d3.scaleLinear() 
    .domain([0, 21]) 
    .rangeRound([height, 0]); 

var x = d3.scaleLinear() 
    .domain([0, barData.length]) 
    .rangeRound([0, width]); 

var y = d3.scaleLinear() 
    .domain([0, 21]) 
    .rangeRound([height, 0]); 

var svg = d3.select('#chart') 
    .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 + ")"); 

svg.append("g") 
    .attr("transform", "translate(0," + height + ")") 
    .call(d3.axisBottom(x)); 

svg.append("g") 
    .call(d3.axisLeft(y)); 

function draw() { 
    x.domain([0, barData.length]); 

var brush = d3.brushY() 
    .extent(function (d, i) { 
     return [[x(i)+ delim/2, 0], 
       [x(i) + x(1) - delim/2, height]];}) 
    .on("brush", brushmove); 

var svgbrush = svg.selectAll('.brush').data(barData); 

svgbrush.enter() 
    .append('g') 
     .attr('class', 'brush') 
    .merge(svgbrush) 
    .append('g') 
     .call(brush) 
     .call(brush.move, function (d){return [d.value, 0].map(scale);}); 

svgbrush.exit().remove(); 

svgbrush 
    .append('text') 
     .attr('y', function (d){return scale(d.value) + 25;}) 
     .attr('x', function (d, i){return x(i) + x(0.5);}) 
     .attr('dx', '-.60em') 
     .attr('dy', -5) 
     .style('fill', 'white') 
     .text(function (d) {return d3.format('.2')(d.value);}) 

function brushmove() { 

    var d0 = d3.event.selection.map(scale.invert); 
    var d = d3.select(this).select('.selection');; 
    var d1 =[d0[0], 0]; 

    if (!d3.event.sourceEvent) return; 
    if (!d3.event.selection) return; 
    if (d3.event.sourceEvent.type === "brush") return; 

    d.datum().value = d0[0]; 
    d3.select(this).call(d3.event.target.move, d1.map(scale)); 

    svgbrush 
     .selectAll('text') 
      .attr('y', function (d){return scale(d.value) + 25;}) 
      .text(function (d) {return d3.format('.2')(d.value);}); 
} 
draw(); 

function upadateChartData() { 
    var newBarsToAdd = document.getElementById('charBarsCount').value; 
    var newBarData = function() { 
     return { index: _.uniqueId(), value: _.random(1, 20) } 
    }; 

    newBarData = _.times(newBarsToAdd, newBarData); 
    barData = _.concat(barData, newBarData) 

    draw(); 
}; 

Antwort

0

Sie das seltsame Bürste Verhalten bekommen, weil Sie die svg, um es wiederum den Kopf:

transform: rotate(180deg); 

Wollen Sie Ihr Diagramm und Etiketten Sie wirklich den Kopf zu sein? Wie auch immer, ich denke, es wäre einfacher, die Transformation zu entfernen, in nicht transformiertem Raum zu arbeiten und die Achsen und Balken dorthin zu verschieben, wo Sie sie haben wollen.

Sie sollten sicherstellen, dass die Auswahl [0] < = Auswahl [1], so dass Sie keine Ausnahmen haben, wenn Sie invertieren aufrufen. Wenn die Auswahl leer ist [0,0] d3 blendet die Auswahl und die Griffe automatisch aus. Es stützt die Griffposition von der Auswahl ab, also denke ich, dass Sie es selbst zeichnen müssen, um es sichtbar zu halten. So etwas in browsmove:

if (!d3.event.selection) { 
     var index = parseInt(d.datum().index) - 1; 
     d3.select(this).selectAll('.handle') 
     .style("display","inline") 
     .attr("x", x(index)) 
     .attr("y", scale(0)) 
     .attr("width", x(index+1) - x(index)) 
     .attr("height", delim); 
     return; 
} 

Alternativ könnten Sie verhindern, dass die Auswahl leer wird.

+0

Ich muss Feature drehen und in diesem einfachen Beispiel habe ich Rotation auf einfachste Weise hinzugefügt. Ich interessiere mich nicht für Etiketten, das ganze Diagramm soll gedreht werden. Dank Ihnen habe ich gefunden, wie man Auswahlwerte überprüft. 'd3.event.selection' was in v4 ist' d3.brushSelection (node) .' Ich vergleiche beide Werte und wenn sie gleich sind, erhält das ursprüngliche '.handle'-Element' display: none' und alle anderen Attribute, die Position, Größe definieren, werden entfernt. Ich möchte es verhindern. – ksh

+0

'let eventSelection = d3.brushSelection (this); if ((Math.round (eventSelection [0] * 10)/10)! == (Math.round (eventSelection [1] * 10)/10)) {d3.select (this) .selectAll ('. Handle ') .style (' display ',' inline ') .attr (' x ',' ... ') } ' Alle Attribute, die ich definiere, werden nicht angewendet, nur Stil mit seiner Anzeige funktioniert . Mein Ziel ist Bahaviour als [hier] (http://bl.ocks.org/mbstock/6498000), aber unglücklicherweise ist es mit d3 v3 geschrieben und ich will es in d3 v4 – ksh