简体   繁体   中英

D3.js not updating properly data from socket.io

I am trying to get mi chart updated with the data I pass, the data comes very fast, if I just make a console log, I see the data arriving just fine, but when I try to render it, everything comes very slow, and my lines only show the first state, never changes, and its so slow that I have to restart Firefox. Heres my code:

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

Any idea why it works so slow, and why it just shows the first result in the line?

Thanks!

EDDIT!

My code that I'm posting right now, was drawing well in time the lines, but the scale wasn't right, was fix, not dinamic, so I wanted to create a dynamic onw, but it's not updating anything since I created a object for the data, instead the var array = data.split(",") This is an example of the object datos:

datos.x should be: 0,1,2,3,4,5,6,7,8,9,10 datos.y Should be: 10,2,7,8,5,3,6,8,1,10,1

And here the code that I was able to have working and drawing:

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

And the new one, that doesn't work:

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

Any Idea Why it's not working fine?

Thanks!

Done and working, I created a cart with objects x and y, and now it's workiing fine, the throttle function and the fragmentation of the seeData function were the key to solve this.

Thanks mark.

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