我正在尝试编写一个应用程序,允许人们将数据插入到表单中,这将通过Chart.js绘制图表如果没有多个数据集但是我找到'/'时,我很好并将值放入数组中。我遇到的问题是我似乎无法获得此表单数据。即我最初加载的图表正确设置了两个数据集。但我尝试使用此代码:
formData[index].value.forEach(function (value, dataset_index) {
console.log(formData[index].name);
chartData.datasets[dataset_index][formData[index].name] = value; // Problem Line
我收到错误“TypeError:chartData.datasets [dataset_index]未定义”。我在这个括号表示法上尝试了多种排列,并得到了类似的错误。
// /public/main.js
const chartData = {
labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
datasets: [{
label: 'apples',
data: [12, 19, 3, 17, 6, 3, 7],
backgroundColor: "rgba(153,255,51,0.4)"
}, {
label: 'oranges',
data: [2, 29, 5, 5, 2, 3, 10],
backgroundColor: "rgba(255,153,0,0.4)"
}]
};
let Options = {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
};
const ctx = document.getElementById("myChart").getContext('2d');
let myChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: Options
});
// Get Chart Info from form
$(document).ready(function() {
$("#render_btn").on("click", function(e) {
e.preventDefault();
// First grab form data off the page
const formData = $('form').serializeArray();
// Get Chart Type and Options Seperate from Form Data
const chartTypeControl = document.getElementById("chart_type");
const chartType = chartTypeControl.options[chartTypeControl.selectedIndex].value;
Options = document.getElementById("chart_options").value;
// Create a data Object for Chart constructor to use
let datasetsItem = {};
// Convert formData array to chartData object
formData.forEach(function(value, index) {
if (formData[index].name == 'labels' || formData[index].name == 'options') {
chartData[(formData[index].name)] = formData[index].value;
} else {
// Check if this form value has multiple datasets(has a '/') and if so
// split the string into seperate dataset's
if (formData[index].value.indexOf('/') > -1) {
// Split the field up into seperate array items
formData[index].value = splitString(formData[index].value, '/');
// Now put the array items into their seperate datasets
formData[index].value.forEach(function (value, dataset_index) {
datasetsItem[formData[index].name] = value;
// console.log(datasetsItem[formData[index].name]);
chartData.datasets[dataset_index] = datasetsItem;
});
} else {
datasetsItem[formData[index].name] = formData[index].value;
chartData.datasets[0] = datasetsItem;
}
}
});
// =====================================================================================
// Now we have to do some converting i.e., chartData.labels must be converted to array
// from string etc.. ==================================================================
chartData.datasets[0].backgroundColor = splitString(chartData.datasets[0].backgroundColor);
chartData.datasets[0].borderColor = splitString(chartData.datasets[0].borderColor);
chartData.datasets[0].data = strToNumberArray(chartData.datasets[0].data);
chartData.labels = splitString(chartData.labels);
chartData.datasets[0].borderWidth = strToNumber(chartData.datasets[0].borderWidth);
if (isNaN(chartData.datasets[0].borderWidth)) {
alert("Attention: Border Width needs to be a number.");
}
// Check if successful
try {
if (!(chartData.datasets[0].data) || !(chartData.labels)) {
throw new Error("Input Error. Recheck your form data.");
}
myChart.type = chartType;
myChart.data = chartData;
myChart.update();
} catch (error) {
alert(error);
}
// ============================================================= //
// ============= Function definitions ========================== //
// ============================================================= //
function splitString(strToSplit, separator = ",") {
if (!strToSplit) {
alert("Error: One of your required fields is empty.");
return "";
}
// Test for a ',' or '/' slash in the string
const result = /[,\/]/g.test(strToSplit);
if (!result) {
// Only one entry in Data form
return strToSplit;
}
// Split a string into an array and trim any whitespace
let arrayOfStrings = strToSplit.split(separator);
arrayOfStrings.forEach(function(value, index) {
arrayOfStrings[index] = value.trim();
});
return arrayOfStrings;
}
// Function to convert string to an array then convert each element to a number
function strToNumberArray(str, separator = ',') {
if (str === undefined) {
alert('Error: string is empty.');
return "";
}
// Test for a comma in the string
const result = /,+/.test(str);
if (!result) {
alert(`Comma delimiter missing from ${str}`);
return false;
}
let arrayOfNumbers = str.split(separator).map(Number);
return arrayOfNumbers;
}
// Function convert string type to number
function strToNumber(str) {
Number(str);
return str;
}
// Functtion remove all whitespace from string
function removeWhiteSpace(str) {
str.replace(/\s+/g, '');
return str;
}
// ============================================================== //
// ================== End Function Definitions ================== //
// ============================================================== //
}); // End .on "click"
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<canvas id="myChart" width="400" height="400"></canvas>
<h2>Input your values:</h2>
<!-- Chart Input Form -->
<!-- We dont want chart_type as part of form when we use serializeArray
gather the data and use in chartData object -->
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="form-group">
<label for="chart_type">Chart Type</label>
<input type="text" name="type" class="form-control" id="chart_type" placeholder="Chart Type">
</div>
</div>
</div>
<form>
<div class="row">
<div class="col-md-4 col-md-offset-4 ">
<div class="form-group">
<label for="chart_type">Chart Type</label>
<select class="form-control input-lg" id="chart_type">
<option value="bar">Bar Chart</option>
<option value="pie">Pie Chart</option>
<option value="line">Line</option>
<option value="doughnut">Doughnut</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="form-group">
<label for="chart_Label">Chart Label</label>
<input type="text" name="label" class="form-control input-lg" id="chart_Label" placeholder="Chart Label">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-4">
<div class="form-group">
<label for="chart_labels">Chart Labels</label>
<input type="text" name="labels" class="form-control input-lg" id="chart_labels" placeholder="Apr, May, June Note:Seperated by Commas">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-4">
<div class="form-group">
<label for="chart_data">Chart Data</label>
<input type="text" name="data" class="form-control input-lg" id="chart_data" placeholder="i.e., 25 44 60 etc">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-4">
<div class="form-group">
<label for="chart_colors">Chart Colors</label>
<input type="text" name="backgroundColor" class="form-control input-lg" id="chart_colors" placeholder="i.e., red, blue, yellow, purple">
</div>
</div>
</div>
<!-- ============ More Options Markup ================================== -->
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#more_options" aria-expanded="false" aria-controls="collapseExample">
More Options
<span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span>
</button>
<div class="collapse" id="more_options">
<div class="well">
<div class="row">
<div class="col-md-6 col-md-offset-4">
<div class="form-group">
<label for="border_color">Border Color(s)</label>
<input type="text" name="borderColor" class="form-control input-lg" id="border_color" placeholder="i.e., red,blue,green,orange">
</div>
</div>
<div class="col-md-6 col-md-offset-4">
<div class="form-group">
<label for="border_width">Border Width</label>
<input type="text" name="borderWidth" class="form-control input-lg" id="border_width" placeholder="i.e., 1">
</div>
</div>
</div>
<!-- Options Markup -->
<div class="col-md-6 col-md-offset-4">
<div class="form-group">
<label for="chart_options">Chart Options</label>
<input type="text" name="options" class="form-control input-lg" id="chart_options" placeholder="See Chart.js Documentation">
</div>
</div>
</div>
</div>
</form>
<div class="row">
<div class="col-md-4 col-md-offset-5">
<button class="btn btn-primary btn-lg" id="render_btn">
<span class="glyphicon glyphicon-stats" aria-hidden="true"></span>
Render Graph
</button>
</div>
</div>
长话短说我似乎无法将苹果/橙子或多个数据集中的任何其他值正确存储到chartData对象数组中。任何帮助/见解非常感谢。
更新: 是的我现在可以在chartData中看到数据集数组,但它不正确。见图:
看起来chartData.datasets {0]和1完全相同?我更新了代码段。当我在forEach中的console.log数据集时,我得到正确的值吐出。有什么建议 ?感谢。
答案 0 :(得分:1)
一目了然,在您的问题行中,chartData.datasets[dataset_index]
尚未定义(如错误所示)。您需要在该索引处分配元素。此时,您将尝试通过变量设置对象键,如here所示。所以这样的事情应该有效:
var data = {};
data[formData[index].name] = value;
chartData.datasets[dataset_index] = data;