2016-12-22 3 views
0

이 간단한 막 대형 차트 http://codepen.io/ksh/pen/BQEGRK을 살펴보면 빨간색 점선 영역을 위아래로 드래그하여 슬라이드하면 되돌아 오는 브러시 움직임이 보입니다. 제대로하기 위해서 무엇을해야합니까? 내가 가진 두 번째 질문은 어떻게 대시 영역을 항상 보이게 할 수 있으며 같은 요소를 다시 끌 수 있습니다. 기본적으로 바 높이가 0 일 때 사라지며 막대를 더 높은 자리 위치로 슬라이드 할 수 없습니다.d3js 막대 차트가 거꾸로되어 있고 슬라이딩 브러시가

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(); 
}; 

답변

0

당신이 뒤집어하기 위해 SVG를 변형하기 때문에 당신은 이상한 브러시 동작을 얻고있다 :

transform: rotate(180deg); 

은 당신이 정말로 차트와 라벨 거꾸로 될를 원하십니까? 어느 쪽이든, 나는 변환을 제거하고 변환되지 않은 공간에서 작업하며 원하는 곳에서 축과 막대를 이동하는 것이 더 쉬울 것이라고 생각합니다.

반전을 호출 할 때 예외가 없도록 [0] < = 선택 [1]을 선택해야합니다. 선택 영역이 비어 있으면 [0,0] d3은 자동으로 선택 영역과 핸들을 숨 깁니다. 그것은 핸들 위치를 선택 영역으로부터 벗어나게하므로 핸들을 직접 보이게 유지해야합니다. 브러시 움직임에서 이와 비슷한 것 :

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; 
} 

또는 선택 영역이 비어 있지 않도록 할 수 있습니다.

+0

회전 기능이 필요하며이 간단한 예제에서 가장 간단한 방법으로 회전을 추가했습니다. 나는 라벨에 신경 쓰지 않는다. 전체 차트가 회전해야한다. 선생님 덕분에 선택 값을 확인하는 방법을 찾았습니다. v4가'd3.brushSelection (node) '인'd3.event.selection'입니다. 두 값을 비교하고 있는데, 원래의'.handle' 요소는'display : none'과 그 외 모든 값을받습니다. 위치, 크기를 정의하는 속성이 제거됩니다. 나는 그것을 막고 싶다. – ksh

+0

'let eventSelection = d3.brushSelection (this); if ((Math.round (eventSelection [0] * 10)/10)! == (eventSelection [1] * 10)) {d3.select (this) .selectAll ('. handle ') .style ('display ','inline ') .attr ('x ','... ') 정의한 모든 속성이 적용되지 않고 디스플레이의 스타일 만 작동합니다. . 내 목표는 [여기] (http://bl.ocks.org/mbostock/6498000)와 같은 bahaviour가 있지만 unfortunatelly d3 v3을 사용하여 작성되었으며 d3 v4에서 필요합니다. – ksh

관련 문제