2016-02-09 42 views
0

我试图让数据更新我的数据传递,数据来得非常快,如果我只是做一个控制台日志,我看到数据到达就好,但是当我尝试渲染它时,一切都变得非常缓慢,我的线条只显示第一个状态,从不变化,而且速度很慢,我不得不重新启动Firefox。我的继承人代码:D3.js没有正确更新来自socket.io的数据

<html> 
    <head> 

    <title>Dinamic Denia</title> 


<svg id="visualisation" width="1000" height="500"></svg> 
<body> 
      <div id="tooltip" class="hidden" style="left: 429px, top: 489.6px"> 
      <p><strong><span id="city">Dar es Salaam</span></strong></p> 

     </div> 
</body> 

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
    <!--Load the AJAX API--> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
    <script type="text/javascript" src="http://localhost:3000/socket.io/socket.io.js"></script> 
<style> 
.axis path, .axis line 
     { 
      fill: none; 
      stroke: #777; 
      shape-rendering: crispEdges; 
     } 

     .axis text 
     { 
      font-family: 'Arial'; 
      font-size: 13px; 
     } 
     .tick 
     { 
      stroke-dasharray: 1, 2; 
     } 
     .bar 
     { 
      fill: FireBrick; 
     } 
#tooltip { 
      position: absolute; 
      width: 230px; 
      height: auto; 
      padding: 10px; 
      background-color: white; 
      /*-webkit*/-border-radius: 10px; 
      /*-moz*/-border-radius: 10px; 
      border-radius: 10px; 
      /*-webkit*/-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      /*-moz-*/box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      pointer-events: none; 
     } 

     #tooltip.hidden { 
      display: none; 
     } 

     #tooltip p { 
      margin: 0; 
      font-family: sans-serif; 
      font-size: 16px; 
      line-height: 20px; 
     } 
</style> 
    <script type="text/javascript"> 



     var socket = io.connect('http://localhost:3000/'); 

     socket.on('connect', function(data){ 
     setStatus('connected'); 
     socket.emit('subscribe', {channel:'realtime'}); 

     }); 

     socket.on('reconnecting', function(data){ 
     setStatus('reconnecting'); 
     }); 

     socket.on('message', function (data) { 

     socket.emit('update', {channel:'realtime'}); 
     InitChart(data); 
     console.log('dades: ', data); 
     console.log('received a message: ', data); 
     addMessage(data); 
     }); 

     function addMessage(data) { 
      $('#online').html(data); 
     } 

     function setStatus(msg) { 
      console.log('Connection Status : ' + msg); 
     } 


function InitChart(data) { 

var array = data.split(','); 
    seeData(array); 

     // d3.tsv("dataDL.tsv", function(data) { 

     //d3.tsv("data2.tsv", function(data) { 
     //seeData(data); 
     // d3.tsv("dataProves.tsv", function(data) { 
     //seeData(data); 

function seeData(data) { 
     console.log(data, function (d) {return d;}); 
    var vis = d3.select("#visualisation"), 
    WIDTH = 1000, 
    HEIGHT = 500, 

    MARGINS = { 
     top: 20, 
     right: 20, 
     bottom: 20, 
     left: 50 
    }, 
//var x = new array("1","2","3","4","5","5","7","8","9","10","11","12"); 
    xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([ 
     0, 
     25 
    ]), 
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([ 
     //Math.min(d3.min(data, function (d) {return +d;}),d3.min(data, function (d) {return +d;})) 
     0,10 
     //Math.max(d3.max(data, function (d) {return +d;}),d3.max(data, function (d) {return +d;})) 
    ]), 
xAxis = d3.svg.axis() 
     .scale(xRange) 
     .tickSize(5) 
     .tickSubdivide(true), 

    yAxis = d3.svg.axis() 
     .scale(yRange) 
     .tickSize(5) 
     .orient("left") 
     .tickSubdivide(true); 



    vis.append("svg:g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")") 
    .call(xAxis); 

    vis.append("svg:g") 
    .attr("class", "y axis") 
    .attr("transform", "translate(" + (MARGINS.left) + ",0)") 
    .call(yAxis); 

    var lineFunc = d3.svg.line() 
    .x(function (d) { 
    return xRange(d); 
    }) 
    .y(function (d) { 
    return yRange(d); 
    }) 
    .interpolate('linear'); 


vis.append("svg:path") 
    .attr("d", lineFunc(data)) 
    .attr("stroke", "blue") 
    .attr("stroke-width", 3) 
    .attr("fill", "none") 
    //acabar 
    .on('click', function(d) { 
     d3.select(this) 
     if(d3.select(this).attr("stroke")!= "red"){ d3.select(this) .attr("stroke", "red")} 
     else {d3.select(this) .attr("stroke", "blue") 
       d3.select(this) .attr("stroke-width", 3);} 
    }) 
    .on('mouseover', function(d) { 
    d3.select(this) 
     .attr("stroke", "blue") 
     .attr("stroke-width", 9); 
      var mousecoord = [0,0]; 
      mousecoord = d3.mouse(this); 

      d3.select("#tooltip") 
       .style("left", mousecoord[0] + "px") 
       .style("top", mousecoord[1]-40 + "px"); 

      d3.select("#city") 
       .text("Denia"); 

      d3.select("#tooltip").classed("hidden", false); 

    }) 

    .on('mouseout', function(d) { 
    d3.select(this) 

     .attr("stroke", "blue") 
      .attr("stroke-width", 3); 

      d3.select("#tooltip").classed("hidden", true);  

    }); 
} 
} 

</script> 

任何想法,为什么这么慢,为什么它只是显示在该行的第一个结果?

谢谢!

EDDIT!

我现在正在发布的代码在绘制时间线上很好,但规模不对,修复,而不是动态,所以我想创建一个动态的onw,但它没有更新任何东西因为我创建用于数据目的,而不是VAR阵列= data.split(“”)这是对象DATOS的示例:

datos.x应该是:0,1,2 ,3,4,5,6,7,8,9,10 datos.y应该是:10,2,7,8,5,3,6,8,1,10,1

还有这里是我能够工作和绘制的代码:

<html> 
    <head> 

    <title>Dinamic Denia</title> 


<svg id="visualisation" width="1000" height="500"></svg> 
<body> 
      <div id="tooltip" class="hidden" style="left: 429px, top: 489.6px"> 
      <p><strong><span id="city">Dar es Salaam</span></strong></p> 

     </div> 
</body> 

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
    <!--Load the AJAX API--> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
    <script type="text/javascript" src="http://localhost:3000/socket.io/socket.io.js"></script> 
<style> 
.axis path, .axis line 
     { 
      fill: none; 
      stroke: #777; 
      shape-rendering: crispEdges; 
     } 

     .axis text 
     { 
      font-family: 'Arial'; 
      font-size: 13px; 
     } 
     .tick 
     { 
      stroke-dasharray: 1, 2; 
     } 
     .bar 
     { 
      fill: FireBrick; 
     } 
#tooltip { 
      position: absolute; 
      width: 230px; 
      height: auto; 
      padding: 10px; 
      background-color: white; 
      /*-webkit*/-border-radius: 10px; 
      /*-moz*/-border-radius: 10px; 
      border-radius: 10px; 
      /*-webkit*/-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      /*-moz-*/box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      pointer-events: none; 
     } 

     #tooltip.hidden { 
      display: none; 
     } 

     #tooltip p { 
      margin: 0; 
      font-family: sans-serif; 
      font-size: 16px; 
      line-height: 20px; 
     } 
</style> 
    <script type="text/javascript"> 


//InitChart(); 
//seeData(); 
     var socket = io.connect('http://localhost:3000/'); 

    var vis; 
    var lineFunc; 
    ini(); 
function ini(){ 
    vis = d3.select("#visualisation"),//.append("svg"), 
    WIDTH = 1000, 
    HEIGHT = 500, 

    MARGINS = { 
     top: 20, 
     right: 20, 
     bottom: 20, 
     left: 50 
    }, 
    xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([ 
     0, 
     25 
    ]), 
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([ 
     //Math.min(d3.min(data, function (d) {return +d;}),d3.min(data, function (d) {return +d;})) 
     0,25 
     //Math.max(d3.max(data, function (d) {return +d;}),d3.max(data, function (d) {return +d;})) 
    ]), 

    xAxis = d3.svg.axis() 
     .scale(xRange) 
     .tickSize(5) 
     .tickSubdivide(true), 

    yAxis = d3.svg.axis() 
     .scale(yRange) 
     .tickSize(5) 
     .orient("left") 
     .tickSubdivide(true); 


//var x = new array("1","2","3","4","5","5","7","8","9","10","11","12"); 

    vis.append("svg:g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")") 
    .call(xAxis); 

    vis.append("svg:g") 
    .attr("class", "y axis") 
    .attr("transform", "translate(" + (MARGINS.left) + ",0)") 
    .call(yAxis); 
    lineFunc = d3.svg.line() 
    .x(function (d) { 
    return xRange(d); 
    }) 
    .y(function (d) { 
    return yRange(d); 
    }) 
    .interpolate('linear'); 

vis.append("svg") 
    .append("path") 
    .attr("d", "0") 
    .attr("stroke", "blue") 
    .attr("stroke-width", 3) 
    .attr("fill", "none") 
} 
function throttle(fn, threshhold, scope) { 
    threshhold || (threshhold = 250); 
    var last, 
     deferTimer; 
    return function() { 
    var context = scope || this; 

    var now = +new Date, 
     args = arguments; 
    if (last && now < last + threshhold) { 
     // hold on to it 
     clearTimeout(deferTimer); 
     deferTimer = setTimeout(function() { 
     last = now; 
     fn.apply(context, args); 
     }, threshhold); 
    } else { 
     last = now; 
     fn.apply(context, args); 
    } 
    }; 
} 


     socket.on('connect', function(data){ 
     setStatus('connected'); 
     socket.emit('subscribe', {channel:'realtime'}); 

     }); 

     socket.on('reconnecting', function(data){ 
     setStatus('reconnecting'); 
     }); 

     socket.on('message', throttle(function (data) { 
       seeData(data); 
    //console.log('tick'); 
        }, 500)); 
     //socket.emit('update', {channel:'realtime'}); 

     //console.log('received a message: ', data); 
     //addMessage(data); 

     //}); 

     function addMessage(data) { 
      $('#online').html(data); 



     console.log('dades: ', data); 
      //$('#visualisation').html(data); 
     } 

     function setStatus(msg) { 
      console.log('Connection Status : ' + msg); 

     } 

function seeData(data){ 
var array = data.split(','); 

var dades = d3.select("#visualisation").selectAll("path"); 
    dades.attr("d", lineFunc(array)) 



    //dades.enter().append("path") 

    .on('click', function(d) { 
     d3.select(this) 
     if(d3.select(this).attr("stroke")!= "red"){ d3.select(this) .attr("stroke", "red")} 
     else {d3.select(this) .attr("stroke", "blue") 
       d3.select(this) .attr("stroke-width", 3);} 
    }) 
    .on('mouseover', function(d) { 
    d3.select(this) 
     .attr("stroke", "blue") 
     .attr("stroke-width", 9); 
      var mousecoord = [0,0]; 
      mousecoord = d3.mouse(this); 

      d3.select("#tooltip") 
       .style("left", mousecoord[0] + "px") 
       .style("top", mousecoord[1]-40 + "px"); 

      d3.select("#city") 
       .text("Denia"); 

      d3.select("#tooltip").classed("hidden", false); 

    }) 

    .on('mouseout', function(d) { 
    d3.select(this) 

     .attr("stroke", "blue") 
      .attr("stroke-width", 3); 

      d3.select("#tooltip").classed("hidden", true);  

    }); 

    //dades.exit().remove(); 


} 






     // d3.tsv("dataDL.tsv", function(data) { 

     //d3.tsv("data2.tsv", function(data) { 
     //seeData(data); 
     // d3.tsv("dataProves.tsv", function(data) { 
     //seeData(data); 






</script> 

,而新的,不工作:

<html> 
    <head> 

    <title>Dinamic Denia</title> 


<svg id="visualisation" width="1000" height="500"></svg> 
<body> 
      <div id="tooltip" class="hidden" style="left: 429px, top: 489.6px"> 
      <p><strong><span id="city">Dar es Salaam</span></strong></p> 

     </div> 
</body> 

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
    <!--Load the AJAX API--> 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
    <script type="text/javascript" src="http://localhost:3000/socket.io/socket.io.js"></script> 
<style> 
.axis path, .axis line 
     { 
      fill: none; 
      stroke: #777; 
      shape-rendering: crispEdges; 
     } 

     .axis text 
     { 
      font-family: 'Arial'; 
      font-size: 13px; 
     } 
     .tick 
     { 
      stroke-dasharray: 1, 2; 
     } 
     .bar 
     { 
      fill: FireBrick; 
     } 
#tooltip { 
      position: absolute; 
      width: 230px; 
      height: auto; 
      padding: 10px; 
      background-color: white; 
      /*-webkit*/-border-radius: 10px; 
      /*-moz*/-border-radius: 10px; 
      border-radius: 10px; 
      /*-webkit*/-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      /*-moz-*/box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      pointer-events: none; 
     } 

     #tooltip.hidden { 
      display: none; 
     } 

     #tooltip p { 
      margin: 0; 
      font-family: sans-serif; 
      font-size: 16px; 
      line-height: 20px; 
     } 
</style> 
    <script type="text/javascript"> 


//InitChart(); 
//seeData(); 
     var socket = io.connect('http://localhost:3000/'); 

    var vis; 
    var lineFunc; 
WIDTH = 1000, 
    HEIGHT = 500, 
    MARGINS = { 
     top: 20, 
     right: 20, 
     bottom: 20, 
     left: 50 
    }; 
    xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([ 
     0, 
     25 
    ]), 
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([ 
     //Math.min(d3.min(data, function (d) {return +d;}),d3.min(data, function (d) {return +d;})), 
     0, 
     25 
     //Math.max(d3.max(data, function (d) {return +d;}),d3.max(data, function (d) {return +d;})) 
    ]); 
ini(); 
function ini(){ 
    vis = d3.select("#visualisation"),//.append("svg"), 


    xAxis = d3.svg.axis() 
     .scale(xRange) 
     .tickSize(5) 
     .tickSubdivide(true), 

    yAxis = d3.svg.axis() 
     .scale(yRange) 
     .tickSize(5) 
     .orient("left") 
     .tickSubdivide(true); 


//var x = new array("1","2","3","4","5","5","7","8","9","10","11","12"); 

    vis.append("svg") 
    .append("g")  
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")") 
    .call(xAxis); 

    vis.append("svg") 
    .append("g") 
    .attr("class", "y axis") 
    .attr("transform", "translate(" + (MARGINS.left) + ",0)") 
    .call(yAxis); 

    lineFunc = d3.svg.line() 
    .x(function (d) { 
    return xRange(d.x); 
    }) 
    .y(function (d) { 
    return yRange(d.y); 
    }) 
    .interpolate('linear'); 

vis.append("svg") 
    .append("path") 
    .attr("d", "0") 
    .attr("stroke", "blue") 
    .attr("stroke-width", 3) 
    .attr("fill", "none") 
} 
function throttle(fn, threshhold, scope) { 
    threshhold || (threshhold = 250); 
    var last, 
     deferTimer; 
    return function() { 
    var context = scope || this; 

    var now = +new Date, 
     args = arguments; 
    if (last && now < last + threshhold) { 
     // hold on to it 
     clearTimeout(deferTimer); 
     deferTimer = setTimeout(function() { 
     last = now; 
     fn.apply(context, args); 
     }, threshhold); 
    } else { 
     last = now; 
     fn.apply(context, args); 
    } 
    }; 
} 
function createArray(length) { 
    var arr = new Array(length || 0), 
     i = length; 

    if (arguments.length > 1) { 
     var args = Array.prototype.slice.call(arguments, 1); 
     while(i--) arr[length-1 - i] = createArray.apply(this, args); 
    } 

    return arr; 
} 

     socket.on('connect', function(data){ 
     setStatus('connected'); 
     socket.emit('subscribe', {channel:'realtime'}); 

     }); 

     socket.on('reconnecting', function(data){ 
     setStatus('reconnecting'); 
     }); 

     socket.on('message', throttle(function (data) { 
       seeData(data); 
    //console.log('tick'); 
        }, 500)); 
     //socket.emit('update', {channel:'realtime'}); 

     //console.log('received a message: ', data); 
     //addMessage(data); 

     //}); 

     function addMessage(data) { 
      $('#online').html(data); 



     console.log('dades: ', data); 
      //$('#visualisation').html(data); 
     } 

     function setStatus(msg) { 
      console.log('Connection Status : ' + msg); 

     } 



function prepara(data){ 
var arre = data.split(','); 
var array = createArray(arre.length); 
for (var i = 0; i < arre.length; i++) { 

    array[i]=""+i; 
} 
var datos = {x:array, y:arre}; 
    xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([ 
     d3.min(datos, function (d) {return +datos.x;}), 
     d3.max(datos, function (d) {return +datos.x;}) 
     //0, 
     //arre.length 

     //Math.min(+datos.x), 
     //Math.max(+datos.x), 
    ]), 
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([ 
     d3.min(datos, function (d) {return +datos.y;}), 
     d3.max(datos, function (d) {return +datos.y;})  


     //Math.min(+datos.y), 
     //0, 
     //25 
     //Math.max(+datos.y) 
    ]); 
console.log("d.x "+datos.x+" d.y "+datos.y); 
return datos; 
} 

function seeData(data){ 
var dades = d3.select("#visualisation").selectAll("path"); 
    dades.attr("d", lineFunc(prepara(data))) 
    .on('click', function(d) { 
     d3.select(this) 
     if(d3.select(this).attr("stroke")!= "red"){ d3.select(this) .attr("stroke", "red")} 
     else {d3.select(this) .attr("stroke", "blue") 
       d3.select(this) .attr("stroke-width", 3);} 
    }) 
    .on('mouseover', function(d) { 
    d3.select(this) 
     .attr("stroke", "blue") 
     .attr("stroke-width", 9); 
      var mousecoord = [0,0]; 
      mousecoord = d3.mouse(this); 

      d3.select("#tooltip") 
       .style("left", mousecoord[0] + "px") 
       .style("top", mousecoord[1]-40 + "px"); 

      d3.select("#city") 
       .text("Denia"); 

      d3.select("#tooltip").classed("hidden", false); 

    }) 

    .on('mouseout', function(d) { 
    d3.select(this) 

     .attr("stroke", "blue") 
      .attr("stroke-width", 3); 

      d3.select("#tooltip").classed("hidden", true);  

    }); 


var rango = d3.select("#visualisation").selectAll("g.y.axis") 
     rango.call(yAxis); 
var dominio = d3.select("#visualisation").selectAll("g.x.axis") 
     dominio.call(xAxis); 





    //dades.enter().append("path") 


    //dades.exit().remove(); 


} 






     // d3.tsv("dataDL.tsv", function(data) { 

     //d3.tsv("data2.tsv", function(data) { 
     //seeData(data); 
     // d3.tsv("dataProves.tsv", function(data) { 
     //seeData(data); 






</script> 

任何想法,为什么它不工作的罚款?

谢谢!

+2

通过websocket可以获得非常频繁的更新,并且每次更新都异步启动昂贵的绘图操作(可能在最后一个绘图操作完成之前)...并且绘图操作完全重新绘制图表 - 它不会只是更新现有的东西...我不知道为什么它如此缓慢?除了讽刺之外,首先研究'd3'输入,更新,退出模式,打断'seeData'函数,然后发现自己是一个不错的[节流](https://lodash.com/docs#throttle)实现。 – Mark

+0

好吧,现在我可以正确更新了,时间不再是问题了,谢谢! 现在我的问题是,我无法获取轴更新写入和我当前的代码,停止显示任何行,我不知道为什么。 – Amnor

+0

我使用新问题和细节引导了帖子。谢谢! – Amnor

回答

0

完成和工作后,我创建了一个对象x和y的购物车,现在工作正常,油门功能和seeData函数的碎片是解决这个问题的关键。

谢谢马克。