Home > front end >  How do you use user input as data values in chart.js?
How do you use user input as data values in chart.js?

Time:02-05

I'm creating a mood tracker that allows people to input the number of days they feel a certain mood. The HTML form accepts the numbers from 0-7, and accordingly I want the pie chart to dynamically shift to reflect that value. When I tried inserting the value in the data array, the whole chart disappears instead. I can't seem to figure out what the issue is, this is my code for reference:

``div  style="float: left; margin-left: 170px; margin-top: 13px; text-align: center;">
            <form>

                <!---Happy--->
                <div >
                    <input type="string" name="happy" id="happy" placeholder="Happy" value="1" required>
                    <button  onclick="updateChart()">Enter</button>
                </div>

                <!---Angry--->
                <div >
                    <input type="string" name="angry" id="angry" placeholder="Angry" value="3" required>
                    <button  onclick="updateChart()">Enter</button>
                </div>

                <!---Sad--->
                <div >
                    <input type="string" name="sad" id="sad" placeholder="Sad" value="5" required>
                    <button  onclick="updateChart()">Enter</button>
                </div>

                <!---Motivated--->
                <div >
                    <input type="string" name="motivated" id="motivated" placeholder="Motivated & Productive" value="6"required>
                    <button  onclick="updateChart()">Enter</button>
                </div>

                <!---Tired--->
                <div >
                    <input type="string" name="tired" id="tired" placeholder="Tired or Burnt out" value="0" required>
                    <button  onclick="updateChart()">Enter</button>
                </div>

                <!---Anxious--->
                <div >
                    <input type="string" name="anxious" id="anxious" placeholder="Anxious & Stressed" value="7" required>
                    <button  onclick="updateChart()">Enter</button>
                </div>
            </form>
        </div>



<!---Mood Chart--->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<div  style=" float: right; margin-right: 150px;position: relative; height: 42vh; width: 42vw; margin-top: 8px">
<canvas id="myChart" width="100px" height="100px"></canvas>
<script>

const ctx = document.getElementById('myChart');
const myChart = new Chart(ctx, {
    type: 'pie',
    data: {
        labels: ['Angry', 'Sad', 'Happy', 'Anxious', 'Motivated', 'Tired'],
        datasets: [{
            label: '# of Votes',
            data: [angryValue.value, sadValue.value, happyValue.value, anxiousValue.value, tiredValue.value, motivatedValue.value],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
        }
    }
});

function updateChart(){
    angryValue = Number(document.getElementById('angry').value);
    sadValue = Number(document.getElementById('sad').value);
    happyValue = Number(document.getElementById('happy').value);
    anxiousValue = Number(document.getElementById('anxious').value);
    motivatedValue = Number(document.getElementById('motivated').value);
    tiredValue = Number(document.getElementById('tired').value);

    data.push({
        angry: angryValue,
        sad: sadValue,
        happy: happyValue,
        anxious: anxiousValue,
        motivated: motivatedValue,
        tired: tiredValue
    });

    chart.render();
}

var moodBtn = document.getElementById('mood-btn');
moodBtn.addEventListener('click', updateChart);


</script>
</div>``

CodePudding user response:

<div  style="float: left; margin-left: 170px; margin-top: 13px; text-align: center;">
            <form>

                <!---Happy--->
                <div >
                    <input type="string" name="happy" id="happy" placeholder="Happy" value="1" required>
                    <button  >Enter</button>
                </div>

                <!---Angry--->
                <div >
                    <input type="string" name="angry" id="angry" placeholder="Angry" value="3" required>
                    <button  >Enter</button>
                </div>

                <!---Sad--->
                <div >
                    <input type="string" name="sad" id="sad" placeholder="Sad" value="5" required>
                    <button  >Enter</button>
                </div>

                <!---Motivated--->
                <div >
                    <input type="string" name="motivated" id="motivated" placeholder="Motivated & Productive" value="6"required>
                    <button  >Enter</button>
                </div>

                <!---Tired--->
                <div >
                    <input type="string" name="tired" id="tired" placeholder="Tired or Burnt out" value="0" required>
                    <button  >Enter</button>
                </div>

                <!---Anxious--->
                <div >
                    <input type="string" name="anxious" id="anxious" placeholder="Anxious & Stressed" value="7" required>
                    <button  >Enter</button>
                </div>
            </form>
        </div>



<!---Mood Chart--->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<div  style=" float: right; margin-right: 150px;position: relative; height: 42vh; width: 42vw; margin-top: 8px">
<canvas id="myChart" width="100px" height="100px"></canvas>
<script>
let chartData =[]
const ctx = document.getElementById('myChart');
const myChart = new Chart(ctx, {
    type: 'pie',
    data: {
        labels: ['Angry', 'Sad', 'Happy', 'Anxious', 'Motivated', 'Tired'],
        datasets: [{
            label: '# of Votes',
            data: chartData,
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
        }
    }
});

function removeData(chart) {
    chart.data.datasets.forEach((dataset) => {
        dataset.data.pop();
    });
    chart.update();
}

function addData(chart, data) {
    
    chart.data.datasets.forEach((dataset) => {
               
        dataset.data = [...data]
    });
    chart.update();
}

function updateChart(event){
    
    event.preventDefault()
    angryValue = Number(document.getElementById('angry').value);
    sadValue = Number(document.getElementById('sad').value);
    happyValue = Number(document.getElementById('happy').value);
    anxiousValue = Number(document.getElementById('anxious').value);
    motivatedValue = Number(document.getElementById('motivated').value);
    tiredValue = Number(document.getElementById('tired').value);
    
    chartData = [
        angryValue,
        sadValue,
        happyValue,
        anxiousValue,
        motivatedValue,
        tiredValue
]
    removeData(myChart)
    addData(myChart, chartData)
    
}

var moodBtn = document.querySelectorAll('.mood-btn');
moodBtn.forEach(btn => {
    btn.addEventListener('click', updateChart, false)
})
</script>
</div>

CodePudding user response:

Inside the updateChart() function, there is no variable named data. So, it looks like you're pushing some data to the uninitialized variable.

Isn't the data supposed to be pushed inside the config of chart.js? You might want to create a separate variable for storing the data so that you can push the data on the fly from other functions and just swap out the data for chart.js.

CodePudding user response:

Maybe this is more what you want?

const moods=['Angry', 'Sad', 'Happy', 'Anxious', 'Motivated', 'Tired'];
const ctx = document.getElementById('myChart');


const cont=document.querySelector(".form-container");
cont.innerHTML=moods.map((M,i)=>{
  let m=M.toLowerCase(); 
  return `<input type="text" name="${m}" placeholder="${M}" value="${i 2}"> ${M}`;
}).join("<br>");
const inps=[...document.querySelectorAll("input")];
cont.addEventListener("input",ev=>{
 myChart.data.datasets[0].data= inps.map(el=> el.value);
 myChart.update()
});

const myChart = new Chart( ctx, {
  type: 'pie',
  data: {
    labels: moods,
    datasets: [{
      label: '# of Votes',
      data: inps.map(el=> el.value),
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  },
  options: {
    scales: {}
  }
});
.form-container  {margin-left:200px; margin-top: 13px;}
.chart-container {float: right; margin-right: 150px;position: relative; height: 42vh; width: 42vw; margin-top: 8px}
#myChart { width=100px; height=100px }
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div ></div>
<div ><canvas id="myChart"></canvas></div>

I replaced some of your lengthy HTML markup by some generated code, based on the moods array. I also skipped the buttons and triggered the update() event by listening to input events on the container wrapping all input elements:

cont.addEventListener("input",ev=>{
 myChart.data.datasets[0].data= inps.map(el=> el.value);
 myChart.update()
});
  •  Tags:  
  • Related