Bertin.js is a JavaScript library for visualizing geospatial data and make thematic maps for the web.

Overview

logo

npm jsdeliver license code size github stars

Bertin.js is a JavaScript library for visualizing geospatial data and make thematic maps for the web.

The project is under active development. Some of features and options are subject to change. We welcome contributions of all kinds: bug reports, code contributions and documentation.

Bertin.js is an easy to use JavaScript library mainly based on D3.js makes creating thematic maps simple. The principle is to work with layers stacked on top of one other. Much like in Geographic Information Software (GIS) software, Bertin.js displays layers with a specific hierarchy. The layer at bottom are rendered and then followed by the layer right above it. Some of the layers are used to display various components of a map, some of common layers are: header, footer, graticule, outline, choro, typo, prop, shadow, scalebar, text etc.

Who is Bertin?

Jacques Bertin (1918-2010) was a French cartographer, whose major contribution was a theoretical and practical reflection on all graphic representations (diagrams, maps and graphs), forming the subject of a fundamental treatise, Graphic Semiology, originally published in 1967. Bertin's influence remains strong not only in academics, teaching of cartography today, but also among statisticians and data visualization specialists.

Installation

In browser

Latest version

">
<script src="https://cdn.jsdelivr.net/npm/bertin" charset="utf-8">script>

Pinned version

">
<script
  src="https://cdn.jsdelivr.net/npm/[email protected]"
  charset="utf-8"
>script>

In Observable

Latest version

bertin = require("bertin");

Pinned version

bertin = require("[email protected]");

Usage

In browser

">
<script src="https://cdn.jsdelivr.net/npm/d3@7">script>
<script src="https://cdn.jsdelivr.net/npm/d3-geo-projection@4">script>
<script src="https://cdn.jsdelivr.net/npm/bertin">script>

<script>
  let geojson =
    "https://raw.githubusercontent.com/neocarto/bertin/main/data/world.geojson";

  d3.json(geojson).then((r) =>
    document.body.appendChild(
      bertin.draw({
        params: {
          projection: d3.geoVanDerGrinten4(),
          clip: true,
        },
        layers: [
          { geojson: r, tooltip: ["$ISO3", "$NAMEen"] },
          { type: "outline" },
          { type: "graticule" },
        ],
      })
    )
  );
script>

See examples: Example 1, Example 2 and Example 3.

In Observable Notebook

The bertin.js library is really easy to use within an Observable notebook. You'll find many examples in this notebook collection. Feel free to fork, copy, modify with your own data.

Drawing a map

draw() is the main function of the library. It allows you to make various thematic maps. It allows to display and overlay different types of layers listed below. The layers written on top are displayed first. Source Example

Global parameters

In the section params, we define the global parameters of the map: its size, projection, background color, etc. To have access to a large number of projections, you will need to load the d3-geo-projection@4 library. This section is optional.

Code

bertin.draw({
  params: {
    projection: d3.geoBertin1953(),
    width: 750,
  },
  layers: [...]
})

Parameters

  • projection: a d3 function or string defining the map projection. Refer d3-geo-projection and spatialreference.org for more detailed explanation. (default: d3.geoEquirectangular() except if you use tiles. in this case, the projection is automatically set to d3.geoMercator()). Moreover, if you define projection as "user", you can display a basemap already projected. Example. Note alsa that custom projections are available. Try "Polar", "Spilhaus" or "HoaXiaoguang".
  • width: width of the map (default:1000);
  • extent: a feature or a bbox array defining the extent e.g. a country or [[112, -43],[153, -9]] (default: null)
  • margin: margin around features to be displayed. This option can be useful if the stroke is very heavy (default: 1)
  • background: color of the background (default: "none")
  • clip: a boolean to avoid artifacts of discontinuous projection (default: "false")

Map types

Simple layer

The layer type allows to display a simple geojson layer (points, lines or polygons). Source. Example 1 and Example 2.

Code

bertin.draw({
  layers: [
    {
      type: "layer",
      geojson: *a geojson here*,
      fill: "#e6acdf",
    }
  ]
})

Parameters

  • geojson: a geojson (compulsory)
  • fill: fill color (default: a random color)
  • 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)
  • symbol: if it is a dot layer, the type of symbol. "circle", "cross", "diamond", "square", "star", "triangle", "wye" (default: "circle")
  • symbol_size: if it is a dot layer, a number indicating the size of the symbol (default: 5)
  • symbol_shift: if it is a dot layer, use a value > 0 to switch symbols and avoid overlay (default: 0)
  • symbol_iteration: Number of iteration to shift symbols (default: 200)

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_w: width of the box (default: 30)
  • leg_h: height of the box (default: 20)
  • leg_title: title of the legend (default: null)
  • leg_text: text of the box (default: "leg_text")
  • leg_fontSize: title legend font size (default: 14)
  • leg_fontSize2: values font size (default: 10)
  • leg_fill: color of the box (same as the layer displayed)
  • leg_stroke: stroke of the box (default: "black")
  • leg_strokeWidth: stroke-width (default: 0.5)
  • leg_fillOpacity: stroke opacity (same as the layer displayed)
  • leg_txtcol: color of the text (default: "#363636")

Choropleth

The choro type aims to draw Choropleth maps. This kind of representation is especially suitable for relative quantitative data (rates, indices, densities). The choro type can be applied to the fill or stroke property of a simple layer. Example.

Code

bertin.draw({
  layers: [
    {
      type: "layer",
      geojson: data,
      fill: {
        type: "choro",
        values: "gdppc",
        nbreaks: 5,
        method: "quantile",
        colors: "RdYlGn",
        leg_round: -1,
        leg_title: `GDP per inh (in $)`,
        leg_x: 100,
        leg_y: 200
      }
  ]
})

Parameters

  • values: a string corresponding to the targeted variable in the properties (compulsory)
  • nbreaks: Number of classes (default:5)
  • breaks: Class breaks (default:null)
  • colors: An array of colors or a palette of categorical colors (default: "Blues") See
  • method: A method of classification. Jenks, q6, quantiles, msd (mean standard deviation), equal (default: quantiles). See statsbreaks example for method implementation in action.
  • middle: for msd method only. middle class or not (default:false);
  • k: for msd method only. number of sd. (default:1);
  • col_missing: Color for missing values (default "#f5f5f5")
  • txt_missing: Text for missing values (default "No data")
  • stroke: stroke color (default: "white")
  • strokeWidth: Stroke width (default: 0.5)
  • fillOpacity: Fill opacity (default: 1)

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_w: width of the box (default: 30)
  • leg_h: height of the box (default:20)
  • leg_text: text of the box (default: "leg_text")
  • leg_fontSize: text font size (default: 10)
  • leg_fill: color of the box (same as the layer displayed)
  • leg_stroke: stroke of the box (default: "black")
  • leg_strokeWidth: stroke-width (default: 0.5)
  • leg_fillOpacity: stroke opacity (same as the layer displayed)
  • leg_txtcol: color of the text (default: "#363636")
  • leg_round: Number of digits (default: undefined)

Typology

The typo type allows to realize a qualitative map. The choro type can be applied to the fill or stroke property of a simple layer. Example.

Code

bertin.draw({
layers: [
  {
    type: "layer",
    geojson: data,
    fill: {
      type: "typo",
      values: "region",
      pal: "Tableau10",
      tooltip: ["$region", "$name"],
      leg_title: `The Continents`,
      leg_x: 55,
      leg_y: 180
    }
  ]
})

Parameters

  • values: a string corresponding to the targeted variable in the properties (compulsory)
  • colors: An array containing n colors for n types, or a a palette of categorical colors (default: "Tableau10"). See the handy color scheme reference for full list of palettes.
  • order: an array of values to set the order of the colors
  • col_missing: Color for missing values (default "#f5f5f5")
  • txt_missing: Text for missing values (default "No data")
  • stroke: stroke color (default: "white")
  • strokeWidth: Stroke width (default: 0.5)
  • fillOpacity: Fill opacity (default: 1)

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_w: width of the box (default: 30)
  • leg_h: height of the box (default:20)
  • leg_title: title of the legend (default; null)
  • leg_fontSize: title legend font size (default: 14)
  • leg_fontSize2: values font size (default: 10)
  • leg_stroke: stroke of the box (default: "black")
  • leg_strokeWidth: stroke-width (default: 0.5)
  • leg_fillOpacity: stroke opacity (same as the layer displayed)
  • leg_txtcol: color of the text (default: "#363636")

Bubble

The bubble type is used to draw a map by proportional circles. Source, Example.

Code

bertin.draw({
  layers: [
    {
      type: "bubble",
      geojson: countries,
      values: "pop",
      k: 60,
      tooltip: ["$country", "$pop", "(inh.)"],
    },
  ],
});

Parameters

  • geojson: a geojson (compulsory)
  • values: a string corresponding to the targeted variable in the properties(compulsory)
  • k: size of the largest circle (default:50)
  • fixmax: Max value to fix the size of the biggest circle, in order to make maps comparable (default:undefined)
  • fill: fill color (default: random color)
  • stroke: stroke color (default: "white")
  • strokeWidth: stroke width (default: 0.5)
  • fillOpacity: fill opacity (default: 1)
  • dorling: a boolean (default:false)
  • iteration: an integer to define the number of iteration for the Dorling method (default: 200)
  • tooltip: an array of values defining what to display within the tooltip. If you use a $, the value within the geojson is displayed. Example.

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_fill: color of the circles (default: "none")
  • leg_stroke: stroke of the circles (default: "black")
  • leg_strokeWidth: stoke-width (default: 0.8)
  • leg_txtcol: color of the text (default: "#363636")
  • leg_title: title of the legend (default var_data)
  • leg_round: number of digits after the decimal point (default: undefined)
  • leg_fontSize: title legend font size (default: 14)
  • leg_fontSize2: values font size (default: 10)

Regular Bubble

The regularbubble type is used to draw a map by proportional circles in a regular grid. Source, Example.

Code

bertin.draw({
  layers: [
    {
      type: "regularbubble",
      geojson: countries,
      step:20,
      values: "pop",
      k: 60,
      tooltip: ["$country", "$pop", "(inh.)"],
    },
  ],
});

Parameters

  • step: Gap between the points (default:20)

All other parameters are the same as for the bubble layer

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.

Code

bertin.draw({
  params: { projection: d3.geoPolyhedralWaterman() },
  layers: [
    {
      type: "bubble",
      geojson: data,
      leg_round: -2,
      values: "pop",
      fill: {
        type: "choro",
        method: "quantile",
        nbreaks: 5,
        values: "gdppc",
        pal: "RdYlGn",
      },
    },
  ],
});

Stock and typo

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 typo type together. Example.

Code

bertin.draw({
  layers: [
    {
      type: "bubble",
      geojson: data,
      values: "pop",
      fill: {
        type: "typo",
        values: "region",
      },
    },
  ],
});

Dorling cartogram

The dorling parameter can be used with the bubble type to design a Dorling cartogram. Example.

Code

bertin.draw({
  layers: [
    {
      type: "bubble",
      geojson: data,
      values: "pop",
      k: k,
      dorling: true,
      iteration: 100,
      fill: "#E95B40",
    },
  ],
});

Dot cartogram

The dotcartogram type is a method of map representation that follows Dorling's cartograms and dot density maps. The data from each territorial unit are dissolved in such a way that a dot represents a constant quantity, the same on the whole map. Source Example.

Code

bertin.draw({
  params: { projection: d3.geoBertin1953() },
  layers: [
    {
      type: "dotcartogram",
      geojson: data,
      onedot: 200000000000,
      iteration: 200,
      values: "gdp",
      radius: radius,
      span: span,
      leg_fill: "none",
      leg_stroke: "black",
      leg_strokeWidth: 1.5,
      leg_x: 800,
      leg_y: 450,
      leg_title: `GDP by world region`,
      leg_txt: "200 billion $",
      fill: "red",
      tooltip: ["$name", "$region"],
    },
  ],
});

Parameters

  • geojson: a geojson (compulsory)
  • values: a string corresponding to the targeted variable in the properties(compulsory)
  • radius: radius of dots (default:4)
  • nbmax: number max of circles on the map (default:200)
  • onedot: dot value (if onedot is filled, nbmax is useless)
  • span: spacing between dots (default 0.5)
  • fill: fill color (default: random color)
  • stroke: stroke color (default: "white")
  • strokeWidth: stroke width (default: 0.5)
  • fillOpacity: fill opacity (default: 1)
  • tooltip an array of values defining what to display within the tooltip. If you use a $, the value within the geojson is displayed.
  • iteration an integer to define the number of iteration for the Dorling method (default 200)

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_fill: color of the circles (default: "none")
  • leg_stroke: stroke of the circles (default: "black")
  • leg_strokeWidth: stoke-width (default: 0.8)
  • leg_txtcol: color of the text (default: "#363636")
  • leg_title: title of the legend (default var_data)
  • leg_txt: text in the legend (default onedot value)
  • leg_fontSize: title legend font size (default: 14)
  • leg_fontSize2: text font size (default: 10)

Mushroom

The mushroom type is used to draw a map with 2 superposed proportional semi-circles. This type of representation can be used when two data with the same order of magnitude need to be compressed. Source, Example.

Code

bertin.draw({
  layers: [
    {
      type: "mushroom",
      geojson: mygeojson,
      top_values: "gdp_pct",
      bottom_values: "pop_pct",
      bottom_tooltip: ["name", "pop", "(thousands inh.)"],
      top_tooltip: ["name", "gdp", "(million $)"],
    },
  ],
});

Parameters

  • geojson: a geojson (compulsory)
  • top_values: a string corresponding to the targeted top variable in the properties (compulsory)
  • bottom_values: a string corresponding to the targeted bottom variable in the properties(compulsory)
  • top_fill: top fill color (default: "#d64f4f")
  • bottom_fill: bottom fill color (default: "#4fabd6")
  • k: size of the largest semi circle (default:50)
  • stroke: stroke color (default: "white")
  • strokeWidth: stroke width (default: 0.5)
  • fillOpacity: fill opacity (default: 1)
  • top_tooltip: an array of values defining what to display within the tooltip. If you use a $, the value within the geojson is displayed.
  • bottom_tooltip: an array of values defining what to display within the tooltip. If you use a $, the value within the geojson is displayed.

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_fontSize: title legend font size (default: 14)
  • leg_fontSize2: values font size (default: 10)
  • leg_round: number of digits after the decimal point (default: undefined)
  • leg_txtcol: color of the text (default: "#363636")
  • leg_title: title of the legend (default "Title, year")
  • leg_stroke: stroke of the circles (default: "black")
  • leg_top_txt title for the top variable (default top_var)
  • leg_bottom_txt title for the bottom variable (default bottom_var)
  • leg_top_fill color of top semi circles (default same as top_fill)
  • leg_bottom_fill color of bottom semi circles (default same as bottom_fill)
  • leg_strokeWidth stroke width of elements in the legend (default 0.8)

Dot Density

The dotdensity type allows to display a doty density layer geojson layer from polygons and attribute data. Source. Example

Code

bertin.draw({
  layers: [
    {
      type: "dotdensity",
      geojson: *a geojson here (polygon)*,
      values: *a fiel here*
      dotvalue: *a number*,
    }
  ]
})

Parameters

  • geojson: a geojson polygons or Multipolygons (compulsory)
  • values: a string corresponding to the targeted variable in the properties(compulsory)
  • dotvalue: a number representing the value of each point (default: a computed number so that there are no more than 1000 dots on the map.)
  • fill: fill color (default: a random color)
  • stroke: stroke color (default: "white")
  • strokeWidth stroke width (default:0.5)
  • fillOpacity: fill opacity (default:1)
  • strokeOpacity: stroke opacity (default:1)
  • symbol: if it is a dot layer, the type of symbol. "circle", "cross", "diamond", "square", "star", "triangle", "wye" (default: "circle")
  • symbol_size: if it is a dot layer, a number indicating the size of the symbol (default: 5)
  • symbol_shift: if it is a dot layer, use a value > 0 to switch symbols and avoid overlay (default: 0)
  • symbol_iteration: Number of iteration to shift symbols (default: 200)

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_w: width of the box (default: 30)
  • leg_h: height of the box (default:20)
  • leg_title: title of the legend (default: null)
  • leg_text: text in the legend (default: dot value)
  • leg_fontSize: title legend font size (default: 14)
  • leg_fontSize2: values font size (default: 10)
  • leg_fill: color of the box (same as the layer displayed)
  • leg_stroke: stroke of the box (default: "black")
  • leg_strokeWidth: stroke-width (default: 0.5)
  • leg_fillOpacity: stroke opacity (same as the layer displayed)
  • leg_txtcol: color of the text (default: "#363636")

Spikes

The spikes type is used to draw a map with spikes. Source, Example.

Code

bertin.draw({
  layers: [
    {
      type: "spikes",
      geojson: countries,
      values: "pop",
      k: 60,
      w: 8,
      tooltip: ["$country", "$pop", "(inh.)"],
    },
  ],
});

Parameters

  • geojson: a geojson (compulsory)
  • values: a string corresponding to the targeted variable in the properties(compulsory)
  • k: height of the highest peak (default:50)
  • w: width of the spikes (default:10)
  • fill: fill color (default: #a31d88)
  • stroke: stroke color (default: #a31d88)
  • strokeWidth: stroke width (default: 0.7)
  • fillOpacity: fill opacity (default: 0.3)
  • tooltip an array of values defining what to display within the tooltip. If you use a $, the value within the geojson is displayed.

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_fill: color of the circles (default: "none")
  • leg_stroke: stroke of the circles (default: "black")
  • leg_strokeWidth: stoke-width (default: 0.8)
  • leg_txtcol: color of the text (default: "#363636")
  • leg_title: title of the legend (default var_data)
  • leg_round: rounding (default: undefined)
  • leg_fontSize: title legend font size (default: 14)
  • leg_fontSize2: values font size (default: 10)

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

Code - Constant Thickness

In order for each object to have the same thickness.

bertin.draw({
  layers: [
    {
      type: "layer",
      geojson: *a geojson here*,
      strokeWidth: 3,
    }
  ]
})

Code - Linear variation

To vary the thickness proportionally to an quantitative data.

bertin.draw({
  layers: [
    {
      type: "layer",
      geojson: *a geojson here*,
      strokeWidth: {type:"linear",values:"migration"},
    }
  ]
})

Parameters

  • values: a string corresponding to the targeted variable in the properties(compulsory)
  • k: thicken with the largest line (default:10)
  • fixmax: Max value to fix the size of the thickest line, in order to make maps comparable (default:undefined)
  • fixmin: Min value to fix the size of the thinest line. If true, the value is the min data. (default:0)

Code - Discrete variation

To vary the thickness according to classes values

bertin.draw({
  layers: [
    {
      type: "layer",
      geojson: *a geojson here*,
      strokeWidth: {type:"discr",values:"migration", method: "q6"},
    }
  ]
})

Parameters

  • values: a string corresponding to the targeted variable in the properties(compulsory)
  • k: thicken with the largest line (default:10)
  • nbreaks: Number of classes (default:5)
  • breaks: Class breaks (default:null)
  • method: A method of classification. Jenks, q6, quantiles, msd (mean standard deviation), equal (default: quantiles).
  • middle: for msd method only. middle class or not (default:false).
  • sizes: an array definig the sizes of each classes.
  • nbsd: for msd method only. number of sd. (default:1)
  • sizes: an array of thicknesses.

Code - Categories

To vary the thickness according to qualitative data.

bertin.draw({
  layers: [
    {
      type: "layer",
      geojson: *a geojson here*,
      strokeWidth: {type:"quali",values:"flow", categories: ["low", "medium", "high", "very high"]},
    }
  ]
})

Parameters

  • values: a string corresponding to the targeted variable in the properties(compulsory)
  • k: thicken with the largest line (default:10)
  • categories: an array containing categories
  • sizes: an array definig the sizes of each classes.
  • nbsd: for msd method only. number of sd. (default:1)
  • sizes: an array of thicknesses.

Parameters of the legends

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_w: width of the lines (default: 30)
  • leg_text: text of the box (default: "leg_text")
  • leg_fontSize: text font size (default: 10)
  • leg_fill: color of the box (same as the layer displayed)
  • leg_stroke: stroke of the box (default: "black")
  • leg_strokeWidth: stroke-width (default: 0.5)
  • leg_fillOpacity: stroke opacity (same as the layer displayed)
  • leg_txtcol: color of the text (default: "#363636")
  • leg_round: Number of digits (default: undefined)

Map components

Footer

The footer type allows to display text under the map. This is useful to display sources. Source.

Code

bertin.draw({
  layers: [
    {
      type: "footer",
      text: "Source: Worldbank, 2021",
      fontSize: 10,
    },
  ],
});

Parameters

  • text: text to be displayed (default:"")
  • anchor: text anchor. start, middle, end (default:"end")
  • fontSize: size of the text (default:15)
  • fill: color of the text (default:"#9e9696")
  • background: background color (default: "white")
  • backgroundOpacity: background opacity (default: 1)

Graticule

The graticule type allows you to display the latitude and longitude lines. Source.

Code

bertin.draw({
  layers: [
    {
      type: "graticule",
      fill: "#644580",
      step: [20, 10],
    },
  ],
});

Parameters

  • stroke: stroke color (default:"white")
  • strokeWidth: stroke width (default:0.8)
  • strokeopacity: stroke opacity (default:0.5)
  • strokedasharray: stroke-dasharray (default:2)
  • step: gap between graticules. The value can be a number or an array of two values (default: [10, 10])

hatch (or hatching)

The hatch type only allows to add hatchings on the whole page to make it a bit prettier. Source.

Code

bertin.draw({
  layers: [
    {
      type: "hatch",
      angle: 45,
    },
  ],
});

Parameters

  • stroke: stroke color (default: "#786d6c")
  • strokeWidth: stroke color (default: 2)
  • strokeOpacity: stroke-opacity (default: 45)
  • strokeDasharray: stroke-dasharray (default:"none")
  • angle: orientation of lines (default: 45)
  • spacing: spacing between lines (default: 8)

Water lines

The waterlines type only allows allows to display lines spaced by a defined distance. It's just a graphic trick to make the maps look nice. Source.

Code

bertin.draw({
  layers: [
    {
      type: "hatch",
      angle: 45,
    },
  ],
});

Parameters

  • dist: distancve between lines (default: 200)
  • unit: unit (default: "kilometers")
  • nb: number of lines (default: 5)
  • stroke: stroke. If more than 1 value is defined, a linear scale is done beetwen values (default:"#5d81ba")
  • strokeOpacity: stroke-opacity. If more than 1 value is defined, a linear scale is done beetwen values (default: [1, 0.1])
  • strokeWidth: stroke-width. If more than 1 value is defined, a linear scale is done beetwen values(default: [1.2, 0.2])
  • strokeDasharray: stroke-dasharray (default: "none")
  • strokeLinecap: stroke-linecap (default: "round")
  • strokeLinejoin: stroke-linejoin (default: "round")

Header

The header type allows to display a title above the map. Source.

Code

bertin.draw({
  layers: [
    {
      type: "header",
      text: "Title of the map",
      fontSize: 40,
    },
  ],
});

Parameters

  • text: text to be displayed (default:"")
  • anchor: text anchor. start, middle, end (default:"middle")
  • fontSize: size of the text (default:20)
  • fill: color of the text (default:"#9e9696")
  • background: background color (default: "white")
  • backgroundOpacity: background opacity (default: 1)

Labels

The label type allows to display labels from a geojson. Source, Example.

Code

bertin.draw({
  layers: [
    {
      type: "label",
      geojson: countries,
      label: "name",
    },
  ],
});

Parameters

  • geojson: a geojson (compulsory)
  • values: a string corresponding to the targeted variable in the properties (compulsory)
  • fill: fill color (default: "#474342")
  • fontSize: font size (default: 10)
  • fontFamily: font family. "Pacifico","Roboto","Rubik","Ubuntu" (default: "Robotto")
  • textDecoration: text decoration. "none", "underline", "line-through", "overline" (default:"none")
  • fontWeight: font weight. "normal", "bold", "bolder", "lighter" (default: "normal")
  • fontStyle: font style. "normal", "italic", "oblique" (default: "normal")
  • opacity: opacity (default: 1)
  • halo: boolean to display a halo below the text (default: false)
  • halo_style: an array defining the halo style. [color, thickness, opacity] (default: ["white","4, 0.5)

Missing

The missing type displays any missing data when creating a map by proportional symbols. The highlight of graphical elements (in white under the symbols) allows for clear data comprehension of gaps in data. Source.

Code

bertin.draw({
  layers: [
    {
      type: "missing",
      geojson: countries,
      values: "pop"
  ]
})

Parameters

  • geojson: a geojson (compulsory)
  • values: a string corresponding to the targeted variable in the properties (compulsory)
  • fill: fill color (default: "white")
  • stroke: stroke color (default: "white")
  • strokeWidth: stroke width (default: 0.5)
  • fillOpacity: fill opacity (default: 1)

Parameters of the legend

  • leg_x: position in x (if this value is not filled, the legend is not displayed)
  • leg_y: position in y (if this value is not filled, the legend is not displayed)
  • leg_w: width of the box (default: 30)
  • leg_h: height of the box (default:20)
  • leg_text: text of the box (default: "leg_text")
  • leg_fontSize: text font size (default: 10)
  • leg_fill: color of the box (same as the layer displayed)
  • leg_stroke: stroke of the box (default: "black")
  • leg_strokeWidth: stroke-width (default: 0.5)
  • leg_fillOpacity: stroke opacity (same as the layer displayed)
  • leg_txtcol: color of the text (default: "#363636")

Outline

The outline type is used to display the limits of the earth area in the given projection. Source.

Code

bertin.draw({
  layers: [
    {
      type: "outline",
      fill: "#4269ad",
    },
  ],
});

Parameters

  • fill: fill color of the outline (default: "#add8f7")
  • opacity: opacity (default:1)
  • stroke: stroke color (default:"none")
  • strokeWidth: stroke width (default: 1)

Scalebar

The scalebar type allows to display a scale bar in miles or kilometers. Source.

Code

bertin.draw({
  layers: [
    {
      type: "scalebar",
      units: "miles",
    },
  ],
});

Parameters

  • x: position in x (if this value is not filled, the legend is displayed on the left)
  • y: position in x (if this value is not filled, the legend is displayed at the bottom)
  • units: distance unit, miles or kilometers (default: "kilometers")

Shadow

The shadow type allows to display a shadow under a layer to give it a relief effect. Source.

Code

bertin.draw({
  layers: [
    {
      type: "shadow",
      geojson: JPN,
      dx: 5,
      dy: 5,
    },
  ],
});

Parameters

  • col: color (default: "#35383d")
  • dx: shift in x (default: 3)
  • dy: shift in y (default: 3)
  • stdDeviation: blur (default: 1.5)
  • opacity: opacity (default: 0.7)

Texts

The text type simply allows you to display text anywhere on the map. Source. Example.

Code

bertin.draw({
  layers: [
    {
      type: "text",
      text: "This is my text",
      position: "bottomright",
      fontSize: 20,
      frame_stroke: "red",
      margin: 4,
    },
  ],
});

Parameters

  • position: position of the text. It can be an array with x,y coordinates. For example [100,200]. It can be also a string defining the position. "topleft", "top", "topright", "left", "middle", "right", "bottomleft", "bottom", "bottomright" (default: "topleft")
  • text: text to display. With the backticks, it is possible to display a text on several lines (default: "Your text here!")
  • fontSize: text size (default: 15)
  • fontFamily: font family. "Pacifico","Roboto","Rubik","Ubuntu" (default: "Robotto")
  • textDecoration: text decoration. "none", "underline", "line-through", "overline" (default:"none")
  • fontWeight: font weight. "normal", "bold", "bolder", "lighter" (default: "normal")
  • fontStyle: font style. "normal", "italic", "oblique" (default: "normal")
  • margin: margin around the text (default: 0)
  • anchor: text anchor. start, middle, end (default: "start")
  • fill: text color (default: "#474342")
  • stroke: stroke color (default: "none")
  • frame_fill: frame background color (default:"none")
  • frame_stroke: frame stroke color (default: "none")
  • frame_strokeWidth: thickness of the frame contour (default: 1)
  • frame_opacity: frame opacity (default: 1)

Mercator Tiles

The tiles type allow to display a raster basemap. Source. Example.

**NB: ** It works only with the d3.geoMercator() projection. if tiles layer is used is the draw function, the projection is automaticaly setted to d3.geoMercator(). And you can't change it.

Code

bertin.draw({
  params: { 
            projection: d3.geoMercator(),
            extent: *a geojson*  
          },
  layers: [
    {
      type: "tiles",
      style: "worldphysical"
    },
  ],
});

Parameters

  • style: tile style: "openstreetmap", "opentopomap", "worldterrain", "worldimagery", "worldStreet", "worldphysical", "shadedrelief", "oceanbasemap". (default: "opentopomap")
  • zoomDelta: zoom offset. See explanations here (default:0)
  • tileSize: tile size. See explanations here (default:512)
  • opacity: tile opacity (default:1) -clip: a geojson to clip the image
  • source: position of the text. It can be an array with x,y coordinates. For example [100,200]. It can be also a string defining the position. "topleft", "top", "topright", "left", "middle", "right", "bottomleft", "bottom", "bottomright" (default: "topleft")
  • increasetilesize: a value to slightly increase the size of the tiles solve the problem of gap between the tiles with chromium (deafault: 1)

Other functions

borders

borders is a function that extract borders from polygons, with ids. Source

Code

bertin.borders({geojson: world, id: "iso3", values: "population", type = "rel"})

Code

  • geojson: a geojson
  • id: id codes
  • values: values
  • type: type of discontinuities calculated: rel(relative), abs(absolute) (default:"rel")

bbox

bbox computes a geojson object form an array defining an extent in latitude and longitude.

Code

bertin.bbox([
  [112, -43],
  [153, -9],
]);

Quickdraw

quickdraw function displays one or more layers directly and easily. Source, Example.

Code

bertin.quickdraw(geojson);
bertin.quickdraw(geojson, 1000, 7);

Parameters

  • param 1 : a geojson (compulsory)
  • param 2 : width
  • param 3 : margin

Match

match() is a function to evaluate the quality of a join between the data and the background map. It returns a chart. Source, Example.

Code

let testjoin = bertin.match(countries, "ISO3_CODE", maddison, "countrycode");

.matched returns an array containing matched ids

testjoin.matched;

.matched_data returns an array containing matched data ids

testjoin.matched_data;

.unmatched_data returns an array containing unmatched data ids

testjoin.unmatched_data;

.unmatched_geom returns an array containing unmatched geom ids

testjoin.unmatched_geom;

Parameters

  • param 1 : a geojson (compulsory)
  • param 2 : a string corresponding to the identifier of the features in the properties (compulsory)
  • param 3 : a json (compulsory)
  • param 4 : a string corresponding to the identifier of the features (compulsory)

Merge

merge is a function to join a geojson and a data file. This is the first step in the mapping process. Source, Example.

Code

const data = bertin.merge(
  countries,
  "ISO3_CODE",
  maddison,
  "countrycode",
  true
);

Parameters

  • param 1 : a geojson (compulsory)
  • param 2 : a string corresponding to the identifier of the features in the properties (compulsory)
  • param 3 : a json (compulsory)
  • param 4 : a string corresponding to the identifier of the features (compulsory)
  • param 5 : a boolean. If true, all geometries will be kept. If false, only matched data are kept (default: true)

links

links is a function that create links from geometries (polygons or points) and a data file (i,j,fij). Source Example.

Code

bertin.links({
  geojson: world,
  geojson_id: "ISO3",
  data: migr2019,
  data_i: "i",
  data_j: "j",
});

Parameters

  • geojson: a geojson
  • geojson_id: id of the geojson
  • data: inj,fij data
  • data_i: i id
  • data_j: j id

subgeo

subgeo function extracts a part of a geojson (e.g. world countries without antarctica). Source

Code

bertin.subgeo({
  geojson: world,
  field: "iso3",
  operator: "!=",
  array: ["ATA"],
});

Parameters

  • geojson: a geojson (or topojson)
  • field: a field in properties
  • operator: an operator (default :"==")
  • array: an array of values

table2geo

table2geo function converts a data table with lat/lon fields to a geojson. Source, Example.

Code

bertin.table2geo(cities, "lat", "lng");

Parameters

  • param 1 : a geojson (compulsory)
  • param 2 : latitude
  • param 3 : longitude
Comments
  • Performance issue ?

    Performance issue ?

    I ran a few simple display tests with bertin.js:

    • 1 department by municipality
    • 1 region by municipality
    • France by municipality

    I am surprised with the measures, maybe it is my PC, up to 2 mn, although pure D3 coding does not exceed 7 s.

    Projection has for sure a significant impact.

    https://observablehq.com/@ericmauviere/hello_bertin1

    opened by ericemc3 7
  • module import in Quarto

    module import in Quarto

    Currently, require("bertin") does'nt work in Quarto. The following error is returned: OJS Error. RequireError$1: invalid module. To import bertin, I have to write: bertin = import('https://cdn.skypack.dev/[email protected]'). However, require works in Observable. It's weird... See also https://talk.observablehq.com/t/quarto-module-require/6573 & https://stackoverflow.com/questions/72300480/error-quarto-require-invalid-module-bertin-js Screenshot from 2022-05-19 10-53-08 Actually, it's very weird. There is an error in rstudio. But when I deploy the page in github (see), the error disappears.

    opened by neocarto 5
  • Error on build

    Error on build

    When I run npm run build, I'm getting error:

    [!] (plugin copy) Error: EACCES: permission denied, mkdir '/var/www'
    

    It looks like it is caused by the path set on this line of rollup.config.js, which is not there in my system.

    opened by saneef 3
  • More styling for header type

    More styling for header type

    Would it be possible to allow for more styling options for the header type, like there are for the text type? Stuff like fontFamily and fontWeight spring to mind.

    Really loving this work, fantastic job! Thanks.

    opened by zachperiscopic 2
  • Import error

    Import error

    Just to clarify (I guess !) the issue reported by @lessthanweb in #83, when importing bertin.js (outside Observable), starting from 1.3.4 you get the following error:

    [email protected]:23 Uncaught TypeError: Cannot read properties of undefined (reading 'contourDensity')
        at [email protected]:23:32172
        at [email protected]:1:175
        at [email protected]:1:254
    

    Import is done as in the README / the examples:

    <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
    

    Due to this error the bertin object is empty and it is not possible to call bertin.draw for example.

    I think you are missing to include d3-contour in the dependencies of package.json so it fails when importing contourDensity here https://github.com/neocarto/bertin/blob/e44b71355ad0d0a4d79bee00f659e3d3e31ae2c5/src/layers/smooth.js#L5

    opened by mthh 2
  • Line Marker Styles

    Line Marker Styles

    Allow customization of line marker styles. Perhaps line markers could have user defined solid, long, short, or dashes.

    A example can be seen on flourish https://help.flourish.studio/article/287-how-to-add-lines-to-your-map image

    Currently Bertin.js support line styles using 'Links'. These are fairly automatic.

    The use case for line markers are used for creating maps that show travel paths as seen here

    image

    opened by arky 2
  • Mushroom plots with point geometry

    Mushroom plots with point geometry

    I've been able to create mushroom plots using Polygon geometry, but I'm having trouble creating one using Point geometry—I just get the mushrooms stacked up in the top-left corner (the same as if I try to use ill-formed Polygon geometry).

    For example, here's some point geometry in testdata.geojson:

    {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": { "some_value": 5, "another_value": 8 },
          "geometry": { "type": "Point", "coordinates": [130.89, -12.42] }
        },
        {
          "type": "Feature",
          "properties": { "some_value": 13, "another_value": 11 },
          "geometry": { "type": "Point", "coordinates": [117.1, -16.72] }
        },
        {
          "type": "Feature",
          "properties": { "some_value": 14, "another_value": 19 },
          "geometry": { "type": "Point", "coordinates": [112.34, -25.32] }
        }
      ]
    }
    

    And here're some polygons around the same points in testdata-polygon.geojson:

    {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": { "some_value": 5, "another_value": 8 },
          "geometry": {
            "type": "Polygon",
            "coordinates": [[
              [130.99, -12.42],
              [130.89, -12.52],
              [130.79, -12.42],
              [130.89, -12.32]
            ]]
          }
        },
        {
          "type": "Feature",
          "properties": { "some_value": 13, "another_value": 11 },
          "geometry": {
            "type": "Polygon",
            "coordinates": [[
               [117.2, -16.72],
               [117.1, -16.82],
               [117.0, -16.72],
               [117.1, -16.62]
            ]]
          }
        },
        {
          "type": "Feature",
          "properties": { "some_value": 14, "another_value": 19 },
          "geometry": {
            "type": "Polygon",
            "coordinates": [[
               [112.44, -25.32],
               [112.34, -25.42],
               [112.24, -25.32],
               [112.34, -25.22]
            ]]
          }
        }
      ]
    }
    

    And here's a test Quarto doc where I try to draw:

    ✅ symbols with the point geometry ❌ mushrooms with the point geometry ✅ mushrooms with the polygon geometry:

    ---
    title: "Test"
    ---
    
    Load the data:
    
    ```{ojs}
    //| label: setup
    bertin = require("[email protected]");
    d3 = require("d3-geo@3", "d3-geo-projection@4");
    ```
    
    Here's the data:
    
    ```{ojs}
    test_data = FileAttachment("testdata.geojson").json();
    test_data
    ```
    
    Symbols work:
    
    ```{ojs}
    //| label: bertin-point-symbols
    bertin.draw({
      params: {
        background: "#dbd1ca",
        margin: 40
      },
      layers: [
        {
          geojson: test_data,
          symbol: "circle",
          fill: "#990000",
          symbol_size: 150
        }
      ]
    });
    ```
    

    image

    But mushrooms don't:
    
    ```{ojs}
    //| label: bertin-point-mushrooms
    bertin.draw({
      params: {
        background: "#dbd1ca",
        margin: 40
      },
      layers: [
        {
          type: "mushroom", 
          geojson: test_data,
          top_values: "some_value",
          bottom_values: "another_value",
          k: 50,
          top_fill: "#b0040f",
          bottom_fill: "#0acbf2",
        }
      ]
    });
    ```
    

    image

    But if we try with polygon geometry, it works:
    
    ```{ojs}
    test_poly_data = FileAttachment("testdata-polygon.geojson").json();
    test_poly_data
    ```
    
    ```{ojs}
    //| label: bertin-poly-mushrooms
    bertin.draw({
      params: {
        background: "#dbd1ca",
        margin: 40
      },
      layers: [
        {
          type: "mushroom", 
          geojson: test_poly_data,
          top_values: "some_value",
          bottom_values: "another_value",
          k: 50,
          top_fill: "#b0040f",
          bottom_fill: "#0acbf2",
        }
      ]
    });
    ```
    

    image

    Is it possible to use Points with the Mushroom plot type? They seem like a natural fit, since the symbol itself is a point, and I'd prefer to just pre-process my polygons down to their centroids if possible!

    opened by jimjam-slam 2
  • Rendering of USA map using geoAlbersUsa not as expected.

    Rendering of USA map using geoAlbersUsa not as expected.

    I've really enjoyed playing with this library - fills a much needed gap in javascript cartography!

    I ran into an issue making a map of the US. I have geojson of US states from the US Census (https://www.census.gov/geographies/mapping-files/time-series/geo/carto-boundary-file.html; converted from shapefile to geojson using mapshaper). When I try to make a state map using bertin.js, I get this: https://observablehq.com/d/c5d2bf78b1e0534e The most interesting thing about the rendering is that one state at a time will be stroked white, and you can trigger a change in the displayed state by mousing out of the cell.

    I'm not sure what is causing this - maybe the Alaska and Hawaii inset in the AlbersUSA projection break things somehow?

    opened by gallowayevan 2
  • Chore: Better README format

    Chore: Better README format

    Reformatted the README for readability. The format of documents allow for quick look up for code examples and follows the style set by Plot documentation.

    opened by arky 2
  • Add Changelog

    Add Changelog

    Add a Changelog file to track the project changes between minor and major release.

    The example format is included in this gist: https://gist.github.com/juampynr/4c18214a8eb554084e21d6e288a18a2c

    opened by arky 2
  • [bertin-js links] filtering links options

    [bertin-js links] filtering links options

    in : https://observablehq.com/@neocartocnrs/bertin-js-links

    Please, for these first examples, allow also filtering links from their volum (flow value).

    Then, it would be interesting to propose to filter according to (by order of importance/difficulty) :

    Type (1)

    • a value to enter
    • the mean value of (fij)
    • median value of (fij)

    Type (2)

    • a decile of of (fij) to be entered or calculated (?). -This proposition is related to the summary proposal issue.

    Type (3)

    • a range of values to enter
    • a range a value to pick on a sort of slider histogram

    Type (4)

    • a range of values to enter as from [a - b[
    • a range a value to pick on a "slider histogram"
    opened by fbahoken 2
  • Localization Support

    Localization Support

    Please kindly provide a way to create thematic maps in multiple languages. The language strings could be encoding with a language prefix such as 'en-us', 'fr'. When multiple languages are present then a suitable language switcher is presented in the UI.

    The elements of thematic map such as titles, legends and tooltips could be localized as well as the map data if the language attributes are present in the map data.

    opened by arky 0
  • Custom button to to download map as image

    Custom button to to download map as image

    Sometimes users would like to export the resulting maps as images to include them in presentations or for print. At the moment, you have to take a screenshot manually.

    Chart service provider datawrapper automatically provides a button to allow users to down the images in various formats. https://app.datawrapper.de/river/_/iTGeS

    Screenshot 2022-12-09 at 15-22-15 River - Datawrapper

    opened by arky 0
  • Add Custom Button to download map data

    Add Custom Button to download map data

    It would be a good idea to allow users to download the map with button.

    This user interface is common feature of charts on the web. You can view this feature on datawrapper charts: https://app.datawrapper.de/river/_/iTGeS

    Screenshot 2022-12-09 at 15-22-15 River - Datawrapper

    opened by arky 0
  • Cheatsheets image have artifacts

    Cheatsheets image have artifacts

    The cheatsheet maps image consist of numerous data point that lie outside the maps.

    Please see the testcase and attached screenshot: https://observablehq.com/d/4e012db9a1e53bb6 test-case

    opened by arky 0
Releases(v1.0.0)
Owner
Nicolas LAMBERT
Nicolas Lambert is cartographer within the CNRS. His work focuses mainly on thematic mapping and the development of open source web applications.
Nicolas LAMBERT
A JavaScript library for visualizing Sankey diagrams.

SanKEY.js v1.0.0 last updated: 20.07.2022 Getting started SanKEY.js is a JavaScript data visualization library that provides a simple object-oriented

Krzysztof Zdąbłasz 12 Nov 8, 2022
App for displaying geospatial data on queues on the Polish-Ukrainian border.

Live app embedded here. App helps coordinate volunteer work with refugees from Ukraine on Polish-Belarusian Border. Data comes from Grupa Granica – a

null 3 Mar 10, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Low-Level GeoSpatial Masking Functions

geomask Low-Level GeoSpatial Masking Functions features calculate raster pixels inside and outside a geometry mask built-in reprojection support for a

Daniel J. Dufour 4 Jul 22, 2022
A lightweight JavaScript library for creating interactive maps and pretty data visualization.

Jsvectormap A lightweight Javascript library for creating interactive maps and pretty data visualization. Explore docs . Report bug · View demo · Down

Mustafa Omar 204 Dec 24, 2022
simple jquery Plugin that utilizes Google API to get data from a Place on Google Maps

jQuery Plugin to display Google Reviews of a Place on Google Maps this will get the 5 reviews, google offers you. But I need more than 5 reviews! if y

Simon Neutert 32 Dec 14, 2022
It's a javascript Class which contains utility methods that simplify working with google maps web SDK

About GoogleMapsJSHelper It's a javascript Class which contains utility methods that simplify working with google maps web SDK Note: i used ES7 Class

Sami Alateya 6 Jul 23, 2022
Cross provider map drawing library, supporting Mapbox, Google Maps and Leaflet out the box

Terra Draw Frictionless map drawing across mapping providers. TerraDraw centralises map drawing logic and provides a host of out the box drawing modes

James Milner 106 Dec 31, 2022
A library for boolean aliases to help you make your code more confusing and make your coworkers hate you.

yup-nope A library for boolean aliases to help you make your code more confusing and make your coworkers hate you. Installation Using npm: npm install

Bence A. Tóth 4 Dec 10, 2022
TypeScript isomorphic library to make work with Telegram Web Apps init data easier.

Telegram Web Apps Init Data TypeScript isomorphic library to make work with Telegram Web Apps init data easier. Feel free to use it in browser and Nod

Telegram Web Apps 2 Oct 7, 2022
Change import URLs in JavaScript code using import maps. e.g. `import * from "before"` to `import * from "after"`

esm-import-transformer Can transform any ESM source code import URLs using an import maps object. This package works in ES modules or in CJS. // Befor

Zach Leatherman 19 Jul 31, 2022
View maps, graphs, and tables of your save and compete in a casual, evergreen leaderboard of EU4 achievement speed runs. Upload and share your save with the world.

PDX Tools PDX Tools is a modern EU4 save file analyzer that allow users to view maps, graphs, and data tables of their save all within the browser. If

PDX Tools 24 Dec 27, 2022
Crowdsource and crowdfund collaboration on maps of problems.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

MapsMap 3 Dec 9, 2022
Utility for generating preview images of StarCraft: Brood War and Remastered maps

bwpreview Utility for generating preview images of StarCraft: Brood War and Remastered maps (.scm and .scx files). All of the actual work of parsing m

Michiel Sikma 5 Oct 14, 2022
A landing page, as well as a results page, that utliize both Yelp API and Google Maps API.

Economic Eats Group Project #1 Maintained By: Austin Donovan John Hysong John Guzzetta Jahnathan Exantus Description This project contains a landing p

John Guzzetta IV 7 Aug 4, 2022
A Travel companion app using Google Maps API, Travel Search and Weather API

Travel Advisor Introduction An advanced Travel Companion Application using Google Maps. With Geolocation, Google Maps API, Searching for places, Fetch

Sunny Bhadani 4 Nov 11, 2022