highcharts how to override reset zoom button event - javascript

Is there a way to override the reset zoom button click event in highcharts? When I click the reset zoom button, I want the chart to display the specific interval using setExtremes instead of zooming out the whole chart.

you can capture it in the selection property of your chart object. Just use the setExtremes()function with where you want to zoom, and a timeout of 0ms so that the graph's 'reset graph' function doesn't overwrite it.
chart: {
events: {
selection: function(event) {
if (!event.xAxis) {
setTimeout(function(){chart.xAxis[0].setExtremes(0, 5)}, 0);
}
}
...
}
working example: http://jsfiddle.net/rhavelka/M7cfm/64/
edit: but make sure that you want to zoom in on that specific interval and essentially hiding data from the user (unless you have a scrollbar on the graph like this example)

You can overwrite default Chart.prototype.showResetZoom and provide your own logic in zoomOut function:
(function(H) {
H.Chart.prototype.showResetZoom = function() {
var chart = this,
defaultOptions = H.defaultOptions,
fireEvent = H.fireEvent,
lang = defaultOptions.lang,
btnOptions = chart.options.chart.resetZoomButton,
theme = btnOptions.theme,
states = theme.states,
alignTo = btnOptions.relativeTo === 'chart' ? null : 'plotBox';
function zoomOut() {
//chart.zoomOut(); // default action
chart.xAxis[0].setExtremes(3, 7); // new action
}
fireEvent(this, 'beforeShowResetZoom', null, function() {
chart.resetZoomButton = chart.renderer.button(
lang.resetZoom,
null,
null,
zoomOut,
theme,
states && states.hover
)
.attr({
align: btnOptions.position.align,
title: lang.resetZoomTitle
})
.addClass('highcharts-reset-zoom')
.add()
.align(btnOptions.position, false, alignTo);
});
}
})(Highcharts);
Live demo: http://jsfiddle.net/BlackLabel/ay0t2e9f/
Docs reference: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts

Related

HighCharts synchronisation tooltip effect other chart

I'm using multiple highChart in a dashboard page e.g linearea, spline, pie and synchronisation of multiple charts
Set tooltip synchronisation for prototype
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
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
};
But above function effect all highchart e.g linearea and spline chart etc. what I want to apply on synchronisation only
Refer to this live demo: http://jsfiddle.net/kkulig/eec3mg9t/
I put every chart to a separate container - it's easier to manipulate them then. class="sync" indicates that chart should be synchronized:
<div id="container0"></div>
<div id="container1" class="sync"></div>
<div id="container2" class="sync"></div>
Then I set common events using this class:
$('.sync').bind('mousemove touchmove touchstart', function(e) {
(...)
I applied wrapping instead of overwriting for Highcharts.Pointer.prototype.reset function so that the default action fires for unsynchronized charts.
// Custom wrap
Highcharts.wrap(Highcharts.Pointer.prototype, 'reset', function(proceed, allowMove, delay) {
if (!this.chart.options.chart.isSynchronized) {
proceed.apply(this, allowMove, delay);
}
});

Leaflet clicking on features

So, I'm trying to map bus routes using leaflet w/geojson for the coordinates. I'm having a difficult time with one aspect where, on a click, the bus line is boldened, and, ideally, the last clicked on feature returns to the default style.
What I have so far
function $onEachFeature(feature, layer) {
layer.on({
click: function(e) {
//calls up the feature clicked on
var $layer = e.target;
var highlightStyle = {
opacity: 1,
weight: 5
};
$layer.bringToFront();
$layer.setStyle(highlightStyle);
}
});
}
//imagine all the leaflet map tile code here
//this is where the features get added in and the $oneachfeature function
var busFeature = L.geoJson(busRoutes, {
style: defaultBusRouteColor,
onEachFeature : $onEachFeature
});
busFeature.addTo(map);
Above, what I have now successfully changes the style of the feature to what's in highlightStyle. However, when another feature is clicked, the style remains. How do I remove the previously clicked on feature's style so that only one feature at a time has the style highlightStyle?
Things I've already tried: using addClass/removeClass to jQuery methods, layer.resetStyle() with leaflet, and a bunch of other things that still didn't work. Note: this would ideally be used in a mobile version, as the desktop version uses a hover function that emphasizes the features, with no problem. this:
function $oneachfeature(feature, layer){
layer.on({
mouseover: function (e){makes feature bold}
});
layer.on({
mouseout: function (e){makes feature normal again}
});
}
Any suggestions?
Store a reference to the highlighted layer so you can later call resetStyle on it:
// Variable to store selected
var selected
// Create new geojson layer
new L.GeoJSON(collection, {
// Set default style
'style': function () {
return {
'color': 'yellow',
}
}
}).on('click', function (e) {
// Check for selected
if (selected) {
// Reset selected to default style
e.target.resetStyle(selected)
}
// Assign new selected
selected = e.layer
// Bring selected to front
selected.bringToFront()
// Style selected
selected.setStyle({
'color': 'red'
})
}).addTo(map)
Example: http://embed.plnkr.co/RnQO1s/preview
Reference: http://leafletjs.com/reference.html#geojson-resetstyle
using resetStyle() would seem to be an easier solution...simply reset the style of the layer before applying the new style to the feature. This requires only a sinlge line of code adding to your original function:
function $onEachFeature(feature, layer) {
layer.on({
click: function(e) {
//calls up the feature clicked on
var $layer = e.target;
var highlightStyle = {
opacity: 1,
weight: 5
};
busFeature.resetStyle();
$layer.bringToFront();
$layer.setStyle(highlightStyle);
}
});
}
Remove previous Highlight before adding the next:
.removeLayer() works to remove the previously set geoJSON selection using .addTo()
theMap = yourMap.Map
geoJson = yourMap.geoJSON();
onclick() {
const highlightedFeature = {
'color': '#12FF38',
'fillColor': '#30D8E0',
'fillOpacity': 0.3
};
this.theMap.removeLayer(this.geoJson);
this.geoJson = yourMap.geoJSON( Feature, {
style: highlightedFeature
});
this.geoJson.addTo(this.theMap);
}

Flot event for range updates in response to panning/zooming

For Flot, is there an event that fires after the user has completed panning or zooming using the mouse scroll wheel (after the range.xaxis.to/from and range.yaxis.to/from have settled)? I am trying to use the line below to update the selection on an overview plot after the user has panned or zoomed in the main plot, but am finding that either the update to the overview plot happens after panning or zooming(not both).
$("#plot").bind("mouseup scroll",updateOverviewSelection);
Edit: http://jsfiddle.net/apandit/nu2rr58h/9/
In the jsfiddle, I am unable to pan in the main plot and the cursor does not seem to change back to normal. The user can click and drag in the overview plot to make a selection, which leads to zooming in the main plot. I would also like to be able to allow the user to pan and zoom in the main plot and have the selection box in the overview plot updated; I am attempting to do this by binding the updateOverviewSelection method to the plot div for the scroll and mouseup events. Is there an event in Flot that fires every time the x- and y-axis limits are updated?
The solution to this issue is below. The issue was that setting the overview plot's selection(overview.setSelection(ranges);) was triggering the zoom method because it was bound to the plotselected event in the overview plot. At the end of the zoom method, the main plot was plotted, which was again calling the overview.setSelection(ranges); line in the updateOverviewSelection method. To prevent this ping-pong between the two methods/events, I added an updatingOverviewSelection flag.
http://jsfiddle.net/apandit/nu2rr58h/12/
var datasets = [[
[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9]
],
[
[0,0],[-1,-1],[-2,-2],[-3,-3],[-4,-4],[-5,-5],[-6,-6],[-7,-7],[-8,-8],[-9,-9]
]];
var plot = $.plot("#plot",datasets,{
pan: {
interactive: true
},
zoom: {
interactive: true,
mode: "x"
}
});
var overview = $.plot("#overview",datasets,{
selection: {
mode: "xy"
}
});
var updatingOverviewSelection = false;
$("#plot").bind("plotpan plotzoom",updateOverviewSelection);
$("#overview").bind("plotselected", zoom);
function zoom(event,ranges) {
if(updatingOverviewSelection) {
updatingOverviewSelection = false;
}
else {
var options = plot.getOptions();
options.xaxes[0].min = ranges.xaxis.from;
options.xaxes[0].max = ranges.xaxis.to;
options.yaxes[0].min = ranges.yaxis.from;
options.yaxes[0].max = ranges.yaxis.to;
plot = $.plot("#plot",datasets,options);
}
};
// get the window x-axis and y-axis ranges for the main plot
// and set the selection in the overview plot to those ranges
function updateOverviewSelection(event) {
var options = plot.getOptions();
var ranges = {
xaxis: {
from: options.xaxes[0].min,
to: options.xaxes[0].max
},
yaxis: {
from: options.yaxes[0].min,
to: options.yaxes[0].max
}
};
updatingOverviewSelection = true;
overview.setSelection(ranges);
};

Updating fontsize with highcharts using zoomtype

I have a column chart in Highcharts with a big number of columns so the columns are very small.
That's fine but I want to do zoom.
So I used zoomtype: 'x' and it work well.
The problem is that I want to make the font bigger on the xAxis when they are selected.
I tried by doing this:
chart: {
type: 'column',
zoomType: 'x',
events: {
redraw: function(event) {
if(this.xAxis[0].tickPositions.length>80){
this.xAxis[0].options.labels.style.fontSize = 1;
}else{
this.xAxis[0].options.labels.style.fontSize = 20;
console.log(this.xAxis[0].options.labels.style.fontSize);
}
}
}
}
When I check the console the value of this.xAxis[0].options.labels.style.fontSize is updated to 20.
This code works only when I press the Reset zoom button.
So my question is how can I update the chart when the event is triggered so it takes the same effects as if I use the Reset zoom button?
Or how can I make changes in the font when I make zoom and when reseting the zoom?
You can catch afterSetExtremes event and then axis.update() with new styles for bales.
events:{
afterSetExtremes:function(){
this.update({
labels:{
style:{
fontSize:20
}
}
});
}
}
Example: http://jsfiddle.net/m180dxsu/

How to get Event or DOM element of selected feature in OpenLayers

I'm implementing an OpenLayers SelectFeature control, and trying to position an JQuery UI dialog widget right on top of the selected feature. To use the JQuery UI Position utility, it requires either a DOM element or an Event.
The onSelect callback of the SelectFeature control gives me an OpenLayers.Feature.Vector object representing the selected feature. From this, how do I get either the DOM element of the selected feature, or the Event object of the click event?
var selectControl = new OpenLayers.Control.SelectFeature(clientsLayer, {
hover : false,
clickout: false,
multiple: false,
onSelect: function(feature) {
// how do I get the DOM element of the feature
// or alternately, the click event of the selection?
}
});
You are doing it right.
If you do a console.log(feature) You'll see that it returns an object with CLASS_NAME =
"OpenLayers.Feature.Vector"
onSelect: function(feature) {
console.log(feature);
}
Update:
I see.
You could add event listeners
var selectControl = new OpenLayers.Control.SelectFeature(clientsLayer, {
hover: false,
clickout: false,
multiple: false,
eventListeners: {
featurehighlighted: function (event) {
console.log(event);
console.log(event.feature);
}
}
});
Is it something like this you look for ?
onSelect: function onFeatureSelect(event) {
var feature = event.feature;
if ( feature.layer.name == 'theone') {
...
}
}
Note I have also posted this answer at How do I get the DOM element from openlayers vector feature
If you want to find the position of the mouse or feature on hover so you can display a custom overlay, create a custom hover control and define the featurehighlighted function as follows:
var featureHoverControl = new OpenLayers.Control.SelectFeature([myLayer], {
id: 'featureHoverControl',
hover: true,
autoActivate: true,
highlightOnly: true,
renderIntent: "temporary",
eventListeners: {
featurehighlighted: function(e) {
// either use the mouse's position when the event was triggered
var mouseXPosition = this.handlers.feature.evt.x;
var mouseYPosition = this.handlers.feature.evt.y;
// or retrieve the feature's center point
var featureCenterLonLat = e.feature.geometry.bounds.getCenterLonLat();
var featureCenterPoint = map.getPixelFromLonLat(featureCenterLonLat);
// display your custom popup here
// e.g. showTooltip(e.feature.attributes.name, featureCenterPoint.x, featureCenterPoint.y)
}
,
featureunhighlighted: function(e) {
// hide your custom popup here
// e.g. hideTooltip()
}
}
});
map.addControl(featureHoverControl);
If you require access to the SVG element representing your layer/feature (in the event you are using a third-party library and you don't feel like modifying the source code), use either of the following lines (depending if you require the layer or feature):
var layerElement = map.getLayersByName("My Layer")[0].features.root;
var layerElementId = map.getLayersByName("My Layer")[0].features.root.id;
var featureElementId = map.getLayersByName("My Layer")[0].getFeaturesByAttribute("name","My Feature Name")[0].geometry.components[0].id;
Note that since this only grabs the element's id, you'll still need to use an appropriate method to grab a reference to the element itself. Something like either of the following:
var elementReference1 = document.getElementById(featureElementId);
var elementReference2 = jQuery('#'+featureElementId)[0];

Categories