【问题标题】:D3.js adding intercept point and area between two pathsD3.js在两条路径之间添加拦截点和区域
【发布时间】:2016-02-14 17:36:07
【问题描述】:

我正在使用简单的 d3 可视化来教授一个简单的商业概念“收支平衡点”。我想通过使用三个滑块使可视化具有交互性。我想知道如何添加一个截点并绘制两条线之间的区域。这是我到目前为止的代码。我想在两条线之间添加截点和区域,并使它们与滑块交互。我想要的图表如下所示:

谢谢!

var margin = {top: 20, right: 60, bottom: 30, left: 60};
var width = 720 - margin.left - margin.right;
var height = 480 - margin.top - margin.bottom;
var xPadding = 20;
var yPadding = 35;

var xScale = d3.scale.linear()
               .domain([0, 10])
               .range([0, width]);

var yScale = d3.scale.linear()
               .domain([0, 50])
               .range([height, 0]);

var xAxis = d3.svg.axis()
              .scale(xScale)
              .orient("bottom")
              .ticks(10);

var yAxis = d3.svg.axis()
              .scale(yScale)
              .orient("left")
              .ticks(10);

  var line = d3.svg.line();
  var line1 = d3.svg.line();

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

// Adds X axis
svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis)
.append("text")
  .attr("class", "label")
  .attr("x", width)
  .attr("y", -6)
  .style("text-anchor", "end")
  .text("Units sold");

// Adds Y axis
svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
.append("text")
  .attr("class", "label")
  .attr("transform", "rotate(-90)")
  .attr("y", 6)
  .attr("dy", ".71em")
  .style("text-anchor", "end")
  .text("Sales")

  var path = svg.append('path');
  var path1 = svg.append('path');

  //y = mx + b

  var m = 0.5;
  var m1=1;
  var b = 130;

  updateSlope = function (newSlope) {
    m = newSlope;
    document.getElementById('slope').textContent = Math.round(newSlope*6);
    draw();
  };
  updateNewSlope = function (newSlope) {
    m1 = newSlope;
    document.getElementById('New_slope').textContent = Math.round(newSlope*6);
    draw();
  };
  updateYInt = function (newYInt) {
    b = newYInt;
    document.getElementById('yInt').textContent = Math.round(newYInt/8.6);
    draw();
  };

  var firstX = 0;
  var secondX = 600;

  yForX = function (x) {
    return -1 * x * m - b + height;
  };

  NewyForX = function (x) {
      return -1 * x * m1 + height;
    };

  // lol axis

  draw = function() {
    var point1 = [firstX, yForX(firstX)];
    var point2 = [secondX, yForX(secondX)];
    var point3 = [firstX, NewyForX(firstX)];
    var point4 = [secondX, NewyForX(secondX)];
    points = [point1, point2];
    points1 = [point3, point4];
    path.datum(points)
      .transition()
      .ease('linear')
      .attr('d', line)
      .attr('class', 'line');
    path1.datum(points1)
      .transition()
      .ease('linear')
      .attr('d', line)
      .attr('class', 'line1');
  }
  draw();
.line {
    stroke: green;
    stroke-width: 2px;
  }
  .line1 {
    stroke: blue;
    stroke-width: 2px;
  }
  
  .slider {
    float: left;
    width: 160px;
    margin-top: 30px;
  }
  .axis path,
  
  .axis line {
    fill: none;
    stroke: black;
    shape-rendering: crispEdges;
}

  .axis text {
    font-family: sans-serif;
    font-size: 11px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>
 <div> 
  <div id="chart1"></div>
  <div class='slider'>
    <div>Price/unit:<span id="New_slope"></span></div>
    <input type="range" min=0 max=2 step=.1 oninput="updateNewSlope(this.value)">
  </div>
  <div class='slider'>
    <div>Variable cost/unit:<span id="slope"></span></div>
    <input type="range" min=0 max=2 step=.1 oninput="updateSlope(this.value)">
  </div>
  <div class='slider'>
    <div>Fixed cost:<span id="yInt"></span></div>
    <input type="range" min=0 max=500 step=8.6 oninput="updateYInt(this.value)">
  </div>
 </div>
</body>

【问题讨论】:

    标签: javascript html css d3.js frontend


    【解决方案1】:

    将这一点添加到您的 draw 函数中应该相当简单:

    if(intersectionX && intersectionY) 
    {
       svg.append("circle")
          .attr("class", "intersection")
          .attr("fill", "red")
          .attr("cx", intersectionX)
          .attr("cy", intersectionY);
    } else {
       svg.selectAll(".intersection").remove();
    }
    

    下一个挑战是计算两点的交集,这实际上是数学问题而不是编码问题。我会指出几个链接供您阅读,因为 StackOverflow 并不是真正为格式化数学而设计的,但基本步骤是:

    • 求两条线的方程
    • 在两个方程中将x 设置为相同的值
    • 求解y 的方程 - 例如两个方程应该相等

    Calculate Intersection of 2 Lines
    Calculate Equation of Lines
    JSFiddle Example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-17
      相关资源
      最近更新 更多