【问题标题】:Show data dynamically in line chart - ChartJS在折线图中动态显示数据 - ChartJS
【发布时间】:2019-02-08 10:02:26
【问题描述】:

一段时间后,我需要在 Angular 6 应用程序的折线图中显示一些数据,因此假设每 333 毫秒显示一些数据。我正在显示最多 30 秒内注册的数据,因此每个图形数据最多可以持续 30 秒。它必须从单击按钮开始。

这是我创建的一些测试数据,仅用于测试目的:

test_data = {
        '222': {
            joy: 66.5057373046875,
            fear: 1.0003513832343742,
            anger: 2.000018799044483,
            disgust: 3.004251452162862,
            sadness: 4.0001135088386945,
            contempt: 5.001299204188399,
            surprise: 6.203749045729637
        },
        '238': {
            joy: 97.06363677978516,
            fear: 17.500137131541123,
            anger: 27.00000593749519,
            disgust: 6.001324078417383,
            sadness: 21.000043172625737,
            contempt: 21.00033742573578,
            surprise: 32.62530106306076
        },
        '722': {
            joy: 66.5057373046875,
            fear: 60.000351383234374,
            anger: 70.00001879904448,
            disgust: 10.004251452162862,
            sadness: 92.0001135088387,
            contempt: 40.0012992041884,
            surprise: 50.20374904572964
        },
        '838': {
            joy: 97.06363677978516,
            fear: 15.000137131541123,
            anger: 64.50000593749519,
            disgust: 24.501324078417383,
            sadness: 31.500043172625737,
            contempt: 18.50033742573578,
            surprise: 6.2048268765211105
        },
        '1722': {
            joy: 66.5057373046875,
            fear: 54.000351383234374,
            anger: 72.00001879904448,
            disgust: 0.004251452162861824,
            sadness: 80.0001135088387,
            contempt: 20.0012992041884,
            surprise: 20.203749045729637
        },
        '2838': {
            joy: 95.37223815917969,
            fear: 41.000168004859006,
            anger: 62.00000752212509,
            disgust: 33.001674098544754,
            sadness: 3.000052563053032,
            contempt: 44.00044780407916,
            surprise: 4.204549819231033
        },
        '2839': {
            joy: 98.75503540039062,
            fear: 1.0001062582232407,
            anger: 1.0000043528652895,
            disgust: 1.0009740582900122,
            sadness: 2.000033782198443,
            contempt: 2.0002270473924,
            surprise: 1.2051039338111877
        }
    };

在这里,这些值“222”、“238”等是毫秒,这些值需要在图表中显示。我对这些数据进行了结构化,所以我有这样的数组:

joyArray = {
    data: [66.5057373046875, 97.06363677978516, 66.5057373046875, 97.06363677978516, 66.5057373046875, 95.37223815917969, 98.75503540039062],
    label: '',
    borderColor: 'rgba(255, 217, 40, 1)',
    backgroundColor: 'transparent',
    fill: false
};

// push all arrays into this array to show it on the graph
this.chartData.push(this.joyArray, this.fearArray, this.angerArray, this.disgustArray, this.sadnessArray,
            this.surpriseArray, this.contemptArray);

等等,对于每个对象属性。

我的图表是这样实现的:

<canvas id="chartCanvas"></canvas>

这就是它的样子:

所以我需要单击一个按钮并为每一帧显示这些值(222ms、238ms...),有人知道如何使用 chartJS 来做到这一点吗?

编辑:改变了数组的结构,现在它是一个里面有数据的对象。绘制图表函数如下所示:

drawChart() {
        this.chart = new Chart('chartCanvas', {
            type: 'line',
            data: this.data,
            options: this.options
        });
    }

数据对象:

data = {
    labels: [],
    datasets: [] // datasets = this.chartData;
};

【问题讨论】:

    标签: javascript angular chart.js


    【解决方案1】:

    test_data = {
        '1222': {
            joy: 66.5057373046875,
            fear: 1.0003513832343742,
            anger: 2.000018799044483,
            disgust: 3.004251452162862,
            sadness: 4.0001135088386945,
            contempt: 5.001299204188399,
            surprise: 6.203749045729637
        },
        '2238': {
            joy: 97.06363677978516,
            fear: 17.500137131541123,
            anger: 27.00000593749519,
            disgust: 6.001324078417383,
            sadness: 21.000043172625737,
            contempt: 21.00033742573578,
            surprise: 32.62530106306076
        },
        '3722': {
            joy: 66.5057373046875,
            fear: 60.000351383234374,
            anger: 70.00001879904448,
            disgust: 10.004251452162862,
            sadness: 92.0001135088387,
            contempt: 40.0012992041884,
            surprise: 50.20374904572964
        },
        '4838': {
            joy: 97.06363677978516,
            fear: 15.000137131541123,
            anger: 64.50000593749519,
            disgust: 24.501324078417383,
            sadness: 31.500043172625737,
            contempt: 18.50033742573578,
            surprise: 6.2048268765211105
        },
        '5722': {
            joy: 66.5057373046875,
            fear: 54.000351383234374,
            anger: 72.00001879904448,
            disgust: 0.004251452162861824,
            sadness: 80.0001135088387,
            contempt: 20.0012992041884,
            surprise: 20.203749045729637
        },
        '6838': {
            joy: 95.37223815917969,
            fear: 41.000168004859006,
            anger: 62.00000752212509,
            disgust: 33.001674098544754,
            sadness: 3.000052563053032,
            contempt: 44.00044780407916,
            surprise: 4.204549819231033
        },
        '7839': {
            joy: 98.75503540039062,
            fear: 1.0001062582232407,
            anger: 1.0000043528652895,
            disgust: 1.0009740582900122,
            sadness: 2.000033782198443,
            contempt: 2.0002270473924,
            surprise: 1.2051039338111877
        }
    };
    
    var arr = Object.entries(test_data)
    
    
    var options = {
        type: 'line',
        data: {
            labels: ["joy", "fear", "anger", "disgust", "sadness", "contempt", "surprise"],
            datasets: []
        },
        options: {
            scales: {
                yAxes: [{
                    ticks: {
                        reverse: false
                    }
                }]
            }
        }
    }
    
    
    
    
    var ctx = document.getElementById('chartJSContainer').getContext('2d');
    var myC = new Chart(ctx, options);
    
    
    arr.forEach((v) => {
        setTimeout(() => {
    
    
            myC.data.datasets.push({
                data: [v[1].joy, v[1].fear, v[1].anger, v[1].disgust, v[1].sadness, v[1].contempt, v[1].surprise],
                label: "#" + v[0] + "Milisec"
            });
            myC.update()
        }, parseInt(v[0]))
    })
    canvas { background-color : #eee;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
    
    <body>
        <canvas id="chartJSContainer" width="600" height="400"></canvas>
    </body>

    【讨论】:

    • 嗯,很接近了,但我需要的有点不同,现在你在一段时间后画了整条线。我需要的是在这么多毫秒后在测试数据中显示这些对象中的每一个 - 例如:在 1222 毫秒之后显示第一个对象,在 2328 之后显示第二个对象......所以图表有一些流程,就像一个视频,你经历了几秒钟和表达情绪
    • 使用类似这个例子:jsfiddle.net/therowf/jp48kb5L
    • 我不确定如何像您在此示例中提供的数据那样构建我的数据:/
    【解决方案2】:

    我了解您希望每 xx 毫秒使用新的 json 数据更新视图 总之,你需要:

    • 有一个服务可以公开一个共享的 observable,比如 data$;
    • 该服务具有获取远程数据并更新上述共享 observable 的方法,例如 getRemoteData()
    • 调用方法来获取远程数据的服务 Observable.interval()
    • 拥有显示数据的组件
    • 让组件订阅可从服务观察到的数据。

    下一个示例代码说明了如何实现它

    import {takeWhile, first} from 'rxjs/operators';
    import { Component, OnInit } from '@angular/core';
    import { interval } from "rxjs";
    import { PositionsModel } from "./positionsmodel";
    import { MouvementService } from './mouvement.service';
    
    @Component({
      selector: 'app-mouvementview',
      template: '<div *ngIf="data"> your chart </div>',
    })
    
    export class MouvementviewComponent implements OnInit {
      public data: PositionsModel;
      private display: boolean; // whether to display info in the component
                                // use *ngIf="display" in your html to take
                                // advantage of this
      private alive: boolean; // used to unsubscribe from the IntervalObservable
                              // when OnDestroy is called.
      results : string;
      // Inject mouvementService
      constructor(private mouvementService: MouvementService) {
        this.display = false;
    
        }
    
    ngOnInit() {
       this.mouvementService.getPositions().pipe(
          first()) // only gets fired once
          .subscribe((data) => {
            this.data = data;
            this.display = true;
            this.alive = true;
    });
    
    // get our data every subsequent 200 mseconds
    interval(200).pipe(
          takeWhile(() => this.alive)) // only fires when component is alive
          .subscribe(() => {
            this.mouvementService.getPositions()
              .subscribe(data => {
            console.log(data);
            this.data = data;
              });
          });
    
    }
    
    ngOnDestroy(){
        this.alive = false; // switches your IntervalObservable off
      }
    }
    

    【讨论】:

    • 我明白你在说什么,我尝试做类似的事情,但它没有为我做这项工作:/ 不知道如何用我的数据结构诚实地实现你的代码,我需要展示每个帧的每个情绪数组的第一个值,不知道该怎么做
    【解决方案3】:

    您可以为此使用 Chart.js 的 addData() 函数和 setTimeout 方法。

    <!DOCTYPE html>
    <html>
        <head>
             <title>Add data</title>
             <script src = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.js"></script>
        </head>
        <body>      
            <div class = "container">
                <canvas id="myChart"></canvas>            
            </div>
            <script src = "script.js"></script>
        </body>
    </html>
    

    script.js

    let ctx = document.getElementById("myChart").getContext('2d');
            let myChart = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
                    datasets: [{
                        label: '# of Votes',
                        data: [7, 9, 3, 5, 2, 3],
                        backgroundColor: [
                            'rgba(255, 99, 132, 0.2)',
                            'rgba(54, 162, 235, 0.2)',
                            'rgba(255, 206, 86, 0.2)',
                            'rgba(75, 192, 192, 0.2)',
                            'rgba(153, 102, 255, 0.2)',
                            'rgba(255, 159, 64, 0.2)'
                        ],
                        borderColor: [
                            'rgba(255,99,132,1)',
                            'rgba(54, 162, 235, 1)',
                            'rgba(255, 206, 86, 1)',
                            'rgba(75, 192, 192, 1)',
                            'rgba(153, 102, 255, 1)',
                            'rgba(255, 159, 64, 1)'
                        ],
                        borderWidth: 1
                    }]
                },
                options: {
                    scales: {
                        yAxes: [{
                            ticks: {
                                beginAtZero:true
                            }
                        }]
                    }
                }
            });
    
            setTimeout(function() {
                addData(myChart, "White", 7);
            },3000);
    
            function addData(chart, label, data) {
                console.log(console.log(chart.data.datasets[0].data));
                chart.data.labels.push(label);
                chart.data.datasets[0].data.push(data);
                chart.update();
            } 
    

    希望这会有所帮助。如果您希望以间隔(例如每 2 秒)向图表添加数据,可以将 setTimeout 更改为 setInterval。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-26
      • 1970-01-01
      • 2022-09-30
      • 2015-06-28
      • 1970-01-01
      • 2015-04-20
      • 2014-10-20
      相关资源
      最近更新 更多