D3实时绘图:从右边滑动并在数据长度超过限制时移动数据转换不起作用

2024-09-26 18:20:33 发布

您现在位置:Python中文网/ 问答频道 /正文

后端使用webframework,前端使用d3绘图。 我的服务器.py内容如下

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)

以及问题的内容AskFromStackoverflow.html文件如下所示

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

当我跑的时候服务器.py在终端上打开本地主机:8004之后当i超过极限时,10秒后,路径不像超过极限前那样平滑。我找不出解决办法,搞不懂是什么问题?我想,也许它是在现有的过渡之上附加新的过渡。但事实并非如此,即使我在updtae函数的else部分中禁用了所有与转换相关的行,但如果更新函数的一部分中没有转换,则转换仍然不在其中。如果你能帮我解决这个问题,我将非常高兴。你知道吗


Tags: svgmarginwstimevarscripttransformwidth
1条回答
网友
1楼 · 发布于 2024-09-26 18:20:33

这很奇怪,你的代码应该可以工作。就好像d3没有拿起transition.attr并应用它。最好的选择是设置自己的插值器:

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

完整工作代码:

相关问题 更多 >

    热门问题