This is my data model:
data = [{y: 123, color: "#FF7600"}, {y: 321, color: "#00FFE3"}, {y: 213,color: "#444444"}]
Then the series is added to a pie chart:
$http({ method: 'GET', url: /pie-chart, params: {})
.success(function (data) {
chart.addSeries({
type: 'pie',
data: data
})
});
Here's the official highcharts demo: http://www.highcharts.com/demo/pie-gradient
It loops through data, read colors, creates color array and uses this array when drawing chart.
But i'm thinking about solution which avoids extracting colors from JSON.
Any idea? Thanks a lot.
Edited, solved
Gave it up :).
I ended up creating color arrays as described in highcharts demo.
It works well.
// Get colors from received data, create color array,
var colors = [];
for (var i = 0; i < data[0].series.length; i++) {
colors.push(data[0].series[i].color);
// Delete original colors, so that new radialized are used
delete(data[i].color);
}
// Use color array and radialize each color
Highcharts.getOptions().colors = Highcharts.map(colors, function(color) {
return {
linearGradient: { x1: 0, y1: 0, x2: 1, y2: 0 },
stops: [
[0, color],
[1, Highcharts.Color(color).brighten(-0.3).get('rgb')] // darken
]
};
});
The solution mentioned above sets the colors in the global defaults. This is okay if you have only one chart, but if you have multiple it can be problematic, as the colors will apply for all charts.
You can colorize this on the individual chart level by remapping the colors just in the local data array. Here is what I do for my pie charts.
chartData is an array of data like:
[
{
"color": "#01080f",
"name": "No Status",
"y": 8570
},
{
"color": "#1A942C",
"name": "Deployed",
"y": 27952
},
...
{
"color": "#f36e20",
"name": "Out of sync",
"y": 241
}
]
In my javascript code it is retrieved from the server and applied to the Highcharts object's series.data element.
Just manipulate that data element before you add it to the highcharts object.
// Retrieve your chart data
$.getJSON('/api/endpoint/policystatus', function (chartData) {
// Function replaces flat colors with gradients
function colorizeData(data) {
data.color = {
radialGradient: {cx: 0.5, cy: 0.3, r: 0.7},
stops: [
[0, data.color],
[1, Highcharts.Color(data.color).brighten(-0.3).get('rgb')] // darken
]
};
}
// Call the function for each element in the retrieved data
chartData.forEach(colorizeData);
// Continue on to build your chart
$('#pie-general-status').highcharts({
// ....
The above 'colorizeData' takes the chart data input, looks for the 'color' element, then replaces it with the Highcharts gradient based on the same color.
Note that you must use hex or RGB values; it will not work with colors defined as the words 'green' or 'blue'.
Related
Hi i am new to highcharts and facing a difficulty in getting a proper fixed column chart which deals with percentage values.
I would like:
But i am able to achieve:
You can format data labels using series.dataLabels.formatter callback. Check demo and code posted below.
Code:
series: [{
name: 'NSV',
color: 'rgba(165,170,217,1)',
data: [38891, 35098, 21296, 19345, 19092],
pointPadding: 0.3,
pointPlacement: -0.2
}, {
name: 'Margin',
color: 'rgba(126,86,134,.9)',
data: [8594.911, 6422.934, 5302.704, 580.35, 3417.468],
pointPadding: 0.4,
pointPlacement: -0.2,
dataLabels: {
formatter: function() {
var chart = this.series.chart,
percentage = (this.y / chart.series[0].points[this.point.index].y) * 100;
return percentage.toFixed(1) + '%';
}
}
}]
Demo:
http://jsfiddle.net/BlackLabel/pxLmjvkh/1/
API reference:
https://api.highcharts.com/highcharts/series.bar.dataLabels.formatter
I'm using Highcharts and initializing the data using;
var graph = Highcharts.chart('container', {
................
series: [{
color: 'red',
data: [[5, 2], [800, 2], [801, 1],[802, 3],[803, 2],[804, 2],[1200, 3]]
},
.............
}
The problem I have is when I want to add more data dynamically, after rendering the initial chart.
In this case I'm using the update;
graph.update(
{
series: [{
color: 'blue',
data: [[100, 2], [101, 2], [102, 1] ]
},
});
And this works but it replaces the entire data set.
So, how should I use the update() function to add points and not replace them?
I saw people are using other functions such as addPoint() and setData() but I couldn't make them work properly...
Thanks in advance
Gus
Refer to this live demo: http://jsfiddle.net/kkulig/opr4Lgpe/
I add all the points in a loop. redraw argument (second one) of the addPoint function is set to false - there's no need to redraw the chart after each addition. The redraw is performed only once in the end.
var chart = Highcharts.chart('container', {
series: [{
data: [1, 2]
}]
});
var pointsToAdd = [4, 5, 6, 6, 7];
pointsToAdd.forEach(function(p) {
chart.series[0].addPoint(p, false);
});
chart.redraw();
API reference:
https://api.highcharts.com/class-reference/Highcharts.Series#addPoint
I have a flask app in which I am using Highcharts to plot data, and if the user enters a lot of inputs for which he needs a graph, I plot multiple plot lines on the graph with different colors. But after 8-10 plot lines the color repeat and hence its not useful coz its not distinguishable.
<script type="text/javascript">
$('document').ready(function(){
window.seriesOptions = [];
window.yAxisOptions = [],
window.seriesCounter = 0,
window.colors = Highcharts.getOptions().colors;
generate_graph( {{ coordinates| safe }} , {{ graph_name | safe }} );
});
</script>
/*
Generate graph function takes two input parameters i.e. Coordinates - which is an array of [x, y] points AND graph_name which is an array of the (service_name,server_name) pair and generates
seriesOptions and calls createChart function.
*/
function generate_graph(coordinates, graph_name){
$.each(graph_name, function(i, name) {
window.seriesOptions[i]= {
name : graph_name[i],
data : coordinates[i],
type : 'line'
};
seriesCounter++;
if (seriesCounter == graph_name.length) {
createChart();
}
});
$('#add-to-dashboard-button').show();
}
/*
createChart function generates the actual graphs and sets the different properties of the graph.
*/
function createChart(){
$('#chart').highcharts('StockChart', {
chart: {
zoomType: 'x'
},
rangeSelector: {
selected: 4
},
xAxis: {
type: 'datetime',
labels: {
formatter: function() {
return Highcharts.dateFormat('%a %d %b', this.value);
}
}
},
title : {
text : 'Graph'
},
legend: {
enabled: true,
layout: 'vertical',
labelFormat: '<span style="color:{color}">{name}</span> - <b> x : ({point.x:.2f}) , </b> y : ({point.y:.2f}) <br/>',
maxHeight: 100
},
series : seriesOptions
});
}
</script>
How to make sure that every time a plot is generated its in a different unique color and hence distinguishable.
Also The tooltip doesn`t appear even though the data for x axis is sorted?
If you don't specify any colours when creating a chart or adding a series, highcharts will pick one from it's default colours. There are a limited number of defaults.
However, you can tell highcharts about a new set of default colours, so you could give it more to chose from, up to the maxumum you want to support. This code sets 9 defaults, but you can add as many as you want, you just need to come up with some unique colours:
Highcharts.setOptions({
colors:[
'#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4']
});
Make this the first thing you call.
I am new to Highcharts.
I have a line chart. Here is the categories:
["9/7/14", "9/8/14", "9/9/14", "9/10/14", "9/11/14", "9/12/14", "9/13/14", "9/14/14", "9/15/14", "9/16/14", "9/17/14", "9/18/14", "9/19/14", "9/20/14", ...]
Here is the data series:
[1, 4, 0, 2, 1, 1, 1, 5, 3, 1, 0, 0, 6, 8, ... ]
I added zoom to my chart, very similar to this jsfiddle demo: http://jsfiddle.net/348sh/3/
chart: {
renderTo: 'container',
zoomType: 'x'
},
I would like to get the total of only those Y values within the zoomed-in window, not the total of the entire data series. For this, I need to capture what values are included in the x axis in the zoomed window. So I added the following based on my research:
xAxis: {
type: 'line',
events: {
setExtremes: function(event) {
console.log(event.min);
console.log(event.max);
}
}
}
However, the values for event.min or event.max are numbers such as 3.6552511415525117, 7.10730593607306. I have no way to know which x values are included in the zoomed window. How can I find which x values are included? Any way to get the start and end x values ?
Thanks!
I did further research. I notice that I may have answered my question already in my question. It turns out that the numbers I gave in my question are very helpful, not clueless. Math.ceil(min) and Math.floor(max) are just the beginning and ending index of the data points in the data series that are show up in the zoomed window. The another thing to note is to use afterSetExtremes event. This is the moment where chart finalizes the starting and ending points in the X axis. So the complete answer is:
xAxis: {
type: 'line',
events: {
afterSetExtremes: function(event) {
var start = Math.ceil(event.min);
var end = Math.floor(event.max);
}
}
}
I am new to Highcharts and love to get corrected if I am wrong.
Cheers.
This may help you . Try this fiddle : http://jsfiddle.net/7kv9a25r/ .
chart: {
events: {
selection: function (event) {
var text,
label;
if (event.xAxis) {
text = 'min: ' + Highcharts.numberFormat(event.xAxis[0].min, 2) + ', max: ' + Highcharts.numberFormat(event.xAxis[0].max, 2);
} else {
text = 'Selection reset';
}
label = this.renderer.label(text, 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
},
zoomType: 'x'
},
Need a hand deciphering the Highcharts methodology please.
I have input data that is a lot of records with three fields (timestamp, min, max) that I'd like to generate a plot from. Goal is to have two lines, one with max-vs-time and the other with min-vs.time, both on that one plot.
I got an arearange to work (fiddle here) but if I change the plot type to spline, I just get one line graph with min vs. time (i.e., it ignores the last data parameter).
Same thing happens when I mess with the Highcharts arearange example, so I'm guessing that my series is not defined correctly, but I'm not deciphering the right terminology to figure out how to ask the question yet I guess. Any help appreciated....
// data is timestamp,min,max for the day
// - this currently plots only the min for each day
// - intent is two lines, one for min and one for max
var data = [
[1186124400000, 57.2, 75.6],
[1186210800000, 51.8, 74.7],
[1186297200000, 53.8, 74.8],
[1186383600000, 56.7, 72.7],
[1186470000000, 59.0, 76.1]
];
var options = {
chart: {
renderTo: 'container',
type: 'arearange'
},
title: {
text: 'historical temperatures'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: 'outsideTemp (F)'
}
},
legend: {
enabled: false
},
series: [{
legend: {
enabled: false
},
data: data
}]
};
$(document).ready(function () {
var chart1 = new Highcharts.Chart(options)
});
You need to create two separate series.
So this:
var data = [
[1186124400000, 57.2, 75.6],
[1186210800000, 51.8, 74.7],
[1186297200000, 53.8, 74.8],
[1186383600000, 56.7, 72.7],
[1186470000000, 59.0, 76.1]
];
Will need to be two separate arrays, each with a single y value, and the same x values:
var data1 = [
[1186124400000, 57.2],
[1186210800000, 51.8],
[1186297200000, 53.8],
[1186383600000, 56.7],
[1186470000000, 59.0]
];
var data2 = [
[1186124400000, 75.6],
[1186210800000, 74.7],
[1186297200000, 74.8],
[1186383600000, 72.7],
[1186470000000, 76.1]
];
Updated Fiddle:
http://jsfiddle.net/jlbriggs/5q5HJ/12/
If your x values are at consistent intervals, you can use the pointStart and pointInterval properties and skip specifying the x values
http://api.highcharts.com/highcharts#plotOptions.series.pointStart
http://api.highcharts.com/highcharts#plotOptions.series.pointInterval