2013-07-01 94 views
2

我期待實現使用d3.js庫interactivey目的圖形GGPLOT2類型分佈圖繪製直線。我喜歡ggplot2,但用戶對交互式圖表感興趣。我一直在探索d3.js庫,並似乎有很多不同的圖形能力,但我真的沒有看到任何統計圖表像直線,給出一個散點圖預測等,是有可能也直線增加了圖形。你怎麼在d3.js

我有這個示例腳本繪製散點圖。我如何在d3.js中的這個圖中添加線性線?

// data that you want to plot, I've used separate arrays for x and y values 
var xdata = [5, 10, 15, 20], 
    ydata = [3, 17, 4, 6]; 

// size and margins for the chart 
var margin = {top: 20, right: 15, bottom: 60, left: 60} 
    , width = 960 - margin.left - margin.right 
    , height = 500 - margin.top - margin.bottom; 

// x and y scales, I've used linear here but there are other options 
// the scales translate data values to pixel values for you 
var x = d3.scale.linear() 
      .domain([0, d3.max(xdata)]) // the range of the values to plot 
      .range([ 0, width ]);  // the pixel range of the x-axis 

var y = d3.scale.linear() 
      .domain([0, d3.max(ydata)]) 
      .range([ height, 0 ]); 

// the chart object, includes all margins 
var chart = d3.select('body') 
.append('svg:svg') 
.attr('width', width + margin.right + margin.left) 
.attr('height', height + margin.top + margin.bottom) 
.attr('class', 'chart') 

// the main object where the chart and axis will be drawn 
var main = chart.append('g') 
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')') 
.attr('width', width) 
.attr('height', height) 
.attr('class', 'main') 

// draw the x axis 
var xAxis = d3.svg.axis() 
.scale(x) 
.orient('bottom'); 

main.append('g') 
.attr('transform', 'translate(0,' + height + ')') 
.attr('class', 'main axis date') 
.call(xAxis); 

// draw the y axis 
var yAxis = d3.svg.axis() 
.scale(y) 
.orient('left'); 

main.append('g') 
.attr('transform', 'translate(0,0)') 
.attr('class', 'main axis date') 
.call(yAxis); 

// draw the graph object 
var g = main.append("svg:g"); 

g.selectAll("scatter-dots") 
    .data(ydata) // using the values in the ydata array 
    .enter().append("svg:circle") // create a new circle for each value 
     .attr("cy", function (d) { return y(d); }) // translate y value to a pixel 
     .attr("cx", function (d,i) { return x(xdata[i]); }) // translate x value 
     .attr("r", 10) // radius of circle 
     .style("opacity", 0.6); // opacity of circle 

回答

3

要將行添加到您的情節,所有你需要做的是一些線SVGs附加到主SVG(chart)或到包含SVG元素(main)組。

你的代碼看起來像下面這樣:

chart.append('line') 
    .attr('x1',x(10)) 
    .attr('x2',x(20)) 
    .attr('y1',y(5)) 
    .attr('y2',y(10)) 

這將借鑑(10,5)一行(20,10)。你可以類似地爲你的線創建一個數據集並追加一大堆。

您可能感興趣的一件事是SVG路徑元素。對於線條而言,這比一次繪製一條直線段更爲常見。該文檔是here.

在另一方面你可能會發現很容易與D3的數據,如果你創造這一切作爲一個對象的工作。例如,如果你的數據在下面的表格:

data = [{x: 5, y:3}, {x: 10, y:17}, {x: 15, y:4}, {x: 20, y:6}] 

你可以使用:

​​

如果你的數據變得更加複雜這將消除潛在的雜亂索引。

2

UPDATE:這裏是相關的塊:https://bl.ocks.org/HarryStevens/be559bed98d662f69e68fc8a7e0ad097

我寫這個函數來計算從數據的線性迴歸,JSON格式。

這需要5個參數:對數據的列名上的x軸 3)中的數據的列名上的繪製繪製 1)你的數據 2)y軸 4)的最小值您的x軸 5)

我得到了公式用於計算線性迴歸從http://classroom.synonym.com/calculate-trendline-2709.html

function calcLinear(data, x, y, minX, minY){ 
    ///////// 
    //SLOPE// 
    ///////// 

    // Let n = the number of data points 
    var n = data.length; 

    var pts = []; 
    data.forEach(function(d,i){ 
    var obj = {}; 
    obj.x = d[x]; 
    obj.y = d[y]; 
    obj.mult = obj.x*obj.y; 
    pts.push(obj); 
    }); 

    // Let a equal n times the summation of all x-values multiplied by their corresponding y-values 
    // Let b equal the sum of all x-values times the sum of all y-values 
    // Let c equal n times the sum of all squared x-values 
    // Let d equal the squared sum of all x-values 
    var sum = 0; 
    var xSum = 0; 
    var ySum = 0; 
    var sumSq = 0; 
    pts.forEach(function(pt){ 
    sum = sum + pt.mult; 
    xSum = xSum + pt.x; 
    ySum = ySum + pt.y; 
    sumSq = sumSq + (pt.x * pt.x); 
    }); 
    var a = sum * n; 
    var b = xSum * ySum; 
    var c = sumSq * n; 
    var d = xSum * xSum; 

    // Plug the values that you calculated for a, b, c, and d into the following equation to calculate the slope 
    // m = (a - b)/(c - d) 
    var m = (a - b)/(c - d); 

    ///////////// 
    //INTERCEPT// 
    ///////////// 

    // Let e equal the sum of all y-values 
    var e = ySum; 

    // Let f equal the slope times the sum of all x-values 
    var f = m * xSum; 

    // Plug the values you have calculated for e and f into the following equation for the y-intercept 
    // y-intercept = b = (e - f)/n = (14.5 - 10.5)/3 = 1.3 
    var b = (e - f)/n; 

    // return an object of two points 
    // each point is an object with an x and y coordinate 
    return { 
    ptA : { 
     x: minX, 
     y: m * minX + b 
    }, 
    ptB : { 
     y: minY, 
     x: (minY - b)/m 
    } 
    } 

} 
您的y軸的最小值