5100

D3 realtime graphing: slide from right&shift data as data length exceeds limit transition is not

Question:

usign bottle webframework for backend and d3 graphing for frontend. my server.py content is as following

from bottle import get,template,run,route,Bottle,static_file from bottle.ext.websocket import GeventWebSocketServer from bottle.ext.websocket import websocket import random import time users = set() @get('/') def mainIndex(): return template('problemToAskFromStackoverflow') import time @get('/websocket', apply=[websocket]) def chat(ws): users.add(ws) startTime = 0#time.time() while True: msg = ws.receive() #print "msg ",msg if msg is not None: for u in users: speed = random.randrange(0,1000) weight = random.randrange(0,50) #elapsedTime = time.time() - startTime startTime += 1 print "time:",startTime obj = '{"speed":'+str(speed) + ',"weight":'+str(weight)+',"time":'+str(startTime)+'}' u.send(str(speed)) #u.send(str(random.randrange(0,1000))) else: print "msg is NONe is guesse" break time.sleep(1) users.remove(ws) run(host='localhost',port=8004,server=GeventWebSocketServer)

and content of the problemToAskFromStackoverflow.html is as following

<pre class="snippet-code-html lang-html prettyprint-override"><script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <!DOCTYPE html> <meta charset="utf-8"> <style> svg { font: 10px sans-serif; } .line { fill: none; stroke: #000; stroke-width: 1.5px; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } </style> <body> <form id="startBtn"> <input type="submit" value="Start Real" /> </form> <div id = "graph1"></div> <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <script> var margin = {top:5, right: 10, bottom: 10, left: 70}, width = 1200 - margin.left - margin.right, height = 250 - margin.top - margin.bottom; var data1; var x,y1,xAxis1,yAxis1,update; var duration = 1000; var moveDuration = 1000; // Parse the date / time var totalSeconds = 60; var n = 10;//totalSeconds; var limit = n; duration = 1000; x = d3.time.scale() .domain([0, ((n - 1) * duration)]) .range([0, width]); var valueline1 = d3.svg.line() .x(function(d,i) { return x(i*duration); }) .y(function(d,i) { return y1(d); }) .interpolate("monotone"); // Set the ranges data1 = [0]; y1 = d3.scale.linear().range([height, 0]) .domain([0,1000]); xAxis1 =d3.svg.axis().scale(x) .orient("bottom") .ticks(d3.time.seconds, 1.0) .tickFormat(d3.time.format('%M:%S')) .innerTickSize(-height); yAxis1 = d3.svg.axis().scale(y1) .innerTickSize(-width) .outerTickSize(0) .tickPadding(10) .orient("left").ticks(10); var svg = d3.select("#graph1") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform","translate(" + margin.left + "," + margin.top + ")"); svg.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); var xAxisLine= svg.append("g") // Add the X Axis .attr("class", "x axis") .attr("transform", "translate("+width+"," + height + ")") .call(xAxis1); svg.append("g") // Add the Y Axis .attr("class", "y axis") .call(yAxis1); var path = svg.append("g") .attr("clip-path","url(#clip)") .append("path") .data(data1) .attr("class", "line") .attr("transform", "translate(" + (width )+")") .attr("d",valueline1(data1)) ; // Add the valueline path. var random = d3.random.normal(0, 50); var i = 0; var shifter = 0; function update(val){ var svg1 = d3.select("#graph1"); i = i + 1; shifter = 0; var val = JSON.parse(val); data1.push(val); if(i >= limit){ shifter = x(-duration); var x_axis_scale = d3.time.scale() .domain([(i+1-limit)*duration,((n-1+(i+1-limit))*duration)]) .range([0,width]); svg1.select(".x.axis") .attr("transition",null) .transition() .duration(moveDuration) .ease("linear") .call(d3.svg.axis().scale(x_axis_scale) .orient("bottom") .ticks(d3.time.seconds, 1.0) .tickFormat(d3.time.format('%M:%S')) .innerTickSize(-height) //.orient("bottom") //.ticks(d3.time.seconds,1.0) //.tickFormat(d3.time.format('%M:%S')) //.innerTickSize(-height) ); //.attr("width",width) path//.attr("transform",null) .attr("d", valueline1(data1)) .attr("transform",null) .transition() .duration(moveDuration) .ease("linear") .attr("transform","translate("+(shifter)+")") //.transition() //.duration(moveDuration) //.ease("linear") ;//.attr("transform","translate("+(shifter-x(-duration))+")"); data1.shift(); // Make the changes } else{ shifter = width - x(i*duration); svg1.select(".x.axis") .transition() .duration(moveDuration) .ease("linear") .attr("transform","translate("+(shifter)+","+(height)+")"); // svg1.select(".line") // change the line path .attr("d", valueline1(data1)) .transition() .duration(moveDuration) .ease("linear") .attr("transform","translate("+(shifter)+")") ;//.attr("transform","translate("+(shifter)+")"); // Make the changes } } var ws = new WebSocket('ws://127.0.0.1:8004/websocket') ws.onopen = function(evt) { } ws.onmessage = function(evt) { //alert(evt.data) update(evt.data); ws.send("arrived"); } $('#startBtn').submit(function() { ws.send("Pressed"); }); </script>

when i run server.py on terminal and open localhost:8004 after the i exceed limit, after 10 sec, the path is not flowing as smooth as it was before exceeding the limit. I searched for the solution could not figured out what is the problem? I thought that may it is appending new transition upon the exsisting transition. But it is not, even when i disabled all transition related lines in else part of the updtae funtion still transition is not being in if part of the update funtion. I will be very glad if you help me solve this problem.

Answer1:

This is bizarre, your code should work. It's like d3 is not picking up the transition.attr and applying it. Your best option may be to set up your own interpolater:

var startTrans = 'translate(0,0)'; var endTrans = 'translate(' + (-x(duration)) + ',0)'; var transInterp = d3.interpolateString(startTrans , endTrans); ... path .attr("d", valueline1(data1)) .attr("transform", null) .transition() .duration(moveDuration) .ease("linear") .attrTween('transform', function (d) { return transInterp; });

Full working code:

<pre class="snippet-code-html lang-html prettyprint-override"><!DOCTYPE html> <meta charset="utf-8"> <style> svg { font: 10px sans-serif; } .line { fill: none; stroke: #000; stroke-width: 1.5px; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } </style> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="graph1"></div> <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <script> var margin = { top: 5, right: 10, bottom: 10, left: 70 }, width = 600 - margin.left - margin.right, height = 250 - margin.top - margin.bottom; var data1; var x, y1, xAxis1, yAxis1, update; var duration = 1000; var moveDuration = 1000; // Parse the date / time var totalSeconds = 60; var n = 10; //totalSeconds; var limit = n; duration = 1000; x = d3.time.scale() .domain([0, ((n - 1) * duration)]) .range([0, width]); var valueline1 = d3.svg.line() .x(function(d, i) { return x(i * duration); }) .y(function(d, i) { return y1(d); }) .interpolate("monotone"); // Set the ranges data1 = [0]; y1 = d3.scale.linear().range([height, 0]) .domain([0, 1000]); xAxis1 = d3.svg.axis().scale(x) .orient("bottom") .ticks(d3.time.seconds, 1.0) .tickFormat(d3.time.format('%M:%S')) .innerTickSize(-height); yAxis1 = d3.svg.axis().scale(y1) .innerTickSize(-width) .outerTickSize(0) .tickPadding(10) .orient("left").ticks(10); var svg = d3.select("#graph1") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); svg.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); var xAxisLine = svg.append("g") // Add the X Axis .attr("class", "x axis") .attr("transform", "translate(" + width + "," + height + ")") .call(xAxis1); svg.append("g") // Add the Y Axis .attr("class", "y axis") .call(yAxis1); var path = svg.append("g") .attr("clip-path", "url(#clip)") .append("path") .data(data1) .attr("class", "line") .attr("transform", "translate(" + (width) + ")") .attr("d", valueline1(data1)); // Add the valueline path. var random = d3.random.normal(0, 50); var i = 0; var shifter = 0; var startTrans = 'translate(0,0)'; var endTrans = 'translate(' + (-x(duration)) + ',0)'; var transInterp = d3.interpolateString(startTrans, endTrans); function update(val) { var svg1 = d3.select("#graph1"); i = i + 1; shifter = 0; var val = JSON.parse(val); data1.push(val); if (i >= limit) { shifter = x(-duration); var x_axis_scale = d3.time.scale() .domain([(i + 1 - limit) * duration, ((n - 1 + (i + 1 - limit)) * duration)]) .range([0, width]); svg1.select(".x.axis") .attr("transition", null) .transition() .duration(moveDuration) .ease("linear") .call(d3.svg.axis().scale(x_axis_scale) .orient("bottom") .ticks(d3.time.seconds, 1.0) .tickFormat(d3.time.format('%M:%S')) .innerTickSize(-height) //.orient("bottom") //.ticks(d3.time.seconds,1.0) //.tickFormat(d3.time.format('%M:%S')) //.innerTickSize(-height) ); path .attr("d", valueline1(data1)) .attr("transform", null) .transition() .duration(moveDuration) .ease("linear") .attrTween('transform', function (d) { return transInterp; }); data1.shift(); // Make the changes } else { shifter = width - x(i * duration); svg1.select(".x.axis") .transition() .duration(moveDuration) .ease("linear") .attr("transform", "translate(" + (shifter) + "," + (height) + ")"); // svg1.select(".line") // change the line path.attr("d", valueline1(data1)) .transition() .duration(moveDuration) .ease("linear") .attr("transform", "translate(" + (shifter) + ")"); //.attr("transform","translate("+(shifter)+")"); // Make the changes } } setInterval(function() { update(Math.random() * 1000); }, 1000); </script>

Recommend

  • Android: Button background XML sometimes loses alpha when setting color filter
  • CSS animation do not work for svg in
  • Can I override some attribute of drawable shape?
  • Creating interactive SVG maps for a web portal
  • Recreate Apple Watch fitness tracker ‘progress’ bar - gradient on CAShapeLayer stroke
  • How to center a menu using flexbox [closed]
  • jinja2 template not found and internal server error
  • How secure are apple APNS push notifications?
  • d3.js selection conditional rendering
  • Why does the font in these TD elements render at different sizes?
  • How to rotate the dial in a gauge chart? Using python plotly
  • I am receiving HibernateException “No Hibernate Session bound to thread, and configuration does not
  • MySQL: Update rows in table by iterating and joining with another one
  • Javascript CORS - No 'Access-Control-Allow-Origin' header is present
  • JBoss External Properties Files in Classpath
  • Adjust width of select element according to selected option's width
  • Android - Material Design - NavigationView - How to put vertical scroll?
  • how to display data from 1st point on words on y axis for line chart in d3.js
  • Custom validator control occupying space even though display set to dynamic
  • How do I alternate colors in Flat List (React Native)
  • Listbox within Listbox and scrolling trouble in Windows Phone 7 Silverlight
  • Jquery UI tool tip close icon
  • Highlight and Bold text in JTextPane
  • Change multiple background-images with jQuery
  • Xamarin Forms - UWP Fonts
  • Retrieving value from sql ExecuteScalar()
  • How to convert from System.Drawing.Color to Excel.ColorFormat in C#? Change comment color
  • Why doesn't :active or :focus work on text links in webkit? (safari & chrome)
  • SSO with signing and signature validation doesn't work
  • How to apply VCL Styles to DLL-based forms in Inno Setup?
  • Change an a tag attribute in JavaScript based on screen width
  • How to show dropdown in excel using jrxml (jasper api)?
  • jquery mobile loadPage not working
  • Properly structure and highlight a GtkPopoverMenu using PyGObject
  • Unanticipated behavior
  • Matrix multiplication with MKL
  • NSLayoutConstraint that would pin a view to the bottom edge of a superview
  • How get height of the a view with gone visibility and height defined as wrap_content in xml?
  • python draw pie shapes with colour filled
  • costura.fody for a dll that references another dll