I'd like to be able to show a spinner while exported image is generated.
Is there any way to achieve that, or an event i can subscribe to that fires when the file is generated and starts downloading?
My current code is
exporting: {
allowHTML: true,
buttons: {
contextButton: {
menuItems: null,
onclick: function () {
this.exportChart({ sourceWidth: 1500, sourceHeight: this.chartHeight }, null);
},
symbol: 'url(assets/images/icon_download.png)'
}
}
See this live demo: http://jsfiddle.net/kkulig/uav1vjtv/
First 80 lines of code alter the Highcharts core. This modification implements beforeExporting and afterExporting events which can be used for managing the spinner icon (creating and destroying it):
chart: {
events: {
beforeExporting: function() {
this.spinner = this.renderer.image('http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif', this.chartWidth / 2 - 50, this.chartHeight / 2 - 50, 100, 100).add();
},
afterExporting: function() {
this.spinner.destroy();
}
}
}
API reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#image
Related
I have built a stock chart using Highcharts. A few blocks from a massive dataset containing years worth of data looks like below -
{
Date: "2018-02-16",
Open: 0.6406,
Close: 0.6697,
High: 0.6697,
Low: 0.6406,
Adjusted_close: 0.5538,
Volume: 284808,
Entry_type: "B"
},
{
Date: "2020-01-15",
Open: 1.02,
Close: 1.02,
High: 1.04,
Low: 1.02,
Adjusted_close: 0.9508,
Volume: 209591,
Entry_type: "S"
}
What I'm trying to do is display a circle or balloon or square or whatever shape containing either B or S based on the value of Entry_type.
I've spent quite sometime trying to understand the examples from Highcharts website. Unfortunately I am not able to make a connection from the examples to my particular use case.
Please could someone help me out here?
This is possible using the render function API Link
chart: {
events: {
render: function() {
try {
this.series[0].data.forEach(point => {
if (point.Entry_type === "B") {
point.dataLabel.attr({y: point.plotLow});
} else if (point.Entry_type === "S") {
point.dataLabel.attr({y: point.plotHigh - 20});
}
});
} catch (error) {
// continue
}
}
}
},
...
series: [{
dataLabels: {
enabled: true,
backgroundColor: "#fdfc59",
shape: "circle",
formatter: function () {
return this.point.Entry_type;
}
...
Edited Fiddle
Edit 3 full example
Full Codepen
Chart has Linear and Logarithmic buttons. How to get the one which is active to be highlighted? Code below changes colour on hover only.
https://jsfiddle.net/stgk1mrx/
navigation: {
buttonOptions: {
theme: {
states: {
hover: {
fill: '#00f'
},
select: {
fill: '#f00'
}
}
}
}
myButton: {
symbol: 'circle',
symbolStrokeWidth: 1,
symbolFill: '#bada55',
symbolStroke: '#330033',
onclick: function() {
// Something happens here
var self = this.exportSVGElements[2]; // 0-1 is first button, 2-3 is second button etc.
self.setState(2);
console.log('clicked!');
},
theme: {
states: {
hover: {
fill: '#FF0000'
},
select: {
fill: '#0000FF'
}
}
},
http://jsfiddle.net/yTRxZ/5/
By setting select state you will get color changed after click on button. You also need to call setState() for that button. Take a look at the example
Consider the Highstocks async data loading example. I want to hide the preview and show just the scroll bar. So I set enabled to false in the chart configuration:
navigator: {
enabled: false,
adaptToUpdatedData: false,
...
This will cause the adaptToUpdatedData option not to work as described, i.e., when zooming the width of the scroll bar will be always 100%. Is it possible to keep the same behavior of the demo while hiding the preview?
You could visually hide all the elements of the navigator instead of disabling it.
For example (JSFiddle):
$('#container').highcharts('StockChart', {
navigator : {
adaptToUpdatedData: false,
height: 0,
handles: {
backgroundColor: 'transparent',
borderColor: 'transparent'
},
series : {
data : data
},
xAxis: {
labels: {
enabled: false
}
}
}
// ...
});
You might notice that the cursor still changes where the handles would be. If you want to get rid of this you could prevent the drawing of the handles all together.
For example (JSFiddle):
(function (H) {
H.wrap(H.Scroller.prototype, 'drawHandle', function (proceed, x, index) {
});
}(Highcharts));
$('#container').highcharts('StockChart', {
navigator : {
adaptToUpdatedData: false,
height: 0,
series : {
data : data
},
xAxis: {
labels: {
enabled: false
}
}
}
// ...
});
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/
I am building a Dashboard and it has around 4 graphs on a row and on click of any graph i want to update another graph which is bigger in size to display the graph so that its visible to the user to analyze.
any idea how to Redraw the map on click on a button.
I did the similar thing on my project.
You can add one button zoom/popup, clicking on which would open a new big chart and disable the exporting buttons in this new chart.
Here's the full code.
function callback($this) {
var img = $this.renderer.image('images/zoom_icon.png', $this.chartWidth - 40, 5, 40, 12);
img.add();
img.css({
'cursor': 'pointer'
});
img.attr({
'title': 'Pop out chart'
});
img.on('click', function () {
var params = {
chart: {
spacingLeft: 100,
spacingRight: 100,
renderTo: 'myChart'
},
title: {
text: 'title'
},
exporting: {
buttons: {
exportButton: {
enabled: false
},
printButton: {
enabled: false
}
}
}
}
new Highcharts.Chart(params, function (chart) {});
})
}
new Highcharts.Chart(charts.params, callback);
// where charts.params is object which contains options for chart