无法将路径附加到svg

时间:2019-06-06 19:41:22

标签: javascript d3.js

我正在尝试向散点图添加回归线。我使用以下代码作为散点图的示例。 http://bl.ocks.org/majetisiri/57da501b3182bd08d17402261c7187f7

我将路径附加到svg,如下所示: Plot regression line on a scatter plot from regression coefficients

但是回归线不可见。

<!DOCTYPE html>
<html>
<meta charset="utf-8">

<!-- Example based on http://bl.ocks.org/mbostock/3887118 -->
<!-- Tooltip example from http://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html -->

<style>
body {
  font: 11px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.dot {
  stroke: #000;
}

.tooltip {
  position: absolute;
  width: 200px;
  height: 28px;
  pointer-events: none;
}
h1 {
        text-align: center;
        }

        h2 {
        text-align: left;
        }   
</style>
<body>

<p><span><label for="y-axis">Select y-axis</label></span>
<select id="y-value">
  <option value="FLFPR">Female LFPR</option>
  <option value="lnGDP">Log GDP per capita</option>
  <option value="Fertility">Fertility rate</option>
  </select>
<p><span><label for="x-axis">Select x-axis</label></span>
<select id="x-value"> 
  <option value="FLFPR">Female LFPR</option>
  <option value="lnGDP">Log GDP per capita</option>
  <option value="Fertility">Fertility rate</option> 
</select>

<button onclick="setGraph()">submit</button>

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://unpkg.com/d3-regression@1.2.3/dist/d3-regression.min.js"></script>


<script>

function drawGraph(xText, yText) {   
    $('svg').remove();
    var margin = {top: 20, right: 20, bottom: 30, left: 40},
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    /* 
     * value accessor - returns the value to encode for a given data object.
     * scale - maps value to a visual display encoding, such as a pixel position.
     * map function - maps from data value to display value
     * axis - sets up axis
     */ 

    // setup x 
    var xValue = function(d) { return d[xText];}, // data -> value
        xScale = d3.scale.linear().range([0, width]), // value -> display
        xMap = function(d) { return xScale(xValue(d));}, // data -> display
        xAxis = d3.svg.axis().scale(xScale).orient("bottom");

    // setup y
    var yValue = function(d) { return d[yText];}, // data -> value
        yScale = d3.scale.linear().range([height, 0]), // value -> display
        yMap = function(d) { return yScale(yValue(d));}, // data -> display
        yAxis = d3.svg.axis().scale(yScale).orient("left");

    // setup fill color
    var cValue = function(d) { return d.IG;},
        color = d3.scale.category20();

    // add the graph canvas to the body of the webpage
    var svg = d3.select("body").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 + ")");

    // add the tooltip area to the webpage
    var tooltip = d3.select("body").append("div")
        .attr("class", "tooltip")
        .style("opacity", 0);

    // load data
    d3.csv("scatter2.csv", function(error, data) {


      // change string (from CSV) into number format
      data.forEach(function(d) {
        d[yText] = +d[yText];
        d[xText] = +d[xText];
    //console.log (d.School);
    //console.dir (d);
      });

      // don't want dots overlapping axis, so add in buffer to data domain
      xScale.domain([d3.min(data, xValue)-1, d3.max(data, xValue)+1]);
      yScale.domain([d3.min(data, yValue)-1, d3.max(data, yValue)+1]);

      // 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(xText);

      // 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(yText);

      // draw dots
      svg.selectAll(".dot")
          .data(data)
        .enter().append("circle")
          .attr("class", "dot")
          .attr("r", 6.6)
          .attr("opacity", 0.9)
          .style("stroke", function(d) { return color(cValue(d));}) 
          .attr("cx", xMap)
          .attr("cy", yMap)
          .style("fill", function(d) { return color(cValue(d));}) 
          .on("mouseover", function(d) {
              tooltip.transition()
                   .duration(200)
                   .style("opacity", .9);
              tooltip.html(d["Player"] + "<br/> " + d.School + "<br/>(" + xValue(d) 
                + ", " + yValue(d) + ")")
                   .style("left", (d3.event.pageX + 10) + "px")
                   .style("top", (d3.event.pageY - 28) + "px");
          })
          .on("mouseout", function(d) {
              tooltip.transition()
                   .duration(500)
                   .style("opacity", 0);
          });

      // draw legend
      var legend = svg.selectAll(".legend")
          .data(color.domain())
        .enter().append("g")
          .attr("class", "legend")
          .attr("transform", function(d, i) { return "translate(10," + (i+7) * 20 + ")"; });

      // draw legend colored rectangles
      legend.append("rect")
          .attr("x", width - 18)
          .attr("width", 18)
          .attr("height", 18)
          .style("fill", color);

      // draw legend text
      legend.append("text")
          .attr("x", width - 24)
          .attr("y", 9)
          .attr("dy", ".35em")
          .style("text-anchor", "end")
          .text(function(d) { return d;})

       // get regression coefficients     
        regData = data.map(item => ({x: item[xText], y: item[yText]}));
        res = drawRegressionLine(regData) 
        console.log("regression results")
        console.log(res)

    var line = d3.svg.line()
    .x(function(d) { return d.x; })
    .y(function(d) { return d.y; })
    .interpolate("linear");      

    // var line = d3.svg.line()
    //              .x(function(d) { return xScale(d['x']); })
    //              .y(function(d) { return yScale(d['y']); });


    // var lineFunction = d3.svg.line()
    //                       .x(function(d) { return d.x; })
    //                       .y(function(d) { return d.y; })
    //                       .interpolate("linear");

    var regLine = svg.append("path")
      .datum(res)
      .attr("d", line)
      .style("stroke", "steelblue")
      .style("stroke-width", "6px");   


    //  var lineGraph = svg.append("path")
    //                     .attr("d", line(res))
    //                     .attr("stroke", "blue")
    //                     .attr("stroke-width", 2)
    //                     .attr("fill", "black");   

    });

}

// draw regression line
function drawRegressionLine(regData) {
    console.log("beginning")
    console.log("inside draw regression lilne")
linearRegression = d3.regressionLinear()
   .x(d => d.x)
   .y(d => d.y);
res = linearRegression(regData)
return res;
}

// drawGraph('Passing TD', 'Rushing TD');

function setGraph() {
    console.log("inside set graph")
    console.log($('#x-value').val())
    drawGraph($('#x-value').val(), $('#y-value').val());
}
</script>
</body>
</html>

请帮助我找到代码有什么问题。

1 个答案:

答案 0 :(得分:3)

您似乎没有将线性回归传递到x和y尺度。

尝试:

var line = d3.svg.line()
    .x(function(d) { return xScale(d[0]); })
    .y(function(d) { return yScale(d[1]); })
    .interpolate("linear");