2016-05-11 6 views
2

添付コードをアニメーション化しようとしています。私は新しいデータポイントの追加の間に軸とパスをスムーズに移動させたい。遷移時間はdeltaTでなければなりません。誰かが私を助けてくれることを願っていますd3を使用したトランジション付きの応答線グラフ

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8" /> 
    <title>Transfer setup rpi1 interface</title> 
    <meta name="viewport" content="width=device-width" /> 
    <link rel="stylesheet" type="text/css" href="style.css"> 
    <script type="text/javascript" src="jquery-1.11.3.min.js"></script> 
    <script src="jquery.flot.min.js"></script> 
    <script src="jquery.flot.time.js"></script> 
    <script src="//d3js.org/d3.v3.js" charset="utf-8"></script> 
    <script type="text/javascript" src="main.js"></script> 
</head> 
<body> 
    <div class="content"> 
    <header> 
    <h1>Transfer Setup Rpi1</h1> 
    </header> 

    <div class="main"> 

    <h2>Control</h2> 

     <fieldset> 
     <legend>Temperature</legend> 
     <div id="widthReader"> 
     <table id="cssTable"> 
      <tr> 
       <td> 

       <table id="cssTable"> 
       <td><label for="toggleFan">Fan</label></td> 
       <td> 
       <input id="toggleFan" class="cmn-toggle cmn-toggle-round" type="checkbox"> 
       <label for="toggleFan"></label> 
       </td> 
       </table> 

       </td> 

       <td> 
       &nbsp; 
       </td> 
       <td> 
       <label>Speed:</label> <input type="text" 
        id="fanSpeed" name="fanSpeed" value=""> 
       </td> 
      </tr> 
      <tr> 
       <td> 

       <table id="cssTable"> 
       <td><label for="toggleHeater">Heater</label></td> 
       <td> 
       <input id="toggleHeater" class="cmn-toggle cmn-toggle-round" type="checkbox"> 
       <label for="toggleHeater"></label> 
       </td> 
       </table> 

       </td> 
       <td> 
       &nbsp; 
       </td> 
       <td> 
       <label>Setpoint:</label> <input type="text" 
        id="heaterTemp" name="heaterTemp" value=""> 
       </td> 
      </tr> 
     </table> 

     </div> 
     </fieldset> 

      <button id="buttonSave">Save Settings</button> 


    <h2>Dashboard</h2> 
    <fieldset> 
    <legend>Chart</legend> 
     <label>Current Temperature:</label> <label id="heater_temperature">&nbsp;</label><label>°C</label> 
     <div id="chart"></div> 
    </fieldset> 
</div> 
    </div> 
</body> 
</html> 

main.js:

var deltaT = 2500; //temperature update intervall 


var Chart = (function(window,d3) { 

    var svg, data, x, y, xAxis, yAxis, dim, chartWrapper, line, path, margin = {}, width, height, locator, textsize, xlabeloff, ylabeloff, xtickpadding, ytickpadding, xtickdistance, ytickdistance; 

    var breakPoint = 400; //for rendering smaller fonts on mobile devices wiht small screen widths 

    var n = 10,//(4)*60,//length of recording 
     duration = deltaT,//duration of deltat in msec 
     now = new Date(Date.now() - duration), 
     count = 0, 
     data = Array.apply(null, new Array(n)).map(Number.prototype.valueOf,20); 


    //called once the data is loaded 
    function init() { 

    //initialize scales 
    x = d3.time.scale() 
     .domain([now - (n+1) * duration, now ]) 
     .range([0, width]); 

    y = d3.scale.linear() 
     .domain([0, (1.1*d3.max(data))]) 
     .range([height, 0]); 

    line = d3.svg.line() 
     .interpolate("basis") 
     .x(function (d, i) { return x(now - ((n-1) - i) * duration); }) 
     .y(function (d, i) { return y(d); }); 

    //initialize axis 
    x.axis = d3.svg.axis().scale(x).orient("top"); 
    y.axis = d3.svg.axis().scale(y).orient("right"); 

    x.axisT = d3.svg.axis().scale(x).orient("bottom").tickFormat(""); 
    y.axisR = d3.svg.axis().scale(y).orient("left").tickFormat(""); 

    //initialize svg 
    svg = d3.select('#chart') 
     .append('svg') 
     .style('pointer-events', 'none'); 

    chartWrapper = svg 
     .append('g') 
     .style('pointer-events', 'all'); 

    //cliping mask needed because trace updates and thus moves 
    clipMask = chartWrapper.append("defs").append("clipPath") 
     .attr("id", "clip") 
     .append("rect"); 

    path = chartWrapper.append('g').attr("clip-path", "url(#clip)").append('path').datum(data).classed('line', true); 


    xAxis = chartWrapper.append('g') 
       .attr("class", "x axis") 
       .call(x.axis); 

    xAxisT = chartWrapper.append('g') 
       .attr("class", "x axis") 
       .call(x.axisT); 

    yAxis = chartWrapper.append('g') 
       .attr("class", "y axis") 
       .call(y.axis); 

    yAxisR = chartWrapper.append('g') 
       .attr("class", "y axis") 
       .call(y.axisR); 

    yLabel = chartWrapper.append("text") 
      .attr("class", "y label") 
      //.attr("transform", "rotate(-90)") 
      .style("text-anchor", "middle") 
      .text("Temperature (°C)"); 

    xLabel = chartWrapper.append("text") 
     .attr("class", "x label") 
     .attr("text-anchor", "middle") 
     .text("Time (h:min)"); 

    chartWrapper.on('mousemove', onMouseMove) 
       .on("mouseover", function() { locator.style("display", null); }) 
       .on("mouseout", function() { locator.style("display", "none"); }); 

    //add locator 
    locator = chartWrapper.append('g') 
       .attr("class", "focus"); 
       //.style("display", "none"); 


    locator.append('circle') 
       .attr('r', 4); 

    locator.append("text") 
      .attr("x", 0) 
      .style("text-anchor", "middle") 
      .attr("dy", "-8"); 

    touchScale = d3.time.scale() 
        .domain([now - (n+1) * duration, now ]); 

    //render the chart 
    render(); 
    } 

    function render() { 
    //get dimensions based on window size 
    updateDimensions(); 

    clipMask.attr("width", width) 
      .attr("height", height); 

    //update x and y scales to new dimensions 
    x.range([0, width]); 
    y.range([height, 0]); 

    touchScale.range([0,width]).clamp(true); 

    //update svg elements to new dimensions 
    svg 
     .attr('width', width + margin.right + margin.left) 
     .attr('height', height + margin.top + margin.bottom); 

    chartWrapper 
     .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); 

    xLabel.attr("y", height + xlabeloff) 
      .attr("x", ((width/2))); 

    yLabel.attr("y", - ylabeloff) 
      .attr("x", (margin.top - height/2)) 
      .attr("transform", "rotate(-90)"); 

    //update the axis and line 
    x.axis.scale(x).tickPadding(xtickpadding); 
    x.axisT.scale(x); 
    y.axis.scale(y).tickPadding(ytickpadding); 
    y.axisR.scale(y); 

    x.axis.ticks(Math.max(width/xtickdistance, 2)); 
    y.axis.ticks(Math.max(height/ytickdistance, 2)); 
    x.axisT.ticks(Math.max(width/xtickdistance, 2)); 
    y.axisR.ticks(Math.max(height/ytickdistance, 2)); 

    xAxis.attr('transform', 'translate(0,' + height + ')').call(x.axis); 
    xAxisT.call(x.axisT); 
    yAxis.call(y.axis); 
    yAxisR.call(y.axisR).attr('transform', 'translate(' +width +' ,0)'); 

    path.attr('d', line); 
    updateTextStyle(); 
    } 

    function updateTextStyle() { 
    winWidth = document.getElementById("widthReader").offsetWidth; 

    textsize = winWidth < breakPoint ? "48%" : "80%"; 
    //scale text size 
    chartWrapper.selectAll("text").style("font-size", textsize); 

    yAxis.call(y.axis).selectAll(".tick text").style("text-anchor", "end"); 
    } 

    function updateDimensions(winWidth) { 
    winWidth = document.getElementById("widthReader").offsetWidth; 

    margin.top = winWidth < breakPoint ? 4 :10; 
    margin.right = winWidth < breakPoint ? 4 : 10; 
    margin.left = winWidth < breakPoint ? 26 : 48; 
    margin.bottom = winWidth < breakPoint ? 22: 40; 

    xlabeloff = winWidth < breakPoint ? 21 : 38; 
    ylabeloff = winWidth < breakPoint ? 20 : 36; 

    xtickpadding = winWidth < breakPoint ? "-17" : "-24"; 
    ytickpadding = winWidth < breakPoint ? "-10" : "-12"; 

    xtickdistance = winWidth < breakPoint ? 50 : 80; 
    ytickdistance = winWidth < breakPoint ? 15 : 35; 

    width = winWidth - margin.left - margin.right; 
    height = .54 * width; 
    } 

    function onMouseMove() { 
    var x0 = x.invert(d3.mouse(this)[0]), 
    y0 = y.invert(d3.mouse(this)[1]); 

    locator.attr("transform", "translate(" + d3.mouse(this)[0] + "," + d3.mouse(this)[1] + ")"); 
    locator.select("text").text(y0); 
    } 



function tick() { 

      // update the domains 
      now = new Date(); 
      touchScale.domain([now - (n-1) * duration, now ]); 
      x.domain([now - (n-1) * duration, now ]); 
      y.domain([0, (1.1*d3.max(data))]); 


      // push a new data point onto the back 
      data.push(Number($('#heater_temperature').text())); 

      path.attr("d", line) 
       .attr("transform", null); 

      // slide the x-axis left, rescale the y-axis 
      xAxisT.call(x.axisT); 
      xAxis.call(x.axis); 
      yAxis.call(y.axis); 
      yAxisR.call(y.axisR); 

      // redraw the line and slide line left 
      path.attr("transform", "translate(" + (x(now - (n+0) * duration)) + " ,0)"); 

      // pop the old data point off the front 
      data.shift(); 
      updateTextStyle(); 

     }; 

    return { 
    render : render, 
    tick : tick, 
    init : init 
    } 

})(window,d3); 



$(document).ready(function() { 

// Start deltaT timer to call RESTful endpoint 
setInterval(function() { 
    $('#heater_temperature').text(Math.random()*220); 
    Chart.tick(); 
}, deltaT); 



}); 


$(window).load(function() { //is done after document ready 

    window.addEventListener('resize', Chart.render); 
    Chart.init(); 
    Chart.render(); 
}); 

のstyle.css

のindex.htmlを(私が働いてそれを得たが、唯一の限りグラフが応答しなかったとして、見添付jsがスニペット)

.x.label 
{ 
    fill: #555; 
} 
.y.label 
{ 
    fill: #555; 
} 
.axis path, 
.axis line { 
    stroke-width: 1px; 
    fill: none; 
    stroke: #ccc; 
} 

.axis text { 

    fill: #555; 
} 

.line { 
    fill: none; 
    stroke: steelblue; 
    stroke-width: 1px; 
} 

ウォーキングJS:

var transition = d3.select({}).transition() 
    .duration(deltaT) 
    .ease("linear"); 


function tick() { 
    transition = transition.each(function() { 

     // update the domains 
     now = new Date(); 
     x.domain([now - (n-1) * duration, now ]); 
     y.domain([0, (1.1*d3.max(data))]); 


     // push a new data point onto the back 
     data.push(Number($('#heater_temperature').text())); 



     // slide the x-axis left, rescale the y-axis 
     xAxisT.call(x.axisT); 
     xAxisB.call(x.axisB); 
     yAxisL.call(y.axisL); 
     yAxisR.call(y.axisR); 

     // redraw the line, and slide it to the left 
     path.attr("d", line) 
      .attr("transform", " translate(" + margin.left + " ," + margin.top+")"); 

     // slide the line left 
     path.transition() 
      .attr("transform", "translate(" + (x(now - (n+0) * duration) + margin.left) + " ," + margin.top+ ")"); 

     // pop the old data point off the front 
     data.shift(); 
    }); 
} 

答えて

0

私は問題なく動作しました。問題は、d3.v2の代わりにd3.v3を使用し始めたことです。ここに私が変更したものがあります:

function tick() { 

    d3.transition().ease("linear").duration(deltaT-100).each(function() { 
     // update the domains 
     now = new Date(Date.now()); 
     markerScale.domain([now - (n-2) * duration, now ]); 
     xScale.domain([now - (n-2) * duration, now ]); 
     yScale.domain([0, (1.1*d3.max(data))]); 

     // slide the x-axis left, rescale the y-axis 
     xAxisContT.transition().call(xAxisT); 
     xAxisCont.transition().call(xAxis); 
     yAxisCont.transition().call(yAxis); 
     yAxisContR.transition().call(yAxisR); 

     plot.attr("transform", null); 

     // push a new data point onto the back 
     data.push(Number($('#heater_temperature').text())); 
     path.attr("d", line); 

     marker.data(data) 
      .attr("cx", xValue)  
      .attr("cy", yValue) 
      .attr("transform", null); 

     // redraw the line and slide plot left 
     plot.transition() 
      .attr("transform", "translate(" + (xScale(now - (n-1) * duration)) + " ,0)"); 

     // pop the old data point off the front 
     data.shift(); 

     updateTextStyle(); 
    }); 
} 
関連する問題