0

I'm using chart.js to displaying a bar chart. I've created an object with my labels and data set, however for some reason, no chart is being displayed and I can't work out why.

At the moment the chart data is just to test the chart works. The chart should display once 'calculate' has been clicked. First, some calculations run, and then the function inserts the new html into the correct section displaying data from the array surveyResults and then it should display a chart using the object chartResults but the chart is not displaying.

Thanks.

const calculate = document.getElementById('one');

const resultsContainer = document.querySelector('.card-wrapper-results');

let myChart = document.getElementById('myChart').getContext('2d');

calculate.addEventListener('click', calc);

let surveyResults = [
    {
        savings: 10.23,
        price: 35.84
    }
];

let yearlySavings;
let scrappagePayment;
let smartPayment;

function calc() {
    event.preventDefault();
    let gas = parseFloat(document.getElementById('gas').value);
    let price = parseFloat(document.getElementById('price').value);
    let gasSaving;
    let smartSaving;
    let result;
    let totalSaving;
    smartSaving = gas * 0.2;
    gasSaving = gas * 0.3;
    totalSaving = smartSaving + gasSaving;
    surveyResults[0].savings = totalSaving;

    result = price - totalSaving;

    let chartResults = new Chart(myChart, {
        type: 'bar',
        data: {
            labels: [ 'Year 1', 'Yeat 2', 'Year 3', 'Year 4', 'Year 5', 'Year 6', 'Year 8', 'Year 9', 'Year 10' ],
            datasets: [
                {
                    label: 'Savings Per Year £',
                    data: [ 342, 410, 443, 501, 557, 602, 673, 702, 764, 823 ]
                }
            ]
        },
        options: {}
    });

    let displayResults = surveyResults.map(function(item) {
        console.log(item);
        return ` <div class="card2-results">


                <h1>Scrappage Payment </h1>
                <p class="job-title">Vaillant EcoTech Plus</p>
                <h2 class="about-h2">
                    £507.23
                </h2>
                <ul class="about-payment">
                    <li><i class="fas fa-check"></i> AAA+ Rated Vaillant Ecotech Plus</li>
                    <li><i class="fas fa-check"></i> 10 Year Guaranty</li>
                    <li><i class="fas fa-check"></i> Big Gas Bill Savings</li>
                    <li><i class="fas fa-check"></i> Which Boiler Of The Year</li>
                

                </ul>

                <a href="" class="btn-results">30% Lower Gas Bill</a>

            </div>
        
        <div class="card2-results">
            
            
                <h1>Monthly Gas Savings</h1>
                <p class="job-title">Instant Savings</p>
                <h2 class="about-h2">
                    £${item.savings.toFixed(2)}
                </h2>
                <ul class="about-payment">
                    <li><i class="fas fa-check"></i> Start Saving Straightaway</li>
                    <li><i class="fas fa-check"></i> 30% Saving From EcoTech Plus </li>
                    <li><i class="fas fa-check"></i> 18% Saving From Hive Smart Heating</li>
                    <li><i class="fas fa-check"></i> Hive Smart Heating System Included</li>
                
                
                </ul>
            
                <a href="" class="btn-results">1st Year £336</a>
            
            </div>
            
              <div class="card3">
            
            
                <h1>Yearly Gas Savings</h1>
                <p class="job-title">Gen 3 Smart Heating</p>
                <canvas id="myChart">
                    
                </canvas>
            
            </div>`;
    });
    resultsContainer.innerHTML = displayResults;
}

6
  • Your console should be showing you some errors, because you are selecting the canvas element and create a context, but the element has not been rendered yet by the calc() function. Commented Sep 21, 2020 at 16:23
  • Yeah it's saying Uncaught ReferenceError: Chart is not defined. So do I need to move the object chartResults inside the function calc()? Commented Sep 21, 2020 at 16:30
  • Exactly. First you calculate, then you render your HTML output and then you select the element and initialize the chart. But keep in mind, currently your canvas has an ID to identify itself with, so only the first canvas in the loop will be initialized. Commented Sep 21, 2020 at 16:31
  • Ok so I moved chart results inside the calc() function. Now I get no error messages in the console but no chart is being displayed. Commented Sep 21, 2020 at 16:35
  • Update the snippet above with your new code and I'll take a look. Commented Sep 21, 2020 at 16:47

1 Answer 1

1

The problem you are having is the order in which you call your functions. Move the selector of the chart element inside the calc function, but after the part where you set the innerHTML. This is because the HTML has to be updated first with the new element, and then you should select the element and initialize the canvas.

const calculate = document.getElementById("one");
const resultsContainer = document.querySelector(".card-wrapper-results");
let surveyResults = [
  {
    savings: 10.23,
    price: 35.84,
  },
];

calculate.addEventListener("click", calc);

function calc(event) {
  event.preventDefault();

  // Do the calculations.
  let gas = parseFloat(document.getElementById("gas").value);
  let price = parseFloat(document.getElementById("price").value);
  let gasSaving;
  let smartSaving;
  let result;
  let totalSaving;
  smartSaving = gas * 0.2;
  gasSaving = gas * 0.3;
  totalSaving = smartSaving + gasSaving;
  surveyResults[0].savings = totalSaving;

  result = price - totalSaving;

  // Generate HTML to show the chart in.
  let displayResults = surveyResults.map((item) => `
    <div class="card2-results">
      <h1>Scrappage Payment</h1>
      <p class="job-title">Vaillant EcoTech Plus</p>
      <h2 class="about-h2">£507.23</h2>
      <ul class="about-payment">
      <li><i class="fas fa-check"></i> AAA+ Rated Vaillant Ecotech Plus</li>
      <li><i class="fas fa-check"></i> 10 Year Guaranty</li>
      <li><i class="fas fa-check"></i> Big Gas Bill Savings</li>
      <li><i class="fas fa-check"></i> Which Boiler Of The Year</li>
      </ul>
    
      <a href="" class="btn-results">30% Lower Gas Bill</a>
    </div>
    
    <div class="card2-results">
      <h1>Monthly Gas Savings</h1>
      <p class="job-title">Instant Savings</p>
      <h2 class="about-h2">£${item.savings.toFixed(2)}</h2>
      <ul class="about-payment">
      <li><i class="fas fa-check"></i> Start Saving Straightaway</li>
      <li><i class="fas fa-check"></i> 30% Saving From EcoTech Plus</li>
      <li><i class="fas fa-check"></i> 18% Saving From Hive Smart Heating</li>
      <li><i class="fas fa-check"></i> Hive Smart Heating System Included</li>
      </ul>
    
      <a href="" class="btn-results">1st Year £336</a>
    </div>
    
    <div class="card3">
      <h1>Yearly Gas Savings</h1>
      <p class="job-title">Gen 3 Smart Heating</p>
      <canvas id="myChart"></canvas>
    </div>
  `);

  // Canvas element exists after this line.
  resultsContainer.innerHTML = displayResults;

  // Now the myChart element is in the DOM, select it.
  let myChart = document.getElementById("myChart").getContext("2d");

  // Create a new chart.
  let chartResults = new Chart(myChart, {
    type: "bar",
    data: {
      labels: [
        "Year 1",
        "Year 2",
        "Year 3",
        "Year 4",
        "Year 5",
        "Year 6",
        "Year 8",
        "Year 9",
        "Year 10",
      ],
      datasets: [
        {
          label: "Savings Per Year £",
          data: [342, 410, 443, 501, 557, 602, 673, 702, 764, 823],
        },
      ],
    },
    options: {},
  });
}
Sign up to request clarification or add additional context in comments.

2 Comments

Legend. Looks like I had my code a bit mixed up. Thanks for your help!
You got it, mate. Please accept the answer if it helped you out and to reward me with fake internet points.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.