2016-11-09 71 views
1

我沒有使用d3的經驗,而且我僅偶爾使用Javascript和jQuery。d3中的散點圖不是渲染

我想在d3(和jQuery)中用滑塊創建一個簡單的scatterplot。滑塊的目的是選擇要繪製的數據集。我有一個JSON對象all_data,一張地圖列表。對於列表中的每個映射,我分別使用"SI""F1"列表作爲x和y值。

當滑塊移動時,我稱之爲plotData()函數作爲參數,它表示該數據集的all_data索引的整數(所以plotData(5)將繪製第6集在all_data)。

現在,由於某些原因,繪圖軸很好地構建,但數據點不繪製。我試圖通過在代碼中的相關部分放置console.log(data)function (d,i) { console.log(d); return x(d['SI'])來調試代碼(請參閱註釋行)。 data對象包含函數中所有點的數據。這個問題似乎出現在g.selectAll("scatter-dots")部分之後。我懷疑最後打電話給繪製'點'的函數沒有被調用,但我不明白爲什麼。

我的問題是:我該如何修復我的代碼,以便將數據點添加到圖中?任何其他編碼,設計或性能改進的提示都非常值得歡迎 - 在這裏學習。

編輯:我使用GitHub

var all_data = [{"REGRESSION_Y": [ list_of_floats ], "F1": [ list_of_floats ], "SI": [ list_of_floats ], "f+": some_float_val } 

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8"> 
     <title>D3 Test</title> 
     <link rel="stylesheet" href="d3/d3-slider-master/d3.slider.css" /> 
     <link rel="stylesheet" href="plot.css" /> 

     <script type="text/javascript" src="jquery/jquery-3.1.1.min.js"></script> 
     <script type="text/javascript" src="d3/d3.v3.min.js"></script> 
     <script type="text/javascript" src="json_data.js"></script> 
     <script type="text/javascript" src="d3/d3-slider-master/d3.slider.js"></script> 
    </head> 
    <body> 

     <h2><span id="slider3text">Data points selected: 5</span></h2> 

     <div id='container' style='width: 75%; height: 100%' class='centered'> 

      <div id="plotfield" style='width: 100%; height: 90%'></div> 
      <div id="slider3" style='height: auto'></div> 

     </div> 

    </body> 
    <script type="text/javascript"> 


    d3.select('#slider3').call(d3.slider().axis(true).min(5).max(all_data.length-1).step(1).on("slide", function(evt, value) { 

        d3.select('#slider3text').text("Data points selected: " + value); 
        plotData(value) 

       })); 


     </script> 


<script type="text/javascript"> 

function plotData(i) { 

    var data = all_data[i] 

    $("#plotfield").empty() 

    var margin = {top: 50, right: 5, bottom: 80, left: 5} 
     , width = $("#container").width() - margin.left - margin.right 
     , height = $("#container").height() - margin.top - margin.bottom; 

    var x = d3.scale.linear() 
       .domain([0, d3.max(data, function(d) { return d['SI']; })]) 
       .range([ 0, width ]); 

    var y = d3.scale.linear() 
      .domain([0, d3.max(data, function(d) { return d['F1']; })]) 
      .range([ height, 0 ]); 

    var chart = d3.select('#plotfield') 
    .append('svg:svg') 
    .attr('width', width + margin.right + margin.left) 
    .attr('height', height + margin.top + margin.bottom) 
    .attr('class', 'chart') 

    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); 

    var g = main.append("svg:g"); 

    //console.log(data), this worked here 

    g.selectAll("scatter-dots") 
     .data(data) 
     .enter().append("svg:circle") 

      // I have tried function (d,i) { console.log(d); return x(d['SI']) 
      //in the below anonymous functions, but that doesn't yield an output, 
      //causing me to suspect that the functions are not executed. 

      .attr("cx", function (d,i) { return x(d['SI']); }) 
      .attr("cy", function (d) { return y(d['F1']); }) 
      .attr("r", 3); 

} 

定製d3.slider延伸和CSS文件:

.centered { 
    position: fixed; 
    top: 50%; 
    left: 50%; 
    /* bring your own prefixes */ 
    transform: translate(-50%, -50%); 
} 

body { 
    font: 11px sans-serif; 
} 

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

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

circle { 
    fill: steelblue; 
} 
+0

'data'有數據嗎? 'console.log(data);'設置好後? – epascarello

+0

是的!我會編輯提到的問題。 – TBZ92

回答

1

從我看到的data[i]返回一個對象。這當然不是問題,但是d3方法的enter()只支持數組。

這意味着在使用enter()添加數據時,您不能擁有諸如d['f1']之類的內容。在使用它們之前將它們轉換爲數組可修復此問題,您可以使用d(數組條目)或i數組條目索引。

+0

這解決了這個問題。下面的答案顯示了工作腳本。 – TBZ92

0

的問題變成了成爲的事實數據返回一個對象,而不是一個數組。我的一位同事提供了以下編輯以使其工作。 (還有一些其他代碼已被更改爲將趨勢線添加到腳本中)。

<script type="text/javascript"> 

    function plotData(i) { 
     // extracting data 
     var data = all_data[i]; 
     var REGRESSION_Y = data.REGRESSION_Y; 
     var F1 = data.F1; 
     var SI = data.SI; 

     // removing previous plot 
     $("#plotfield").empty() 

     // margins and spacings (slightly larger, y-axis was invinsible) 
     var margin = {top: 50, right: 15, bottom: 80, left: 15} 
     , width = $("#container").width() - margin.left - margin.right 
     , height = $("#container").height() - margin.top - margin.bottom; 

     var x = d3.scale.linear() 
      .domain([0, d3.max(SI)]) 
      .range([ 0, width ]); 

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

     var chart = d3.select('#plotfield') 
      .append('svg:svg') 
      .attr('width', width + margin.right + margin.left) 
      .attr('height', height + margin.top + margin.bottom) 
      .attr('class', 'chart') 

     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); 

     // append extra g part in svg and append to it 
     var g = main.append("svg:g") 

     // append the line 
     g.append('line') 
      .attr('x1', x(d3.min(SI)))//function(d, i) { return x(d[]) + i; }) 
      .attr('x2', x(d3.max(SI)))//(2)//function(d, i) { return y(d['REGRESSION_Y']); }); 
      .attr('y1', y(d3.min(REGRESSION_Y))) 
      .attr('y2', y(d3.max(REGRESSION_Y))) 
      .style('stroke', '#1B3277') 
      .style('stroke-width','1') 

     // append the dots 
     g.selectAll("scatter-dots") 
      .data(SI) 
      .enter().append("svg:circle") 
      .attr("cx", function (d,i) { return x(SI[i]); }) 
      .attr("cy", function (d,i) { return y(F1[i]); }) 
      .attr("r", 3); 

    } 


</script>