Related
From the official documentation I can't get if it is possible for me to build a chart in the way I want.
Simple example of the initial data:
{
'Player1': {'item1': '50'},
'Player2': {'item1': '60', 'item2': '20'},
'Player3': {'item3': '40'}
}
It is like the 3 dimensions: Players/Items/Values.
I would like to build a chart with the column type.
X-Axis for the PlayerNames and Y-Axis for the Values.
The Items might be like the series-names so I can select them one by one and switch their visible option.
The issues - is that I don't get how to properly build the series and is that possible to bind their values between X-Y:
series: [{
name: 'item1',
data: [{x: 'Player1', y: 50}, {x: 'Player2', y: 60}],
visible: false
},
{
name: 'item2',
data: [{x: 'Player2', y: 20}],
visible: false
},
{
name: 'item3',
data: [{x: 'Player3', y: 40}],
visible: false
}
]
This would let me to show on the X-Axis only the colums that actually have the data. Without the empty space.
Can I achieve this somehow?
Thanks!
I was lucky to find the way how to do it:
First of all I should mention that x works only for the numbers:
x: number
Here is the way how to do it for string values:
xAxis: {
type: 'category',
},
And then just as:
series: [
{
name: 'item1',
data: [['Player1', 50], ['Player2', 75]],
visible: true
},
{
name: 'item2',
data: [['Player1', 25], ['Player3', 60], ['Player4', 40]],
visible: false
}
],
I am using the Javascript ECharts library for displaying some data in my Angular 2+ app. I see that all the examples have some configuration like the following:
{
xAxis: [
data: ['00:00', '01:15', '02:30', '03:45']
],
series: [
{ name: 'A', type: 'line', data: [300, 280, 250, 260] },
{ name: 'B', type: 'line', data: [200, 120, 700, 290] },
]
}
But my data does not always provide values for all the labels in the x axis. For example, I would need to fit these arrays of custom objects into the chart:
const series1 = [{ label: '00:00', value: 300 }, { label: '02:30', value: 120 }];
const series2 = [{ label: '03:45', value: 890} ];
Of course, I could manually insert null or empty values in all the series so that all of them provide a value for each label in the axis. But I believe there should be a more straightforward way to achieve this in ECharts, as it is quite simple in other chart libraries like Kendo Charts.
Assuming you are working with line chart, below is the solution, anyway it is not that different for other charts, just make sure your xAxis type is category
Your xAxis type should be set to category, and data should be something like this
xAxis: [
type: 'category'
data: [ {name: '00:00'}, ....]
]
your series data should look like this
//dimx , value
const series2 = [['03:45', 890]];
You can use the 'time' format to fit series with different lengths.
Even the series, in this way, can have different lengths.
const colors = ['#5470C6', '#EE6666'];
let option = {
color: colors,
xAxis: {
type: 'time',
splitNumber: 11,
axisLabel: {
rotate: 45,
formatter: { hour: '{hh} : {mm}' },
},
},
yAxis: {
type: 'value',
},
series: [
{
name: 'Precipitation(2015)',
type: 'line',
data: [
['2012-03-01T12:22:33.123', 2.2],
['2012-03-01T12:23:33.123', 5.6],
['2012-03-01T12:24:33.123', 7.9],
['2012-03-01T12:25:33.123', 9.0],
['2012-03-01T12:28:33.123', 7.9],
['2012-03-01T12:30:33.123', 9.0],
['2012-03-01T12:32:33.123', 26.4],
['2012-03-01T12:40:33.123', 28.7],
],
},
{
name: 'Precipitation(2016)',
type: 'line',
data: [
['2012-03-01T12:22:33.123', 2.2],
['2012-03-01T12:23:33.123', 5.6],
['2012-03-01T12:38:33.123', 26.4],
['2012-03-01T12:40:33.123', 28.7],
],
},
],
};
result
I tried to plot JSON data using JSON data.JSFiddle
Below is my JSON data in JavaScript.
var JSON = [
{ name:"Maintenance",
data:[[2017-06-26,1.5],
[2017-07-03,5.2],
[2017-07-10,1.65],
[2017-07-17,2.5],
[2017-07-24,1.5]
]
},
{ name:"Others",
data:[[2017-06-26,1.5],
[2017-07-03,1.5],
[2017-07-10,1.5],
[2017-07-17,1.25],
[2017-07-24,1.5]
]
},
{ name:"Project",
data:[[2017-06-26,6.5],
[2017-07-03,6.1],
[2017-07-10,6.7],
[2017-07-17,7],
[2017-07-24,6.5]
]
},
{ name:"Training",
data:[[2017-06-26,0],
[2017-07-03,0.75],
[2017-07-10,1.9],
[2017-07-17,0.5],
[2017-07-24,1]
]
},
{ name:"Day-Off",
data:[[2017-06-26,0],
[2017-07-03,0],
[2017-07-10,0],
[2017-07-17,0],
[2017-07-24,1]
]
}]
However, the chart looks strange. For every series, there is an additional line connecting the start point and the end point. In addition, the x-axis value is not the date that I want.
//Draw chart
Highcharts.chart('trend_bl', {
title: {
text: 'Trend by Business Lines'
},
yAxis: {
title: {
text: ' Resource Allocation'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
series : JSON,
});
Can anyone tell me why this would happen? In addition, I would also like to know the proper JSON data structure for line chart and pie chart in Highchart.
Your date in JSON should be string. This date should be converted to millisecond.
var JSON = [{
name: "Maintenance",
data: [
['2017-06-26', 1.5],
['2017-07-03', 5.2],
['2017-07-10', 1.65],
['2017-07-17', 2.5],
['2017-07-24', 1.5]
]
}, {
name: "Others",
data: [
['2017-06-26', 1.5],
['2017-07-03', 1.5],
['2017-07-10', 1.5],
['2017-07-17', 1.25],
['2017-07-24', 1.5]
]
}, {
name: "Project",
data: [
['2017-06-26', 6.5],
['2017-07-03', 6.1],
['2017-07-10', 6.7],
['2017-07-17', 7],
['2017-07-24', 6.5]
]
}, {
name: "Training",
data: [
['2017-06-26', 0],
['2017-07-03', 0.75],
['2017-07-10', 1.9],
['2017-07-17', 0.5],
['2017-07-24', 1]
]
}, {
name: "Day-Off",
data: [
['2017-06-26', 0],
['2017-07-03', 0],
['2017-07-10', 0],
['2017-07-17', 0],
['2017-07-24', 1]
]
}];
//updating jsons date to millisecond
Object.keys(JSON).map(function(key, index) {
JSON[key].data.map(function(value, keys, index) {
JSON[key].data[keys][0]=new Date(value[0]).getTime()
})
});
//console.log(JSON)
Fiddle Demo
First of all, you have made a mistake in your demo. Instead of data: JSON it should be series: JSON. Secondly, put your dates inside of strings, otherwise they will be treated as numbers (e.g. 2017 - 06 - 26 = 1985).
Example:
http://jsfiddle.net/3yumsp8m/
I'm creating charts using Chart.js and I want to show the labels for the bars in the legend, not the title of the dataset (there is only one), please see the below image as an example:
My current legend just looks like this:
I have looked through the docs but to no avail, I found them very confusing actually.
Here is my current code:
var chart_0 = new Chart($('#cp_chart_0'), {
type: 'bar'
, data: {
labels: ['Blue','Green','Yellow','Red','Purple','Orange']
, datasets: [{
label: 'Dataset 1'
, borderWidth: 0
, backgroundColor: ['#2C79C5','#7FA830','#7B57C3','#ED4D40','#EC802F','#1DC6D3']
, data: ['12','2','5','0','9','1']
}]
}
});
Thanks!
In one of the most recent releases of Chart.js 2.1.x, they added back this functionality. So go get the latest release first. Then insert the code below.
It is located under the options and legend. Here is how you use it:
options: {
legend: {
position: 'right'
}
}
Easiest way is to provide your data with multiple sets :
data: {
labels: ['total votes']
, datasets: [{
label: 'Blue'
, backgroundColor: ['#2C79C5']
, data: ['12']
},{
label: 'Green'
, backgroundColor: ['#7FA830']
, data: ['2']
},
...
]
}
But you can generate a custom labels using generateLabels - http://www.chartjs.org/docs/#chart-configuration-legend-configuration
Or even customise the whole legend, including formatting, with legendCallback - http://www.chartjs.org/docs/#chart-configuration-common-chart-configuration
This solution uses Chart.js version 3. You can pre-process your data using the Plugin Core API. The API offers different hooks that may be used for executing custom code.
I use the beforeInit hook to create individual datasets for each defined label/value pair. Note that the data of these new datasets are defined in point format (for instance [{ x: 1, y: 12 }]):
beforeInit: chart => {
let dataset = chart.config.data.datasets[0];
chart.config.data.datasets = chart.config.data.labels.map((l, i) => ({
label: l,
data: [{ x: i + 1, y: dataset.data[i] }],
backgroundColor: dataset.backgroundColor[i],
categoryPercentage: 1
}));
chart.config.data.labels = undefined;
}
Further you need to define a second x-axis that will contain the labels.
x1: {
offset: true,
gridLines: {
display: false
}
}
The labels on x1 need to be collected and defined programmatically each time the hidden state of a dataset changes. This can be done in the beforeLayout hook.
beforeLayout: chart => chart.options.scales.x1.labels = chart.config.data.datasets.filter((ds, i) => !chart.getDatasetMeta(i).hidden).map(ds => ds.label)
Please take a look at below runnable code and see how it works.
new Chart('chart', {
type: 'bar',
plugins: [{
beforeInit: chart => {
let dataset = chart.config.data.datasets[0];
chart.config.data.datasets = chart.config.data.labels.map((l, i) => ({
label: l,
data: [{ x: i + 1, y: dataset.data[i] }],
backgroundColor: dataset.backgroundColor[i],
categoryPercentage: 1
}));
chart.config.data.labels = undefined;
},
beforeLayout: chart => chart.options.scales.x1.labels = chart.config.data.datasets.filter((ds, i) => !chart.getDatasetMeta(i).hidden).map(ds => ds.label)
}],
data: {
labels: ['Blue', 'Green', 'Yellow', 'Red', 'Purple', 'Orange'],
datasets: [{
data: ['12', '2', '5', '0', '9', '1'],
backgroundColor: ['#2C79C5', '#7FA830', '#FFF200', '#ED4D40', '#800080', '#EC802F']
}]
},
options: {
interaction: {
intersect: true,
mode: 'nearest'
},
plugins: {
legend: {
position: 'right'
},
tooltip: {
callbacks: {
title: () => undefined
}
}
},
scales: {
y: {
beginAtZero: true
},
x: {
display: false
},
x1: {
offset: true,
gridLines: {
display: false
}
}
}
}
});
canvas {
max-width: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.min.js"></script>
<canvas id="chart" height="120"></canvas>
I have a series of high and low temperatures that I would like to display in a column range chart with Highcharts.
I would specifically like a chart like the one shown in the demo example at: http://www.highcharts.com/stock/demo/columnrange
I have placed my data in a file called datatest.json, and it contains this text:
[
[1230771600000, -5.8, 10.1],
[1230858000000, -4.1, 1.4],
[1230944400000, -0.5, 4.1],
[1231030800000, -8.9, -0.7],
[1231117200000, -9.7, -3.7],
[1231203600000, -3.4, 3.2],
[1231290000000, -3.9, -0.2],
[1231376400000, -2.4, 6.7],
[1231462800000, 3.8, 6.9],
[1262221200000, -12.2, -6.5]
]
When I load the data from the file, it doesn't give me a chart. For example, with this:
$(function () {
$.getJSON('data/datatest.json', function (data) {
$('#container').highcharts('StockChart', {
chart: {
type: 'columnrange'
},
rangeSelector: {
selected: 2
},
title: {
text: 'Temperature variation by day'
},
tooltip: {
valueSuffix: '°C'
},
series: [{
name: 'Temperatures',
data: data
}]
});
});
});
But if I put the data directly into my code (as follows), it does display the chart as I expect:
$(function () {
$('#container').highcharts('StockChart', {
chart: {
type: 'columnrange'
},
rangeSelector: {
selected: 2
},
title: {
text: 'Temperature variation by day'
},
tooltip: {
valueSuffix: '°C'
},
series: [{
name: 'Temperatures',
data: [
[1230771600000, -5.8, 10.1],
[1230858000000, -4.1, 1.4],
[1230944400000, -0.5, 4.1],
[1231030800000, -8.9, -0.7],
[1231117200000, -9.7, -3.7],
[1231203600000, -3.4, 3.2],
[1231290000000, -3.9, -0.2],
[1231376400000, -2.4, 6.7],
[1231462800000, 3.8, 6.9],
[1262221200000, -12.2, -6.5]
]
}]
});
});
I think that I am either formatting the data incorrectly in my data file, or that I'm not reading from the file in the proper way.
Any suggestions or guidance to help me get on the right track would be much appreciated.
Credit to #SebastianBochan for directing my attention to the fact that my JSON was not valid.
Here is an abbreviated clip of what the correctly formatted JSON looks like:
{
"data":
[
[1420640460000,36.7,37.25],
[1420640520000,37.19,37.74],
[1420640580000,37.74,38.6],
[1420640640000,38.72,39.33],
[1420640700000,39.33,39.51]
]
}
I used a JSON validator: http://jsonformatter.curiousconcept.com/
It didn't matter whether I called it "data" or "temperature" It just had to be a string, and then when I referenced it, I needed to be sure to reference it as data.data. If I had called it "temperature" then it would have been data.temperature. In any case, here is the bit of code:
series: [{
data: data.data
}]