Skip to content

Commit

Permalink
1st commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Abel Vazquez committed Dec 31, 2020
1 parent 6092042 commit 4d5111d
Show file tree
Hide file tree
Showing 11 changed files with 3,118 additions and 1 deletion.
100 changes: 99 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,99 @@
# maplibre-gaugelegend-pre
# Dynamic gauge legend for MapLibre

![img](screenshot.png)

This simple control adds a dynamic legend component to a [MapLibre GL](https://github.com/MapLibre/maplibre-gl-js) map, where, for a given layer and property, the average value of this property for the features currently rendered is displayed and a tick points to its position in the gauge scale.

It's based in the gauge I implemented in the app [Distanciamiento peatonal in Madrid](https://distanciamiento.inspide.com/) (a map where the width of the sidewalks in Madrid are evaluated in terms of keeping the required social distancing), but made into a proper parametric control.

## How to

It has no dependencies, but if you want to use it as an UMD bundle, you need to

```bash
yarn install
yarn build
```

You will find the deliverables in the `/dist` folder. Just reference the CSS in your html

```html
<link rel="stylesheet" type="text/css" href="dist/gaugelegend.css" />
```
If you want to use the global `GaugeLegend` object instead of importing the module, then you need to add the script too

```html
<script src="dist/gaugelegend.js"></script>
```

Then, in your script

```javascript
const map = new maplibre.Map({ ... });

map.on('load', function () {
map.addLayer({
id: 'my_layer',
...
});
const gauge = new GaugeLegend({
layer: 'my_layer',
property: 'my_property',
colors: ["#007080", "#546e82", "#7f6984", "#a16287", "#c25689", "#e0448b", "#ff1d8e"],
breaks: [7,17,32,57,129,253,334]
});
map.addControl(gauge, 'top-right');
})

```

And Ta-da!


Check the live example [here]()

## Parameters

| Param | Datatype | Description | Default |
|---|---|---|---|
| layer | string | The ID of the layer to be observed | |
| property | string | The property that will be observed | |
| colors | string[ ] | Array of HEX colors to be used in the legend. Should match the ones used to style the layer | |
| breaks | number[ ] | Array of breaks of the classification of the selected property. Must have the same size as `colors` | |
| theme | enum['dark', 'light'] | Avaliable themes | 'dark' |
| size | string | Max diameter of the control in [CSS units](https://www.w3schools.com/cssref/css_units.asp). It tries to grow up to 20% of the height of the viewport, limited by this value | '100px' |
| unit | string | Unit symbol to be added to the displayed value | '' |
| text1 | string | Upper text | '' |
| text2 | string | Bottom text | '' |
| trigger | enum['idle', 'moveend'] | Map event that fires the control update. It defaults to `idle` as it's safer when the tiles are heavy or the number of rendered features is high. `moveend` gives a smoother experience but might give false results | 'idle' |

## Custom theming
Custom themes can be used by adding the needed classes in your CSS:

```css
.gauge-mycustomtheme {
/* Using semitransparent background
lightens the visual weight of the control */
background: my_background_color;
}
.text-mycustomtheme {
color: my_font_color;
/* Adding a halo to improve readability
if semitransparent background was used */
text-shadow: 0 0 3px my_background_color_no_transparency;
}
```

The tick won't be themed as its color doesn't rely on CSS, but this issue can be overrided:

```javascript
gauge._tick.setAttribute('stroke', my_tick_color);
```

## To Do

* Change CSS classes to `maplibre` namespace when available.

## Notes

Example favicon by [Nick Roach](https://www.elegantthemes.com/)
Binary file added example/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions example/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="icon"
type="image/png"
href="favicon.png" />

<title>Gauge Legend for MapLibre</title>

<link rel="stylesheet" type="text/css" href="https://cdn.skypack.dev/maplibre-gl/dist/mapbox-gl.css" />
<link rel="stylesheet" type="text/css" href="../dist/gaugelegend.css" />


<link rel="stylesheet" type="text/css" href="style.css" />
<script type="module" src="script.js"></script>

</head>

<body>
<div id="map"></div>
</body>

</html>
51 changes: 51 additions & 0 deletions example/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* jshint esversion: 6 */
import maplibre from 'https://cdn.skypack.dev/pin/[email protected]/min/maplibre-gl.js';
import '../dist/gaugelegend.js';

const config = {
layer: 'test',
property: 'kdensity',
text1: 'kernel',
text2: 'density',
colors: ["#007080", "#546e82", "#7f6984", "#a16287", "#c25689", "#e0448b", "#ff1d8e"],
breaks: [7,17,32,57,129,253,334]
};

const map = new maplibre.Map({
container: 'map',
style: 'https://tiles.basemaps.cartocdn.com/gl/positron-gl-style/style.json',
center: [-3.703793, 40.416687],
zoom: 12,
minZoom: 10,
maxZoom: 21,
});

map.on('load', function () {
map.addLayer({
id: 'test',
type: 'circle',
source: {
type: 'vector',
tiles: ['https://abelvm.carto.com/api/v1/map/named/tpl_55d34678_9879_4bb8_ac58_d3b93056a3cb/mapnik/{z}/{x}/{y}.mvt'],
maxzoom: 15
},
'source-layer': '4bca3307-6917-4394-9261-cda2b92706cf',
"paint": {
'circle-radius': 4,
'circle-color':{
"property": "kdensity",
"stops": [
[config.breaks[0], config.colors[0]],
[config.breaks[1], config.colors[1]],
[config.breaks[2], config.colors[2]],
[config.breaks[3], config.colors[3]],
[config.breaks[4], config.colors[4]],
[config.breaks[5], config.colors[5]],
[config.breaks[6], config.colors[6]]
]
}
}
});
const gauge = new GaugeLegend(config);
map.addControl(gauge, 'bottom-right');
});
14 changes: 14 additions & 0 deletions example/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
body {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
}
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "gauge-legend",
"version": "0.0.1",
"author": {
"name": "Abel Vázquez Montoro",
"url": "https://abelvm.github.io"
},
"main": "src/index.js",
"private": true,
"devDependencies": {
"browserify": "^17.0.0",
"cssnano": "^4.1.10",
"postcss": "^8.2.2",
"postcss-cli": "^8.3.1",
"terser": "^5.5.1"
},
"dependencies": {},
"scripts": {
"build": "browserify src/index.js --standalone GaugeLegend | terser -c -m --source-map -o dist/gaugelegend.js & postcss src/index.css > dist/gaugelegend.css"
}
}
7 changes: 7 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
plugins: [
require('cssnano')({
preset: 'default',
}),
],
}
Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 75 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
.gauge-core {
padding: 10px;
border-radius: 50%;
margin: 8px;
pointer-events: none;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position:relative;
}

.legend,
.gauge-core {
width: 20vh;
height: 20vh;
}

.gauge-core svg {
position: absolute;
top: 0px;
left: 0px;
z-index: 99999;
}

/*
TODO: change to maplibre namespace a soon as its available
*/
.mapboxgl-ctrl-top-right .gauge-core ,
.mapboxgl-ctrl-bottom-right .gauge-core {
margin-left: auto;
}

.titol {
font-size: x-small;
}

.valor {
font-size: x-large;
font-weight: bolder;
}

.min,
.max {
font-size: xx-small;
position: absolute;
}

.min {
top: 50%;
left: 5px;
}

.max {
top: 50%;
right: 5px;
}

.text-light {
text-shadow: 0 0 3px #ffffff;
color: #333;
}

.text-dark {
text-shadow: 0 0 3px #000000;
color: #ddd;
}

.gauge-light {
background: rgba(255, 255, 255, 0.7);
}

.gauge-dark {
background: rgba(0, 0, 0, 0.7);
}
Loading

0 comments on commit 4d5111d

Please sign in to comment.