OpenLayers toggle feature visibility (Show/hide) - javascript

I am trying to show or hide features on click.
I have many points with different colors, I am trying to change opacity to 0/1.
What I managed to do is set 2 different feature styles and use setStyle on click.
I can hide a feature but when I try to unhide it all features become the same image I use instead of going to colors they were before hiding. I'll try to explain better with picture examples and some code snippets. Image 1 shows features on map load, Image 2 shows features when toggled to Hide, Image 3 shows features when toggled to Show (I don't want features to be styled like that, I want to features be styled as they were in Image 1)
This is the code snippet:
//visible style
var visibleStyleIcon = {
Point: [
new ol.style.Style({
image: new ol.style.Icon({
src: "https://openlayers.org/en/latest/examples/data/dot.png",
opacity: 1,
}),
}),
],
};
// invisible Style Icon Opacity
var invisibleStyleIcon = {
Point: [
new ol.style.Style({
image: new ol.style.Icon({
src: "https://openlayers.org/en/latest/examples/data/dot.png", //still need something even if it's invisible
opacity: 0,
}),
}),
],
};
forEachFeatureInExtent(extent, function (feature) {
if (
Object.values(Object.values(feature.get("info"))[0][2])[1] === t
) {
if (e.target.className === "menu-selector2")
feature.setStyle(
invisibleStyleIcon[feature.getGeometry().getType()]
);
if (e.target.className === "menu-selector")
feature.setStyle(
visibleStyleIcon[feature.getGeometry().getType()]
);
}
});
So is there a way to just set opacity for feature to 0 or 1?
I tried this with no success.
var style = feature.getStyle();
var color = style.getFill().getColor();
var colorArray = ol.color.asArray(color).slice();
colorArray[3] = 1;
style.getFill().setColor(colorArray);
feature.setStyle(style);
selectedLayer.redraw();
I found this also:
feature.getStyle().getImage().setOpacity(0);
But that function shows/hides all points with same Style, not just the selected one. For example, if I want to hide 1 feature and its a grey circle, it will hide all grey circles in extent.

Layer setStyle method will iterate through all features of that layer.
you should have a function like this example, and every time that you want style features based on a specific condition (it can be feature id or any other property) you can call this function and pass the layer and featureId and style your features accordingly.
function setLayerStyle(layer, featureId) {
layer.setStyle(feature => {
if (feature.getProperties().id === featureId) {
return style a
} else {
return style b
}
})
}

Related

Opacity is not applied for Fill for KML layer in openlayers 5

I am currently upgrading our openlayers from 2.x to 5.3.
We have some KML files on the server which should be displayed as individual layers on the map. This is working perfectly fine after the upgrade except that the fill of the polygons of the KML do not apply the opacity provided in the color alpha [r,g,b,alpha].
I know this issue has been discussed frequently but the suggested solution always included to add the opacity in the alpha of the color, which is not working for me. I tried to use both, a color array and defining the color via rgba text. But the opacity of the KML content fill is always one.
However, the opacity is working when I add the opacity field to the layer object. But I only need the fill to have an opacity and not the stroke.
As this might be of interest, I have integrated Google layers in my project by applying the OL3GM project. Thus, the ol.js file is integrated by this ol3gm project.
//pConfig contains all the relevant information
var lKmlLayers = [];
for(var i = 1; i < pConfig['kmlFiles'].length;++i) {
var lLayerName = getBaseName(pConfig['kmlFiles'][i][1]);
var lDropBoxPathParamValue = '?dropBoxPath=' + pConfig['kmlFiles'][i][0];
var lContextParamValue = '&context=' + pConfig['context'];
var lProjectIdParamValue = '&projectId=' + pConfig['projectId'];
var lKmlFileNameParamValue = '&kmlFileName=' + pConfig['kmlFiles'][i][1];
//here I define the fill color and set the opacity value
var fillColor = ol.color.asArray(pConfig['kmlFiles'][i][2]);
fillColor = fillColor.slice();
fillColor[3] = 0.3;
var strokeColor = ol.color.asArray(pConfig['kmlFiles'][i][2]);
strokeColor = strokeColor.slice();
strokeColor[3] =1;
lKmlLayers[i-1] = new ol.layer.Vector({
title:lLayerName,
source: new ol.source.Vector({
url: pConfig['context'] + '/filedata' + lDropBoxPathParamValue + lContextParamValue + lProjectIdParamValue + lKmlFileNameParamValue,
format: new ol.format.KML()
}),
style: new ol.style.Style({
fill: new ol.style.Fill({
color: fillColor
}),
stroke: new ol.style.Stroke({
color: strokeColor,
width: 1
})
}),
//opacity: 0.3//if I add this, the opacity is applied for the complete layer
});
}
The opacity of the fill is not applied. The KML layers fill is always displayed with an opacity of 1 although I set it to 0.3. Can somebody tell me why and tell me how to fix this?
Thank you for your support.
In this case specifying
format: new ol.format.KML({ extractStyles: false })
was sufficient to prevent styles being applied directly to the features and allow the layer style to take effect. In some cases that might not work as OpenLayers can apply a default style and you would need to loop through the features and remove the styles. See Heatmap in Openlayers using an XML (KML formatted) string, styling is incorrect

Set feature before selected element in OpenLayers

I have a some features that must be always in front of any other feature, the problem is that when I draw new feature or select current one it overlaps all other features.
Is there a way I can set some features or a layer to be always on top of everything ?
I suspect you are not specifying zIndex in the selected style for the interaction. In this code sample for hover on features in certain layers I set the selected style to be the same as the normal unselected style for the layer and only change the cursor
var interStyle;
function interFilter(feature, layer) {
for (var i = 0; i < layerTypes.length; i++) {
if (layer && layer.get("jsonName") && layer.get("jsonName").slice(-7) == layerTypes[i] + ".json") {
interStyle = layer.getStyle();
return true;
}
}
return false;
}
var interHover = new ol.interaction.Select({ condition: ol.events.condition.pointerMove,
style: function(feature) { return interStyle; },
filter: interFilter });
interHover.on( "select",
function(event) { rowMap.getViewport().style.cursor = event.selected.length > 0 ? "pointer" : "";
// optional callback to inform the calling page the mouse is over/off a feature
if (options.setMouseOver) { options.setMouseOver(event.selected.length > 0); } }
);
The purple line remains below the green line at all times:
However if I comment out the style setting
var interHover = new ol.interaction.Select({ condition: ol.events.condition.pointerMove,
// style: function(feature) { return interStyle; },
filter: interFilter });
When hovering over the purple line it takes OpenLayers default blue selected style and appears above the green line

Make Highcharts 'shared' tooltip color different from series color [duplicate]

By default, the border takes the color of the corresponding series or point. But I'd like to set a different color to the tooltip of a certain data point, without changing the color of the data point itself.
I needed something like this:
series: [ { x:1, value: 2.34, tooltip:{borderColor: '#112233'} }, ... ];
Sadly this property can not be set from a series.
By setting a formatter callback function in the tooltip configuration one can only define the inner HTML of the tooltip, i.e. the border color can not be changed from within this function.
Can this only be achieved by some CSS trickery?
It can be achieved by wrapping tooltip.refresh() method.
First, I check if the tooltip is shown, not shared, not split (a shared or split tooltip require a little different code). Then, I check if the options are set and change svg element's stroke attribute.
Highcharts.wrap(Highcharts.Tooltip.prototype, 'refresh', function(p, point, mouseEvent) {
p.call(this, point, mouseEvent);
if (!this.isHidden && !this.shared && !this.split) {
var pointTooltipBorderColor = point &&
point.options.tooltip &&
point.options.tooltip.borderColor,
seriesTooltipBorderColor = point &&
point.series &&
point.series.options.tooltip &&
point.series.options.tooltip.borderColor,
borderColor = pointTooltipBorderColor || seriesTooltipBorderColor,
label = this.label;
if (label && borderColor) {
label.attr({
stroke: borderColor
});
}
}
});
Example: http://jsfiddle.net/oLnfqhmn/2/

Label to flows in JointJS

I'm working with jointJs and Rappid. I know how to draw a bpmn diagram, as the photo I have attached. I'm drawing the elements, but I'm having some problems with rows (flows). Is there any way to add a flow label or name? As I added on my image in red color.
I have seen this in their documentation, but I can't see anything about labels
var flow = new joint.shapes.bpmn.Flow({
source: { id: task.id },
target: { id: annotation.id },
flowType: 'association'
});
Thanks,
You may want to look into dia.Link.prototype.labels, since BPMN Flows are just Links extensions (joint.shapes.bpmn.Flow = joint.dia.Link.extend({).
An example to your flow:
flow.label(0, // the label's index (you can have multiple labels per link/flow)
{
position: .5, // place it halfway on the link (0-1)
attrs: {
text: { fill: 'red', text: 'Label' }
}
}
);

How to change the color of clustered pins in BingMaps?

I am trying to change the color of the clustered pushpins from the default purple to something else. I don't see anything obvious in the documentation. I tried the following:
var layer = new Microsoft.Maps.ClusterLayer(clusterPins, {
color: 'yellow'
});
but it has no effect. Oddly enough, the individual pins themselves (when they are not clustered) can be colored:
var clusterPin = new Microsoft.Maps.Pushpin(location, {
color: 'yellow'
});
Do I really have to go the route of creating an SVG just to change the color of the clustered pin?
You need to use the clusteredPinCallback option to set the style of clustered pushpins. For example:
var clusterLayer = new Microsoft.Maps.ClusterLayer(pins, {
clusteredPinCallback: function(clusterPin){
clusterPin.setOptions({ color: 'yellow' });
}
});
This is done as most devs want to customize the cluster based on the cluster size or content inside the cluster. Here is a more in-depth code sample: http://bingmapsv8samples.azurewebsites.net/#Clustering_Customization

Categories

Resources