I am trying to solve the following three problems
Decimal Places on Y Axis (all Axis) - should be constant 5
Decimal Places on Tooltip - should be constant 5
Adding a Suffix to all points on the tooltip
I need to keep the values shown on the on Y Axis fixed to 5 decimal places ( say 0.96724 or 1.55400 ) as received from the data feed.
I have forked and created a new jsfiddle to highlight the problem. This shows only upto two digits.
From various examples, I tried to create a tooltip, but it did not worked.
Any help or pointers would be highly appreciated. Created a jsfiddle below
Regards
Amit
http://jsfiddle.net/amonga141/tgz469a5/2/
// Some styling options for yAxis
Highcharts.theme = {
yAxis: {
gridLineWidth: 1,
gridLineColor: "rgb(240, 240, 240)",
minorGridLineColor: 'rgba(255, 255, 255, 0.07)',
lineColor: "rgb(241, 141, 5)",
lineWidth: 1,
tickColor: "rgb(241, 141, 5)",
tickWidth: 1,
showEmpty: false,
labels: {
style: {
color: 'rgb(102, 102, 102)',
fontWeight: 'bold'
}
},
title: {
style: {
color: 'rgb(229, 64, 40)',
font: "bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif"
}
}
}
};
// Apply the styling options
Highcharts.setOptions(Highcharts.theme);
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Data generator helper
function data(start, end, samples, min, max) {
var temp = [];
var range = ~~ ((end - start) / samples);
for (var i = 1; i < samples; i++) {
temp.push([start.getTime() + range * i, min + Math.random() * (max - min)]);
}
return temp;
}
//
var tooltipSuffix ='<br> TTIP Sufix:Suffix';
// Create a timer
var now = new Date();
var start = new Date(now - 60000);
var example_data = [{
name: 'Signal 1',
data: data(start, now, 20, 1.55478, 1.55481),
yAxis: 0
}, {
name: "Signal 2",
data: data(start, now, 20, 1.32419, 1.13253),
yAxis: 1
}, {
name: "Signal 3",
data: data(start, now, 20, 0.97456, 0.97545),
yAxis: 2
}];
//////////////////////
// Chart definition //
//////////////////////
var chart = $("#chart").highcharts({
legend: {
enabled: true
},
chart: {
animation: Highcharts.svg,
events: {
load: function () {
// set up the updating of the chart each second
var chart = this,
series = chart.series;
setInterval(function () {
var x = new Date(); // current time
series[0].addPoint(data(x, x, 2, 1.55678, 1.59133)[0], false, true);
series[1].addPoint(data(x, x, 2, 1.33456, 1.39921)[0], false, true);
series[2].addPoint(data(x, x, 2, 0.95989, 0.99092)[0], false, true);
chart.redraw();
}, 2000);
}
}
},
yAxis: [{
opposite: false,
showRects: true,
offset: 40,
title: {
text: 'Scale 1'
}
}, {
opposite: true,
showRects: true,
offset: 90,
title: {
text: 'Scale 2'
}
}, {
opposite: false,
showRects: true,
offset: 140,
title: {
text: 'Scale 3'
}
}],
xAxis: {
type: 'datetime'
},
// tooltip: {
// xDateFormat: '%A, %b %e, %H:%M:%S', // Shows only [Day, Mon dd, hh:mi:ss]
// shared: true,
// pointFormat: ' <span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> <br/>'+tooltipSuffix,
// valueDecimals: 5,
// crosshairs: true
// } ,
series: example_data
});
<div id="chart"></div>
See Working fiddle with your code here
For labels use following in your options of yAxis.
labels: {
format: '{value:.5f}',
}
for tooltip see the formatter function below
tooltip: {
shared: true,
pointFormat: ' <span style="color:{series.color}">{series.name}</span>: <b>{point.y:.5f}</b>'+tooltipSuffix+' <br/>',
}
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
I changed the official chart, but the crosshair not my expected.
DEMO : Official synchronized-charts
What I changed :
Add xAxis.categories as my custom xAxis labels
Change series[0].fillOpacity 0.3 to 1
Use my custom json data
CODE :
```javascript
//$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=activity.json&callback=?', function (activity) {
var json = {
xData: ["1/1", "1/2", "1/3", "1/4", "1/5", "1/6", "1/7", "1/8", "1/9", "1/10"],
datasets: [{
name: "Num of dog",
data: [1,2,3,4,5,1,2,3,4,5],
unit: "dogs",
type: "area",
valueDecimals: 0
},{
name: "Num of cat",
data: [1,2,3,4,5,1,2,3,4,5],
unit: "cats",
type: "area",
valueDecimals: 0
}]
};
//$.each(activity.datasets, function (i, dataset) {
$.each( json.datasets, function (i, dataset) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function (val, j) {
//return [activity.xData[j], val];
return [json.xData[j], val];
});
$('<div class="chart">')
.appendTo('#container')
.highcharts({
...,
xAxis: {
crosshair: true,
events: {
setExtremes: syncExtremes
},
categories: ["1/1", "1/2", "1/3", "1/4", "1/5", "1/6", "1/7", "1/8", "1/9", "1/10"],
//labels: {
//format: '{value} km'
//}
},
...,
series: [{
...,
fillOpacity: 1,
//fillOpacity: 0.3,
...
});
```
DEMO : My synchronized-charts
What I need:
Display crosshair line, like Official synchronized-charts
Don't show circle point, like Official synchronized-charts
Show circle point When mouse hover, like Official synchronized-charts
Crosshair line put to front
Does anyone know to accomplish this?
Thank you!
For Don't show circle point, like Official synchronized-charts. Added
plotOptions: {
series: {
marker: {
enabled: false
}
pointPlacement: 'on'
}
},
For Crosshair line put to front. Updated xAxis
xAxis: {
categories: json.xData,
tickmarkPlacement: 'on',
crosshair: {
width: 2,
zIndex: 3
},
events: {
setExtremes: syncExtremes
},
},
/*
The purpose of this demo is to demonstrate how multiple charts on the same page can be linked
through DOM and Highcharts events and API methods. It takes a standard Highcharts config with a
small variation for each data set, and a mouse/touch event handler to bind the charts together.
*/
/**
* In order to synchronize tooltips and crosshairs, override the
* built-in events with handlers defined on the parent element.
*/
$('#container').bind('mousemove touchmove touchstart', function(e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(e);
}
}
});
/**
* Override the reset function, we don't need to hide the tooltips and crosshairs.
*/
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
/**
* Highlight a point by showing tooltip, setting hover state and draw crosshair
*/
Highcharts.Point.prototype.highlight = function(event) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
/**
* Synchronize zooming through the setExtremes event handler.
*/
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function(chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, {
trigger: 'syncExtremes'
});
}
}
});
}
}
// Get the data. The contents of the data file can be viewed at
// https://github.com/highcharts/highcharts/blob/master/samples/data/activity.json
var json = {
xData: ["1/1", "1/2", "1/3", "1/4", "1/5", "1/6", "1/7", "1/8", "1/9", "1/10"],
datasets: [{
name: "Num of dog",
data: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
unit: "dogs",
type: "area",
valueDecimals: 0
}, {
name: "Num of cat",
data: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
unit: "cats",
type: "area",
valueDecimals: 0
}]
}
//$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=activity.json&callback=?', function(activity) {
$.each(json.datasets, function(i, dataset) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function(val, j) {
return [json.xData[j], val];
});
$('<div class="chart">')
.appendTo('#container')
.highcharts({
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
categories: json.xData,
tickmarkPlacement: 'on',
crosshair: {
width: 2,
zIndex: 3
},
events: {
setExtremes: syncExtremes
},
},
yAxis: {
title: {
text: null
},
zIndex: 1000
},
plotOptions: {
series: {
marker: {
enabled: false
},
pointPlacement: 'on'
}
},
tooltip: {
positioner: function() {
return {
x: this.chart.chartWidth - this.label.width, // right aligned
y: 10 // align to title
};
},
borderWidth: 0,
backgroundColor: 'none',
pointFormat: '{point.y}',
headerFormat: '',
shadow: false,
style: {
fontSize: '18px'
},
valueDecimals: dataset.valueDecimals
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
fillOpacity: 1,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
}]
});
});
//});
.chart {
min-width: 320px;
max-width: 800px;
height: 220px;
margin: 0 auto;
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
Fiddle demo
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 using Area chart with navigator, what I am trying to do is highlight high and Low point markers (only two points ) in the current visible chart, and on top of these markers I want to display fixed tooltips displaying the point information.
And as user navigates through navigator these point markers should be recalculated and tooltips should follow them.
[This is what I am trying to accomplish][1]
So far I have been able to calculate high and low points and highlight corrosponding markers in chart, and I have also been able to display two tooltips, but they are not ACURATELY positioned along with point markers.
![So far this has been accomplished][2]
Here is my Code:
function customTooltip(point) {
console.log(chart);
var text = chart.renderer.text(
'Max',
point.plotX + chart.plotLeft + 10,
point.plotY + chart.plotTop - 10
).attr({
zIndex: 5
}).add();
var box = text.getBBox();
chart.renderer.rect(box.x - 5, box.y - 5, box.width + 10, box.height + 10, 5)
.attr({
fill: '#FFFFEF',
stroke: 'gray',
'stroke-width': 1,
zIndex: 4
})
.add();
}
var labelArr = [], // keeps Tooltips for High and Low
chart = $('#container').highcharts('StockChart', {
chart: {
type: 'line',
width: 900
},
scrollbar: {
enabled: false
},
navigator: {
top: -1,
height: 25,
handles: {
backgroundColor: 'transparent',
borderColor: 'transparent'
}
},
rangeSelector: {
inputPosition: {
align: 'left',
x: 10,
y: 30
},
buttons: [{
type: 'year',
count: 1,
text: ''
}],
buttonTheme: { // styles for the buttons
fill: 'none',
stroke: 'none',
'stroke-width': 0,
states: {
hover: {
fill: 'none'
},
select: {
fill: 'none'
}
}
},
inputDateFormat: '%m-%d-%Y',
inputStyle: {
fontSize: '14px',
borderColor: '#FFF'
},
selected: 0
},
yAxis: {
labels: {
align: 'right',
x: -5,
formatter: function () {
return "$" + this.value;
}
}
},
xAxis: {
type: 'datetime',
tickWidth: 0,
labels: {
y: 20
},
dateTimeLabelFormats: {
month: '%B'
},
events: {
setExtremes: function () {
var pointMax, pointMin, labelLength = labelArr.length;
// Flush out Old Tooltips for High and Low
if (labelLength > 0) {
for (var i = 0; i < labelLength; i++) {
var popVal = labelArr.pop();
this.chart.container.firstChild.removeChild(popVal);
}
}
$.each(this.series[0].points, function (i, point) {
if (!pointMax && !pointMin) pointMax = pointMin = point;
// If marker is enabled for any point, disable it
if (typeof point.marker != 'undefined') point.marker.enabled = false;
// Calculate Highest point
if (pointMax.y < point.y) pointMax = point;
// Calculate Lowest point
if (pointMin.y > point.y) pointMin = point;
});
pointMax.update({
marker: {
enabled: true
}
}, false, false);
//customTooltip( pointMax );
pointMin.update({
marker: {
enabled: true
}
}, false, false);
//customTooltip( pointMin );
}
}
},
tooltip: {
crosshairs: false
/*useHTML: true,
borderRadius: 0,
backgroundColor: '#000',
shadow: false,
borderWidth: 0,
enabled: true,
formatter: function(){
/* Temp Disable Custom tool-Tip
var arr = [];
$.each(this.points, function(k, obj){
arr.push( "<span style='color:#FFF'>Low price w/o sales charge</span>" );
arr.push( "<br>" );
arr.push( "<span style='font-weight:bold;color:#FFF'>$" + obj.y + "</span>" );
arr.push( "<br>" );
});
return arr.join(' ');
} */
},
plotOptions: {
area: {
marker: {
fillColor: '#f7941e',
states: {
hover: {
enabled: false
}
}
}
},
series: {
point: {
events: {
update: function (event) {
event.target.series.chart.tooltip.refresh([event.target]);
var cloneToolTip = event.target.series.chart.tooltip.label.element.cloneNode(true);
event.target.series.chart.container.firstChild.appendChild(cloneToolTip);
labelArr.push(cloneToolTip);
}
}
}
}
},
series: [{
name: 'Quarterly Returns w/o sales charge',
data: [
[1149120000000, 62.17],
[1149206400000, 61.66],
[1369699200000, 441.44],
[1369785600000, 444.95]
]
// pointWidth: 14,
}]
}).highcharts();
});
Can you please guide me on how to proceed from here?
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.