I am developing bar chart using Highchart library.I created two y axis, first is for TAM and second for Share.Share is in percentage while TAM is not.For the Share y-axis value, I made the maximum value is 100 and it fixed, but for TAM the value is dynamic.
Referring to the graph
[http://jsfiddle.net/unidha/vGVRb/45/][1]
There a requirement to make Share bar height to depend on the Tam bar height. For example, currently Tam one is 12,300,000 unit and share one is 70% .Based on the graph, Share One is taller than Tam One because it has it's own axis.Now how I want to make the Share One's height is 70% from Tam One 's bar height?
Is it possible to do that?As my understanding for all this time, the bar height should be determined by the y-axis NOT based on other bar height.In case got solution for such requirement, what possibility it should be?
Here the same code that reside in above jsfiddle for your reference.
$(function () {
$('#container').highcharts({
chart: {
type:'column',
zoomType: 'xy',
alignTicks:false
},
title: {
text: 'Performance Snapshot'
},
xAxis: [{
categories: ['Tam One Share One ', ' Tam Two Share Two '],
//NUR
tickWidth:0
}],
yAxis: [{ // Primary yAxis
labels: {
// format: '{value}%',
style: {
// color: '#89A54E'
color: 'FFFFFF'
},
//NUR
step:2,
y:0
} ,
min: 0,
minRange:0.1,
max:100,
title: {
text: 'Share',
style: {
// color: '#89A54E'
color: '#4572A7'
}
}
}, { // Secondary yAxis
title: {
text: 'Tam',
style: {
color: '#4572A7'
}
},
labels: {
//NUR format: '{value} unit',
style: {
color: '#4572A7'
}
},
opposite: true
}],
tooltip: {
shared: true
},
series: [{
name: 'Tam Unit',
color: '#4572A7',
type: 'column',
yAxis: 1,
data: [12300000, 34400000],
tooltip: {
valueSuffix: ' unit'
},
groupPadding: 0
}, {
name: 'Share',
color: '#89A54E',
type: 'column',
data: [70,40],
tooltip: {
valueSuffix: '%'
},
groupPadding: 0
}]
});
});
Thanks
You can do this, but you need to pass series data as calculated values, not percent, for example: http://jsfiddle.net/vGVRb/48/
tooltip: {
shared: true,
formatter: function () {
var s = this.x,
points = this.points,
len = points.length;
for (var i = 0; i < len; i++) {
var p = points[i];
console.log(p);
s += '<br><span style="color:' + p.series.color + '">' + p.series.name + '</span><span>: ' + p.point.label + '</span>';
}
return s;
}
},
series: [{
name: 'Tam Unit',
color: '#4572A7',
type: 'column',
data: [{
y: 12300000,
label: '12300000 units'
}, {
y: 34400000,
label: '34400000 units'
}],
groupPadding: 0
}, {
name: 'Share',
color: '#89A54E',
type: 'column',
data: [{
y: 12300000 * 0.7,
label: '70%'
}, {
y: 34400000 * 0.4,
label: '40%'
}],
groupPadding: 0
}]
You can observe 'label' property under data, which is used later in tooltip.formatter to make sure you will display proper tooltip. Also, values are calculated accordingly to percentage in label.
Related
I am using Highcharts to create a column chart with two data points. There's only one series. I am using styling to make each column a different color, but I would also like to add a background image behind each column. I've tried using pattern fill, but it repeats the image for the whole area of the column, whereas I just need a single 30x30 image at the bottom of each column. I also tried using chart.renderer.image to add the svg image and managed to position it well, but can't make the image responsive (chart will be viewed on tablets and mobile devices in addition to computer screens).
My chart details are below:
const categoryColors = {
'cat1': '#ff9800',
'cat2': '#8256ce'
};
Highcharts.chart('gap_bar_chart', {
chart: {
type: 'column'
},
title: {
text: null
},
xAxis: {
categories: ['cat1','cat2'],
labels: {
useHTML: true,
formatter: function () {
console.log(this);
return '<span style="color: ' +categoryColors[this.value] + '">'+this.value+'</span>';
}
},
},
yAxis: {
min: 0,
title: {
useHTML: true,
text: '<b>Percent Earning Junior Status</b>'
},
labels: {
format: "{value} %"
},
lineWidth: 0,
minorGridLineWidth: 0,
gridLineWidth: 0,
lineColor: 'transparent'
},
tooltip: {
headerFormat: '<table><tr><th>Percent of Students Earning Junior Status within 2 Years</th></tr><tr><th><hr/></th></tr>',
pointFormat: '<tr><td><b>{point.name}</b>: {point.y: .0f}% ({point.numberStr} students)</td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
legend: {
enabled: false
},
series: [{
data: [
{
y: chartData.p_jun2yr_nongap*100 || 0,
total: chartData.n_jun2yr_nongap,
color: '#FCCA7D',
category: 'Non-URM',
name: 'Non-URM',
numberStr: chartData.n_jun2yr_nongap.toLocaleString()
},
{
y: chartData.p_jun2yr_gap*100 || 0,
total: chartData.n_jun2yr_gap,
color: '#9675CF',
category: 'cat2',
name: 'cat2',
numberStr: chartData.n_jun2yr_gap.toLocaleString()
}
]
}]
});
Here is what I would like to accomplish: https://imgur.com/a/oTG34G6
In render event you can use Highcharts.SVGRenderer.image to add the image and make its position and size dynamically dependent on the column:
events: {
render: function() {
var chart = this,
shape,
points = this.series[0].points;
if (chart.customImages) {
chart.customImages.forEach(function(el) {
el.destroy();
});
chart.customImages.length = 0;
} else {
chart.customImages = [];
}
points.forEach(function(p) {
shape = p.shapeArgs;
chart.customImages.push(
chart.renderer.image(
'https://www.highcharts.com/samples/graphics/sun.png',
shape.x + chart.plotLeft + shape.width / 2 - shape.width / 2,
shape.y + chart.plotTop + shape.height - shape.width,
shape.width,
shape.width
).attr({
zIndex: 3
}).add()
);
});
}
}
Live demo: http://jsfiddle.net/BlackLabel/eLwv9ruh/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#image
Im trying to make this chart have multiple Y Axes, all of which have different values and tick intervals. Like Signal Strength be on a scale of 0%-100%, Temperature 0F-100F and Main Power be 0V to 25V but cant seem to figure it out. Here's my jFiddle:
http://jsfiddle.net/0k5k8ygz/
Code:
function createChart() {
Highcharts.stockChart('container', {
rangeSelector: {
selected: 4
},
yAxis: [{ // Primary yAxis
labels: {
format: '{value}°F',
style: {
color: Highcharts.getOptions().colors[2]
}
},
title: {
text: 'Temperature',
style: {
color: Highcharts.getOptions().colors[2]
}
},
opposite: true
}, { // Secondary yAxis
gridLineWidth: 0,
title: {
text: 'Main Power',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '{value} volts',
style: {
color: Highcharts.getOptions().colors[0]
}
}
}, { // Tertiary yAxis
gridLineWidth: 0,
title: {
text: 'Signal Strength',
style: {
color: Highcharts.getOptions().colors[1]
}
},
labels: {
format: '{value} %',
style: {
color: Highcharts.getOptions().colors[1]
}
},
opposite: true
}],
plotOptions: {
series: {
compare: 'percent',
showInNavigator: true
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2,
split: true
},
series: seriesOptions
});
}
$.each(names, function(i, name) {
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=' + name.toLowerCase() + '-c.json&callback=?', function(data) {
seriesOptions[i] = {
name: name,
data: data
};
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter += 1;
if (seriesCounter === names.length) {
createChart();
}
});
});
If you add some data to each of the y-axes, they will get tick marks automatically. You assign data to a specific y-axis using the series.yAxis index:
seriesOptions[i] = {
name: name,
data: data,
yAxis: i,
};
If you also want to specify a valid range for the y-axes, you can set min and max on each individual axis:
...
labels: {
format: '{value} volts',
},
min: 0,
max: 25,
...
http://jsfiddle.net/0k5k8ygz/5/
I am trying to finalize a graph where I report the daily production within a month and a couple of other daily based series. The graph is always set at full scale, meaning that I always show all the days within a month, even if I do not have values for them, whichever is the reason why. On the first day of each month, I display the graph of the previous month, as a report.
This is the jfiddle I've set up so that you can have an idea. The problem I've been fighting against is that, whatever I try to do, Highcharts simply ignores me and displays wrong labels on x axis. So the days start from 2, go throughout the whole month to the last and they end with 1.
This is the code for my chart:
$(function() {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'tab-month-graph',
zoomType: 'xy'
},
title: {
text: 'Daily - August 2015'
},
xAxis: {
type: 'datetime',
tickInterval: 24 * 3600 * 1000,
labels: {
align: 'center',
text: 'Giorni',
style: {
fontSize: '10px',
fontFamily: 'Verdana, sans-serif'
}
},
dateTimeLabelFormats: {
day: '%e'
}
},
yAxis: [{ // Primary yAxis
title: {
text: 'Produzione giornaliera',
style: {
color: Highcharts.getOptions().colors[1]
}
}
},
{ // Secondary yAxis
title: {
text: 'PR giornaliero',
style: {
color: Highcharts.getOptions().colors[0]
}
},
min: 0,
startOnTick: false,
opposite: true
}],
legend: {
enabled: false
},
series: [{
name: 'Prod.',
type: 'column',
data: [[1438466230000, 4603.36],[1438552630000, 4264.92],[1438639030000, 3108.05],[1438725430000, 2047.03],[1438811830000, 2270.39],[1438898230000, 2258.2],[1438984630000, 3971.95],[1439071030000, 3784.45],[1439157430000, 3674.53],[1439243830000, 3131.95],[1439330230000, 1963.13],[1439416630000, 3333.52],[1439503030000, 4161.8],[1439589430000, 4408.59],[1439675830000, 2968.83],[1439762230000, 2808.05],[1439848630000, 4439.77],[1439935020000, 3746.48],[1440021430000, 4980],[1440107830000, 3683.91],[1440194230000, 4480.78],[1440280630000, 4406.48],[1440367030000, 4518.98],[1440453430000, 4492.73],[1440539830000, 3924.14],[1440626230000, 4062.89],[1440712630000, 3225.47],[1440799030000, 3213.75],[1440885430000, 4631.95],[1440971830000, 4471.17],[1441058230000, 4223.91]],
color: '#89CE7F',
dataLabels: {
enabled: true,
rotation: -90,
color: '#000000',
align: 'right',
x: 4,
y: 10,
style: {
fontSize: '11px',
fontFamily: 'Verdana, sans-serif',
textShadow: '0 0 3px black'
}
}
},
{
name: 'PR',
type: 'spline',
yAxis: 1,
lineWidth: 0,
marker: {
radius: 6
},
data: [[1438466230000, 73.36],[1438552630000, 75.08],[1438639030000, 57.54],[1438725430000, 38.85],[1438811830000, 39.14],[1438898230000, 63.78],[1438984630000, 76.03],[1439071030000, 75.78],[1439157430000, 77.61],[1439243830000, 79.74],[1439330230000, 77.35],[1439416630000, 73.98],[1439503030000, 75.79]],
color: '#AA0000',
tooltip: {
valueSuffix: ' %'
}
},
{
name: 'PR Cont.',
type: 'spline',
yAxis: 1,
lineWidth: 0,
marker: {
radius: 5,
symbol: 'circle'
},
data: [[1438466230000, 78.84],[1438552630000, 79.85],[1438639030000, 75.16],[1438725430000, 59.15],[1440971830000, 78.5],[1441058230000, 78.45]],
color: '#BBBB00',
tooltip: {
valueSuffix: ' %'
}
}
],
tooltip: {
xDateFormat: '%A, %d %B %Y',
valueSuffix: ' kW',
shared: true // LEGENDA CONDIVISA
},
plotOptions: {
series: {
pointStart: Date.UTC(2015, 7, 1),
pointRange: 24 * 3600 * 1000
}
}
});
});
I've read tons of posts on Stack Overflow, tried tons of suggestions, I've even tried this post tinyurl.com/psbzxeh on HighCharts official forum which is referred to a similar problem, but it did not solve my issue.
Could someone point me out to the right solution?
Just to clarify things: columns look like translated by one day, because of that time (21:57:10 UTC) - which is almost another day (without UTC it's 23:57:10 for GMT+2:00). In general, if you have daily data, then it's better to use 00:00:00 as this is when exactly date starts. Manipulating JSON shouldn't be that hard, see:
function modify(data) {
var time;
data.map(function(e) {
time = new Date(e[0]);
time.setUTCHours(0);
time.setUTCMinutes(0);
time.setUTCSeconds(0);
e[0] = time.getTime();
return e;
});
return data;
}
And:
series: [{
name: 'Prod.',
type: 'column',
data: modify([
[1438466230000, 4603.36],
...
])
}]
Demo: http://jsfiddle.net/p7vnqmt7/3/
Note: to remove extra tick at the last place on the axis, you can simply set xAxis.max.
And to answer question in the comment: no, pointInterval shouldn't be used when you have data as x-y pair.
try below function above your highchart function and set xAxis min and max.
Use very first timestamp(date) as min and last timestamp(date) as max value.
$( function () {
Highcharts.setOptions( {
lang : {
rangeSelectorZoom : ' '
},
global : {
useUTC : false
}
} );
} );
With HighCharts 3.0, it is now possible to indicate to colors above and below one threshold. Like this example :
http://jsfiddle.net/highcharts/YWVHx/
Following code :
$(function () {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=range.json&callback=?', function(data) {
$('#container').highcharts({
chart: {
type: 'arearange'
},
title: {
text: 'Temperature variation by day'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: null
}
},
tooltip: {
crosshairs: true,
shared: true,
valueSuffix: '°C'
},
legend: {
enabled: false
},
series: [{
name: 'Temperatures',
data: data,
color: '#FF0000',
negativeColor: '#0088FF'
}]
});
});
});
Is it possible to have another threshold with a third color, like this for example :
Thanks in advance for your help.
It actually is possible if you don't mind plotting the data twice.
$('#container').highcharts({
chart: {
type: 'arearange'
},
title: {
text: 'Temperature variation by day'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: null
}
},
tooltip: {
crosshairs: true,
shared: true,
valueSuffix: '°C'
},
legend: {
enabled: false
},
series: [{
name: 'Temperatures',
threshold : 0,
data: data,
color: 'orange',
negativeColor: 'blue'
},
{
name: 'Temperatures',
threshold : 10,
data: data,
color: 'red',
negativeColor: 'transparent'
}]
});
});
http://jsfiddle.net/YWVHx/97/
A feature to solve this without "hacks" was added in Highcharts 4.1.0 (February 2015), called zones (API). The given problem can be solved like this, using zones:
plotOptions: {
series: {
zones: [{
value: 0, // Values up to 0 (not including) ...
color: 'blue' // ... have the color blue
},{
value: 10, // Values up to 10 (not including) ...
color: 'orange' // ... have the color orange
},{
color: 'red' // Values from 10 (including) and up have the color red
}]
}
}
See this JSFiddle demonstration of how it looks.
Unfortunately this option is not possible, but you can request your suggestion in http://highcharts.uservoice.com and vote for it.
By the way, I can try use a plotLine, like this:
yAxis: {
title: {
text: 'My Chart'
},
plotLines: [{
id: 'limit-min',
dashStyle: 'ShortDash',
width: 2,
value: 80,
zIndex: 0,
label : {
text : '80% limit'
}
}, {
id: 'limit-max',
color: '#008000',
dashStyle: 'ShortDash',
width: 2,
value: 90,
zIndex: 0,
label : {
text : '90% limit'
}
}]
},
http://jsfiddle.net/gabrielesandoval/efHq7/
Is there a way to fill in the gap between the y-axis and the first point. The first point on my chart should be "25 years" and i would like the area between 0 and 25 to be filled in as well. Even if the tooltip doesn't work for that point, I would just like to visually show that the values between 0 and the first point.
I tried adding a point with a x value of zero but that didnt work. The only area charts I have seen where there is no gap between the two axis and the area are examples where the chart is inverted. Is there a proper way to do this?
Current Code:
$(function () {
$('#container').highcharts({
chart: {
type: 'areaspline'
},
title: {
text: 'Monthly Comparison'
},
subtitle: {
text: '1 vs 2'
},
xAxis: {
min: 0,
categories: [0, '25 years', '30 years', '35 years', '40 years', '45 years']
},
yAxis: {
labels: {
formatter: function() {
return '$' + this.value;
}
},
min: 0,
title: {
text: 'Cost'
}
},
tooltip: {
shared: true,
valuePrefix: '$'
},
credits: {
enabled: false
},
legend: {
enabled: false
},
plotOptions: {
area: {
lineWidth: 1,
marker: {
enabled: false
},
shadow: false,
states: {
hover: {
lineWidth: 1
}
}
}
},
series: [{
type: 'area',
name: 'series1',
data: [['',60],['25 years',60], ['30 years',60], ['35 years',60], ['40 years',60], ['45 years',60]]
}, {
type: 'area',
name: 'series2',
data: [['',90], ['25 years',100], ['30 years',175], ['35 years',300], ['40 years',400], ['45 years',400]]
}]
});
});
You should set minPadding/maxPadding as 0, but these parameters doesn't work with categories. So you need to use numeric xAxis, instead of categories.