In my chart I want the change xAxis extremes depend on various series.
Let say for series 1, If I hide/show series, the extremes of xAxis should not change. It should have same behavior like if I have ignoreHiddenSeries=false
But for series 2 the extremes should change on show/hide series, like if I have ignoreHiddenSeries=true
How can I achieve this?
I made a jsfiddle example here: https://jsfiddle.net/cjchLqaa/2/
In beginning xAxis has extremes 0,4 where series 1 and 2 are visible.
But if I hide series 1 then xAsis still should have same extremes as before.
But for series 2 it should change in its normal way.
jsfiddle code:
$(function () {
$('#container').highcharts({
chart:{
//ignoreHiddenSeries:true,
},
xAxis: {
},
series: [{
data: [
[0, 29.9],
[1, 71.5],
[2, 106.4]
]
},
{
data: [
[2, 29.9],
[3, 71.5],
[4, 106.4]
]
}]
});
var chart=$('#container').highcharts();
$("#button1").click(function () {
var series = chart.series[0];
if (series.visible) {
series.hide();
} else {
series.show();
}
});
$("#button2").click(function () {
var series = chart.series[1];
if (series.visible) {
series.hide();
} else {
series.show();
}
});
});
I would approach this by checking for the series name (or id), and if it meets the criteria, grab the x axis extremes, hide the series, and the use the original extremes values to run setExtremes().
Like this:
function(e) {
e.preventDefault();
var ext = this.xAxis.getExtremes();
this.setVisible();
if(this.name == 'Series 1') {
this.xAxis.setExtremes(ext.min,ext.max);
}
else {
this.xAxis.setExtremes();
}
}
Example, using the legendItemClick event:
http://jsfiddle.net/jlbriggs/sas2jawm/
$("#button1").click(function () {
chart.options.chart.ignoreHiddenSeries = false;
var series = chart.series[0];
if (series.visible) {
series.hide();
} else {
series.show();
}
});
$("#button2").click(function () {
chart.options.chart.ignoreHiddenSeries = true;
var series = chart.series[1];
if (series.visible) {
series.hide();
} else {
series.show();
}
});
Related
I have a bar chart with labels. Is it possible to get the "points" data by hovering over said labels using custom-events library?
By points data I mean the variable from here:
tooltip: {
useHTML: true,
formatter(this: { points: any[] }) {
}
}
You can loop through all series points and match a point with a label position. Example:
xAxis: {
...,
labels: {
events: {
mouseover: function() {
const points = [];
this.axis.series.forEach(s => {
s.points.forEach(point => {
if (point.x === this.pos) {
points.push(point);
}
})
});
console.log(points);
}
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/3xvgtw2c/
I am using Highcharts it is working fine but i want to change in pie slice when i click on single pie slice then that slice overlap two slice(right or left slice).
Below is the image attached tha i have done in pie chart.
Below is the image attached of the expexted pie chart result
You can add your own method, which will resize shape on click, for example: http://jsfiddle.net/BlackLabel/8vd6cod1/
function resizeSlice(point, change) {
// Original shape params are stored in shapeArgs:
var shape = point.shapeArgs;
if (point.graphic) {
point.graphic.attr({
// "r" is outer radius:
r: shape.r + change,
// "innerR" is inner radius:
innerR: shape.innerR - change
});
}
}
// Build the chart
Highcharts.chart('container', {
chart: {
type: 'pie',
events: {
// On window resize, apply change:
redraw: function() {
Highcharts.each(this.series[0].points, function(point) {
resizeSlice(point, point.customResized ? 5 : 0)
});
}
}
},
plotOptions: {
pie: {
innerSize: '90%',
cursor: 'pointer',
dataLabels: {
enabled: false
},
point: {
events: {
click: function() {
var change = 0;
// Custom param, can be called whatever we want:
this.customResized = !this.customResized;
if (this.customResized) {
// Let's resize!
change = 5;
}
resizeSlice(this, change);
}
}
}
}
},
series: [{
data: [3, 4, 5, 6]
}]
});
I have make some change to this code for re size all other pie.
: http://jsfiddle.net/8vd6cod1/2/
function resizeSlice(point, change) {
// Original shape params are stored in shapeArgs:
var shape = point.shapeArgs;
if (point.graphic) {
point.graphic.attr({
// "r" is outer radius:
r: shape.r + change,
// "innerR" is inner radius:
innerR: shape.innerR - change
});
}
}
// Build the chart
Highcharts.chart('container', {
chart: {
type: 'pie',
events: {
// On window resize, apply change:
redraw: function() {
Highcharts.each(this.series[0].points, function(point) {
resizeSlice(point, point.customResized ? 5 : 0)
});
}
}
},
plotOptions: {
pie: {
innerSize: '90%',
cursor: 'pointer',
dataLabels: {
enabled: false
},
point: {
events: {
click: function() {
Highcharts.each(this.series.points, function(point) {
resizeSlice(point, 0)
});
var change = 0;
// Custom param, can be called whatever we want:
this.customResized = !this.customResized;
if (this.customResized) {
// Let's resize!
change = 5;
}
resizeSlice(this, change);
}
}
}
}
},
series: [{
data: [3, 4, 5, 6]
}]
});
I have a chart with multiple y axes. I have moved one chart to bottom using top option. When I hover on the graph moved to bottom, shared tooltip does not appear. When I hover on the space just above the bar chart. Space between the bar and 100 (in Y axis), the tool -tip does not appear. Hover on the space right or left to the bar, tool-tip does not appear.
I don't want to have the graph in its default position. It looks cleaner when I have two graphs separated. Can I make the shared tool tip work when graph is moved down ?
My code:
yAxis: [{
top: 148
},
{
top: 0
}],
tooltip: {
shared: true,
crosshairs: {
color: 'rgba(27,161,218,0.5)',
dashStyle: 'solid',
zIndex: -1
}
},
Here is the fiddle: multi-axes graph with positioning
Any input appreciated.
Thanks
Look at using synchronized charts.
http://www.highcharts.com/demo/synchronized-charts
The JSFiddle is updated to use synchronized charts.
JSFiddle
$(function() {
$('#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'
});
}
}
});
}
}
var dataset = [{
"name": "Series 1",
"type": "column",
"data": [29.9, 71.5, 106.4]
}, {
"name": "Series 2",
"type": "line",
"data": [216.4, 194.1, 95.6]
}];
for (var i = 0; i < dataset.length; i++) {
var dataitem = dataset[i];
$("<div class=\"chart\">")
.appendTo('#container').highcharts({
title: {
text: dataitem.name
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar']
},
tooltip: {
crosshairs: {
color: 'rgba(27,161,218,0.5)',
dashStyle: 'solid',
zIndex: -1
}
},
series: [{
data: dataitem.data,
name: dataitem.name,
type: dataitem.type
}]
});
};
});
Can we disable zoom on highchart graph while graph is loading.
I have multiple graphs therfore would like to disable the zoom option until all graphs gets loaded.
It is possible to change zoomType of a chart dynamically, but it is not a part of official API. That way after all charts are loaded you will be able to change their zoomType from none to some.
$(function () {
$('#container').highcharts({
chart: {
zoomType: ''
},
xAxis: {
minRange: 1
},
series: [{
data: [1,2,3,4,5,6,7]
}]
});
function enableZoom(zoomType) {
var chart = $('#container').highcharts(),
zoomX = /x/.test(zoomType),
zoomY = /y/.test(zoomType);
chart.options.zoomType = zoomType;
chart.pointer.zoomX = zoomX;
chart.pointer.zoomY = zoomY;
chart.pointer.zoomHor = zoomX;
chart.pointer.zoomVert = zoomY;
}
$('#zoomX').click(function () {
enableZoom('x');
});
$('#zoomY').click(function () {
enableZoom('y');
});
$('#zoomXY').click(function () {
enableZoom('xy');
});
$('#noZoom').click(function () {
enableZoom('');
});
});
JSFiddle: http://jsfiddle.net/pearp126/
you can do so by simple setting zoomType as null in your chart config
zoomType: null
See the documentation here for more details
Basically the only thing you need to get done is removing the chart and replacing it with one with the settings you like.
See the code below:
var chart = $('#container').highcharts();
function renderChart(){
chart = new Highcharts.Chart(chart.options);
chart.render();
}
Once you want to enable zooming (or any other setting):
$('#container').highcharts().options.chart.zoomType = 'xy';
renderChart();
To be honest I'm not sure what happens to the old chart. Hopefully it's just overwritten and doesn't it impose a big memory issue.
I created a fiddle you can find here
Basically you can stop the "selection" event (zoom), when the loading label of the chart is displayed.
Using the default Highcharts function .showLoading() for show the loading label, and the default variable loadingShown, for verify is the loading label is displayed or not.
So, by using the function .showLoading(), let's say before doing an AJAX request, and validating with the variable loadingShown if the loading label is displayed or not, we can stop the selection event.
Another way, is to use a thirdparty loading mask, and add it to the chart's container.
In the next example you'll find how to cancel the zoom using the .showLoading() function and how to use jQuery plugin: pLoading https://github.com/joseshiru/p-loading (for show the loading mask)
$(function () {
var setEvents;
var chart;
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=usdeur.json&callback=?', function (data) {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
zoomType: 'x',
events: {
selection: function () {
//Quit the selection event, while the loading spinner is displayed.
if (chart.loadingShown) {
return false;
}
}
}
},
title: {
text: 'USD to EUR exchange rate over time'
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' : 'Pinch the chart to zoom in'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: 'Exchange rate'
}
},
legend: {
enabled: false
},
plotOptions: {
area: {
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
},
marker: {
radius: 2
},
lineWidth: 1,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
},
series: [{
type: 'area',
name: 'USD to EUR',
data: data
}]
});
});
setEvents = function () {
var $showLoadingBtn = $('.show-loading');
var $hideLoadingBtn = $('.hide-loading');
var $showExternalMask = $('.show-toggle-mask');
var $hideExternalMask = $('.hide-toggle-mask');
$showLoadingBtn.on('click.showLoading', function () {
chart.showLoading();
});
$hideLoadingBtn.on('click.hideLoading', function () {
chart.hideLoading();
});
$showExternalMask.on('click.toggleMask', function () {
$('#container').ploading({action: 'show'});
});
$hideExternalMask.on('click.toggleMask', function () {
$('#container').ploading({action: 'hide'});
});
}();
});
Example in jsfiddle: http://jsfiddle.net/8p2fzbxw/3/
After any sort of zoom (mouse drag, range selector, date input) the datetime returned from the point click event is usually incorrect. I've not yet found this problem when using an area chart, have found it using both bar and column chart.
To recreate: run the fiddle, zoom using the mouse across a few of the columns, click a datapoint. The alert will show the datetime returned. Notice it's different from the tooltip (which is correct).Usually fails after first click, even for the same datapoint.
BTW useUTC setting doesn't matter.
Fiddle: http://jsfiddle.net/jrEDT/
Code for completeness:
$(function() {
var seriesOptions = [],
yAxisOptions = [],
seriesCounter = 0,
names = ['MSFT'],
colors = Highcharts.getOptions().colors;
$.each(names, function(i, name) {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename='+ name.toLowerCase() +'-c.json&callback=?', function(data) {
seriesOptions[i] = {
name: name,
data: data,
type: 'column'
};
// 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++;
if (seriesCounter == names.length) {
createChart();
}
});
});
// create the chart when all data is loaded
function createChart() {
Highcharts.setOptions({
global: {
useUTC: false // datetime reflects time on db (ie, local) rather than GMT
}
});
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
zoomType: 'x'
},
exporting: {
enabled: false
},
rangeSelector: {
selected: 4
},
yAxis: {
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}],
offset: 25
},
plotOptions: {
series: {
cursor: 'pointer',
allowPointSelect: true,
point: {
events: {
click: function() {
var series = this.series.name;
var utc = this.x;
var d = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x);
alert(d);
}
}
}
}
},
tooltip: {
formatter:function(a,b,c){
var d = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x);
return d;
},
enable:true
},
series: seriesOptions
});
}
});
Thanks!
Have you tried to disable datagrouping http://api.highcharts.com/highstock#plotOptions.series.dataGrouping ?