我正在使用chart.js 制作跟踪器程序。这里的图表接受用户输入值并生成图表。我希望用户能够将值保存在 localStorage 中,我可以成功做到这一点。问题在于检索图表值并生成图表。我尝试过使用 Chart.update();和图表.render();函数,但它们不创建图表。我该如何解决这个问题?
HTML
```<div class="form-container" style="float: left; margin-left: 80px; margin-top: 13px; text-align: center; padding-bottom: 530px; margin-bottom: 20px; padding-top: 10px;">
<form>
<!---Monday--->
<div class="sleep">
<p style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">Monday</p>
<input type="integer" name="monday" id="monday" placeholder="Monday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!---Tuesday--->
<div class="sleep">
<p style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">Tuesday</p>
<input type="integer" name="tuesday" id="tuesday" placeholder="Tuesday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!---Wednesday--->
<div class="sleep">
<p style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">Wednesday</p>
<input type="integer" name="wednesday" id="wednesday" placeholder="Wednesday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!---Thursday--->
<div class="sleep">
<p style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">Thursday</p>
<input type="integer" name="thursday" id="thursday" placeholder="Thursday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!---Friday--->
<div class="sleep">
<p style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">Friday</p>
<input type="integer" name="friday" id="friday" placeholder="Friday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!---Saturday--->
<div class="sleep">
<p style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">Saturday</p>
<input type="integer" name="saturday" id="saturday" placeholder="Saturday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!---Sunday--->
<div class="sleep">
<p style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">Sunday</p>
<input type="integer" name="sunday" id="sunday" placeholder="Sunday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
</form>
<!---Save and clear buttons for local storage--->
<div>
<button class="save-btn" id="save-btn">Save</button>
<button class="clear-btn" id="clear-btn">Clear</button>
</div>
</div>```
JAVASCRIPT
```<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div class="chart-container" style=" float: right; margin-right: 100px; position: relative; height: 60vh; width: 60vw; margin-top: 100px">
<canvas id="myChart" width="100px" height="100px"></canvas>
<script>
//Chart setup and configuration
let chartData =[]
const ctx = document.getElementById('myChart');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
datasets: [{
label: 'Hours of sleep',
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)',
'rgba(222, 184, 135, 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)',
'rgba(222, 184, 135, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
//Removing general data
function removeData(chart) {
chart.data.datasets.forEach((dataset) => {
dataset.data.pop();
});
chart.update();
}
//Adding user data in
function addData(chart, data) {
chart.data.datasets.forEach((dataset) => {
dataset.data = [...data]
});
chart.update();
}
//Calling input values to update chart
function updateChart(event){
event.preventDefault()
monValue = Number(document.getElementById('monday').value);
tuesValue = Number(document.getElementById('tuesday').value);
wedValue = Number(document.getElementById('wednesday').value);
thursValue = Number(document.getElementById('thursday').value);
friValue = Number(document.getElementById('friday').value);
satValue = Number(document.getElementById('saturday').value);
sunValue = Number(document.getElementById('sunday').value);
chartData = [
monValue,
tuesValue,
wedValue,
thursValue,
friValue,
satValue,
sunValue
]
removeData(myChart)
addData(myChart, chartData)
}
//Updating chart with values
var sleepBtn = document.querySelectorAll('.sleep-btn');
sleepBtn.forEach(btn => {
btn.addEventListener('click', updateChart, false)
})
//Local storage functions
const saveButton = document.querySelector('.save-btn');
const clearButton = document.querySelector('.clear-btn');
const dataPoints = JSON.parse(window.localStorage.getItem("sdps"));
function storageValues(){
myChart.update(myChart, sdps);
chart.render();
}
const saveToLocalStorage = () =>{
window.localStorage.setItem('sdps', JSON.stringify(chartData));
}
function clearStorage(){
localStorage.clear();
};
saveButton.addEventListener('click', saveToLocalStorage);
clearButton.addEventListener('click', clearStorage);
</script>
</div>```
我会通过根据 localStorage 值设置 UI 的初始状态来解决此问题。
let chartData = loadFromLocalStorage();
setUIData(chartData);
然后,我会让所有输入按钮和保存按钮执行基本相同的操作:从 UI 获取当前数据,将其保存到 localStorage,然后更新图表。
function updateChart(event) {
if (event) event.preventDefault();
chartData = getUIData();
saveToLocalStorage(chartData);
addData(myChart, chartData);
}
完整代码如下所示。请参阅工作示例https://jsbin.com/bujomeliho/3/edit?html,output(我会在此处使用嵌入式片段,但不允许使用 localStorage。)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div class="form-container"
style="float: left; margin-left: 80px; margin-top: 13px; text-align: center; padding-bottom: 530px; margin-bottom: 20px; padding-top: 10px;">
<form>
<!-- Monday -->
<div class="sleep">
<p
style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">
Monday</p>
<input type="number" name="monday" id="monday" placeholder="Monday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!-- Tuesday -->
<div class="sleep">
<p
style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">
Tuesday</p>
<input type="number" name="tuesday" id="tuesday" placeholder="Tuesday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!-- Wednesday -->
<div class="sleep">
<p
style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">
Wednesday</p>
<input type="number" name="wednesday" id="wednesday" placeholder="Wednesday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!-- Thursday -->
<div class="sleep">
<p
style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">
Thursday</p>
<input type="number" name="thursday" id="thursday" placeholder="Thursday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!-- Friday -->
<div class="sleep">
<p
style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">
Friday</p>
<input type="number" name="friday" id="friday" placeholder="Friday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!-- Saturday -->
<div class="sleep">
<p
style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">
Saturday</p>
<input type="number" name="saturday" id="saturday" placeholder="Saturday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
<!-- Sunday -->
<div class="sleep">
<p
style="color: #55725d; font-size: 20px; text-align: left; font-style: bold; margin-bottom: 4px; text-align: center; margin-top: 18px;">
Sunday</p>
<input type="number" name="sunday" id="sunday" placeholder="Sunday" value="">
<button class="sleep-btn" style="margin-left: 78px;">Enter</button>
</div>
</form>
<!-- Save and clear buttons for local storage -->
<div>
<button class="save-btn" id="save-btn">Save</button>
<button class="clear-btn" id="clear-btn">Clear</button>
</div>
</div>
<div class="chart-container"
style=" float: right; margin-right: 100px; position: relative; height: 60vh; width: 60vw; margin-top: 100px">
<canvas id="myChart" width="100px" height="100px"></canvas>
</div>
<script>
//Chart setup and configuration
let chartData = loadFromLocalStorage();
setUIData(chartData);
const ctx = document.getElementById('myChart');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
datasets: [{
label: 'Hours of sleep',
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)',
'rgba(222, 184, 135, 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)',
'rgba(222, 184, 135, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
//Adding user data in
function addData(chart, data) {
chart.data.datasets.forEach((dataset) => {
dataset.data = [...data]
});
chart.update();
}
//Calling input values to update chart
function updateChart(event) {
if (event) event.preventDefault();
chartData = getUIData();
saveToLocalStorage(chartData);
addData(myChart, chartData);
}
//Updating chart with values
document.querySelectorAll('.sleep-btn').forEach(btn => {
btn.addEventListener('click', updateChart);
});
function setUIData(data) {
document.querySelectorAll('.sleep input').forEach((el, i) => el.value = data[i] || '');
}
function getUIData() {
return Array.from(document.querySelectorAll('.sleep input'))
.map(el => Number(el.value));
}
//Local storage functions
function loadFromLocalStorage() {
return JSON.parse(localStorage.getItem('sdps') || '[]');
}
function saveToLocalStorage(chartData) {
localStorage.setItem('sdps', JSON.stringify(chartData));
}
function clearStorage() {
localStorage.clear();
setUIData(['','','','','','','']);
updateChart();
};
document.querySelector('.save-btn').addEventListener('click', updateChart);
document.querySelector('.clear-btn').addEventListener('click', clearStorage);
</script>
</body>
</html>
对于需要 2 个数据集的堆积条形图,您如何做到这一点?
let labelData = loadLabelFromLocalStorage();
let plannedCostData = loadPCFromLocalStorage();
let actualCostData = loadACFromLocalStorage();
setUILabel(labelData);
setUIPCData(plannedCostData);
setUIACData(actualCostData);
const ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labelData,
datasets: [{
data: actualCostData,
backgroundColor: "#2E9CCA",
},{
data: plannedCostData,
backgroundColor: "#AAABB8",
}]
},
options: {
plugins: {
legend: {
display: false,
}
},
scales: {
y: {
beginAtZero: true,
min: 0,
}
}
}
});
// add label
function addLabel(chart, data) {
chart.data.labels.forEach((dataset) => {
dataset.data = [...data]
});
chart.update();
}
function updateLabel(event) {
if (event) event.preventDefault();
labelData = getUILabel();
saveLabelToLocalStorage(labelData);
addLabel(myChart, labelData);
}
//Updating chart with values
function setUILabel(data) {
document.querySelectorAll('.labelinput').forEach((el, i) => el.value = data[i] || '');
}
function getUILabel() {
return Array.from(document.querySelectorAll('.labelinput'))
.map(el => String(el.value));
}
function saveLabelToLocalStorage(labelData) {
localStorage.setItem('Label', JSON.stringify(labelData));
}
function loadLabelFromLocalStorage() {
return JSON.parse(localStorage.getItem('Label') || '[]');
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//add "planned cost" data
function addPC(chart, data) {
chart.data.datasets.forEach((dataset) => {
dataset.data = [...data]
});
chart.update();
}
//Calling input values to update chart
function updatePC(event) {
if (event) event.preventDefault();
plannedCostData = getUIPCData();
savePCToLocalStorage(plannedCostData);
addPC(myChart, plannedCostData);
}
//Updating chart with values
function setUIPCData(data) {
document.querySelectorAll('.plannedcost').forEach((el, i) => el.value = data[i] || '');
}
function getUIPCData() {
return Array.from(document.querySelectorAll('.plannedcost'))
.map(el => Number(el.value));
}
function savePCToLocalStorage(plannedCostData) {
localStorage.setItem('number2', JSON.stringify(plannedCostData));
}
function loadPCFromLocalStorage() {
return JSON.parse(localStorage.getItem('number2') || '[]');
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//add actual cost
function addAC(chart, data) {
chart.data.datasets.forEach((dataset) => {
dataset.data = [...data]
});
chart.update();
}
//Calling input values to update chart
function updateAC(event) {
if (event) event.preventDefault();
actualCostData = getUIACData();
saveACToLocalStorage(actualCostData);
addAC(myChart, actualCostData);
}
//Updating chart with values
function setUIACData(data) {
document.querySelectorAll('.actualcost').forEach((el, i) => el.value = data[i] || '');
}
function getUIACData() {
return Array.from(document.querySelectorAll('.actualcost'))
.map(el => Number(el.value));
}
function saveACToLocalStorage(actualCostData) {
localStorage.setItem('number3', JSON.stringify(actualCostData));
}
function loadACFromLocalStorage() {
return JSON.parse(localStorage.getItem('number3') || '[]');
}
body {
background-color:#25274D;
}
.container {
flex: 0 0 auto;
width: 100%;
box-sizing: border-box;
display: block;
max-width: 100%;
}
.card {
width: 57.5rem;
height: 18rem;
background-color: white;
border-radius: 4px;
}
.container {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
}
.inputfield {
display: flex;
grid-template-columns: 1fr 1fr;
gap: 0.65rem;
border-radius: 4px;
width: 0.5rem;
}
.inputs-container {
display: grid;
gap: 0.65rem;
}
.chart-heading {
text-align: left;
padding: 1.2rem 0 1.2rem 1rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.15);
width: 100%;
}
.input-title {
display: flex;
gap: 8rem;
}
.plannedcost {
width: 3.5rem;
}
.actualcost {
width: 3.5rem;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>LS&INPUTS - Colum</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="card">
<p class="chart-heading">Job progress</p>
<div class="container">
<div class="chart-container">
<canvas id="myChart"></canvas>
</div>
<div class="inputs-container">
<div class="input-title">
<p>Job</p>
<p>Job progress(%)</p>
</div>
<!-- Input 1 -->
<div class="inputfield">
<input class="labelinput" type="text" id="input1text" onkeyup="updateLabel()" maxlength="10">
<input class="plannedcost" type="number" id="plannedinput1" onchange ="updatePC()">
<input class="actualcost" type="number" id="actualinput1" onchange ="updateAC()">
</div>
<!-- Input 2 -->
<div class="inputfield">
<input class="labelinput" type="text" id="input2text" onkeyup="updateLabel()" maxlength="10">
<input class="plannedcost" type="number" id="plannedinput2" onchange="updatePC()">
<input class="actualcost" type="number" id="actualinput2" onchange ="updateAC()">
</div>
<!-- Input 3 -->
<div class="inputfield">
<input class="labelinput" type="text" id="input3text" onkeyup="updateLabel()" maxlength="10">
<input class="plannedcost" type="number" id="plannedinput3" onchange="updatePC()">
<input class="actualcost" type="number" id="actualinput3" onchange ="updateAC()">
</div>
<!-- Input 3 -->
<div class="inputfield">
<input class="labelinput" type="text" id="input4text" onkeyup="updateLabel()" maxlength="10">
<input class="plannedcost" type="number" id="plannedinput4" onchange="updatePC()">
<input class="actualcost" type="number" id="actualinput4" onchange ="updateAC()">
</div>
<!-- Input 5 -->
<div class="inputfield">
<input class="labelinput" type="text" id="input5text" onkeyup="updateLabel()" maxlength="10">
<input class="plannedcost" type="number" id="plannedinput5" onchange="updatePC()">
<input class="actualcost" type="number" id="actualinput5" onchange ="updateAC()">
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="script.js"></script>
</body>
</html>