2012-03-13 6 views
4

Я пытаюсь построить динамическую стеклянную гистограмму, используя D3.js. Основным требованием является то, что я получаю новую точку данных каждые несколько секунд, и я должен иметь возможность переустанавливать (переходить) сложную диаграмму. Это код, который я написали:Динамическая сводная диаграмма в D3

<html> 
<head> 
    <title>Page Title</title> 
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script> 
    <script src="d3/d3.js"></script> 
    <script src="d3/d3.csv.js"></script> 
    <script src="d3/d3.layout.js"></script> 
</head> 

<body> 
    <style type="text/css"> 
     .chart rect { 
     stroke: white; 
     } 
    </style> 

<script> 


    var t = 1297110663, // start time (seconds since epoch) 
     v = 70, // start value (subscribers) 
     sentidata = d3.range(33).map(next); // starting dataset 

    var w = 20, 
     h = 80; 

    var x = d3.scale.linear() 
     .domain([0, 1]) 
     .range([0, w]); 

    var y = d3.scale.linear() 
     .domain([0, 200]) 
     .rangeRound([0, h]); 

    var z = d3.scale.ordinal() 
     .range(["lightpink", "darkgray"]); 

    //This function creates random test data of format : time, posvalue, negvalue 
    function next() { 
     return { 
     time: ++t, 
     posvalue: v = ~~Math.max(10, Math.min(90, v + 10 * (Math.random() - .5))), 
     negvalue: v = ~~Math.max(10, Math.min(90, v + 10 * (Math.random() - .5))) 
     }; 
    } 

    //This function readjusts the data with one new data point and calls redraw function to replot the graph 
    setInterval(function() { 
     sentidata.shift(); 
     sentidata.push(next());  
     redraw(sentidata); 
     }, 1500); 

    var svg = d3.select("body").append("svg:svg") 
     .attr("class", "chart") 
     .attr("width", w * sentidata.length - 1) 
     .attr("height", h); 


    //Transpose the data into layers by Sentiment 
    var sent = d3.layout.stack()(["posvalue","negvalue"].map(function(sentiment){ 
     return sentidata.map(function(d){ 
      return {x:d.time, y:+d[sentiment]}; 
      }); 
     })); 


    //Add a group for each Sentiment 
    var sentiment = svg.selectAll("g.sentiment") 
         .data(sent) 
         .enter() 
         .append("svg:g") 
         .attr("class","sentiment") 
         .style("fill", function(d,i){return z(i);}) 
         .style("stroke", function(d,i){return d3.rgb(z(i)).darker();}); 

    //Add a rectangle for each time value 
    var rect = sentiment.selectAll("rect") 
         .data(Object) 
         .enter() 
         .append("svg:rect") 
         .attr("x",function(d, i) { return x(i) - .5; }) 
         .attr("y",function(d){return h - y(d.y0)-y(d.y);}) 
         .attr("height", function(d){return y(d.y);}) 
         .attr("width",w); 


    svg.append("line") 
     .attr("x1", 0) 
     .attr("x2", w * sentidata.length) 
     .attr("y1", h - .5) 
     .attr("y2", h - .5) 
     .style("stroke", "#000"); 


    function redraw(data) { 

     //Transpose the data into layers by Sentiment 
     var sent = d3.layout.stack()(["posvalue","negvalue"].map(function(sentiment){ 
      return data.map(function(d){ 
       return {x:d.time, y:+d[sentiment]}; 
       }); 
      })); 

     //Add a group for each Sentiment 
     var sentiment = svg.selectAll("g.sentiment") 
         .data(sent) 
         .transition() 
         .duration(1000) 
         .attr("class","sentiment") 
         .style("fill", function(d,i){return z(i);}) 
         .style("stroke", function(d,i){return d3.rgb(z(i)).darker();}); 

     var rect = sentiment.selectAll("rect") 
       .data(Object) 
       .transition() 
       .duration(1000) 
       .attr("y",function(d){return h - y(d.y0)-y(d.y);}) 
       .attr("height", function(d){return y(d.y);}); 

    } 

</script> 
</body> 
</html> 

Первоначальная штабелированная диаграмма получает строчную оценку. Но когда я вызываю метод перерисовывания, он дает мне «объект объекта» не имеет ошибки «данные» метода. Эта ошибка возникает, когда я пытаюсь инициализировать переменную переменную

var rect = sentiment.selectAll("rect") 
        .data(Object) 

Не уверен, что я делаю неправильно. Я что-то искал similar

Любые предложения будут действительно оценены!

+0

'.data()' принимает массив значений или объектов для использования участка. Вместо передачи «Объект» передайте ему данные, которые вы хотите показать. –

+0

Получил. Я определил 'var sentiment' как переход в моем перерисовке, так как Я использовал цепочку методов для создания перехода сразу после , вызывающего selectAll. Поэтому он не имеет метода данных, поскольку подразумевается сообщение об ошибке . Поэтому я создал переход как отдельный оператор , чтобы избежать конфликта. Спасибо Майку Бостоку за столь быстрое реагирование на группы D3 Google. –

ответ

Смежные вопросы