Utilizing Chart.js with Vue for dynamic time axis plots from JSON data through computed properties

Trying to generate a chart with a time axis in Vue using Chart.js has been a challenge. Initially, everything worked perfectly when the data was set directly in the Data object as shown below:

chartData: {
    datasets: [
        {
            backgroundColor: '#ED645A',
            borderColor: '#ED645A',
            fill: false,
            data: [
                {
                    t: new Date("1998-1-1"),
                    y: 7.1
                },
                {
                    t: new Date("1998-2-1"),
                    y: 8.4
                },
                {
                    t: new Date("1998-3-1"),
                    y: 18.5
                },
                {
                    t: new Date("1998-4-1"),
                    y: 16.2
                },
                {
                    t: new Date("1998-5-1"),
                    y: 18.4
                }
            ]
        }
    ]
},

However, attempting to load the data from a JSON file and formulating the datasets object in a computed property like this, resulted in failure:

import pureSecondDatasetJson from "../assets/pureSecondDataset.json"

...

export default {

...

data () {
    return {
        pureSecondDataset: pureSecondDatasetJson,
        charts: [
            chartData: {
            datasets: this.foo
},

...

computed: {
    foo() {
        var plotData = []
        for (var i=0; i<this.pureSecondDataset.length; i++) {        
            plotData.push({t: new Date(this.pureSecondDataset[i].t), y: this.pureSecondDataset[i].y})
        }
        var chartData = [
            {
                backgroundColor: '#ED645A',
                borderColor: '#ED645A',
                fill: false,
                data: plotData
            }
        ];
        return chartData
    }
}

The object created in the computed property seems identical to the one added directly. So, why doesn't it work?

Answer №1

Avoid accessing a computed property directly from your data, as discussed on the Vue Forum.

Remember that the data gets evaluated before the computed array.

It is recommended to modify your computed property like the example below and then utilize it for your chart data:

foo() {
    var chartData = []
    for (var i=0; i<this.pureSecondDataset.length; i++)        
        chartData.push({t: new Date(this.pureSecondDataset[i].t), y: this.pureSecondDataset[i].y})

    return {
        chartData: {
            datasets:[{
                backgroundColor: '#ED645A',
                borderColor: '#ED645A',
                fill: false,
                data: chartData
            }]
        }
    }
}

I have provided a fiddle demonstrating how you can achieve this without relying on the computed property within the data. While creating the fiddle, I discovered that to create a proper line graph, you need to include labels for the x-values or use type: scatter along with drawLine:true to specify both x and y values together. Chart.js - Plot line graph with X , Y coordinates

new Vue({
  el: "#app",
  data: () => {
    return {
      chartData: [{
        x: 1,
        y: 1
      }, {
        x: 2,
        y: 2
      }, {
        x: 3,
        y: 3
      }]
    }
  },
  computed: {
    foo() {
      return {
        type: 'scatter',
        data: {
          datasets: [{
            showLine: true,
            label: 'My First dataset',
            backgroundColor: 'rgb(255, 99, 132)',
            borderColor: 'rgb(255, 99, 132)',
            data: this.chartData
          }]
        }
      }
    }
  },
  mounted() {
    var ctx = document.getElementById('chart').getContext('2d');
    new Chart(ctx, this.foo);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3350666f654d62746b617068756d24696962">[email protected]</a>"></script>
<div id="app">
  <canvas id="chart" width="400" height="400"></canvas>
</div>

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

The function chrome.notifications.create() is producing incorrect notification IDs upon clicking

Greetings for my first post here. I've been struggling with an issue in a personal project lately. I remember coming across a similar topic on this forum before, but now I can't seem to find it. As far as I recall, the question went unanswered. ...

When scrolling, the selected text does not maintain its correct position

I'm looking to enable my users to search by selecting text. Once they select text, a new button will appear on the right side of the selected text giving them the option to search or not. However, when the user scrolls to the bottom of the page, the p ...

Is it possible to make changes to dynamically inserted HTML using jQuery.ajax?

I'm facing a scenario in jQuery where I make an ajax call that inserts HTML into my website. However, I also need to perform operations on this inserted HTML within the same ajax call's success callback function. Here is a simplified version of ...

What is the best way to hide the background of an extension's HTML?

Currently, I am working on developing a Chrome extension for a university project. However, I am facing challenges in making the background or body of the extension's HTML completely transparent to achieve a cleaner interface. The issue specifically l ...

What is the best way to create an Office Script autofill feature that automatically fills to the last row in Excel?

Having trouble setting up an Excel script to autofill a column only down to the final row of data, without extending further. Each table I use this script on has a different number of rows, so hardcoding the row range is not helpful. Is there a way to make ...

What are the steps to installing a .deb file offline using Docker?

I am planning to install a .deb file on my Docker container. In my Dockerfile, I execute the following command: RUN apt-get install -y ./fonts/ttf-mscorefonts-installer_3.6_all.deb ROOT Folder |->Dockerfile |->fonts |-> ttf ...

Incorporate JQuery into your NodeJS project by leveraging the existing minified file

Can we integrate JQuery into Node.js and make JQuery AJAX calls without altering the syntax by using a pre-downloaded minimized JQuery file? To clarify, I have the minified file and wish to incorporate it into Node.js in this manner: var jquery = require( ...

What is the method for utilizing string interpolation in Angular/Typescript in order to retrieve a value from a variable?

I have a variable called demoVars, which is an array of objects with properties var1, var2, and var3. In my component class, I have a variable named selectedVar that holds the name of one of these properties: var1, var2, or var3. I want to dynamically pu ...

What is the best way to send a JSON object in Vue.js?

<template> <div id="app"> <div id="bee-plugin-container"></div> </div> </template> <script> // import axios from "axios"; // import Bee from "@mailupinc/bee-plugin"; import $ from 'jquery' ...

I encountered an issue with Array map when attempting to access the data during a dynamic rendering process

function UserTransactionsComponent1() { const [accounts, setAccounts] = useState(); useEffect(() => { async function fetchData() { const res = await fetch( 'https://proton.api.atomicassets.io/atomicassets/v1/accounts' ...

Unable to submit form data in AWS Amplify & React: The message "Not Authorized to access createRecipe on type Mutation" is displaying

I've recently set up a project using React and AWS Amplify. I've successfully added some data to DynamoDB in AWS, but when I try to submit form data from my React App, I encounter an error from the API. I'm a bit stuck on what to do next. I ...

Failed to retrieve the requested item using fetch, encountering a NetworkError

My API is being accessed to retrieve data using this code snippet. It sends the email and password to the API: onSubmitSignIn = () => { fetch('http://localhost:3001/signin', { method: 'post', headers: {'Content-Type&ap ...

Searching for different forms of multiple words using regular expressions

I have a value saved in a variable: var myvalue = "hello bye"; var myText = "hellobye is here and hello-bye here and hello.bye" Is there a way to check if different versions of myvalue are present in the text? I am currently using this pattern: hello ...

Unable to retrieve the iframe variable from the parent as it returns undefined

I am trying to retrieve a variable within an iframe from the parent index.html. Here is the index.html code: <!doctype html> <html lang="en-us> <head> <title>Test</title> </head> <body> <p>Test& ...

Exploring the possibilities of combining OpenCV with web technologies like Javascript

I am currently faced with the challenge of integrating OpenCV into a web application using Express.js. While I am familiar with the Python and C++ libraries for OpenCV, I now need to work with it in conjunction with Express.js. My main requirements include ...

Having trouble with a basic select tag and options not functioning properly in Chrome browser

I encountered an issue where I am unable to expand a simple select tag in Chrome. <select id="filterCategory" class=""> <option>1</option> <option>2</option> <option>3</option> <option>4</option ...

Error: Trying to modify a property that is set as read-only while attempting to override the toString() function

I have a specific object that includes an instance variable holding a collection of other objects. Right now, my goal is to enhance this list of elements by adding a customized toString() method (which each Element already possesses). I experimented with t ...

What is the purpose of employing useMemo in the Material-UI autocomplete documentation?

My focus is on this specific demo in the autocomplete documentation. In the google maps example, there is a throttled function that is returned from a useMemo with an empty array as the second parameter. However, it raises the question of what exactly is ...

Learn how to toggle the visibility of three div elements arranged horizontally

$(document).ready(function () { $("#toggle").click(function () { if ($(this).data('name') == 'show') { $("#sidebar").animate({ width: '10%' }).hide() $("#map").an ...

The new and improved Vue 3 computed feature in the Composition API

The temporary object appears as: tmp : { k1: { k2 : { k3 : [abc, def] } } To access k3 in the setup, it should be: tmp.value.k1.k2.k3[0 or 1]. I am looking to change its name to something like - k3_arr = tmp.value.k1.k2.k3; Within my Vue single componen ...