I have the following array:
Where the arrays keys are the dates and the only element I want to plot, of each set, is the weight. Look:
I am putting the code as follows. Notice that I am already grouping in the date attribute the whole set belonging to each that key.
var ctx = document.getElementById("barChart").getContext("2d");
var data = {
labels: ['21/03/2018','01/04/2018','02/04/2018','04/04/2018','05/04/2018','06/04/2018'],
datasets: [
{
label: '21/03/2018',
data: [12, 0, 0]
},
{
label: '01/04/2018',
data: [15.00, 15.00,15.00]
},
{
label: '02/04/2018',
data: [25.00, 25.00, 25.00]
},
{
label: '04/04/2018',
data: [25.00, 25.00, 25.00]
},
{
label: '05/04/2018',
data: [-8.14,-7.93, -7.84]
},
{
label: '06/04/2018',
data: [-35.9 ,-38.1, -37.5]
},
]
};
var myBarChart = new Chart(ctx, {
type: 'bar',
data: data,
});
But in this way ChartJs does not understand that it only needs to plot the data set present in the "data" attribute and grouping them by the key. Plotting the graph in the wrong way.
How could I plot the data correctly knowing that they are already grouped?
You need to organize your data as such:
var ctx = document.getElementById("canvas").getContext("2d");
var data = {
labels: ['21/03/2018','01/04/2018','02/04/2018','04/04/2018','05/04/2018','06/04/2018'],
datasets: [
{
data: [12, 15.00, 25.00, 25.00, -8.14, -35.9]
},{
data: [0, 15.00, 25.00, 25.00, -7.93, -38.1]
},{
data: [0, 15.00, 25.00, 25.00, -7.84, -37.5]
}
]
};
var myBarChart = new Chart(ctx, {
type: 'bar',
data: data,
options:{
legend: 'none'
}
});
I took your legend out as it's useless in this case. To look at it in the coding persepective, whatever index the date in labels is at needs to correlate with the index of the information you want to display in that grouping. data[0] refers to labels[0] and so on.
Related
So Im trying to find an smart way to pass data with dates to chart.js.
On the x-axis i would like to show a time line for example a week,
14/06 15/06 16/06 17/06 18/06 19/06 20/6
But the data will not inculde every day
for example
[{'date': 15/06, 'bought': 2}, {'date': 17/06, 'bought': 5}]
for what I read, I would need to create a new array (same index number as the time period), compare the dates and replace the value depending on the index value...
Is there a better process?
I would like to show a time period for like a year.
LeeLenalee's perfectly shows how Chart.js is instructed to correctly parse your data. In order to obtain a time line, you'll also need to define the x-axis as a time cartesian axis.
Please take a look at below runnable code and see how it works.
new Chart('myChart', {
type: 'line',
data: {
datasets: [{
label: 'Purchases per day',
data: [
{ 'date': '15/06', 'bought': 2 },
{ 'date': '17/06', 'bought': 5 },
{ 'date': '20/06', 'bought': 3 }
],
borderColor: 'rgb(0, 0, 255)',
backgroundColor: 'rgba(0, 0, 255, 0.5)'
}]
},
options: {
parsing: {
xAxisKey: 'date',
yAxisKey: 'bought'
},
scales: {
y: {
ticks: {
stepSize: 1
}
},
x: {
type: 'time',
time: {
parser: 'DD/MM',
unit: 'day',
tooltipFormat:'MMM DD'
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.3.2/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment#2.27.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#0.1.1"></script>
<canvas id="myChart" height="90"></canvas>
You can just provide that array as is to chart.js, you only need to specify which field should be mapped to the x Axis and which field to the yAxis in the parsing block of the options object.
Live example:
var options = {
type: 'line',
data: {
datasets: [
{
label: '# of Votes',
data: [{'date': '15/06', 'bought': 2}, {'date': '17/06', 'bought': 5}, {'date': '20/06', 'bought': 3}],
borderWidth: 1
}
]
},
options: {
parsing: {
xAxisKey: 'date',
yAxisKey: 'bought'
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.3.2/chart.js"></script>
</body>
I am creating a combination chart taking data from a database. I am able to import all the data and render it in single type i.e. Column. There is one series though which I want to render in spline type. The tutorial I am following only teaches about rendering in a single type, so I am kind of lost here.
This is my JavaScript
$(document).ready(function(){
var options = {
chart: {
renderTo: 'fetch-render',
type: 'column',
},
xAxis: {
title: {
text: 'Date'
},
categories: []
},
yAxis: {
title: {
text: 'Number'
},
series: []
}
$.getJSON("includes/fetch-data.php", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
options.series[1] = json[2];
/*so on...... */
options.series[7] = json[8];
/* i want to draw this series in spline */
options.series[8] = json[9];
chart = new Highcharts.Chart(options);
});
})
I want to draw data from series 8 as a spline unlike others which are drawn in column type
Highcharts Demos have all kinds of demos of using Highcharts. One of them shows how to draw different types of series in the same chart: http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/combo/
Basically, instead of defining the type on the chart object like you did, you will set the type for each series on your series object:
series: [{
type: 'column',
name: 'Jane',
data: [3, 2, 1, 3, 4]
}, {
type: 'column',
name: 'John',
data: [2, 3, 5, 7, 6]
}, {
type: 'column',
name: 'Joe',
data: [4, 3, 3, 9, 0]
}, {
type: 'spline',
name: 'Average',
data: [3, 2.67, 3, 6.33, 3.33],
marker: {
lineWidth: 2,
lineColor: Highcharts.getOptions().colors[3],
fillColor: 'white'
}
}
Thanks for the heads up by #João Menighin . i adopted the method given in this demo. its neater, cleaner and can be used to add as many chart types as needed. here is the code for someone else who wants to make a combined chart taking data from the database.
$(document).ready(function(){
$.getJSON("includes/fetch-data.php", function(json){
Highcharts.chart('fetch-render', {
title: {
text: 'Fetched Data'
},
xAxis: {
categories: json[0]['data']
},
series: [{
type: json[1]['type'],
name: json[1]['name'],
data: json[1]['data']
}, {
type: json[2]['type'],
name: json[2]['name'],
data: json[2]['data']
}, {
type: json[3]['type'],
name: json[3]['name'],
data: json[3]['data']
},{
type: json[4]['type'],
name: json[4]['name'],
data: json[4]['data']
}, {
type: json[5]['type'],
name: json[5]['name'],
data: json[5]['data']
}, {
type: json[6]['type'],
name: json[6]['name'],
data: json[6]['data']
}, {
type: json[7]['type'],
name: json[7]['name'],
data: json[7]['data']
},{
type: json[8]['type'],
name: json[8]['name'],
data: json[8]['data']
},{
type: json[9]['type'],
name: json[9]['name'],
data: json[9]['data']
}],
});
})
})
And i have set the chart types in fetch-data.php like this
$date = array();
$date['name'] = 'Date';
$blank=array();
$blank['name'] = 'Blank';
$blank['type'] = 'column';
$direct=array();
$direct['name'] = 'Direct';
$direct['type'] = 'area';
$checked_in=array();
$checked_in['name'] = 'Checked In';
$checked_in['type'] = 'column';
$conf=array();
$conf['name'] = 'Conf';
$conf['type'] = 'column';
$gdf=array();
$gdf['name'] = 'GDF';
$gdf['type'] = 'column';
$gdp=array();
$gdp['name'] = 'GDP';
$gdp['type'] = 'column';
$gtn=array();
$gtn['name'] = 'GTN';
$gtn['type'] = 'column';
$prov=array();
$prov['name'] = 'PROV';
$prov['type'] = 'column';
$enquire=array();
$enquire['name'] = 'ENQUIRE';
$enquire['type'] = 'spline';
I'm a complete newb with js and jquery but have muddled my way through getting a chart to properly display using Flask and an Ajax request. Where I'm having a problem is getting the charts data to refresh. I can get the chart to display just fine if I create it as a new chart as shown in the code below
$(document).ready(function() {
var getdata = $.post('/charts');
var ctx = document.getElementById('myChart').getContext('2d');
var myChart
getdata.done(function(results){
var chartData = {
labels: results['month'],
datasets: [{
label: 'Debits',
data: results['debit'],
backgroundColor: "rgba(153,255,51,0.4)"
}, {
label: 'Credits',
data: results['credit'],
backgroundColor: "rgba(255,153,0,0.4)"
}, {
label: 'Balance',
data: results['balance'],
backgroundColor: "rgba(50,110,0,0.4)"
}]
}
myChart = new Chart(ctx, {type: 'line', data: chartData});
});
$("form :input").change(function() {
year = $(this).val();
console.log(year)
$.ajax({
type: "POST",
url: "/data",
data: {'year':year},
success: function(results){
var updatedData = {
labels : results['month'],
datasets : [{
label: 'Debits',
data: results['debit'],
backgroundColor: "rgba(153,255,51,0.4)"
}, {
label: 'Credits',
data: results['credit'],
backgroundColor: "rgba(255,153,0,0.4)"
}, {
label: 'Balance',
data: results['balance'],
backgroundColor: "rgba(50,110,0,0.4)"
}]
}
myChart= new Chart(ctx, {type: 'line', data: updatedData});
}
});
});
});
But if I change the last line to
myChart.update(updatedData)
nothing happens, I don't get any errors, the chart doesn't update. Nothing. The strange thing is that I know the myChart is global because I don't have to create it again after the Ajax request.
Thanks
From the documentation of charts.js (http://www.chartjs.org/docs/#getting-started-creating-a-chart), you first need to change data and then call update (arguments for update function are not the data, but duration etc.):
.update(duration, lazy)
Triggers an update of the chart. This can be safely called after replacing the entire data object. This will update all scales, legends, and then re-render the chart.
// duration is the time for the animation of the redraw in milliseconds
// lazy is a boolean. if true, the animation can be interrupted by other animations
myLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
myLineChart.update(); // Calling update now animates the position of March from 90 to 50.
So in your case:
myChart.data = updatedData;
myChart.update();
I have this example from chart.js docs:
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Item 1', 'Item 2', 'Item 3'],
datasets: [
{
type: 'bar',
label: 'Bar Component',
data: [10, 20, 30],
},
{
type: 'line',
label: 'Line Component',
data: [30, 20, 10],
}
]
}
});
It works fine. However, my intention is to change the type dynamically.
I am aware that there is getDatasetMeta() method, that you can apply to your chart instance, and if I output the result it returns to the console I get something like this:
{
bar: true,
controller: ChartElement,
data: Array[...],
dataset: null,
hidden: false,
type: 'bar',
...
}
I can control the appearance of a certain dataset via hidden property, though if I change type to line and invoke update() it won't re-render.
So, is there a way to dynamically change dataset type?
Found a workaround here: Chart.js: Dynamic Changing of Chart Type (Line to Bar as Example)
Sad that it's not yet supported officially.
EDIT:
So now I have a chart with all my data pushed off to the right, BUT I have labels in different colors for the sets I want to show but no data?? Updated my code
Original post:
I have a working highchart here http://opensourcesurf.com/chart.html . The problem is when I try and change the color of an individual data set, they all change. How could I change these settings given my code? Thanks in advance!
code:
var options1 = {
chart: {
renderTo: 'container1',
type: 'area'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'Swell Period',
color: '#0066FF',
data: 'newSeriesData',
},
{ name: ' Maximum Breaking Wave Height',
color: '#ffffff',
data: 'newSeriesData',
},
{ name: 'Swell Height',
color: '#123456',
data: 'newSeriesData',
}],
};
var drawChart = function(data, name, color) {
var newSeriesData = {
name: name,
data: data
};
// Add the new data to the series array
options1.series.push(newSeriesData);
// If you want to remove old series data, you can do that here too
// Render the chart
var chart = new Highcharts.Chart(options1);
};
$.getJSON('decode.php', function(data){
drawChart(data, 'Swell Height');
});
$.getJSON('decode2.php', function(data){
drawChart(data, ' Maximum Breaking Wave Height');
});
$.getJSON('decode3.php', function(data){
drawChart(data, 'Swell Period');
});
Try this:
// 'series' is an array of objects with keys:
// - 'name' (string)
// - 'data' (array)
// - 'color' (HTML color code)
var newSeriesData = {
name: name,
data: data,
color: color
};
The way to specify a color for a specific series is to define it when you're defining the series. For example:
series: [{
name: 'John',
color: '#0066FF',
dashStyle: 'ShortDash',
data: [
[Date.UTC(2010, 0, 1), 29.9],
[Date.UTC(2010, 2, 1), 71.5],
[Date.UTC(2010, 3, 1), 106.4]
]
},
So essentially when you're creating your series in your drawchart function, do a check for the name, and appropriately assign a color:
var color;
if(name=="Swell Height"){
color="#0066FF";
}else if(name=="Maximum Breaking Wave Height"){
color="#0066EE";
}else if(name=="Swell Period"){
color="#0066HH";
}
var newSeriesData = {
name: name,
data: data,
color: color
};
It looks to me like you are not looping through the array of data and/or you only have one set of data in data.