"Click to view the latest data visualization using the Chart.js

I am exploring ways to enhance the animations in Chart.js for a new web project. The content is organized in tabs, with the chart displayed on the third tab out of four.

Currently, the chart animates upon loading. How can I make it so that when #chartTrigger (Tab Three) is clicked, a new chart is generated?

Furthermore, is there a way to limit the number of animations? For instance, if a user switches to Tab Four and then returns to Tab Three, can we prevent the animation from replaying?

You can preview what I have implemented here: https://codepen.io/drewalth/pen/wppNbJ

<style>
body {
  font-family:sans-serif;
}

div.tab button {
   border: none;
   outline: none;
   cursor: pointer;
   padding: 0.6em 1em;
   flex-basis: 12%;
   color: #34495E;
    letter-spacing: 1px;
   text-transform: capitalize;
    font-size: 0.9em;
    background-color: #BDC3C7;
}
div.tab button.active {
    background-color: #34495E;
    color:#fff;
}

.tabcontent {
  display: none;
  height:300px;
  width:50%;
  color:#fff;
  padding:35px;
}

#tabOne {
  background-color:#E74C3C;
}
#tabTwo {
  background-color:#3498DB;
}

#tabThree {
  text-align:center;
}

#tabFour {
  background-color:#2ECC71;
}


</style>

<div class="tab">
            <button id="defaultOpen" class="tablinks" 
onclick="openTab(event, 'tabOne')">Tab One</button>
            <button class="tablinks" onclick="openTab(event, 
'tabTwo')">Tab Two</button>
            <button id="chartTrigger" class="tablinks" 
onclick="openTab(event, 'tabThree')">Tab Three</button>
            <button class="tablinks" onclick="openTab(event, 
'tabFour')">Tab Four</button>

        </div>
<div id="tabOne" class="tabcontent">
  Click Tab Three for Chart
</div>
<div id="tabTwo" class="tabcontent">

</div>
<div id="tabThree" class="tabcontent">
  <canvas id="test-chart" height="500"></canvas>
</div>
<div id="tabFour" class="tabcontent">

</div>
<script>

// function to switch between tabs

function openTab(evt, tabName) {

  var i, tabcontent, tablinks;

  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }

  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }

  document.getElementById(tabName).style.display = "block";
  evt.currentTarget.className += " active";
}

document.getElementById("defaultOpen").click();

// Working Chart.js

var ctx = document.getElementById("test-chart").getContext('2d');
    var newTestChart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: ["10/21", "10/22", "10/23", "10/24", "10/25", "10/26", 
"10/27", "10/28", "10/29", "10/30", "10/31", "11/01", "11/02", "11/03", 
"11/04"],
        datasets: [{
          data: [150, 550, 500, 880, 200, 100, 102, 102, 99, 105, 100, 
103, 100, 102, 100],
          backgroundColor: ['rgba(77, 112, 144, 0.4)', ],
          borderColor: ['rgba(77, 112, 144,1)', ],
          borderWidth: 2
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        defaultFontFamily: "'Titillium Web'",
        defaultFontSize: 16,
        scales: {
          yAxes: [{
            ticks: {
              beginAtZero: true
            }
          }]
        },
      }
    });



// Desired functionality...

var $chartTrigger = document.getElementById("chartTrigger");

$chartTrigger.onclick(newChart);

</script>

Answer №1

To optimize the chart loading process, it is recommended to move the chart code inside the openTab function and utilize a global variable as a flag. This flag can be used to determine if the chart has already been loaded, in which case it does not need to be loaded again. You can refer to the CodePen demo provided below for implementation details.

// switch between tabs
var isLoaded = false;

function openTab(evt, tabName) {

  var i, tabcontent, tablinks;

  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }

  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }

  document.getElementById(tabName).style.display = "block";
  evt.currentTarget.className += " active";

  if (tabName == 'tabThree' && !isLoaded) {
    isLoaded = true;
    // Working Chart.js
    console.log('loaded');
    var ctx = document.getElementById("test-chart").getContext('2d');
    var newTestChart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: ["10/21", "10/22", "10/23", "10/24", "10/25", "10/26", "10/27", "10/28", "10/29", "10/30", "10/31", "11/01", "11/02", "11/03", "11/04"],
        datasets: [{
          data: [150, 550, 500, 880, 200, 100, 102, 102, 99, 105, 100, 103, 100, 102, 100],
          backgroundColor: ['rgba(77, 112, 144, 0.4)', ],
          borderColor: ['rgba(77, 112, 144,1)', ],
          borderWidth: 2
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        defaultFontFamily: "'Titillium Web'",
        defaultFontSize: 16,
        scales: {
          yAxes: [{
            ticks: {
              beginAtZero: true
            }
          }]
        },
      }
    });


  }
}

document.getElementById("defaultOpen").click();
...

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

Enhancing table field functionality in Backbone.js

In my Backbone application, I am trying to debug the following code outline. window.TableView = Backbone.View.extend({ initialize: function() {... .. .. ... }); }, selectRow: function() { ... ... .. }, render: function() { // ...

What is the best way to specifically target header elements within article elements using a CSS selector?

As someone who is not well-versed in CSS, I am looking to target specifically the header elements within article elements. I have some understanding of selectors such as #, ., or ,. article header article, header article.header article#header I believe t ...

Organize items within an array based on dual properties rather than a single one

Here is an array of objects that I would like to group based on certain keys (JSON format): [ { "name": "john", "lastName": "doe", "gender": "male" }, { "name": &qu ...

Guide to dynamically displaying location data using JSON string on Google Maps in ASP.NET

A script is being used to display locations on a Google map: <script type="text/javascript"> $(document).ready(function () { var markersdetails = { "Iran": { "title": "Iran", "lat": "32.000000", ...

The left border is failing to appear on the Td element

When attempting to add border styling to td elements, the left border is not displaying correctly. This issue seems to vary across different browsers. Here is the HTML code: <table class="table-bordered"> <thead> <tr> ...

Guide on integrating jQuery for AJAX responses to gracefully transition into view within an MVC3 View

Is there a way to create a smooth fade in effect for a <p> element on my website? Currently, I am using Ajax to retrieve the server time and display it. However, the elements appear abruptly and I would like to make the transition more gradual by ad ...

Passing a reference to a react functional component (react.FC) results in a type error: The property ref is not recognized on the type 'IntrinsicAttributes & Props & { children: ReactNode}'

Currently, I am working on mastering the utilization of forward refs. In a functional component (FC), I am trying to initialize all my refs and then pass them down to its child components so that I can access the canvas instances of some chartjs charts. Ho ...

Stop Browsers from Saving the Current Page in the History Log

Currently, I am facing an issue with a user-triggered popup window on my website that redirects to another site. It is important that users do not access this page directly and only navigate to it if the popup window opens as intended. mysite.com -> my ...

Steps for converting a JSON response into a .json file.Steps to transform a

I am looking to create a .json file within my local project directory. My goal is to store the response from a fetch API call, which is an array of objects, into a .json file. Here is the code snippet I am working with: ts : getRecords(){ this.serv ...

React JS: Component failing to render

My react component is not rendering and I can't find any bugs. The problem arises when I set the isLoggedIn state to "true", resulting in my HeroSlide not rendering If isLoggedin = false, then: If isLoggedIn = true, then: This is the code snippet: ...

`Issues with AJAX PHP file upload`

I've been working on an AJAX PHP upload script, but I'm facing some issues. Once the user selects an image to upload, it should display in the specific div container specified in my javascript file (which is working fine). However, I believe ther ...

Strange behavior detected in TypeScript generic function when using a class as the generic parameter

class Class { } const f0 = <T extends typeof Class> (c:T): T => { return c } const call0 = f0 (Class) //ok const f1 = <T extends typeof Class> (c:T): T => { const a = new c() return a //TS2322: Type 'Class' is not assigna ...

What is the best way to send a continuous stream of data in Express?

I've been attempting to configure an Express application to send the response as a stream. var Readable = require('stream').Readable; var rs = Readable(); app.get('/report', function(req,res) { res.statusCode = 200; ...

Troubleshooting the issue with Protractor/Jasmine test when browser.isElementPresent does not detect a class in the

As a newcomer to Jasmine testing, I've been facing some challenges while running my tests. Specifically, I have been struggling with my webdriver closing the browser before it can check the '.detailsColumn' element for expected results. Afte ...

Modifying an element in an array while preserving its original position

Currently, I am working on updating the state based on new information passed through response.payload. Here is my existing code snippet: if(response.events.includes('databases.*.collections.*.documents.*.update')) { setMemos(prevState => pre ...

How about connecting functions in JavaScript?

I'm looking to create a custom function that will add an item to my localStorage object. For example: alert(localStorage.getItem('names').addItem('Bill').getItem('names')); The initial method is getItem, which retrieves ...

Exploring Data and Models within AngularJS

I am working on a WebApp that has a unique HTML layout Nav-column-| Center Column---- | Right Column Link1---------|Data corresponding|Data Corresponding to Link1-A Link2---------| to Nav-column------| (ie based oon Center Column Link) Link3----- ...

Create a dynamic background for content output by checkboxes using jQuery

Is it possible to have each individual tag match the background color of its corresponding checkbox's data-color? Currently, all tags change color simultaneously. $("input").on("click", function(e) { var tagColor = $(this).attr("data-color"); ...

Manipulate state in parent component from child component using onClick function with React hooks

Hello, I am facing a challenge trying to store data from a modal (child function) within the main (parent) function. Depending on which button is clicked, the modal loads specific HTML content (all buttons perform the same action). export default function ...

How can we deliver pure JS, HTML, and CSS content without relying on static HTML pages?

Looking to create a fast app prototype without using React or Vue? I'd like to avoid simply making an html and js file imported within it. Can npm packages, SCSS be used while programming vanilla Javascript minus a framework? ...