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

Developing a Fresh Settings Tab and Vue Module in Laravel Spark

When working with Laravel Spark, you'll find that most settings panels come with a corresponding Vue JS component that is called upon using a custom tab. <spark-create-tests :user="user" inline-template> <div> </div> </sp ...

Create dynamic animations using AngularJS to transition between different states within an ng-repeat loop

Here's a simplified explanation of my current dilemma: I have an array containing a list of items that are being displayed in an Angular view using ng-repeat, like... <li ng-repeat="item in items"> <div class="bar" ng-style="{'width ...

Generating a component and rendering it according to the dynamic route parameters using mapStateToProps and reselect techniques

I have set up a global app container to store data for different rooms, with a sub-container called roomDetails that utilizes a reselect selector to pick a room from the global state based on ownProps.params.slug. This process is accomplished through mapSt ...

Steps to activating CORS in AngularJS

I've put together a demonstration using JavaScript to interact with the Flickr photo search API. Now, I'm in the process of transitioning it to AngularJs, and after some research online, I have come across the following configuration: Configurat ...

Discover the Vue.js component names in this array list-based show

I currently have multiple components in my code, which has made it quite lengthy. I believe there is a way to simplify it. Is it possible to structure it like the following example code: Where the component names are referenced dynamically based on data? ...

Troubleshooting a TypeScript error when trying to access an imported service in Angular 2

I've been working on creating a form that allows users to input required details, which will trigger a server call and save the information. However, no matter what I try, I keep encountering the following error: ORIGINAL EXCEPTION: TypeError: this.po ...

What are some solutions for dealing with NodeJS heap memory errors?

I am currently working with a NodeJS connected database that is 723.1 MB in size, and I am running into memory size issues. To make my database available as an API for use in my VueJS application, I have successfully rendered all the necessary data from a ...

What is the best way to implement a link instead of a string within a custom JavaScript function?

I am looking for a way to replace parameters in a string with the values provided using a helper function - type FormatStringParameter = string | number; /** * Helper function to substitute parameters in a string with the specified values * * @param in ...

Using Special Characters in React JS Applications

When handling CSV uploads with accented characters such as émily or ástha, I encountered the need to encode and pass them to the backend. Experimenting with different approaches, I tried adjusting the file type in FormData from 'text/plain' to ...

Implementing VueJS 3 component loading in Laravel 9

I am currently working on creating a component using Laravel 9 and VueJS 3. The component includes a datatable, and I am utilizing vue-good-table-next for this purpose. However, I am encountering an issue trying to display it in my blade template and I&apo ...

What steps can I take to persistently subscribe to SignalR from an Angular service even in the event of connection failures?

Is there a way to safely attempt to connect to SignalR with intervals between attempts until the connection is established? Also, does anyone have advice on how to handle the different stages of connectivity to the web sockets effectively? We are utilizin ...

Adjusting speed dynamically within a setInterval function in JavaScript

I am working on a react application that requires displaying text with varying intervals between sentences, one at a time. To achieve this functionality, I stored all the sentences in an array and implemented a setInterval function: startShowingText() ...

Unlocking the request object within a GraphQL resolver with Apollo-Server-Express

My express server is standard and I'm using GraphQL with it const server = express(); server.use('/graphql', bodyParser.json(), graphqlExpress({ schema })); I am wondering how to access the request object within a resolver. Specifically, ...

Issues with the functionality of the asynchronous socket.io JavaScript callback are being experienced

I am facing an issue with my JavaScript code that involves querying data from a database using Node.js and Socket.io. Currently, I have implemented setTimeout() functions to make it work, but I want to switch to using callbacks for better reliability. Howe ...

Ensuring Vue.js correctly re-renders an array item

In my vue.js 2 project, I am working with an array that has the following structure: data() { return { ports: [ { id: 1, name: "example", "age": 10, scores: [ {index: 1, value: 100}, {index: 2, value: 200} ]}, { id: 2, ...

`Python automation for seamless HTTP browsing and HTML document generation`

My weekly routine at work involves printing out Account analysis and Account Positions for more than 50 accounts every Monday. I have to navigate through the page, select "account analysis", input the account name, format the page for printing, print the o ...

Display webpage content in an Iframe using Javascript after PHP code has been executed

Despite researching keywords like PHP // Javascript // Load // URL online, I'm still struggling to fully grasp the concepts. Real-life case studies have been helpful, but I must admit that I'm feeling a bit overwhelmed at the moment. I created a ...

Issue: requireJS configuration is invalid

Here is the file structure of my project - src |- main.js |- math.js The math.js file acts as an AMD module and is being required in main.js. I have npm installed require.js and included it in main.js. //main.js var rjs = require('requirejs' ...

Creating input fields using Vuejs

Currently, I am learning how to incorporate HTML content rendering in Vuejs. I'm experimenting with creating a small input component that is generated through the render function. Here is a snippet of what I have so far: export default { name: &qu ...

Animating all the numbers on a jQuery countdown timer

http://jsfiddle.net/GNrUM/ The linked jsfiddle showcases a countdown of 2 seconds, with only the numbers displayed. My goal was to explore: a) How can I incorporate animations into the JavaScript code so that the number changes in size, color, and positi ...