如何使用d3制作实时多线图,其中数据来自json格式的api

时间:2018-01-20 07:25:46

标签: javascript json d3.js charts

我正在尝试使用d3.js生成多行实时图表。我通过反复调用api获得的数据是json格式。我怎么能反复打电话给api。这是我的工作代码。

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

在此代码中,随机生成新数据。我怎样才能用api中的json数据实时更新它。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您需要API端的端点为您提供数据,并使用fetch获取该数据。然后,您需要通过您必须编写的函数传递数据,这将生成类似于上面的代码。

这将是获取数据一次。你可以在间隔上设置它,但最好的解决方案是使用socket.io,这需要在服务器端和你的js代码中实现。