Creating Dynamic Graphs using Angular and Chart.js with Array Values

I have implemented ChartJS-2 to visualize a graph displaying an array of user activities, but it appears distorted:

import { Component, OnInit, Input } from '@angular/core';
import { ChartOptions, ChartType, ChartDataSets } from 'chart.js';
import * as pluginDataLabels from 'chartjs-plugin-datalabels';
import { Label } from 'ng2-charts';
import { IblinkPoint } from 'src/app/iblink-point';
import { OpenWebService } from 'src/app/blinking/open-web.service';

@Component({
  selector: 'app-graph',
  templateUrl: './graph.component.html',
  styleUrls: ['./graph.component.scss']
})
export class GraphComponent implements OnInit {
  public barChartOptions: ChartOptions = {
    responsive: true,
    scales: { xAxes: [{}], yAxes: [{}] },
    plugins: {
      datalabels: {
        anchor: 'end',
        align: 'end',
      }
    }
  };
  public barChartType: ChartType = 'bar';
  public chartColors: Array<any> = [
    {
      backgroundColor: 'rgb(77, 0, 77, 1)',
      borderColor: 'rgba(77, 0, 77, 1)',
      borderWidth: 2,
    }
  ];

  public barChartData: ChartDataSets[];
  public barChartLabels: Label[];

  @Input() blinks: IblinkPoint[];
  constructor(private openWebService: OpenWebService) { }

  ngOnInit() {
    let arrBlinks = this.openWebService.getBlinkData();
    let startDateArry: any[] = [];
    let endDateArry: any[] = [];
    let blinkArry: any[] = [];
    arrBlinks.forEach(element => {
    blinkArry.push(element.blinkCounter).toString;
    startDateArry.push(element.startDate.getMinutes().toString());
   // console.log(startDateArry);
    // endDateArry.push(element.endDate.getHours());
    });
    this.barChartLabels = [startDateArry];
    this.barChartData = [{ data: blinkArry, label: 'blinks'}];
  //  console.log(this.barChartData);
  //  console.log(this.barChartLabels);
  }

}
<div style="display: block">
  <canvas baseChart
    [datasets]="barChartData"
    [labels]="barChartLabels"
    [chartType]="barChartType"
    [colors]="chartColors">
  </canvas>
</div>

Instead of the expected graph, all barChartLabels are stacked on top of each other and only one barChartData is displayed. I attempted to debug my code without success.

Answer №1

The root of the problem lies in this particular line

this.barChartLabels = [startDateArry];

At this point, you are essentially inserting the array startDateArry as the first item within the array this.barChartLabels; instead, you should simply do:

this.barChartLabels = startDateArry;

relevant HTML:

<div style="display: block;">
  <canvas baseChart 
    [datasets]="barChartData"
    [labels]="barChartLabels"
    [options]="barChartOptions"
    [plugins]="barChartPlugins"
    [legend]="barChartLegend"
    [chartType]="barChartType">
  </canvas>
</div>

relevant TS:

import { Component, OnInit } from '@angular/core';
import { ChartOptions, ChartType, ChartDataSets } from 'chart.js';
import { Label } from 'ng2-charts';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  public barChartOptions: ChartOptions = {
    responsive: true,
    // We use these empty structures as placeholders for dynamic theming.
    scales: { xAxes: [{}], yAxes: [{}] },
    plugins: {
      datalabels: {
        anchor: 'end',
        align: 'end',
      }
    }
  };
  public barChartLabels: Label[];
  public barChartType: ChartType = 'bar';
  public barChartLegend = true;
  public barChartPlugins = [];
  public barChartData: ChartDataSets[];

  constructor() {
  }

  ngOnInit() {
    let startDateArry: any[] = [];
    let blinkArry: any[] = [];

    for (var i = 0; i < 7; i++) {
      blinkArry.push(Math.round(Math.random() * 100));
      startDateArry.push(Math.round(Math.random() * 100));
    }

    this.barChartData = [{ data: blinkArry, label: 'blinks' }];

    this.barChartLabels = [startDateArry];
    console.log('this is where the issue lies!', this.barChartLabels);

    /* SOLUTION */
    this.barChartLabels = startDateArry;
    console.log('this is how to fix it!', this.barChartLabels);
  }
}

You can observe the distinction between these two statements in the linked functioning stackblitz as well.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it necessary to separate Lodash orderby functions to ensure they function correctly?

For some reason, I'm having trouble sorting my data using lodash in my front-end client code. All the examples I've come across don't involve working with data in an interface, so I can't figure out where I'm going wrong. Let&apo ...

Angular 5 failing to navigate to new page upon successful login

Implementing an authentication system using Angular 5 that utilizes Tokens has been my recent project. However, I encountered a hurdle while trying to authenticate on the login-form - it initiates the process but ends up refreshing the page instead: View ...

Identifying a shift in data model within a component

It seems like there's a piece I might be overlooking, but here's my current situation - I have data that is being linked to the ngModel input of a component, like so: Typescript: SomeData = { SomeValue: 'bar' } Snippet from the vie ...

What is the reason for the inclusion of information in the error log by the `ng

After initiating a production build with the command ng build --configuration production, Angular logs some information to the error log: - Generating browser application bundles (phase: setup)... ✔ Browser application bundle generation complete. ✔ Bro ...

Tips for obtaining the "inner type" of a particular "instance" in TypeScript's generics

Unable to find more appropriate language to elaborate beyond the title, I'm going to rely on the code itself: let var1 = someExternalLibraryMethod(); // assume var1 is implicitly Promise<string> let var2: typeof var1; // this approach enables ...

Error 404 encountered when updating packages in Angular2 tutorial: platform-browser-dynamic.umd.js

I recently started following an Angular2 tutorial, but upon returning to it and reaching the Routing chapter, I realized that the tutorial had been slightly updated. This required me to go back and update the package.json file to match the current version, ...

Keyhole Markup Language (KML) - a specialized layer for mapping

Is there a way to create a KML layer for a polygon with specific coordinates in such a way that the area outside of the polygon is disabled from being clicked or utilized by drawing managers? [33.832681,-84.504041], [33.889129,-84.361905],[33.756788,-84. ...

Writing TypeScript, Vue, and playing around with experimental decorators

After creating a Vue project through Vue-CLI v3.0.0-beta.15, the project runs smoothly when using npm run serve. However, TypeScript displays an error message stating that support for decorators is experimental and subject to change in a future release, bu ...

Setting up APIGateway for CORS with the CDK: A Step-by-Step Guide

My API relies on AWS ApiGateway with an underlying AWS Lambda function provisioned through the CDK. The default CORS settings for the API are as follows: const api = new apiGateway.RestApi(this, "comments-api", { defaultCorsPreflightOptions: { ...

How to troubleshoot the issue of "Error: (SystemJS) module is not defined" in Angular 2?

I am a beginner in the world of Angular2. It is known that in Angular2, there is a way to reference a file using a relative path by defining moduleId : module.id in the component meta data. However, I have tried doing it this way and keep encountering the ...

Using Angular's filter pipe to search within a nested array

We are attempting to implement an angular pipe for filtering a list of sub-items, with the goal of removing parent items if there are no child items present. Here is the HTML code snippet we are using: <div class="row border-bottom item" *n ...

Exploring the world of typed props in Vue.js 3 using TypeScript

Currently, I am attempting to add type hints to my props within a Vue 3 component using the composition API. This is my approach: <script lang="ts"> import FlashInterface from '@/interfaces/FlashInterface'; import { ref } from &a ...

Encountering difficulties in generating a personalized Angular Element

Currently, I am in the process of developing a custom Component that needs to be registered to a module. Here is how it is being done: app.module.ts import { createCustomElement } from "@angular/elements"; @NgModule({ declarations: [ExtensionCompone ...

BehaviorSubject Observable continuously notifies unsubscribed Subscription

Utilizing a service called "settings", initial persisted values are read and provided through an observable named "settings$" to components that subscribe to it. Many components rely on this observable to retrieve the initial values and exchange updated va ...

Introduce a specialized hierarchical data structure known as a nested Record type, which progressively ref

In my system, the permissions are defined as an array of strings: const stringVals = [ 'create:user', 'update:user', 'delete:user', 'create:document', 'update:document', 'delete:document&ap ...

Guide on Retrieving an Array from an Observable

Hey there! I've come across a function that is supposed to return an Array. In the function below, this.cordovaFile.readAsArrayBuffer(this.cordovaFile.dataDirectory, storageId) actually returns a Promise Array. I'm converting it into an Observabl ...

Encounter a net::ERR_EMPTY_RESPONSE error while trying to deploy an Angular application on a production server

I have successfully developed an Angular App on my local machine and now I am facing challenges while trying to deploy it on a Windows production server. I have set up Apache to serve the App along with the Rest Service API. Accessing the App through the ...

Navigating through the nested object values of an Axios request's response can be achieved in React JS by using the proper

I am attempting to extract the category_name from my project_category object within the Axios response of my project. This is a singular record, so I do not need to map through an array, but rather access the entire object stored in my state. Here is an ex ...

Incorporate a visual element into an Angular Library Component Template using an image asset

Currently, I am working with Angular 10 and aiming to develop a component library that includes images and stylesheets. My main goal is to be able to access these images from the component templates defined in the HTML template. Although I have limited ex ...

Angular - Detecting Scroll Events on Page Scrolling Only

I am currently working on implementing a "show more" feature and need to monitor the scroll event for this purpose. The code I am using is: window.addEventListener('scroll', this.scroll, true); Here is the scroll function: scroll = (event: any) ...