What are the features of the vertical line with annotation plugin and category axis in Chart.js?

I am currently facing an issue with the vertical line in my chart created using chart.js. Specifically, the problem lies with the category axis where the years are labeled as [year 0, year 1, year 2, year 3..].

Here is an example of a functioning chart with annotations displaying horizontal lines.

var lines = [{
            type: 'line',
            mode: 'horizontal' ,/*set vertical for vertical line */
            scaleID: 'y-axis-label', /* id of the axis */
            value:  50,
            borderColor: '#E35500',
            borderWidth: 3
        }];

        var config = {
  type: 'bar',

  data: {
  labels: ["Year 0", "Year 1", "Year 2", "Year 3", "Year 4", "Year 5", "Year 6"],
 //   labels: ["Year 0", "Year 1", "Year 2", "Year 3", "Year 4", "Year 5", "Year 6"],
    datasets: [{
      type: 'line',
      label: 'Cost',
      data: [35, 15, 25, 14, 10, 7],
      borderColor: '#E35500',
      fill: false,
        lineTension : 0,
   borderJoinStyle: 'miter',
    }, {
      type: 'line',
      label: 'Cash Flow',
      data: [-50, 180, 170, 220, 160, 190],
      borderColor: '#FFC000',
      fill: false,
        lineTension : 0,
       
      

       
    },
           {
      type: 'bar',
      label: 'Benifit(One time)',
      backgroundColor: "#005998",
      data: [0,50, 60, 80, 50, 60],
    }, {
      type: 'bar',
      label: 'Benifit(Recurring)',
      backgroundColor: "#0FAAFF",
      data: [0,150, 150, 180, 120, 140],
    }],
      lineAtIndex: 2
  },
  options: {
      title: {
            display: true,
            text: 'Cash Flow Analysis and Breakdown'
        },
     
                    annotation: {
                        drawTime: "afterDraw",
                        annotations: lines
                    },
      
    scales: {
        
      xAxes: [{
         
          
          stacked : true,
      beginAtZero: true,
          barPercentage: 0.3,
          id : 'x-axis-label',
       position:'bottom',
          scaleStartValue: 20,
          labelString: 'Year',
          gridLines: {
                    display:false
                },
          
          
      }],
      yAxes: [{
            
            stacked : true,
 id : 'y-axis-label',
          ticks: {
                    max: 300,
                    min: -50,
                    stepSize: 50,
              
                },
          position:'left',
          gridLines: {
                    display:false
                },
      }]
    },
      legend : {
      position: 'right',
          labels:{
        boxWidth:20,
              
             
    }
      },
      maintainAspectRatio: false,
      scaleBeginAtZero: true
      
      
  }
};
        window.onload = function() {
            var ctx = document.getElementById("canvas").getContext("2d");
            new Chart(ctx, config);
         
        };
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.0/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<script src="https://rawgit.com/chartjs/chartjs-plugin-annotation/master/chartjs-plugin-annotation.js"></script>
<div style="width:100%; height:800px">
        <canvas id="canvas"></canvas>
    </div>

Below is an example of a non-working chart with annotations plugin attempting to show a vertical line.

Is there any way I can create a vertical line at 4.5 years on the chart?

Thank you in advance.

Answer №1

The documentation for Chart.js lacks clarity, especially when it comes to Category scales (they seem to only work reliably with linear scales). However, there is a workaround available.

Instead of directly inputting your labels into the chart, consider using an array of indices as labels and then implementing a callback function to format the ticks using these index values.

Unfortunately, when dealing with category scales, you can only specify whole numbers for tick labels (e.g., 4 or 5, but not 4.5). If you need more precision, you will have to use a linear scale and apply a similar method as demonstrated here.

I've made modifications to your code snippet to illustrate this concept.

UPDATE: I've adjusted the code snippet to demonstrate how to achieve this using linear scales. Make sure to include x and y values in your dataset data. For brevity, I've only edited one dataset.

var lines = [{
            type: 'line',
            mode: 'vertical' ,/*set vertical for vertical line */
            scaleID: 'x-axis-label', /* id of the axis */
            value:  4.5,
            borderColor: '#E35500',
            borderWidth: 3
        }];

var labels = ["Year 0", "Year 1", "Year 2", "Year 3", "Year 4", "Year 5", "Year 6"];

        var config = {
  type: 'bar',

  data: {
    datasets: [{
      type: 'line',
      label: 'Cost',
      data: [{x:0, y:35}, {x:1,y:15}, {x: 2, y:25}, {x:3, y:35}, {x:4,y:15}, {x: 5, y:25}],
      borderColor: '#E35500',
      fill: false,
        lineTension : 0,
   borderJoinStyle: 'miter',
    }],
      lineAtIndex: 2
  },
  options: {
      title: {
            display: true,
            text: 'Cash Flow Analysis and Breakdown'
        },
     
                    annotation: {
                        drawTime: "afterDraw",
                        annotations: lines
                    },
      
    scales: {
        
      xAxes: [{
         
          
          stacked : true,
     
          barPercentage: 0.3,
          id : 'x-axis-label',
          position:'bottom',
          type: 'linear',
          ticks: {
            callback: (index) => {
              return labels[index];
            }
          }     
      }],
      yAxes: [{
            
            stacked : true,
 id : 'y-axis-label',
         
          
      }]
    },
      legend : {
      position: 'right',
          labels:{
        boxWidth:20,
              
             
    }
      },
      maintainAspectRatio: false,
      scaleBeginAtZero: true
      
      
  }
};
        window.onload = function() {
            var ctx = document.getElementById("canvas").getContext("2d");
            new Chart(ctx, config);
         
        };
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.0/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<script src="https://rawgit.com/chartjs/chartjs-plugin-annotation/master/chartjs-plugin-annotation.js"></script>
<div style="width:100%; height:800px">
        <canvas id="canvas"></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

Transmitting OfficeJS 2D Array via an Ajax Call

Struggling with sending a "large" table using OfficeJS: functionfile.html loaded from manifest route <script> (function (){ "use strict"; Office.initialize = function (reason) { $(document).ready(function() { $("#send-data-button").cli ...

Is HTML5 local storage not functioning properly on IE11 in Windows 8.1 x64? Encountering an error message:

Is anyone else experiencing this issue where information cannot be found, even though it was previously fixed in a patch a long time ago? Has anyone else encountered this? localStorage.setItem("hello", "somedata"); alert(localStorage.getItem(" ...

The bootstrap feature isn't functioning properly on my MAC operating system

Strange issue, my Bootstrap is not functioning correctly on macOS, but works fine on Linux Ubuntu (on my other laptop). Attached below is an image showing the file hierarchy. https://i.sstatic.net/9mGyp.png Below is how I import Bootstrap in my code (im ...

Is it possible to swap two classes with each other using jQuery?

I am trying to implement a tree view with the following code snippet. Within the tree view, there are spans that have either the CollOpen or CollClosed class assigned to them. How can I toggle between these two classes on click for each span? .tree ...

Retrieve the PDF document from the AJAX call and save it as a

My goal is to have the browser automatically download a PDF file that is received from an AJAX response. After reading about how to download a PDF file using jQuery AJAX, I attempted to simulate a click/download event in this way: var req = new XMLHt ...

Having trouble implementing a circular progress bar with a custom Tailwind CSS library, the desired effect is not being achieved

I am on a mission to create a circular progress indicator. Recently, I stumbled upon the daisyui library and its component called radial progress - The documentation mentions that: "Radial progress requires the use of the --value CSS variable." ...

Issue with displaying Bootstrap 3 modal on Mozilla browser

Hello everyone, I've encountered an issue with my Bootstrap modal on Mozilla browser. Everything works perfectly on Chrome and Safari, but when I click the modal button in Mozilla, nothing happens. Here's a snippet of my code: <button type="b ...

Should the HTML inputs be positioned within the label or placed outside of it?

Check out this site for some on/off switches: <div class="onoffswitch"> <input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch" checked> <label class="onoffswitch-label" for="myonoffswitch"> < ...

Toggle the visibility of a checkbox based on the JSON data

I have 4 check boxes that need to be dynamically displayed based on the value retrieved from my JSON. The JSON will only contain one checkbox name, and that specific checkbox should be shown to the user as checked. How can I achieve this functionality? Bel ...

Challenges when utilizing AJAX and JQuery for selecting multiple items and retrieving data from a JSON file

I am currently working on a live search feature that extracts data from a JSON file using AJAX and jQuery. The goal is to make the fetched value clickable and populate a multiselect field with it. Once this is achieved, the plan is to capture the remaining ...

Creating client side scripts for an ajax call to generate a Json object is simple once you understand the basics

Typically, when I make ajax calls, I request pure HTML. However, for various reasons, I require guidance on constructing a table (let's say of individuals and their information) when receiving a Json object. While I am capable of creating a table in J ...

Improving React code by using conditional statements such as IF and Else

Currently, I am delving into the world of React and have managed to devise some logic for rendering a DIV. However, upon reflection, it has become evident that there is redundancy present in my code structure and I am uncertain about how to efficiently ref ...

Obtaining the clicked element within a functional component in React

I'm having trouble in React because I am unable to select the clicked element. The use of "this" in a functional component is not functioning as expected. function Test(data) { function getElement() { } return ( <div> ...

Ways to properly update a state variable when using onClick within a functional component

I'm having an issue with my tabs that are supposed to display different products and filters when clicked. Currently, I have to click each tab twice before the 'options' list updates with the correct filters. I know that calling setOptions w ...

How to Maintain Hover State After Leaving an Element in jQuery?

1. I am working on a website with two menus, "Main" and "Sub". When you hover over a specific link in the main menu, it highlights the corresponding link in the sub-menu by adding a class to it. However, the issue is that when I move my cursor off the main ...

Exploring the distinctions among different xpath implementations in Selenium WebDriver

Looking at this snippet of HTML code: <div id="divTooltips_Section_Filter" style="float:right; padding-right: 30px; padding-bottom: 10px;"> <img src="/mkteditor/css/images/tooltip.png" width="25px" height="25px" alt=""> </div> I've ...

Unable to process submission

Greetings all, I am facing an issue where my submit button seems to be malfunctioning. Despite trying various methods, the problem persists. It is worth mentioning that I am utilizing bootstrap modal, which might be causing this unusual behavior. Let&apos ...

An Internal Server Error (500) occurred while running an Ajax request

I have a JavaScript script that makes an AJAX call to a method in my DeviceUsage controller. There seems to be an issue as the breakpoint I placed at the start of the C# method is not getting hit. $(document).ready(function () { $('.z').on(& ...

No departure animation employed - Polymer

I am working on a project that involves animating a paper-icon-button with spin and opacity effects when hovering over an image using the on-mouseenter and on-mouseleave events. Everything works smoothly when hovering over the image, but I am facing an is ...

What is the origin of this mysterious error?

I'm working on a function to format various types of variables and utilize a toString() method. It's handling complex objects, arrays, and circular references flawlessly. However, when testing it on a jQuery object using format($("body")) with l ...