2016-07-19 3 views
0

D3 버전 4에서는 브러시 개념이 크게 수정 된 것으로 보입니다. 다른 코드를 업데이트하기 위해 새로운 패러다임을 이해하기 위해 솔질하는 아주 간단한 예제를 작성하려고합니다. 내 현재 코드는 아래와 같습니다. 브러시가 만들어져 적절한 요소와 연결되지만 사용자에게는 보이지 않거나 활성화되지 않습니다. 그러나 brush.move 호출은 예상대로 콘솔에보고합니다. 브러시 동작을 상단 데이터 패널에 적용하고 새로운 패러다임을 통해 브러시 크기가 포함 된 요소 (First paragraph here)에서 추출되었음을 명확히 알 수 있습니다. 결국 브러시 처리 된 영역이 아래쪽 패널에 표시됩니다. 내가 뭘 놓치고 있니?D3 버전 4 : 브러쉬가 표시되지 않지만 액세스 가능하지만 백그라운드에서 활성 상태입니다.

<!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> 

답변

0

당신은,이 브러시 이벤트를 "먹는"하는 rect에 브러시를 추가하고 외관의 마스킹된다. examples 일부에 표시된대로 해당 요소를 g으로 변경하십시오.

<!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("g") // outline original data region 
 
    .attr("id", "orig_data") 
 
    .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>

+0

감사 마크. 그러나 브러쉬는 메인 SVG 컨테이너에 "부착"되어 있으므로 아무 데나 갈 수 있습니다. 데이터 1 영역 (즉, 상단 패널)으로 만 제한하고 싶습니다. 그리고 그 개요 직사각형을 유지하고 싶습니다 (나중에 추가 할 수 있습니까?). –