Tips for personalizing the tooltip on a line chart in Vue.js using Chart.js

Attempting to create a line graph using chart js and vue, but new to both technologies. In the chart below, I am trying to change the tooltip to display "10 Answers July 19, 2023". I have attempted to use the beforeLabel and afterLabel options without success.

https://i.stack.imgur.com/PWEvH.png

<template>
  <div class="col-xs-12 col-md-4 analytic-container">
    <div class="row title justify-between">
      <div class="answer-count">
        <div class="">Answers</div>
        <h2 v-if="totalAnsCount != 0" class="q-ma-none">{{ totalAnsCount }}</h2>
      </div>
      <div class="filter">
        Last
        <q-btn-group flat>
          <q-btn
            :class="btnFlag === 7 ? 'select-interval' : 'unselect-interval'"
            flat
            label="7"
            @click="getChartData(7)"
          />
          <q-btn
            :class="btnFlag === 30 ? 'select-interval' : 'unselect-interval'"
            flat
            label="30"
            @click="getChartData(30)"
          />
          <q-btn
            :class="btnFlag === 90 ? 'select-interval' : 'unselect-interval'"
            flat
            label="90"
            @click="getChartData(90)"
          />
          <q-btn
            :class="btnFlag === 0 ? 'select-interval' : 'unselect-interval'"
            flat
            label="All"
            @click="getChartData(0)"
          />
        </q-btn-group>
        days
      </div>
    </div>
    <div class="row justify-between">
      <LineChart
        v-if="loaded"
        :data="data"
        :options="options"
        :style="{ height: '150px', width: '100%' }"
      />
    </div>
  </div>
</template>

<script>
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  TimeScale,
} from "chart.js";

import { Line as LineChart } from "vue-chartjs";
import "chartjs-adapter-moment";
import { api } from "boot/axios";
import { useUserStore } from "src/stores/user";

// const infoStore = useUserStore();

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  TimeScale
);

export default {
  name: "App",
  components: {
    LineChart,
  },
  props: {
    workspaceUid: {
      type: String,
      default: null,
    },
  },
  data() {
    return {
      btnFlag: 0,
      totalAnsCount: 0,
      loaded: false,
      options: {
        responsive: true,
        hover: {
          intersect: false,
        },
        pointRadius: 1,
        plugins: {
          tooltip: {
            displayColors: false,
            callbacks: {
              label: function (context) {
                const label = context.dataset.label || "";
                const value = context.parsed.y;
                return `${label} ${value} Answers`;
              },
            },
          },
        },
        scales: {
          x: {
            type: "time", // Use time scale for X-axis
            time: {
              parser: "YYYY-MM-DD", // Specify the input date format
              unit: "day", // Display ticks as day
              displayFormats: {
                day: "MM/DD", // Format for the X-axis labels (day/month)
              },
              tooltipFormat: "MMMM D, YYYY", // Format for the tooltip
            },
            grid: {
              display: false,
            },
            border: {
              display: true,
              width: 1.5,
              color: "black",
            },
            ticks: {
              font: {
                size: 12, // Change the font size
                weight: "bold", // Set the font weight (e.g., "normal", "bold")
              },
            },
          },
          y: {
            grid: {
              display: false,
            },
            border: {
              display: true,
              width: 1.5,
              color: "black",
            },
            title: {
              display: true,
              color: "black",
              text: "# of Answers",
              font: {
                size: 14,
                weight: "bold",
              },
            },
            ticks: {
              font: {
                size: 12, // Change the font size
                weight: "bold", // Set the font weight (e.g., "normal", "bold")
              },
            },
          },
        },
      },
      data: {
        labels: [],
        datasets: [
          {
            data: [],
            borderColor: "#0d1f91",
            fill: false,
            borderWidth: 1,
          },
        ],
      },
    };
  },
  async mounted() {
    this.getChartData(7);
  },

  methods: {
    getChartData(interval) {
      this.totalAnsCount = 0;
      this.btnFlag = interval;
      this.loaded = false;
      api
        .get(
          process.env.BASE_URL +
            "/api/strategyAI/analytics/answers/?workspace_uid=" +
            this.workspaceUid +
            "&interval=" +
            interval
        )

        .then((response) => {
          console.log(
            response.data.data.map((item) => item.date),
            response.data.data.map((item) => item.answer_count)
          );
          this.data.labels = response.data.data.map((item) => item.date);
          this.data.datasets[0].data = response.data.data.map(
            (item) => item.answer_count
          );
          this.data.datasets[0].data.forEach((item) => {
            this.totalAnsCount += item;
          });
          this.loaded = true;
        })

        .catch((error) => {
          console.log(error);
        });
    },
  },
};
</script>
<style scoped>
.title {
  font-size: 14px;
  font-weight: bold;
  padding: 15px 0px;
}
.primary {
  color: black;
  font-size: 12px;
}
.answer-count h2 {
  font-size: 40px;
  font-weight: 800;
  color: #0d1f91;
  text-align: right;
}
.analytic-container {
  display: flex;
  padding: 0px 15px 15px;
  justify-content: space-between;
  border: 1px solid #000;
  /* width: 750px; */
  flex-direction: column;
}
.answer-count {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2px 15px;
}
.select-interval {
  background: #acb9c7;
  color: #0d47a1;
  padding: 5px 12px;
}
.unselect-interval {
  background: #fff !important;
  color: #333333;
  padding: 5px 12px;
}
</style>

Attempting to draw a line graph using chart js and vue, but facing challenges due to being new to both technologies. Looking to modify the tooltip in the graph to show "10 Answers July 19, 2023", experimentation with beforeLabel and afterLabel options yielded no results.

Answer №1

If you want to customize the tooltip label in your chart, you can utilize the callbacks property within the tooltip configuration.

...
tooltip {
  displayColors: true,
  callbacks: {
    title: function () {
      return '';
    },
    label: function (context) {
      const category = context.label;
      const amount = context.parsed.y;
      return `${amount} Items ${category}`;
    },
  },
};

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

What could be the reason for the React component not re-rendering even after its prop has been updated?

One of the challenges I'm facing with an application I'm currently working on is a re-render issue. To simplify, let's say we have two components - DisplayElement1 and DisplayElement2. In this scenario, DisplayElement2 iterates through a ba ...

"Working with Node.js: Implementing a Static Variable in Module Ex

I am working on exporting a module that will store information in a hashtable to be accessed later. However, I am encountering difficulties in maintaining the consistency of the hashtable as a global variable throughout the application. Here is my current ...

What is the best way to save the city name received from geolocation into a variable and then make an AJAX request?

<script> new Vue({ el: '#fad' , data: { data: {}, }, mounted() { var self = this; navigator.geolocation.getCurrentPosition(success, error); function success(position) { var GEOCO ...

Troubleshooting 404 Error When Using Axios Put Request in Vue.js

I'm trying to update the status of an order using Axios and the Woocommerce REST API, but I keep getting a 404 error. Here's my first attempt: axios.put('https://staging/wp-json/wc/v3/orders/1977?consumer_key=123&consumer_secret=456&apos ...

AngularJS dropdown not reflecting changes when using ng-selected

While working with AngularJS, I have encountered an issue where the first child of the select element remains empty despite my efforts to populate it. Below is the HTML code snippet: <select id="connectTV" aria-label="How many Dish TVs" ng-model="conn ...

What is causing only one route to be functional with the Backbone Router?

In the segment below, I have incorporated a variety of routes and view events created using Backbone.js. All the routes seem to be working as expected except for the last one 'products'. Initially, I had it set up differently but noticed that it ...

Synchronized scrolling and equal height for multiple divs

Looking to create a system similar to GitHub's conflict resolver for my project. I have multiple versions represented by values in columns, and I want to be able to select different values from each column to create a new solution. It's important ...

A more organized method for assigning Enter key presses

function onLoad() { eworkData.FieldByName('SearchReference').HTMLfield.onkeydown=function(evt) { var keyCode = evt ? (evt.which ? evt.which : evt.keyCode) : event.keyCode; if( keyCode == 13 ) { eworkDat ...

What is the best way to determine the number of characters that will fit within the width of the document?

I am looking to create a JavaScript function using jQuery that can determine the number of characters that will fit in a single line within the browser window. While I am currently utilizing a monospace font for simplicity's sake, I would like to adap ...

Can you explain the contrast between EJS's render() function and renderFile() method?

const express = require('express'); const ejs = require('ejs'); const app = express(); app.engine('ejs', ejs.renderFile); app.get('/', (req, res) => { res.render('index.ejs', { ...

I am encountering an issue stating "indexRouter has not been defined"

Encountering an error "indexRouter is not defined" while attempting to run the code below. Despite attempts to remove the line, additional errors persist. Can anyone clarify the rationale behind using the common variable router for both index.js and user.j ...

Update the contents of a neighbor div within the same parent element using jQuery

Attempting to set the range slider value within the slider parent sibling var updateRangeSlider = function() { var slider = $('.range-slider'), range = $('.range- value = $('.range-slider__value'); sli ...

Exploring the Functionality of Cookies in Nuxt 3 API Endpoints and Middlewares

Can cookies be utilized on the server side in Nuxt 3? For instance, I need to set a cookie in an API and then access its data in middleware: // ~/server/api/testApi.ts export default defineEventHandler(event => { /* setCookie('myCookie', ...

Do these two JavaScript statements behave the same under the principles of functional programming in a React environment?

Is there a rule in functional programming that states these two approaches are equivalent? When working on a React application, I initially passed a function as an attribute using the second version where the first parameter is also passed. Out of curiosi ...

Prevent the hover() effect from affecting all div elements at once

I am aiming to achieve a function where hovering over a div with the "rectangle" class will display another div with the "description" class. Initially, the description div will have a display value of "none", but upon hovering, it should become visible. ...

Creating a Vue equation that utilizes props to dynamically assign a class

I am trying to dynamically apply a class to a data table based on the data being passed to it. Although I can successfully run the equation in the template, I'm having trouble figuring out how to do so within the bound class. Let me show you what my ...

What is the best method for consolidating all record names into a single array?

I'm currently working on a small webpage and utilizing Airtable as my database. Within my base, I have several fields, with the most crucial ones being "name" and "icon_png". Using vue.js, I log in through axios and retrieve all the database entries i ...

End of container Bootstrap 4 row with two columns at the edge

I'm currently working on an angular project with bootstrap 4. Within the container, there are two rows. I specifically want one row to always be positioned at the bottom of the container. Despite trying methods like justify-content: flex-end;, botto ...

Ways to efficiently group and aggregate data in JavaScript, inspired by LINQ techniques

I'm feeling overwhelmed by this. Could you lend a hand? Consider the following .NET classes: Teacher: public class Teacher { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } publ ...

Preflight request rejection due to access control check failure in React and Express

I am facing a similar issue to this question, but my problem is specific to using Express with React on the frontend. The error I am encountering is: Access to fetch at 'http://localhost:8000/api/users/auth/github' from origin 'http: ...