Skip to content

Commit

Permalink
feat: smooth
Browse files Browse the repository at this point in the history
  • Loading branch information
neocarto committed Nov 2, 2022
1 parent 36aeb62 commit 913b87d
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 29 deletions.
87 changes: 86 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ All other parameters are the same as for the bubble layer
### Regular Square
The _regularsquare_ type is used to draw a map by proportional squares in a regular grid, from absolute quantitative data. [Source](https://github.com/neocarto/bertin/blob/main/src/layers/regularsquare.js), [Example ans methodology](https://observablehq.com/@neocartocnrs/bertin-js-regular-squares?collection=@neocartocnrs/bertin).
The _regularsquare_ type is used to draw a map by proportional squares in a regular grid, from absolute quantitative data. [Source](https://github.com/neocarto/bertin/blob/main/src/layers/regularsquare.js), [Example and methodology](https://observablehq.com/@neocartocnrs/bertin-js-regular-squares?collection=@neocartocnrs/bertin).
![](./img/regularsquare.png)
Expand All @@ -459,6 +459,40 @@ bertin.draw({
All other parameters are the same as for the square layer
### Regular grid
The _regulargrid_ type is a way to transform an irregular geographic mesh into a regular mesh. The values of the grid cells are obtained in proportion to the intersected surface. This representation mode is only suitable for absolute quantitative data. But you can use 2 quantitative data to compute a ratio [Source](https://github.com/neocarto/bertin/blob/main/src/layers/regulargrid.js), [Example and methodology](https://observablehq.com/@neocartocnrs/bertin-js-regular-grid).
![](./img/regulargrid.png)
#### Code
```js
bertin.draw({
layers: [
{
type: "regulargrid",
geojson: countries,
step:20,
values: "pop",
fill:{
nbreaks: 6,
method: "quantile",
colors: "Blues"
}
tooltip: "$value",
},
],
});
```
#### Parameters
- **step**: Gap between the points (default:20)
- **blur**: radius of the kernel defined in [d3.blur2](https://github.com/d3/d3-array/blob/main/README.md#blur) (default: 0)
All other parameters are the same as for [choropleth maps](https://github.com/neocarto/bertin#choropleth)
### Stock and ratio
In thematic mapping, we often have to represent an absolute quantitative data with a size variation and relative quantitative data with color variations. For this we can use the bubble type and the choro type together. [Example](https://observablehq.com/d/31a3309790d7bed9?collection=@neocartocnrs/bertin).
Expand Down Expand Up @@ -756,6 +790,57 @@ Parameters of the legend
- **leg_fontSize**: title legend font size (default: 14)
- **leg_fontSize2**: values font size (default: 10)
### Smooth
The _smooth_ type (or heatmap or contour) is a way to produce a continuous représentations from quantitative data. The algorithm is complex. The values produced do not really make sense. Explanations with the parameters. [Source](https://github.com/neocarto/bertin/blob/main/src/layers/smooth.js), [Example and methodology](https://observablehq.com/@neocartocnrs/smooth).
![](./img/smooth.png)
#### Code
```js
bertin.draw({
layers: [
{
type: "smooth",
geojson: data,
values: "pop",
thresholds: 50,
bandwidth: 25,
colorcurve: 1,
},
],
});
```
#### Parameters
- **geojson**: a geojson (**compulsory**)
- **values**: a string corresponding to the targeted variable in the properties
- **stroke**: stroke color (default: "white")
- **strokeWidth** stroke width (default:0.5)
- **strokeLinecap**: stroke-linecap (default:"round")
- **strokeLinejoin**: stroke-linejoin (default:"round")
- **strokeDasharray**: stroke-dasharray (default:"none")
- **fillOpacity**: fill opacity (default:1)
- **strokeOpacity**: stroke opacity (default:1)
- **display**: Boolean to allow to show or hide the layer. This parameter has no effect on the calculation of the extent. (default: true)
Contour parameters
-**fill**: color palette (default: RdYlGn)
-**thresholds**: number of classes (default: 100)
-**bandwidth**: bandwidth (the standard deviation) of the Gaussian kernel and returns the estimate. (default: 5)
-**colorcurve**: a value to curve the color interpolation (default: 2)
-**reverse**: a boolean reverse the colors (default: false)
-**remove**: number of polygons to remove (default: 0)
-**clip**: a boolean to clip the contours with the input geojson (default: false)
By default, the smooth layer is calculated from dots or centroids. But it is possible to go through a regular grid by using theses parameters.
- **grid_step**: Gap between the points (default:20)
- **grid_blur**: radius of the kernel defined in [d3.blur2](https://github.com/d3/d3-array/blob/main/README.md#blur) (default: 0)
### Thickness
On each layer, you can dynamically vary the thickness of the paths. This can be useful to make for example flow maps or discontinuity maps. [Source](https://github.com/neocarto/bertin/blob/main/src/helpers/thickness.js)
Expand Down
Binary file added img/smooth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ export function draw({ params = {}, layers = {} } = {}) {
projection,
{
display: layer.display,
clip: layer.clip,
geojson: layer.geojson,
values: layer.values,
grid_step: layer.grid_step,
Expand Down
68 changes: 40 additions & 28 deletions src/layers/smooth.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { grid } from "../helpers/grid.js";
import { figuration } from "../helpers/figuration.js";
import { centroid } from "../helpers/centroid.js";
import { geoIdentity, geoPath } from "d3-geo";
import { contourDensity } from "d3-contour";
import { scaleSequentialQuantile } from "d3-scale";
Expand All @@ -23,6 +25,7 @@ export function smooth(
) {
// Variables
let display = options.display == false ? false : true;
let clip = options.clip != undefined ? options.clip : undefined;
let reverse = options.reverse == undefined ? false : options.reverse;
let fill = options.fill ? options.fill : "RdYlGn";
let strokeLinecap = options.strokeLinecap ? options.strokeLinecap : "round";
Expand All @@ -45,32 +48,40 @@ export function smooth(
let cellsize = options.cellSize != undefined ? options.cellSize : 1;
let colorcurve = options.colorcurve != undefined ? options.colorcurve : 2;

let id = Date.now().toString(36) + Math.random().toString(36).substring(2);
if (display) {
let data;

if (options.grid_step != undefined || options.grid_blur != undefined) {
let grid_step = options.grid_step != undefined ? options.grid_step : 20;
let grid_blur = options.grid_blur != undefined ? options.grid_blur : 0;

options.geojson = grid({
geojson: options.geojson,
projection: projection,
width: width,
height: height,
step: grid_step,
values: options.values,
blur: grid_blur,
});

data = decompose(options.geojson, "value", 1000, d3.geoIdentity());

// console.log("GRID");
// console.log(data);
} else {
data = decompose(options.geojson, options.values, 1000, projection);

// console.log("PAS GRID");
// console.log(data);
if (figuration(options.geojson) == "z") {
if (options.clip) {
// test

selection
.append("clipPath")
.attr("id", `clip_${id}`)
.append("path")
.datum(options.geojson)
.attr("d", d3.geoPath(projection));
}

if (options.grid_step != undefined || options.grid_blur != undefined) {
let grid_step = options.grid_step != undefined ? options.grid_step : 20;
let grid_blur = options.grid_blur != undefined ? options.grid_blur : 0;

let mygrid = grid({
geojson: options.geojson,
projection: projection,
width: width,
height: height,
step: grid_step,
blur: grid_blur,
values: options.values,
});
data = decompose(mygrid, "value", 1000, d3.geoIdentity());
} else {
options.geojson = centroid(options.geojson);
data = decompose(options.geojson, options.values, 1000, projection);
}
}

let contour = d3
Expand Down Expand Up @@ -140,9 +151,14 @@ export function smooth(

contours.splice(0, remove);

// Smooth

selection
.append("g")
.attr("clip-path", clipid == null ? `none` : `url(#clip_${clipid})`)
.attr(
"clip-path",
options.clip == undefined ? `none` : `url(#clip_${id})`
)
.selectAll("path")
.data(contours)
.join("path")
Expand All @@ -155,10 +171,6 @@ export function smooth(
.attr("stroke-linecap", strokeLinecap)
.attr("stroke-linejoin", strokeLinejoin)
.attr("stroke-dasharray", strokeDasharray);

// console.log(options.geojson);

// simple(selection, geoIdentity(), options, clipid, width, height);
}
}

Expand Down

0 comments on commit 913b87d

Please sign in to comment.