How to load dynamic label and data from controller in chart? - javascript

I'm using List to load radar chart from controller.
How can i load dynamic labels and data for that chart from controller.
List<MyModel> modelIist = new List<MyModel>();
MyModel model = new MyModel();
model.Data = 1;
model.Label = "First";
modelIist.Add(model);
model = new MyModel();
model.Data = 2;
model.Label = "Second";
modelIist.Add(model);
model = new MyModel();
model.Data = 3;
model.Label = "Third ";
modelIist.Add(model);
ViewBag.radarDesc = modelIist;
I'm loading data above from above list.
<script>
$(document).ready(function () {
var ctx = $("#chart-line");
var myLineChart = new Chart(ctx, {
type: 'radar',
data: {
labels: [], //want to load from the list
/*},*/
datasets: [{
data: [],//want to load from the list
label: "MyData",
borderColor: "#458af7",
backgroundColor: '#458af7',
fill: true
}]
},
options: {
title: {
display: true,
text: '(Max points - 300)'
}
}
});
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.bundle.min.js"></script>
<canvas id="chart-line" width="299" height="200" class="chartjs-render-monitor" style="display: block; width: 299px; height: 200px;"></canvas>
How can load label: [], data:[] from mvc.

Try this way:
Install Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet Package and then serialize the ViewBag.radarDesc into a valid JavaScript array:
ViewBag.radarDesc = Newtonsoft.Json.JsonConvert.SerializeObject(modelIist);
Then take out the Label and Data in the Page and fill it to the appropriate position:
$(document).ready(function () {
var Label = [];
var Data = [];
var radarDesc = #Html.Raw(#ViewBag.radarDesc);
$.each(radarDesc, function (index, value) {
Label.push(value.Label);
Data.push(value.Data);
});
var ctx = $("#chart-line");
var myLineChart = new Chart(ctx, {
type: 'radar',
data: {
labels: Label, //want to load from the list
/*},*/
datasets: [{
data: Data,//want to load from the list
label: "MyData",
borderColor: "#458af7",
backgroundColor: '#458af7',
fill: true
}]
},
options: {
title: {
display: true,
text: '(Max points - 300)'
}
}
});
});
Test Result:

Related

How can I show extra data in chart.js tooltip?

I'm trying to show weight_id retrieved from mysql data in a chart.js tooltip (shown as (weight_ids[index]) in the image). And later, I intend to show a modal instead of a tooltip to let users update or delete that data. I presume I cannot achieve that without linking the linechart's point data with id stored in mysql. How can I incorporate this id data?
I would appreciate any help very much.
enter image description here
My code is as follows:
<canvas id="myChart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.4/dist/Chart.min.js"></script>
{{-- グラフを描画--}}
<script>
//ラベル
const labels = #json($date_labels);
// id
const weight_ids = #json($weight_ids);
//体重ログ
const weight_logs = #json($weight_logs);
const aryMax = function(a, b) {
return Math.max(a, b);
};
const aryMin = function(a, b) {
return Math.min(a, b);
};
let min_label = Math.floor((weight_logs).reduce(aryMin) - 0.5);
let max_label = Math.ceil((weight_logs).reduce(aryMax) + 0.5);
console.log(weight_ids);
console.log(weight_logs);
console.log(min_label, max_label);
//グラフを描画
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data : {
labels: labels, // x軸ラベル
datasets: [
{
label: `Weight (weight_ids[index])`,
data: weight_logs,
tension: 0,
borderColor: "rgba(37,78,255,1)",
backgroundColor: "rgba(0,0,0,0)",
pointRadius: 3
}
]
},
options: {
title: {
display: false,
text: ''
},
legend: {
display: false,
},
scales: {
yAxes: [
{
ticks: {
min: min_label, // ラベル最小値
max: max_label, // ラベル最大値
},
scaleLabel: {
display: true,
fontSize: 16,
labelString: '体重 (kg)'
}
}
],
},
hover: {
mode: 'point'
},
onClick: function clickHandler(evt) {
var firstPoint = myChart.getElementAtEvent(evt)[0];
if (firstPoint) {
var label = myChart.data.labels[firstPoint._index];
var value = myChart.data.datasets[firstPoint._datasetIndex].data[firstPoint._index];
console.log(label);
console.log(value);
if (value) {
$('#weidhtModal').modal('show');
}
}
}
}
});
</script>
Thank you!
I found a way to retrieve weight_id using the following function.
onClick: function clickHandler(evt, activeElements) {
if (activeElements.length) {
var element = this.getElementAtEvent(evt);
var index = element[0]._index;
var _datasetIndex = element[0]._datasetIndex;
var weightId = weight_ids[index];
var weightLog = weight_logs[index];
console.log(index);
console.log(weightId);
console.log(this.data.labels[index]);
console.log(weightLog);
}
}

How to create a multi line chart with with dynamic x and y axis in one graph using chart js?

I want to create a multi line chart with dynamically changing values of x and y axis.Value for my Y axis are
traverse1 = [10,20,30,45,65,98]
traverse2 = [10,36,56,44,60,100]
traverse3 = [55,65,90,49,55,13]
traverse4 = [59,68,95,59,35,15]
Values for my X axis are
master = [0.1,0.2,0.3,0.5,,0.6]
All the values of X and Y will change dynamically by user.
I have tried to plot a graph but after changing the value dynamically my graph looks something like this grah. .
As you can see in the graph that for each line there is a seperate labels for X axis. What I want is common x axis for all the lines in the graph. Below Is the code that I have used to plot the graph.
function chartCall(master, traverse1, traverse2, traverse3, traverse4)
{
var canvas = document.getElementById("barChart");
var ctx = canvas.getContext('2d');
// Global Options:
Chart.defaults.global.defaultFontColor = 'black';
Chart.defaults.global.defaultFontSize = 16;
var dataFirst = {
label: "Traverse 1",
data: traverse1,
borderColor: "rgb(151,187,205)",
};
var dataSecond = {
label: "Traverse 2",
data: traverse2,
borderColor: "rgb(220,220,220)",
};
var dataThird = {
label: "Traverse 3",
data: traverse3,
borderColor: "rgb(247,70,74)",
};
var dataFourth = {
label: "Traverse 4",
data: traverse4,
borderColor: "rgb(70,191,189)",
};
var speedData = {
labels: master,
datasets: [dataFirst,dataSecond,dataThird,dataFourth]
};
// Chart declaration:
var myBarChart = new Chart(ctx, {
type: 'line',
data: speedData,
options: {}
});
}
the chart seems to draw fine with the code posted in the question,
even after changing the values and calling again.
see following working snippet,
click the button to update the chart with different values...
$(document).ready(function() {
var traverse1 = [10,20,30,45,65,98];
var traverse2 = [10,36,56,44,60,100];
var traverse3 = [55,65,90,49,55,13];
var traverse4 = [59,68,95,59,35,15];
var master = [0.1,0.2,0.3,0.5,,0.6];
chartCall(master, traverse1, traverse2, traverse3, traverse4);
document.getElementById('update').addEventListener('click', function () {
var traverse1 = getRandomValues(6);
var traverse2 = getRandomValues(6);
var traverse3 = getRandomValues(6);
var traverse4 = getRandomValues(6);
var master = [0.1,0.2,0.3,0.5,,0.6];
chartCall(master, traverse1, traverse2, traverse3, traverse4);
});
function chartCall(master, traverse1, traverse2, traverse3, traverse4) {
var canvas = document.getElementById("barChart");
var ctx = canvas.getContext('2d');
// Global Options:
Chart.defaults.global.defaultFontColor = 'black';
Chart.defaults.global.defaultFontSize = 16;
var dataFirst = {
label: "Traverse 1",
data: traverse1,
borderColor: "rgb(151,187,205)",
};
var dataSecond = {
label: "Traverse 2",
data: traverse2,
borderColor: "rgb(220,220,220)",
};
var dataThird = {
label: "Traverse 3",
data: traverse3,
borderColor: "rgb(247,70,74)",
};
var dataFourth = {
label: "Traverse 4",
data: traverse4,
borderColor: "rgb(70,191,189)",
};
var speedData = {
labels: master,
datasets: [dataFirst,dataSecond,dataThird,dataFourth]
};
// Chart declaration:
var myBarChart = new Chart(ctx, {
type: 'line',
data: speedData,
options: {}
});
}
function getRandomValues(length) {
var values = [];
for (var i = 0; i < length; i++) {
values.push(Math.random() * 10);
}
return values;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<input id="update" type="button" value="Update Chart" />
<canvas id="barChart"></canvas>

multiple charts js in page but with same tooltips (about last chart)

I have more doughnut charts in one page, every chart have different data but I show the same tooltips. It's tooltips of the last chart. I don't found the problem.
This is js code:
var idList = [];
// --------------------
// Memo ID list...
// --------------------
jQuery('.idKQI').each(function (i) {
idList.push( jQuery(this).text() );
});
var idListLength = idList.length;
// ------------------
// Doughnut loop...
// ------------------
var dataDoughnutChart = {
labels: [
'KO',
'OK'
],
datasets: [{
data: [30,70],
backgroundColor: [
'#DF0101', // red
'#31B404' // green
]
}]
};
var optionsDoughnutChart = {
maintainAspectRatio: false,
responsive: true,
legend: {
display: false
},
tooltips: {
mode: 'dataset'
}
};
var idLav;
var ctxDoughnut;
var labelAdd;
var errati;
var esatti;
for (var i = 0, max = idListLength; i < max; i++) {
idLav = '#' + idList[i] + "_chartDoughnut";
ctxDoughnut = jQuery(idLav);
labelAdd = jQuery(idLav).data("labeladd");
errati = jQuery(idLav).data("errati");
esatti = jQuery(idLav).data("esatti");
dataDoughnutChart.labels[0] = 'Errati' + labelAdd;
dataDoughnutChart.labels[1] = 'Esatti' + labelAdd;
dataDoughnutChart.datasets[0].data[0] = errati;
dataDoughnutChart.datasets[0].data[1] = esatti;
var myDoughnutChart = new Chart(ctxDoughnut, {
type: 'doughnut',
data: dataDoughnutChart,
options: optionsDoughnutChart
});
}
If I have two doughnut chart, in witch in the first chart datasets.data = [10,90], and in the second chart datasets.data = [2,98], the tooltips for all two chart show 'Errati: 2' and 'Esatti: 98'. It's values like the second chart.
I'm also try to use an array for var dataDoughnutChart like:
var myDoughnutChart = new Chart(ctxDoughnut, {
type: 'doughnut',
data: dataDoughnutChart[i],
options: optionsDoughnutChart
});
but don't resolve.
Thanks for your help.
Resolved like below:
// .....
configDoughnutList.push(
{
type: 'doughnut',
data: {
datasets: [{
data: [
30,
70
],
backgroundColor: [
'#DF0101', // rosso
'#31B404' // verde
],
label: 'daughnut_163'
}],
labels: [
'Errati',
'Corretti'
]
},
options: {
responsive: true,
legend: {
display: false
},
animation: {
animateScale: true,
animateRotate: true
},
tooltips: {
mode: 'dataset'
}
}
}
);
configDoughnutList[i].data.datasets[0].data[0] = errati;
configDoughnutList[i].data.datasets[0].data[1] = esatti;
configDoughnutList[i].data.labels[0] = 'Errati' + labelAdd;
configDoughnutList[i].data.labels[1] = 'Esatti' + labelAdd;
window.myDoughnut = new Chart(ctxDoughnut, configDoughnutList[i]);

How do I keep chart.js charts in one JS file, and not get errors when the ID from the JS file don't exist on one specific html page?

I'm quite new with JS, and have a problem with Chart.js and multiple charts.
I load all libraries like jquery and chart.js from CDNs
Then I have one plugins.js for localy loaded plugins
And one js called main.js with all the custom JS.
I get this error:
Uncaught TypeError: Cannot read property 'style' of undefined
My question is:
How do I keep all my Chart.js charts in one .js file, that get loaded on all website pages, but not all pages contains all charts.
(I have a site that consists on multiple pages with different charts, and I'm thinking it's smarter to load all at once in one JS-file)
Appreciate any other pointers also. :)
-
About the code
I've posted the code below and also created a JSFiddle: https://jsfiddle.net/NoLooseEnds/1pt3m41a/
In the main.js I have all my Chart.js data like so (among other things):
// *************************************
// Chart.js
// *************************************
// Global Settings
Chart.defaults.global.defaultFontColor = "rgba(43,43,43,1)";
Chart.defaults.global.defaultFontFamily = "'ApexNew-Medium', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif";
Chart.defaults.global.defaultFontSize = 12;
Chart.defaults.global.defaultFontStyle = "normal";
Chart.defaults.global.maintainAspectRatio = false;
// Disable click on legend
Chart.defaults.global.legend.onClick = (e) => e.stopPropagation();
// Bar Charts settings
var barChart__options = {
};
// Doughnut settings
var dnutChart__options = {
legend: {
position: "bottom",
// Disable click on legend
onClick: (e) => e.stopPropagation()
}
};
// *************************************
// Datasets
// *************************************
// Bar Chart X
var barChartX__data = {
labels: ["Alpha", "Bravo", "Charlie"],
datasets: [
{
label: "2015",
borderWidth: 0,
backgroundColor: "rgba(43,43,43,1)",
data: [410,430,110]
},
{
label: "2016",
borderWidth: 0,
backgroundColor: "rgba(233,131,0,1.0)",
data: [405,360,150]
}
]
};
const barChartX = $("#barChartX");
let ChartX = new Chart(barChartX, {
type: "bar",
data: barChartX__data,
options: barChart__options
});
// Doughnut Chart Y
var dnutChartY__data = {
labels: ["Alpha", "Bravo"],
datasets: [
{
label: "Points",
borderWidth: 0,
backgroundColor: ["rgba(43,43,43,1)", "rgba(233,131,0,1.0)"],
data: [90,270]
}
]
};
const dnutChartY = $("#dnutChartY");
let ChartY = new Chart(dnutChartY, {
type: "doughnut",
data: dnutChartY__data,
options: dnutChart__options
});
// Doughnut Chart Z
var dnutChartZ__data = {
labels: ["Alpha", "Bravo", "Charlie"],
datasets: [
{
label: "Points",
borderWidth: 0,
backgroundColor: ["rgba(233,131,0,1.0)","rgba(239,162,64,1.0)","rgba(244,193,127,1.0)"],
data: [405,360,150]
}
]
};
const dnutChartZ = $("#dnutChartZ");
let ChartZ = new Chart(dnutChartZ, {
type: "doughnut",
data: dnutChartZ__data,
options: dnutChart__options
});
And my HTML like so:
<div class="example__chart">
<div>
<canvas id="barChartX" height="400" width="400"></canvas>
</div>
<!--
<div>
<canvas id="dnutChartY" height="400" width="400"></canvas>
</div>
-->
<div>
<canvas id="dnutChartZ" height="400" width="400"></canvas>
</div>
</div>
As you can see I have commented out a part to trigger the error.
You can create a helper function and check whenever the DOM element exists for the barChartX, dnutChartY, dnutChartZ or any other DOM element like this:
var doChart = function(o, d) {
if (typeof(o) != 'undefined' && o.length > 0) {
return new Chart(o, d);
} else {
return null;
}
}
Then your Chart.js code will be like this
// *************************************
// Chart.js
// *************************************
// Global Settings
Chart.defaults.global.defaultFontColor = "rgba(43,43,43,1)";
Chart.defaults.global.defaultFontFamily = "'ApexNew-Medium', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif";
Chart.defaults.global.defaultFontSize = 12;
Chart.defaults.global.defaultFontStyle = "normal";
Chart.defaults.global.maintainAspectRatio = false;
// Disable click on legend
Chart.defaults.global.legend.onClick = (e) => e.stopPropagation();
var doChart = function(o, d) {
if (typeof(o) != 'undefined' && o.length > 0) {
return new Chart(o, d);
} else {
return null;
}
}
// Bar Charts settings
var barChart__options = {};
// Doughnut settings
var dnutChart__options = {
legend: {
position: "bottom",
// Disable click on legend
onClick: (e) => e.stopPropagation()
}
};
// *************************************
// Datasets
// *************************************
// Bar Chart X
var barChartX__data = {
labels: ["Alpha", "Bravo", "Charlie"],
datasets: [{
label: "2015",
borderWidth: 0,
backgroundColor: "rgba(43,43,43,1)",
data: [410, 430, 110]
},
{
label: "2016",
borderWidth: 0,
backgroundColor: "rgba(233,131,0,1.0)",
data: [405, 360, 150]
}
]
};
const barChartX = $("#barChartX");
/*let ChartX = new Chart(barChartX, {
type: "bar",
data: barChartX__data,
options: barChart__options
});*/
let ChartX = doChart(barChartX, {
type: "bar",
data: barChartX__data,
options: barChart__options
});
// Doughnut Chart Y
var dnutChartY__data = {
labels: ["Alpha", "Bravo"],
datasets: [{
label: "Points",
borderWidth: 0,
backgroundColor: ["rgba(43,43,43,1)", "rgba(233,131,0,1.0)"],
data: [90, 270]
}]
};
const dnutChartY = $("#dnutChartY");
let ChartY = doChart(dnutChartY, {
type: "doughnut",
data: dnutChartY__data,
options: dnutChart__options
});
// Doughnut Chart Z
var dnutChartZ__data = {
labels: ["Alpha", "Bravo", "Charlie"],
datasets: [{
label: "Points",
borderWidth: 0,
backgroundColor: ["rgba(233,131,0,1.0)", "rgba(239,162,64,1.0)", "rgba(244,193,127,1.0)"],
data: [405, 360, 150]
}]
};
const dnutChartZ = $("#dnutChartZ");
let ChartZ = doChart(dnutChartZ, {
type: "doughnut",
data: dnutChartZ__data,
options: dnutChart__options
});
Please check my working example with no javascript errors here: http://zikro.gr/dbg/html/chartsjs/
UPDATE
Please have a look at the JSFiddle example here: https://jsfiddle.net/h1dafqjx/2/
UPDATE 2
Problem analysis and solution
The problem you are facing, is that you want to have multiple declarations and chart setups in one javascript file that you are going to use on many location which may happen some of these locations do not have some of the declared elements, thus you want your code to handle those cases.
You declare a chart like this:
const barChartX = $("#barChartX");
let ChartX = new Chart(barChartX, {
type: "bar",
data: barChartX__data,
options: barChart__options
});
In order to handle a missing DOM element, like when the $("#barChartX") does not exists, you need to create a condition to check those cases.
For excample:
const barChartX = $("#barChartX");
if(typeof(barChartX) != 'undefined' && barChartX.length > 0) {
let ChartX = new Chart(barChartX, {
type: "bar",
data: barChartX__data,
options: barChart__options
});
}
With the obove code, you check if the barChartX is defined and if it actually contains any elements with the barChartX.length > 0 condition.
Now, in order to do not repeat things, we keep it simple and do all that checking in a function. Thus we create the function doChart like this:
var doChart = function(o, d) {
if (typeof(o) != 'undefined' && o.length > 0) {
return new Chart(o, d);
} else {
return null;
}
}
The first parameter o is the DOM element we want to check and the second parameter d is the chart object properties.
For example:
let ChartX = doChart(barChartX, {
type: "bar",
data: barChartX__data,
options: barChart__options
});
Here we pass to the doChart function the barChartX jQuery object of the element in order for the function to check if exists. Then we pass the chart object parameters by the second parameter named d, which is the chart object properties for creating the new chart:
{
type: "bar",
data: barChartX__data,
options: barChart__options
}

My chart is not shown on browser screen using chart.js in meteor

My chart is not shown on browser screen. I am using chart.js with meteor and also trying to do it with onRendered or onCreated but it didn't work for me.
Here is my code
<div class="pie-canvas">
<canvas id="myChart" width="350" height="350"></canvas>
</div>
Js file ->
Template.home.rendered = function() {
Deps.autorun(function() { drawChart(); });
};
function drawChart() {
var oldCount = 2;
var newCount = 4;
var data = [{
value: newCount,
color: "#e53935",
highlight: "#c62828",
label: "New"
}, {
value: oldCount,
color: "#3949ab",
highlight: "#1a237e",
label: "Regular"
}];
var pieOptions = {
animation: false,
}
if ($("#myChart").get(0)) {
var ctx = $("#myChart").get(0).getContext("2d");
var myNewChart = new Chart(ctx);
new Chart(ctx).Pie(data, pieOptions);
}
}
home is my template name
When you console log '$("#myChart").get(0)' this will return you undefined, because on rendered your get(0) is not initialized, For prevent this you have to add a callback when you initialized you chart. So your get(0) will be initialized first then you can create your chats.
'$("#myChart").get(0)' is not a reative thing so your view will be not re-initialized.
Here is the working code:
function drawChart() {
var oldCount = 2;
var newCount = 4;
var data = [{
value: newCount,
color: "#e53935",
highlight: "#c62828",
label: "New"
}, {
value: oldCount,
color: "#3949ab",
highlight: "#1a237e",
label: "Regular"
}];
var pieOptions = {
animation: false,
}
// Added a callback here.
setTimeout( function(){
if ($("#myChart").get(0)) {
var ctx = $("#myChart").get(0).getContext("2d");
var myNewChart = new Chart(ctx);
console.log(myNewChart);
new Chart(ctx).Pie(data, pieOptions);
}
})
}

Categories

Resources