如何用D3.js调用API获取JSON数据实现实时多折线图
实现D3.js实时多折线图接入API数据
我来帮你把代码改成调用API获取JSON数据来实时更新图表,主要需要调整数据获取逻辑和定时调用方式,以下是具体修改方案:
关键修改点
- 替换随机数据为API请求:使用
d3.json(或者原生fetch)获取API返回的JSON数据,替换原来的随机生成值 - 调整定时调用逻辑:因为API请求是异步操作,不能用原来的动画结束递归调用,改用
setTimeout控制请求间隔,避免并发请求堆积 - 处理API数据映射:假设你的API返回结构和现有
groups对应(包含current、target、output字段),直接将返回值对应到各组的数值
修改后的完整代码
<!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) } // 定义API请求函数 function fetchData() { // 替换成你的API地址 return d3.json('your-api-url-here') .catch(function(error) { console.error('API请求失败:', error); // 请求失败时返回默认值,避免图表中断 return { current: 0, target: 0, output: 0 }; }); } function updateChart(apiData) { now = new Date() // 使用API返回的数据更新各组数值 for (var name in groups) { var group = groups[name] // 确保API返回对应字段,否则用0兜底 group.value = apiData[name] || 0; group.data.push(group.value); 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) + ')') // Remove oldest data point from each group for (var name in groups) { var group = groups[name] group.data.shift() } } // 定时调用API并更新图表 function tick() { fetchData().then(function(apiData) { updateChart(apiData); // 设置下一次调用的间隔,这里和动画duration保持一致,可根据需求调整 setTimeout(tick, duration); }); } // 启动实时更新 tick() </script> </body> </html>
代码说明
- API请求部分:
fetchData函数用d3.json请求你的API,同时添加了错误处理,避免请求失败导致图表停止更新 - 图表更新逻辑:
updateChart函数负责将API返回的数据映射到各组,然后执行原来的图表更新逻辑 - 定时控制:改用
setTimeout在每次API请求完成并更新图表后,再安排下一次请求,避免并发请求问题 - 数据兼容性:添加了字段存在性判断,确保API返回数据缺失时图表仍能正常运行
你只需要把your-api-url-here替换成实际的API地址,确保API返回的JSON结构包含current、target、output三个数值字段即可。
内容的提问来源于stack exchange,提问作者Jyothi
相关产品推荐
相关产品推荐

