getSelectedPoints array delay problem in HighCharts - javascript

I need to access to getSelectedPoints array on click event but there is a delay i get the previous selected points and to solve that now i am using setTimeout function as shown code below but this is not a solving; Because i can not expect when points are selection finished.
I have seen this question
HighCharts Multiple Point selection - access/update getSelectedPoints array immediately after point select
but it's solve the problem in JQuery and old version of hightcharts that has select event and it's deprecated in new versions of hightcharts. I need answer to be in javascript and hightcharts v8.
plotOptions: {
series: {
events: {
click: function(event) {
var chart = new Highcharts.Chart(this.divElement.nativeElement,this.options);
chart.getSelectedPoints().forEach(point=>{
setTimeout(()=>{
// do something here
},500);
});
}
}
}

Where have you found the information that the select event is deprecated? It's not true, the event is fully supported - API: https://api.highcharts.com/highcharts/series.line.point.events.select
And the demo which shows how to get the array of selected points:
https://jsfiddle.net/BlackLabel/uq4nrtky/
point: {
events: {
select: function() {
var selectedPoints = chart.getSelectedPoints()
selectedPoints.push(this);
console.log(selectedPoints)
}
}
}

Related

Add event listener to element after DOMContentLoaded

I have some trouble with adding event listener to element after DOM updating.
I have some page, that sort two lists and save the stage.
I can move elements between this lists by d&d and by clicking special button. And it work fine for me.
https://jsfiddle.net/bmj32ma0/2/
But, I have to save stage of this lists, and after reloading I have to extract stage, so I write code below.
function saveFriendsLists(e) {
if(e.target.classList.contains("b--drugofilter--save-button")){
var vkFriends = document.querySelector('.b--friends-from-vk .js--friends-container').innerHTML;
var choosenFriends = document.querySelector('.b--friends-choosen .js--friends-container').innerHTML;
localStorage.setItem('vkFriends', vkFriends);
localStorage.setItem('choosenFriends', choosenFriends);
}
}
function loadFriensListFromStorage() {
if(localStorage&&localStorage.choosenFriends&&localStorage.vkFriends){
document.querySelector('.b--friends-from-vk .js--friends-container').innerHTML = localStorage.vkFriends;
document.querySelector('.b--friends-choosen .js--friends-container').innerHTML = localStorage.choosenFriends;
}
}
document.addEventListener("DOMContentLoaded", loadFriensListFromStorage);
But after adding this, the preview functionality like D&D doesn't work. And I can't provide you valid jsfidle because, as I can understand, localStoradge reason or something.
When I tried to move my addEventListener to loadFriensListFromStorage function, like this:
function loadFriensListFromStorage() {
if(localStorage&&localStorage.choosenFriends&&localStorage.vkFriends){
document.querySelector('.b--friends-from-vk .js--friends-container').innerHTML = localStorage.vkFriends;
document.querySelector('.b--friends-choosen .js--friends-container').innerHTML = localStorage.choosenFriends;
}
[].forEach.call(friends, function(friend) {
friend.addEventListener('dragstart', handleDragStart, false);
});
}
But that doesn't have any effect.
How can I fix this issue? Thx.

Openlayers 3: how to select a feature programmatically using ol.interaction.Select?

I'm using OpenLayers v3.6 (this is important, because most of solutions that I found and would potentialy work are for OpenLayers 2).
I have a table and when I select a row in that table, I would like to highlight/select a corresponding feature on the OpenLayers map. All features are simple polygons (ol.geom.Polygon) in the same vector layer (ol.layer.Vector).
I set up select interaction like this:
// there is a lot of other code here
...
addSelectListener: function() {
this.SelectInteraction = new ol.interaction.Select({
condition: ol.events.condition.singleClick,
layers: function (layer) {
// defines layer from which features are selectable
return layer.get('id') == 'polygons_layer';
},
style: this.Style.Selected
});
// Map = ol.Map
Map.addInteraction(this.SelectInteraction);
this.SelectInteraction.on('select', this.selectPolygon, this);
}
...
selectPolygon: function(event) {
var selectSrc = this.getSelectInfo(event);
// some code that relies on selectSrc data
}
...
getSelectInfo: function (event) {
var selectSrc = {
deselected: null,
selected: null,
type: null
};
if (event.selected.length == 0 && event.deselected.length == 1) {
// click outside of polygon with previously selected
selectSrc.type = 'deselect';
selectSrc.deselected = {
feature: event.deselected[0],
id: event.deselected[0].getId()
};
} else if (event.deselected.length == 0 && event.selected.length == 1) {
// click on polygon without previously selected
selectSrc.type = 'select';
selectSrc.selected = {
feature: event.selected[0],
id: event.selected[0].getId()
}
} else if (event.deselected.length == 0 && event.selected.length == 1) {
// click on polygon with previously selected
selectSrc.type = 'switch';
selectSrc.deselected = {
feature: event.deselected[0],
id: event.deselected[0].getId()
};
selectSrc.selected = {
feature: event.selected[0],
id: event.selected[0].getId()
}
} else {
selectSrc.type = 'out';
}
return selectSrc;
}
This functions well when I want to select polygon by clicking on it on the map. But what I want is to achieve the same, not by clicking on map but rather click on some element outside the map (table row in my example, but it could be anything really).
I would like to use select interaction because of event that is emitted and because of the styling it applies to selected features. However, if by any chance I can just manipulate the selected features in select interaction without having the same event it would be ok.
I'm aware of this question & answer - Openlayers 3: Select a feature programmatically - but the problem is that I cannot ask in comments for clarification (for example, what exactly is mySelectControl), because I don't have any reputation :)
The way to do is in the linked question. So, push a ol.Feature into the selected collection:
var select = new ol.interaction.Select({
//some options
});
map.addInteraction(select);
var selected_collection = select.getFeatures();
selected_collection.push(featurePoint);
If you want to trigger the select event:
select.dispatchEvent('select');
// OR
select.dispatchEvent({
type: 'select',
selected: [featurePoly],
deselected: []
});
See demo!

Highcharts tooltipRefresh check for hovered item

In Highcharts, I am currently using tooltipRefresh to run a function that renders dynamic content within the current tooltip.
For example, I am using:
chart: {
events: {
tooltipRefresh: function (e) {
createTableChartGauge();
}
}
}
I only want createTableChartGauge() to be run if the hovered data is a specific colour. I tried logging e that is passed through the tooltipRefresh function, although that just contains all chart data and nothing specific to the hovered data set.
How can I detect what element is currently be hovered so that I can render specific content per type?
You have access to this.hoverPoint, which contains actual point. So run your method only when colors match:
chart: {
events: {
tooltipRefresh: function (e) {
if(this.hoverPoint.color === "#eefffe") {
createTableChartGauge();
}
}
}
},

Hiding points in HighCharts on click

I got a HighChart with several 2 series.
Now I want certain points in series 1 to be disabled when I click a link.
This is my code so far:
$('.remove').click(function () {
var chart = $('#plot').highcharts(),
series = chart.series[0];
if (series.data.length) {
chart.series[0].data[0].remove();
}
});
The problem is, that after removing this point, [0] changes to another value and after clicking it again, it goes on and on with deleting.
I just want the points to disappear, this is possible with visible:
visible Since 1.2.0 Read only. The series' visibility state as set by
series.show(), series.hide(), or the initial configuration.
But I just don't manage to implement it the right way in my onClick event.
If I understand you well, you need to keep "place" where the point was? If yes, you can try to use point.update() function and set null value.
Example: http://jsfiddle.net/gd4q4jo0/1/
I solved clicks on a link to delete points like this:
$('.remove').click(function () {
var series = chart.series[0];
var id = $(this).data('id');
if (series.data.length) {
// disable point in graph
chart.series[0].data[id-1].update(
{
y:null
});
}
// delete used tablerow
$(this).closest("tr").fadeOut(50);
});
And I managed to expulse points onClick on the graph with an event, it's working like this:
series: [{
name: 'time',
data: data: [[1, 129386],[2, 123966],[3, 123162],[4, 123245],[5, 124314],[6, 123946],[7, 124156],[8, 123367],[9, 124460],[10, 123366],[11, 123182],[12, 123915],[13, 124627],[14, 123142],[15, 124044],[16, 124346],[17, 123156],[18, 124356],[19, 123511],[20, 124239],[21, 123252],[22, 125169],[23, 125027],[24, 123508],[25, 124065],[26, 122719],[27, 124199],[28, 122968],[29, 124132],[30, 124052],[31, 124383],[32, 123265],[33, 124083],[34, 123855],[35, 124284],[36, 123719],[37, 123213],[38, 124245],[39, 123079],[40, 123721]],
events: {
// if point gets clicked, it'll be deleted
click: function(event) {
console.log(event.point);
var pointId = event.point.x;
$("#hidden-points-table").fadeIn(1000);
$('#hidden-elements').append(pointId + ", ");
event.point.update(
{
y: null
});
// deleting the table row
$("[data-id='"+pointId+"']").closest("tr").fadeOut(50);
}
}
}
Since it was hard to find solutions, I hope this will help some people with it.
This page was really helpful, too.

Openlayers and catching drag event

Im using OpenLayers and i need to be able to tell difference between when map has been moved by my own scrip or by user. Yeah im aware that i can use moveend. But it also triggers when the same script is moving or repositioning map based on incoming data from ajax calls. So moveend or other map events wont work.
I did some googling and found OpenLayers.Hander.Drag. But all that i managed with it was to stop users from dragging map.
My script:
this.dragger = new OpenLayers.Handler.Drag('',{
'dragStart': function(evt){
this.userdragged = true;
console.log('drag');
}},{
'map':this.mymap
});
this.dragger.activate();
As you can see, i tried to set userdragged variable to true to use this same variable in moveend event later. Unfortunately all this did was to stop my map from beeing draggable.
Can someone assist me please?
Alan
Got it!
What got it working was :
dragcontrol = new OpenLayers.Control.DragPan({'map':this.mymap, 'panMapDone':function(evt){
this.userdragged = true;
console.log('drag');
}});
dragcontrol.draw();
this.mymap.addControl(dragcontrol);
dragcontrol.activate();
Booyaka!
Edit:
Actually this.userdragged wont work in there... the scope of this is different there. you would need to do something like var that = this; before that object initialization and use that.userdragged = true....
Edit2:
I later found, that this panMapDone function overwrites DragPans own method which has same name. With just my previous example, you can end up with map that results in vector features going out of sync with map, when user drags map. To stop that from happening, you should copy the original functionality into that function too... to make it look something like that:
dragcontrol = new OpenLayers.Control.DragPan({'map':this.mymap, 'panMapDone':function(xy){
if(this.panned) {
var res = null;
if (this.kinetic) {
res = this.kinetic.end(xy);
}
this.map.pan(
this.handler.last.x - xy.x,
this.handler.last.y - xy.y,
{dragging: !!res, animate: false}
);
if (res) {
var self = this;
this.kinetic.move(res, function(x, y, end) {
self.map.pan(x, y, {dragging: !end, animate: false});
});
}
this.panned = false;
}
that.userdragged = true;
// do whatever you want here
}});
dragcontrol.draw();
this.mymap.addControl(dragcontrol);
dragcontrol.activate();
Alan
Looking at the documentation on Drag handlers, it states that it's supposed to be used with a Control object. Are you using it that way? Maybe the code snippet doesn't show it?
"If a handler is being used without a control, the handlers setMap method must be overridden to deal properly with the map."
I haven't tried it, but it seems as you should go for something like this:
var myControl = new OpenLayers.Control();
var dragger = new OpenLayers.Handler.Drag{
control: myControl,
callbacks: { 'done': function() { // do something }},
options: {}
}
myMap.addControl(myControl);
myControl.activate();
Just posting an example here of executing an arbitrary function when the user drag the map, without interfering with the normal click-drag used to pan the map, because this page was the most frequent result during my search to find how to do that.
var CustomDragControl = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: {
'stopDown': false
/* important, otherwise it prevent the click-drag event from
triggering the normal click-drag behavior on the map to pan it */
},
initialize: function(options) {
this.handlerOptions = OpenLayers.Util.extend(
{}, this.defaultHandlerOptions
);
OpenLayers.Control.prototype.initialize.apply(
this, arguments
);
this.handler = new OpenLayers.Handler.Drag(
this, {
'down': this.onDown //could be also 'move', 'up' or 'out'
}, this.handlerOptions
);
},
onDown: function(evt) {
// do something when the user clic on the map (so on drag start)
console.log('user clicked down on the map');
}
});
then add the control to you map's controls list when creating the map instance, or with a map.addControl(), with
new CustomDragControl ({'autoActivate': true})
i have use that in OpenLayers 6:
map.on('pointerdrag', function (event) {
is_map_center = false;
})
hf gl!

Categories

Resources