简体   繁体   中英

filtering data and working with scales - d3js

I have a simple scatterplot in d3js. The aim of the visualization is to fade out points on a selection. This works. Congruent with this, a new trendline should appear only for those selected points as well as an updated slope equation and R2 value. The fading of points and updating of slope equation/R2 values is working on selection. However, the trendline appears to be truncated and not scaled correctly, but I can't figure out why.

Here is a working version.

Following the on.change the following code is executed:

filteredData  = filterJSON(data, 'name', value); // gets filtered json data

  var x = d3.scaleLinear()
      .range([0,width]);

  var y = d3.scaleLinear()
      .range([height,0]);


  var xSeries1 = filteredData.map(function(e) { return e.x; }); // new x values
  var ySeries1 = filteredData.map(function(e) { return e.y; }); // new y values
  var rsq1 = leastSquares(xSeries1,ySeries1); // calculates r2/slope etc. - see function below

 // Add trendline
  ptAx1 =  d3.min(xSeries1);
  ptAy1 =  rsq1[0] *  d3.min(xSeries1) + rsq1[1];
  ptBy1 =  d3.min(ySeries1);
  ptBx1 =  (d3.min(ySeries1) - rsq1[1]) / rsq1[0];



  svg.append("line")
        .attr("class", "regression")
        .attr("x1", x(ptAx1))   
        .attr("y1", y(ptAy1))
        .attr("x2", x(ptBx1))
        .attr("y2", y(ptBy1));




// calculate linear regression
function leastSquares(xSeries,ySeries) {

  var reduceSumFunc = function(prev, cur) { return prev + cur; };

  var xBar = xSeries.reduce(reduceSumFunc) * 1.0 / xSeries.length;
  var yBar = ySeries.reduce(reduceSumFunc) * 1.0 / ySeries.length;

  var ssXX = xSeries.map(function(d) { return Math.pow(d - xBar, 2); })
    .reduce(reduceSumFunc);

  var ssYY = ySeries.map(function(d) { return Math.pow(d - yBar, 2); })
    .reduce(reduceSumFunc);

  var ssXY = xSeries.map(function(d, i) { return (d - xBar) * (ySeries[i] - yBar); })
    .reduce(reduceSumFunc);

  var slope = ssXY / ssXX;
  var intercept = yBar - (xBar * slope);
  var rSquare = Math.pow(ssXY, 2) / (ssXX * ssYY);

  return [slope, intercept, rSquare];
}

This code works well when all data points (no filtering of data), but doesn't when filtering occurs.

This is all points - trendline ok 在此处输入图片说明

This is filtered points - trendline truncated 在此处输入图片说明

It looks like you left "min" where you meant "max" in assigning values to ptBy1 and ptBx1

Made this change in your "blockbuilder" and it seemed to work as intended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM