javascript - D3 无法同时绘制两个画笔

标签 javascript d3.js

所以我试图制作一些用户可以在折线图中拖动并创建两个相同大小的画笔的东西,问题是在我尝试绘制第二个画笔后画笔消失了。我尝试创建单独的 attr 和单独的画笔调用,但仍然无法做到。 这是我的代码https://jsfiddle.net/f0gxs41t/

有什么帮助吗?

    <!DOCTYPE html>
<html>
<head>
    <svg width="960" height="400"></svg>
  <meta charset="utf-8">
  <title>
    line chart with drag and drop
  </title>
  <script src="https://d3js.org/d3.v3.min.js"></script>
  <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
  <script src="./line_graph.js"></script>
  <link rel="stylesheet" type= "text/css" href="./style.css">
</head>
<body>
</body>
</html>

js文件:

var data=[1,5,2,7,4,7,8,9,5,3,6,8,2,3,5,9,8,5]

var svg=d3.select("svg")
var margin={top:100,bottom:50,left:100,right:0},
   width = +svg.attr("width") - margin.left - margin.right,
   height = +svg.attr("height") - margin.top - margin.bottom,
   g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");


var x_extent=d3.extent(data,function(d,i){return i})
var y_extent=d3.extent(data,function(d,i){return d})


x=d3.scale.linear()
.range([0,width])
.domain(x_extent)

y=d3.scale.linear()
.range([height,0])
.domain(y_extent)

var line=d3.svg.line()
.x(function(d,i){ return x(i)})
.y(function(d,i){return y(d)})

var xAxis = d3.svg.axis().scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis().scale(y)
    .orient("left");

// g.append("g")
// .append("text")
// .attr("fill", "#000")
// .attr("transform","rotate(-90)")
// .attr("y",-35)
// .attr("dy","0.71em")
// .attr("text-anchor","end")
// .text("break something")

g.append("path")
.attr("class","line")
.datum(data)
.attr("d",line)

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate("+margin.left+"," + (height+margin.top) + ")")
    .call(xAxis);

// Add the Y Axis
svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate("+margin.left+ ","+margin.top+")")
    .call(yAxis);

var focus = svg.append("g")
    .attr("class", "focus")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// if (brush.empty()!==true){
//
// }



var brushes = [];
var parent_brush=d3.svg.brush()
          .x(x)
          .on("brushend",brushed)

var brush1=d3.svg.brush()
          .x(x)
          .on("brushend",brushed)



function brushed(){
  if (parent_brush.empty()==true){
    console.log(parent_brush,"empty")
  }
  else {
    brush_width=parent_brush.extent()[1]-parent_brush.extent()[0]
        console.log(parent_brush,"not empty")
  }
}


svg.append("g")
.attr("class","parent")
.call(parent_brush)
.selectAll("rect")
.attr("x",margin.left)
.attr("y",margin.top)
.attr("height",height)
.style("fill","orange")
.style("fill-opacity",".2")


svg.append("g")
.attr("class","child")
.call(brush1)
.selectAll("rect")
.attr("x",margin.left)
.attr("y",margin.top)
.attr("height",height)
.style("fill","orange")
.style("fill-opacity",".2")

CSS 文件:

.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}
.hover-line {
  stroke: #6F257F;
  stroke-width: 2px;
  stroke-dasharray: 3,3;
}
.area {
  fill: lightsteelblue;
}
.line{
  fill:none;
  stroke:brown;
  stroke-linejoin:round;
  stroke-linecap:round;
  stroke-width:1.5
}

.focus circle {
  fill: none;
  stroke: steelblue;
}
.brush {
  fill: grey;
  pointer-events: all;
  fill-opacity:0.3;
}

.resize  {
  fill: grey;
  pointer-events: all;
  fill-opacity:0.7;
}

最佳答案

考虑使用 d3.js v4...

子画笔是在父画笔“结束”事件处理程序中创建的,我们还需要禁用新的父画笔选择。

var parent_brush = d3.brushX()
  .extent([
    [margin.left, margin.top],
    [margin.left + width, margin.top + height]
  ])
  .on("end", brushedParent);
var child_brush;

svg.append("g")
  .attr("class", "parent")
  .call(parent_brush);

function brushedParent() {
  // remove new brush selection capture area
  svg.select('.parent .overlay').remove();

  if (!child_brush) {
    child_brush = d3.brushX()
      .extent([
        [margin.left, margin.top],
        [margin.left + width, margin.top + height]
      ])
      .on("end", brushedChild);

    svg.append("g")
      .attr("class", "child")
      .call(child_brush);
  }
}

function brushedChild() {
  // remove new brush selection capture area
  svg.select('.child .overlay').remove();

  child_selection = d3.brushSelection(svg.select('.child').node());

  var parent_selection = d3.brushSelection(svg.select('.parent').node());
  var parent_width = parent_selection[1] - parent_selection[0];
  var resized_child = [child_selection[0], child_selection[0] + parent_width];

  child_brush.on("end", null);
  child_brush.move(svg.select('.child'), resized_child);
}

这是工作代码片段:

var data = [1, 5, 2, 7, 4, 7, 8, 9, 5, 3, 6, 8, 2, 3, 5, 9, 8, 5]

var svg = d3.select("svg")
var margin = {
    top: 100,
    bottom: 50,
    left: 100,
    right: 0
  },
  width = +svg.attr("width") - margin.left - margin.right,
  height = +svg.attr("height") - margin.top - margin.bottom,
  g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var x_extent = d3.extent(data, function(d, i) {
  return i
})
var y_extent = d3.extent(data, function(d, i) {
  return d
})

x = d3.scaleLinear()
  .range([0, width])
  .domain(x_extent)

y = d3.scaleLinear()
  .range([height, 0])
  .domain(y_extent)

var line = d3.line()
  .x(function(d, i) {
    return x(i)
  })
  .y(function(d, i) {
    return y(d)
  })

var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);

g.append("path")
  .attr("class", "line")
  .datum(data)
  .attr("d", line)

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(" + margin.left + "," + (height + margin.top) + ")")
  .call(xAxis);

// Add the Y Axis
svg.append("g")
  .attr("class", "y axis")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
  .call(yAxis);

var focus = svg.append("g")
  .attr("class", "focus")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var brushes = [];
var parent_brush = d3.brushX()
  .extent([
    [margin.left, margin.top],
    [margin.left + width, margin.top + height]
  ])
  .on("end", brushedParent);
var child_brush;

svg.append("g")
  .attr("class", "parent")
  .call(parent_brush);

function brushedParent() {
  // remove new brush selection capture area
  svg.select('.parent .overlay').remove();

  if (!child_brush) {
    child_brush = d3.brushX()
      .extent([
        [margin.left, margin.top],
        [margin.left + width, margin.top + height]
      ])
      .on("end", brushedChild);

    svg.append("g")
      .attr("class", "child")
      .call(child_brush);
  }
}

function brushedChild() {
  // remove new brush selection capture area
  svg.select('.child .overlay').remove();

  child_selection = d3.brushSelection(svg.select('.child').node());

  var parent_selection = d3.brushSelection(svg.select('.parent').node());
  var parent_width = parent_selection[1] - parent_selection[0];
  var resized_child = [child_selection[0], child_selection[0] + parent_width];

  child_brush.on("end", null);
  child_brush.move(svg.select('.child'), resized_child);
}
.axis path,
.axis line {
  fill: none;
  stroke: grey;
  stroke-width: 1;
  shape-rendering: crispEdges;
}

.hover-line {
  stroke: #6F257F;
  stroke-width: 2px;
  stroke-dasharray: 3, 3;
}

.area {
  fill: lightsteelblue;
}

.line {
  fill: none;
  stroke: brown;
  stroke-linejoin: round;
  stroke-linecap: round;
  stroke-width: 1.5
}

.focus circle {
  fill: none;
  stroke: steelblue;
}

.brush {
  fill: grey;
  pointer-events: all;
  fill-opacity: 0.3;
}

.resize {
  fill: grey;
  pointer-events: all;
  fill-opacity: 0.7;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="400"></svg>

关于javascript - D3 无法同时绘制两个画笔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44083715/

相关文章:

javascript - 在 Angular 服务中包含 Jquery

javascript - 添加 cordova.js 时混合移动应用程序崩溃

javascript - d3.js 中每一行的多个列值的总和

javascript - d3.js 如何动态添加节点到树

javascript - 从图像 URL 中提取颜色

trello - 如何从卡片页面检索 Trello Board 短链接?

javascript - 使用 css 遇到一些字符后转到新行

javascript - 单击其他元素添加 SVG 元素

javascript - d3 饼图全黑填充,d3.schemeCategory20c 未被调用

javascript - 如何用 sinon 模拟 d3.select.selectall ?