使用实际数据使用d3实时绘制数据图表

时间:2016-11-21 03:25:16

标签: node.js d3.js

我已经看过许多使用D3实时数据绘图的精彩演示。 http://bl.ocks.org/simenbrekken/6634070是我喜欢的人。但是,我见过的所有示例都使用随机生成的值。我想绘制实时数据,并将最新值显示为更新数字显示。我使用python脚本将传感器读数中的数据写入csv文件。 csv在每一行上有3个值:unixtime,sensor1_value,sensor2_value。每5秒钟就有一个新的数据线被添加到一个具有720行数据的环形缓冲区文件中。当显示网页时,我想读取缓冲区文件中的720行,然后使用写入文件末尾的每个新值更新图形。我还可以每5秒创建一个只有新行csv的文件,这样就可以通过只读取1行csv而不是操作整个缓冲区来执行更新。

有没有人知道一个例子,或者正确的代码来实现这个目标?

上述例子的代码是:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">

        <style>
        body {
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        }

        .graph .axis {
            stroke-width: 1;
        }

        .graph .axis .tick line {
            stroke: black;
        }

        .graph .axis .tick text {
            fill: black;
            font-size: 0.7em;
        }

        .graph .axis .domain {
            fill: none;
            stroke: black;
        }

        .graph .group {
            fill: none;
            stroke: black;
            stroke-width: 1.5;
        }
        </style>
    </head>
    <body>
        <div class="graph"></div>

        <script src="http://d3js.org/d3.v3.min.js"></script>
        <script>
        var limit = 60 * 1,
            duration = 750,
            now = new Date(Date.now() - duration)

        var width = 500,
            height = 200

        var groups = {
            current: {
                value: 0,
                color: 'orange',
                data: d3.range(limit).map(function() {
                    return 0
                })
            },
            target: {
                value: 0,
                color: 'green',
                data: d3.range(limit).map(function() {
                    return 0
                })
            },
            output: {
                value: 0,
                color: 'grey',
                data: d3.range(limit).map(function() {
                    return 0
                })
            }
        }

        var x = d3.time.scale()
            .domain([now - (limit - 2), now - duration])
            .range([0, width])

        var y = d3.scale.linear()
            .domain([0, 100])
            .range([height, 0])

        var line = d3.svg.line()
            .interpolate('basis')
            .x(function(d, i) {
                return x(now - (limit - 1 - i) * duration)
            })
            .y(function(d) {
                return y(d)
            })

        var svg = d3.select('.graph').append('svg')
            .attr('class', 'chart')
            .attr('width', width)
            .attr('height', height + 50)

        var axis = svg.append('g')
            .attr('class', 'x axis')
            .attr('transform', 'translate(0,' + height + ')')
            .call(x.axis = d3.svg.axis().scale(x).orient('bottom'))

        var paths = svg.append('g')

        for (var name in groups) {
            var group = groups[name]
            group.path = paths.append('path')
                .data([group.data])
                .attr('class', name + ' group')
                .style('stroke', group.color)
        }

        function tick() {
        now = new Date()

            // Add new values
            for (var name in groups) {
                var group = groups[name]
                //group.data.push(group.value) // Real values arrive at irregular intervals
                group.data.push(20 + Math.random() * 100)
                group.path.attr('d', line)
            }

            // Shift domain
            x.domain([now - (limit - 2) * duration, now - duration])

            // Slide x-axis left
            axis.transition()
                .duration(duration)
                .ease('linear')
                .call(x.axis)

            // Slide paths left
            paths.attr('transform', null)
                .transition()
                .duration(duration)
                .ease('linear')
                .attr('transform', 'translate(' + x(now - (limit - 1) * duration) + ')')
                .each('end', tick)

            // Remove oldest data point from each group
            for (var name in groups) {
                var group = groups[name]
                group.data.shift()
            }
        }

        tick()
        </script>
    </body>
</html>

而我用来创建一个静态图表的代码来自我的csv和一行:

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style> /* set the CSS */

    body { font: 12px Arial;}

    path {
      stroke: steelblue;
      stroke-width: 2;
      fill: none;
    }

    .axis path,
    .axis line {
            fill: none;
            stroke: grey;
            stroke-width: 1;
            shape-rendering: crispEdges;
    }

    </style>
    <body>

    <!-- load the d3.js library -->
    <script src="http://d3js.org/d3.v3.min.js"></script>

    <script>

    // Set the dimensions of the canvas / graph
    var     margin = {top: 30, right: 20, bottom: 30, left: 50},
            width = 900 - margin.left - margin.right,
            height = 270 - margin.top - margin.bottom;

    // Set the ranges
    var     x = d3.scale.linear().range([0, width]);
    var     y = d3.scale.linear().range([height, 0]);

    // Define the axes
    var     xAxis = d3.svg.axis().scale(x)
            .orient("bottom").ticks(10);

    var     yAxis = d3.svg.axis().scale(y)
            .orient("left").ticks(10);

    // Define the line
    var     valueline = d3.svg.line()
            .x(function(d) { return x(d.time); })
            .y(function(d) { return y(d.o2); });

    // Adds the svg canvas
    var     svg = d3.select("body")
            .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 + ")");

    // Get the data
    d3.csv("./data/buffer.txt", function(error, data) {
            data.forEach(function(d) {
                    d.time = +d.time;
                    d.o2 = +d.o2;
                    console.log(d.time);
            });

            // Scale the range of the data
            x.domain(d3.extent(data, function(d) { return d.time; }));
            y.domain([0, d3.max(data, function(d) { return d.o2; })]);

            // Add the valueline path.
            svg.append("path")
                    .attr("class", "line")
                    .attr("d", valueline(data));

            // Add the X Axis
            svg.append("g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + height + ")")
                    .call(xAxis);

            // Add the Y Axis
            svg.append("g")
                    .attr("class", "y axis")
                    .call(yAxis);



    });

</script>
</body>

0 个答案:

没有答案