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 is the reason for all the buttons activating the same component instead of triggering separate components for each button?

I am facing an issue with my parent component that has 3 buttons and 3 children components. Each button is supposed to open a specific child component, but currently all the buttons are opening the same child component when clicked. The children components ...

Ways to ensure that the form data stays consistent and visible to the user continuously

Is there a way to ensure that the user submits the form, stores it in a MYSQL database, and then displays the same submitted data in the form field? <div class="form-group"> <label class="control-label col-sm-2" for="lname">Last Name*</l ...

Steps for inputting time as 00:00:00 in MUI's X DateTimePicker

React:18.2.0 mui/material: 5.10.5 date-fns: 2.29.3 date-io/date-fns: 2.16.0 formik: 2.2.9 I'm facing an issue with using DateTimePicker in my project. I am trying to enter time in the format Hour:Minute:Second, but currently, I can only input 00:00 f ...

When the child element's "aria-expanded" attribute is set to true, a CSS class should be dynamically

Is there a way to apply a grey background to the first div when the dropdown is open? I've managed to add CSS based on the child elements' aria-expanding attribute, but I'm unsure how to do it for a parent element. Since I am using Vue, I pr ...

How to Embed a Javascript (jquery) Variable within a JSON Object

I have searched everywhere for a "simple answer" to this problem, but unfortunately, I cannot find a solution that aligns with my understanding of JSON and jQuery. Perhaps I am too much of a beginner in JSON to accurately formulate the right question (and ...

ESLint: The "react" plugin encountered a conflict

In my development environment, I have a React application within a single npm component package. This React app acts as a demonstration site that consumes the component package in addition to Storybook. local-component-package ├── .storybook ├─ ...

What is the method for retrieving the bound key of a Vue.js list item?

In Vue, when using a v-for directive without providing a key for list items, a warning is displayed. By adding a key like this: <MyComponent v-for="item in items" :key="item.someProp" /> the warning disappears. But how can you access that key withi ...

My component reference seems to have gone missing in angular2

Trying to load my Angular 2 app, I encountered this error: https://i.stack.imgur.com/FmgZE.png Despite having all the necessary files in place. https://i.stack.imgur.com/kj9cP.png Any suggestions on how to resolve this issue? Here is a snippet from ap ...

Issue encountered while validating password using regex pattern?

There seems to be an issue with password validation when requiring 1 upper case, 1 lower case, 1 number, and 1 special character. methods: { validateBeforeSubmit() { this.$validator.localize('en', dict) this.$validator.validate ...

What is the purpose behind enclosing a function expression in parentheses in JavaScript (apart from creating an IIFE)?

While delving into some advanced JavaScript concepts, I stumbled upon a piece of jQuery code on GitHub that caught my eye. It was an anonymous function wrapped in parentheses, which you can find here. Although I'm familiar with Immediately Invoked Fu ...

Tips for enlarging an image by tapping on it in handlebars

I currently have the handlebars template engine integrated with node.js, and I'm facing an issue where thumbnail images from the database are displaying at a fixed width and height of 70. Is there a way to enable users to click on these images in orde ...

Using Sails.js to display JSON data retrieved from an HTTPS request in the view

Just getting the hang of Sails.js, so any help is appreciated. I've used an XML service and successfully converted it to JSON using xml2js var req = https.request(options, function(res) { var xml = ''; res.on('data', fun ...

Implementing AJAX to dynamically insert content into div elements on the page

Currently facing a small issue with my AJAX implementation for creating comments on posts. The functionality is working well, but the problem arises when executing it in the index.html.erb view. The create.js.erb file locates the initial div labeled "comme ...

Leverage the Ajax response within a Jade template

I'm currently utilizing ExpressJS with the Jade template engine. My goal is to achieve the following: Within a Jade file, I need to extract a variable that will be used in a JavaScript file. This JavaScript file will then make an Ajax request to the ...

modify brand information through the use of javascript and customizable settings

In the default setting, I want all product details to be displayed. If the option value matches the product's brand name (b_name), then I want to display the corresponding details. Let's consider a list of products with their details: Samsung ...

Tips for troubleshooting an external reactive variable

Whenever I work on my components, I always make sure to import state from './state' so that I can easily access a global state. Although it's not a cutting-edge state machine with mutations, it works perfectly for my small project. The stat ...

programming for the final radio button text entry

I am struggling with a form that has 5 radio buttons, including an "other" option where users can manually enter text. The issue I'm facing is that the form only returns the manual entry text and not any of the preset radio values. I need it to work f ...

What is the best way to implement Quasar Dialog within the root or parent component?

Is there a way to mount the dynamically created Dialog under div#app or under its parent, instead of being automatically placed beneath the <body> tag which prevents the use of global Provide and Inject? ...

Error: Trying to access the parent node of an undefined property

After incorporating this script into my webpage for the newsletter sign-up process, I aimed to reveal customized content post user subscription. <script> function insertAfter(referenceNode, newNode) { referenceNode.parentNode.insertBefore(newNode ...

Issue with updating dropdown values in real-time in React

I am a beginner with React and I have a question regarding fetching dropdown values from the backend. Despite using async-await functions, the list is not getting populated with items. Any assistance in this matter would be greatly appreciated. Here is th ...