Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add resetStyle to L.featureGroup #9309

Open
3 tasks done
kraktus opened this issue Apr 2, 2024 · 1 comment
Open
3 tasks done

Add resetStyle to L.featureGroup #9309

kraktus opened this issue Apr 2, 2024 · 1 comment
Labels

Comments

@kraktus
Copy link

kraktus commented Apr 2, 2024

Checklist

  • I've searched through the plugins to make sure this feature isn't already available, or think it shouldn't require a plugin.
  • I've searched through the current issues to make sure this feature hasn't been requested already.
  • I agree to follow the Code of Conduct that this project adheres to.

Motivation

Hello, thanks for the great lib.

The geojson layers has plenty of QoL methods like geojson.resetStyle() that would be great to have when working with other types of layers, in my case L.featureGroup.

When hovering off a featureGroup it is very inconvenient to reset its style, when each element of it has a different style. The advice found on the internet advising to store a default and highlight style, only works when you want to style all the elements similarly.

pseudo-code MCVE

const highLightStyle = {
  weight: 3,
  color: '#666',
  dashArray: '',
  fillOpacity: 0.7,
};

let currentlyHighlighted: L.Layer | undefined = undefined;

const resetHighlight = (e: L.LeafletMouseEvent) => {
  ??? // here layer.resetStyle() would be perfect
  // layer.options does not work for FeatureGroup
};

const highlightFeature = (e: L.LeafletMouseEvent) => {
    let layer = e.target;
    currentlyHighlighted = layer;
    layer.setStyle(highLightStyle);
    layer.bringToFront();
  };

export const mcve = (map: L.Map) => {
  // minimal geojson polygon
  const polygon = {
    ...
  }
  const geojson = L.geoJson(polygon, { style: ... }); // different than the circles
  const circles = [...] // each circle has a different style
  // in my case the click behavior is different for circles and geojson, and is added independently 
  ...
  // mouseover is shared
  const layer = L.featureGroup([polygon, ...circles]);
    layer.on({
      mouseover: highlightFeature,
      mouseout: resetHighlight,
    });
    
  layer.addTo(map);
}

Suggested solution

Add resetStyle method to L.featureGroup, behaving exactly like the method of the same name on L.geojson

Alternatives considered

Maybe to amend the geojson to add the circles as a MultiPoint in it? But in that case hovering over a point would not display the outline of the polygon.

@kraktus kraktus added feature needs triage Triage pending labels Apr 2, 2024
@kraktus
Copy link
Author

kraktus commented Apr 4, 2024

In the meantime, if someone else stumbles on this issue, here is a workaround (basically tracking the style of each object yourself).

const highLightStyle = {
  weight: 3,
  color: '#666',
  dashArray: '',
  fillOpacity: 0.7,
};

const resetHighlight = (originalStyle: OriginalStyle) => (e: L.LeafletMouseEvent) => {
  originalStyle.resetStyle()
};

const highlightFeature = (e: L.LeafletMouseEvent) => {
    let layer = e.target;
    currentlyHighlighted = layer;
    layer.setStyle(highLightStyle);
    layer.bringToFront();
  };

export const mcve = (map: L.Map) => {
  // minimal geojson polygon
  const polygon = {
    ...
  }
  const originalStyle = new OriginalStyle();
  const geojson = L.geoJson(polygon, { style: style }); // different than the circles
  originalStyle.addGeoJson(geojson, style(style));
  const circles = [...] // each circle has a different style
  circles.foreach(c => originalStyle.addPath(c));
  // in my case the click behavior is different for circles and geojson, and is added independently 
  ...
  // mouseover is shared
  const layer = L.featureGroup([polygon, ...circles]);
    layer.on({
      mouseover: highlightFeature,
      mouseout: resetHighlight(originalStyle),
    });
    
  layer.addTo(map);
}

const style = (feature?: Feature): L.PathOptions => { ... }

// Manually track the original style of each object in the layer
class OriginalStyle {
  private elm: [L.Path | L.GeoJSON, L.PathOptions][];
  constructor() {
    this.elm = [];
  }
  addPath(layer: L.Path) {
    // deepCopy is conservative here
    this.elm.push([layer, deepCopy(layer.options)]);
  }

  addGeoJson(geojson: L.GeoJSON, styleOptions: L.PathOptions) {
    // deepCopy is conservative here
    this.elm.push([geojson, deepCopy (styleOptions)]);
  }

  resetStyle() {
    for (const [layer, style] of this.elm) {
      layer.setStyle(style);
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant