如何使用RxJS在Angular中提取API返回数据的指定属性并填充至数组(适配Plotly图表)
问题分析与解决方案
首先,你的代码里有两个关键问题导致y轴数据无法正常加载:
1. 错误使用Array.push()方法
res.push(res.map(countUp => countUp.countUp))这行代码逻辑完全错误:
Array.push()的返回值是数组的新长度(数字类型),而不是你期望的数组本身,所以y轴最终得到的是一个数字,不是数据数组。- 而且这里根本不需要用
push,你要做的是从现有数组中提取特定属性生成新数组,直接用map就够了。
2. 属性名不匹配
你的模型里定义的是count_up(下划线命名),但你在map里写的是countUp(小驼峰),这会导致提取到undefined,即使逻辑正确也拿不到数据。
修正后的代码方案
方案一:直接在订阅回调中修正y轴数据提取
把错误的y轴赋值代码替换成:
y: res.map(item => item.count_up)
完整的订阅回调修改后如下:
this.showLineChart().subscribe((res) => { console.log(res); // 从API返回的数据中提取x轴的时间和y轴的count_up const xAxisData = res.map(item => item.dt); const yAxisData = res.map(item => item.count_up); this.graph = { data: [ { x: xAxisData, // 改用API返回的真实时间数据,不用硬编码 y: [-10, -87, -30, -69, -50], stackgroup: 'one', fillcolor: '#F2A2A2', mode: 'none', }, { x: xAxisData, y: yAxisData, // 这里是正确提取的count_up数组 stackgroup: 'two', fillcolor: '#F3CFCF', mode: 'none', }, ], layout: { autosize: true, margin: { t: 15, r: 30, b: 30, l: 45, }, xaxis: { range: this.xrange, showgrid: false, zeroline: true, showline: false, autotick: true, ticks: '', showticklabels: true, }, yaxis: { range: this.yrange, showgrid: false, zeroline: true, showline: false, autotick: true, ticks: '', showticklabels: true, }, showlegend: false, }, }; });
方案二:提前在RxJS管道中处理数据(推荐)
可以把数据提取逻辑放到API调用的pipe里,让订阅回调更简洁:
showLineChart() { return this.sensorNodeService .cameraDataInInterval(16, '2021-01-19 00:00:00', '2021-01-19 23:59:59', '1') .pipe( map((data) => { // 一次性提取需要的x和y轴数据 return { x: data.map(item => item.dt), y: data.map(item => item.count_up) }; }) ); }
然后订阅的时候直接使用处理好的数据:
this.showLineChart().subscribe((chartData) => { console.log(chartData); this.graph = { data: [ { x: chartData.x, y: [-10, -87, -30, -69, -50], stackgroup: 'one', fillcolor: '#F2A2A2', mode: 'none', }, { x: chartData.x, y: chartData.y, stackgroup: 'two', fillcolor: '#F3CFCF', mode: 'none', }, ], layout: { autosize: true, margin: { t: 15, r: 30, b: 30, l: 45, }, xaxis: { range: this.xrange, showgrid: false, zeroline: true, showline: false, autotick: true, ticks: '', showticklabels: true, }, yaxis: { range: this.yrange, showgrid: false, zeroline: true, showline: false, autotick: true, ticks: '', showticklabels: true, }, showlegend: false, }, }; });
额外提示
如果API返回的dt时间格式不符合Plotly的解析要求,可以在map里用new Date(item.dt)转换为Date对象,确保x轴能正确渲染时间刻度。
内容的提问来源于stack exchange,提问作者niceCoderToTheBest
相关产品推荐
相关产品推荐

