I wanted to stream live data in the form of a chart. I'm new to Javascript, so I wanted to first experiment with the sample on this page.
https://web.archive.org/web/20211113012042/https://nagix.github.io/chartjs-plugin-streaming/latest/samples/charts/line-horizontal.html
The code is given as:
var chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
function randomScalingFactor() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
}
function onRefresh(chart) {
chart.config.data.datasets.forEach(function(dataset) {
dataset.data.push({
x: Date.now(),
y: randomScalingFactor()
});
});
}
var color = Chart.helpers.color;
var config = {
type: 'line',
data: {
datasets: [{
label: 'Dataset 1 (linear interpolation)',
backgroundColor: color(chartColors.red).alpha(0.5).rgbString(),
borderColor: chartColors.red,
fill: false,
lineTension: 0,
borderDash: [8, 4],
data: []
}, {
label: 'Dataset 2 (cubic interpolation)',
backgroundColor: color(chartColors.blue).alpha(0.5).rgbString(),
borderColor: chartColors.blue,
fill: false,
cubicInterpolationMode: 'monotone',
data: []
}]
},
options: {
title: {
display: true,
text: 'Line chart (hotizontal scroll) sample'
},
scales: {
xAxes: [{
type: 'realtime'
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
}
}]
},
tooltips: {
mode: 'nearest',
intersect: false
},
hover: {
mode: 'nearest',
intersect: false
},
plugins: {
streaming: {
duration: 20000,
refresh: 1000,
delay: 2000,
onRefresh: onRefresh
}
}
}
};
window.onload = function() {
var ctx = document.getElementById('myChart').getContext('2d');
window.myChart = new Chart(ctx, config);
};
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data.forEach(function(dataObj) {
dataObj.y = randomScalingFactor();
});
});
window.myChart.update();
});
var colorNames = Object.keys(chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[config.data.datasets.length % colorNames.length];
var newColor = chartColors[colorName];
var newDataset = {
label: 'Dataset ' + (config.data.datasets.length + 1),
backgroundColor: color(newColor).alpha(0.5).rgbString(),
borderColor: newColor,
fill: false,
lineTension: 0,
data: []
};
config.data.datasets.push(newDataset);
window.myChart.update();
});
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.pop();
window.myChart.update();
});
document.getElementById('addData').addEventListener('click', function() {
onRefresh(window.myChart);
window.myChart.update();
});
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<script src="https://github.com/nagix/chartjs-plugin-streaming/releases/download/v1.5.0/chartjs-plugin-streaming.min.js"></script>
</head>
<body>
<div>
<canvas id="myChart"></canvas>
</div>
<p>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
</p>
</body>
When I copy and paste it into jsfiddle, the first code snippet going into the Javascript section and the second going into the HTML section. However, nothing happens? Could someone explain why/help me edit it so that it works?
Note: the code above is not my own, it belongs to this guy
In JSFiddle, the load type is set to 'On Load' by default, so you cannot handle the load event. Setting the load type to 'No wrap - bottom of ' works (in the pop-up menu in the Javascript section).
Related
I need to make a chart at the level with a row in the table, are there any tips on how to implement this enter image description here
I need the chart lines to match the row level in the table
and this code draws a separate chart
const diag = () => {
document.getElementById("canvasic").innerHTML = ' ';
document.getElementById("canvasic").innerHTML = '<canvas id="densityChart" className="canav"></canvas>';
densityCanvas = document.getElementById("densityChart");
//remove canvas from container
Chart.defaults.global.defaultFontFamily = "Arial";
Chart.defaults.global.defaultFontSize = 16;
var densityData = {
label: 'CallVol',
data:calloiList1,
backgroundColor: 'rgba(0,128,0, 0.6)',
borderColor: 'rgba(0,128,0, 1)',
borderWidth: 2,
hoverBorderWidth: 0
};
var densityData1 = {
label: 'PutVol',
data:calloiList3 ,
backgroundColor: 'rgba(255,0,0, 0.6)',
borderColor: 'rgba(255,0,0, 1)',
borderWidth: 2,
hoverBorderWidth: 0
};
var chartOptions = {
scales: {
yAxes: [{
barPercentage: 0.5
}]
},
elements: {
rectangle: {
borderSkipped: 'left',
}
}
};
var barChart = new Chart(densityCanvas, {
type: 'horizontalBar',
data: {
labels: calloiList4,
datasets: [densityData,densityData1],
},
options: chartOptions
}
);
}
enter image description here
I'm trying to periodically update a chart. The data is making into the dataset but I can't get it to draw the chart. What am I doing wrong?
const ctx = document.querySelector('#apichart canvas').getContext('2d');
const apichart = new Chart(ctx, {
type: 'line',
data: {datasets:[{
label:'Pressure',
data: [1025,1000],
fill:false,
borderColor: 'rgb(75, 192, 192)',
tension:0.1
}]},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
setInterval(function run(){
apichart.data.datasets[0].data.push(1025 * Math.random());
apichart.update();
}, 10000);
#apichart{background:#777; position:absolute; top:0; right:0; bottom:0; left:0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.2/chart.min.js"></script>
<div id="apichart">
<canvas></canvas>
</div>
I think this problem related to labels, so I have added labels array and update them in setInterval each time and it works.
const ctx = document.querySelector('#apichart canvas').getContext('2d');
const apichart = new Chart(ctx, {
type: 'line',
data: {labels: [1, 2],
datasets:[{
label:'Pressure',
data: [1025,1000],
fill:false,
borderColor: 'rgb(75, 192, 192)',
tension:0.1
}]},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
setInterval(function run(){
apichart.data.labels.push(Math.random());
apichart.data.datasets[0].data.push(1025 * Math.random());
apichart.update();
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.2/chart.min.js"></script>
<div id="apichart">
<canvas></canvas>
</div>
I create a radar chart to display data which comes from my backend. The data is dynamic, but I would like to highlight the gridline at 60 as shown below. Does chartjs have any solution to achieve it?
const gray = "rgb(200, 200, 200)";
const color = Chart.helpers.color;
const config = {
type: 'radar',
data: {
labels: [['Eating', 'Dinner'], ['Drinking', 'Water'], 'Sleeping', ['Designing', 'Graphics'], 'Coding', 'Cycling', 'Running'],
datasets: [{
label: 'My dataset',
backgroundColor: color(gray).alpha(0.2).rgbString(),
borderColor: gray,
pointBackgroundColor: gray,
data: [
80,
90,
60,
65,
78,
97,
55
]
}]
},
options: {
scale: {
gridLines: {
circular: true,
color: [gray, gray, 'blue', gray, gray, gray, gray, gray, gray, gray]
},
ticks: {
beginAtZero: true,
stepsize: 20
},
}
}
};
window.onload = function () {
window.myRadar = new Chart(document.getElementById('chart'), config);
};
<body>
<canvas id="chart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js" integrity="sha512-hZf9Qhp3rlDJBvAKvmiG+goaaKRZA6LKUO35oK6EsM0/kjPK32Yw7URqrq3Q+Nvbbt8Usss+IekL7CRn83dYmw==" crossorigin="anonymous"></script>
</body>
enter code hereSince your data is dynamic, you need to compute scale.gridLines.colors based on the data. This could be done as follows:
const data = [80, 90, 60, 65, 78, 97, 55];
const gridLinesStepSize = 20;
const highlightedGridLine = 60;
const gridLineColors = Array.from(Array(Math.ceil(Math.max(...data) / gridLinesStepSize) + 1).keys())
.map(n => n * 20)
.slice(1)
.map(v => v == highlightedGridLine ? 'blue' : gray);
Please take a look at your amended runnable code and see how it works.
const gray = "rgb(200, 200, 200)";
const color = Chart.helpers.color;
const data = [80, 90, 60, 65, 78, 97, 55];
const gridLinesStepSize = 20;
const highlightedGridLine = 60;
const gridLineColors = Array.from(Array(Math.ceil(Math.max(...data) / gridLinesStepSize) + 1).keys())
.map(n => n * 20)
.slice(1)
.map(v => v == highlightedGridLine ? 'blue' : gray);
new Chart('chart', {
type: 'radar',
data: {
labels: [
['Eating', 'Dinner'],
['Drinking', 'Water'], 'Sleeping', ['Designing', 'Graphics'], 'Coding', 'Cycling', 'Running'
],
datasets: [{
label: 'My dataset',
backgroundColor: color(gray).alpha(0.2).rgbString(),
borderColor: gray,
pointBackgroundColor: gray,
data: data
}]
},
options: {
scale: {
gridLines: {
circular: true,
color: gridLineColors
},
ticks: {
beginAtZero: true,
stepsize: gridLinesStepSize
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"></script>
<canvas id="chart" height="120"></canvas>
In my controller I have an Action method that will find all questions in a table called Questions, and the answers for each question.
This Action is of type ContentResult that will return a result serialized in Json format.
public ContentResult GetData()
{
var datalistQuestions = db.Questions.ToList();
List<PsychTestViewModel> questionlist = new List<PsychTestViewModel>();
List<PsychTestViewModel> questionanswerslist = new List<PsychTestViewModel>();
PsychTestViewModel ptvmodel = new PsychTestViewModel();
foreach (var question in datalistQuestions)
{
PsychTestViewModel ptvm = new PsychTestViewModel();
ptvm.QuestionID = question.QuestionID;
ptvm.Question = question.Question;
questionlist.Add(ptvm);
ViewBag.questionlist = questionlist;
var agree = //query
var somewhatAgree = //query
var disagree = //query
int Agree = agree.Count();
int SomewhatAgree = somewhatAgree.Count();
int Disagree = disagree.Count();
ptvmodel.countAgree = Agree;
ptvmodel.countSomewhatAgree = SomewhatAgree;
ptvmodel.countDisagree = Disagree;
questionanswerslist.Add(ptvmodel);
ViewBag.questionanswerslist = questionanswerslist;
}
return Content(JsonConvert.SerializeObject(ptvmodel), "application/json");
}
Now, my problem is the pie chart is not being created and I don't quite know how to push the values to my data structure?
What should I be doing instead?
Here is my script:
#section Scripts {
<script type="text/javascript">
var PieChartData = {
labels: [],
datasets: [
{
label: "Agree",
backgroundColor:"#f990a7",
borderWidth: 2,
data: []
},
{
label: "Somewhat Agree",
backgroundColor: "#aad2ed",
borderWidth: 2,
data: []
},
{
label: "Disgree",
backgroundColor: "#9966FF",
borderWidth: 2,
data: []
},
]
};
$.getJSON("/PsychTest/GetData/", function (data) {
for (var i = 0; i <= data.length - 1; i++) {
PieChartData.datasets[0].data.push(data[i].countAgree);
PieChartData.datasets[1].data.push(data[i].countSomewhatAgree);
PieChartData.datasets[2].data.push(data[i].countDisagree);
}
var ctx = document.getElementById("pie-chart").getContext("2d");
var myLineChart = new Chart(ctx,
{
type: 'pie',
data: PieChartData,
options:
{
responsive: true,
maintainaspectratio: true,
legend:
{
position : 'right'
}
}
});
});
</script>
You need two arrays for creating your chart. One of them indicates titles and another one shows the number of each titles. You have titles in the client side, so you only need the number of each options and it could be fetched from a simple server method like:
[HttpGet]
public JsonResult Chart()
{
var data = new int[] { 4, 2, 5 }; // fill it up whatever you want, but the number of items should be equal with your options
return JsonConvert.SerializeObject(data)
}
The client side code is here:
var aLabels = ["Agree","Somewhat Agree","Disagree"];
var aDatasets1 = [4,2,5]; //fetch these from the server
var dataT = {
labels: aLabels,
datasets: [{
label: "Test Data",
data: aDatasets1,
fill: false,
backgroundColor: ["rgba(54, 162, 235, 0.2)", "rgba(255, 99, 132, 0.2)", "rgba(255, 159, 64, 0.2)", "rgba(255, 205, 86, 0.2)", "rgba(75, 192, 192, 0.2)", "rgba(153, 102, 255, 0.2)", "rgba(201, 203, 207, 0.2)"],
borderColor: ["rgb(54, 162, 235)", "rgb(255, 99, 132)", "rgb(255, 159, 64)", "rgb(255, 205, 86)", "rgb(75, 192, 192)", "rgb(153, 102, 255)", "rgb(201, 203, 207)"],
borderWidth: 1
}]
};
var opt = {
responsive: true,
title: { display: true, text: 'TEST CHART' },
legend: { position: 'bottom' },
//scales: {
// xAxes: [{ gridLines: { display: false }, display: true, scaleLabel: { display: false, labelString: '' } }],
// yAxes: [{ gridLines: { display: false }, display: true, scaleLabel: { display: false, labelString: '' }, ticks: { stepSize: 50, beginAtZero: true } }]
//}
};
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx, {
type: 'pie',
data: dataT,
options: opt
});
<script src="https://github.com/chartjs/Chart.js/releases/download/v2.7.1/Chart.min.js"></script>
<div Style="font-family: Corbel; font-size: small ;text-align:center " class="row">
<div style="width:100%;height:100%">
<canvas id="myChart" style="padding: 0;margin: auto;display: block; "> </canvas>
</div>
</div>
If you are still looking to use json for chart.js charts.
Here is a solution which fetch a json file and render it on chart.js chart.
fetch('https://s3-us-west-2.amazonaws.com/s.cdpn.io/827672/CSVtoJSON.json')
.then(function(response) {
return response.json();
})
.then(function(ids) {
new Chart(document.getElementById("bar-chart"), {
type: 'bar',
data: {
labels: ids.map(function(id) {
return id.Label;
}),
datasets: [
{
label: "value2",
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
data: ids.map(function(id) {
return id.Value2;
}),
},
{
label: "value",
//backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850"],
data: ids.map(function(id) {
return id.Value;
}),
},
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Sample Json Data Chart'
}
}
});
});
see running code on jsfiddle here
Wondering if anyone can help me out please.
I'm having trouble getting a Chart.js LineChart (with AJAX data) to refresh every "X" seconds. I've tried to put the code below in a function inside a setInterval and eventhough it does refresh, it redraws itself in a "zoomed-in" manner...
I want the chart to refresh itself every 10 seconds.
Code:
$.ajax({
type: "POST",
url: '#Url.Action("ChartRT")',
contentType: "application/json",
dataType: "json",
success:
function (chartsdata_RT) {
var aData = chartsdata_RT;
var aLabels = aData.map(c => c.Period);
var aDatasets1 = aData.map(c => c.FAILED);
var aDatasets2 = aData.map(c => c.OTHER);
var aDatasets3 = aData.map(c => c.DELIVERED);
var aDatasets4 = aData.map(c => c.PENDING);
var dataT = {
labels: aLabels,
datasets: [
{
label: "FAILED",
data: aDatasets1,
borderColor: '#ff0000',
backgroundColor: "rgba(255, 0, 0, 0.3)",
fill: 'true'
},
{
label: "OTHER",
data: aDatasets2,
borderColor: '#3366ff',
backgroundColor: "rgba(32, 162, 219, 0.3)",
},
{
label: "DELIVERED",
data: aDatasets3,
borderColor: '#009900',
backgroundColor: "rgba(0, 102, 0, 0.3)",
},
{
label: "PENDING",
data: aDatasets4,
borderColor: '#ff9900',
backgroundColor: "rgba(255, 153, 219, 0.3)",
}
]
};
var ctx = $("#chart_last2hours").get(0).getContext("2d");
ctx.canvas.height = "50";
var myNewChart = new Chart(ctx, {
type: 'line',
data: dataT,
options: {
legend: {
display: true,
position: 'right',
fullWidth: false,
labels: {
fontColor: '#484848',
fontsize: 10,
boxWidth: 20,
padding: 5,
lineWideth: 0
}
}
}
});
}
});
ended wrapping the above code in a function (drawChartRT). I then:
1) Call the function drawChartRT() to draw the LineChart.
2) Inside a setInterval remove and add the canvas and call the function drawChartRT().
drawChartRT();
setInterval(function () {
$("canvas#chart_last2hours").remove();
$("#chartdiv_rt").append('<canvas id="chart_last2hours" height="200"></canvas>');
var div = document.getElementById("chart_last2hours");
//console.log(div);
drawChartRT();
}, 10000);
Works like a charm!
Thanks. José