Anything unclear or missing? Feel free to ask !
Here are few concepts on Gridviz to be aware of:
A gridviz map is composed of a stack of layers. Layers may have different types (background image, boundaries, labels, etc.). The main layer type is GridLayer, for gridded data. Background layers are usually drawn below, usually a single one. Boundaries and label layers should also be drawn as foreground, on top of grid layers.
Gridded datasets are defined independantly from their grid layer. Each gridded dataset may thus be reused by several layers: It is loaded and stored once, and reused several times. This reuse allows saving memory space and loading time.
A gridded dataset may be multi-resolution. Gridviz then takes care of selecting the most suitable resolution according to the visualisation zoom level (and a predefined minPixelsPerCell parameter). This ensures only the relevant data for the visualisation view and zoom level is loaded and displayed.
GridViz supports data tiling, and also Parquet format.
A grid layer draws a single gridded dataset using one or several styles. It is thus possible to combine styles and draw them on top of each other to show different aspects of the data.
A style specifies how to draw the cells within the view. The style is not defined at cell level only - it allows defining more advanced styling techniques using cell sets, based on the relations of each cell with its neigbours.
Gridviz comes with a library of predefined styles. These styles are customisable. Users are also offered a full flexibility to define their own style and show their cells the way they need. Predefined style may be seen only as examples and inspiration sources.
Predefined styles parameters are usually not static values, but functions of usually four parameters: The cell to be drawn, its resolution, the zoom level, and a viewscale object. Styling parameters (such as colors, size, etc.) may thus be computed depending on each cell, its resolution, and the zoom level. Size parameters are usually specified in the unit of measurement of the grid coordinate reference system, usually ground meters. They may also be specified in screen pixels. These functions allow adapting the cartographic styles (colors, dimensions, etc.) to the cell values, their size and the zoom level.
For some predefined style parameters, viewscale parameter allows defining styling parameters based on the cells within the map view only. This parameter is an object computed only once from the cells within the view. It may be used for example to compute the minimum and maximum values of these cells and adapt a color scale to this for a better contrast. It should generally be used to compute scales that are view dependant - hence the name viewscale. See this section for some examples.
Gridviz zoom level, usually noted z, is defined in ground UoM per pixel. The ground UoM is usually meter. z value can be used directly to transorm distances from ground distance to map screen distance, in pixels, as a division. resolution parameter is the cell size, in ground UoM. Its size in map screen pixel is thus ‘resolution / z’.
A grid layer shows gridded data in the grid coordinate reference system. Several gridded datasets may be overlayed, as soon as they are defined in the same coordinate reference system. Other layers (background, labels, etc.) must be defined also in the grid coordinate reference system.
When building a gridviz map, in addition to the container element you can also specify an options object with the properties outlined in the table below.
For example:
new gridviz.Map(document.getElementById('map'), {
x: 4500000,
y: 2900000,
z: 1000,
legendContainer: document.getElementById('myLegendDiv'), // if you want your legend in an external container
selectionRectangleColor: 'red', // cell hover
selectionRectangleWidthPix: (resolution, z) => '1',
backgroundColor: 'white',
tooltip: {
// the default values, which are those of the tooltips of the statistical atlas
maxWidth: '20em',
fontSize: '1rem',
color: '#171a22',
lineHeight: '1.5',
background: 'white',
padding: '4px',
border: '1px solid #d5d5d5',
'border-radius': '6px',
'box-shadow': '0px 4px 6px rgba(0, 0, 0, 0.1), 0px 1px 3px rgba(0, 0, 0, 0.08)',
'font-family': "'Helvetica Neue', Arial, Helvetica, sans-serif",
transitionDuration: 100,
xOffset: 30,
yOffset: 20,
yMouseOffset: 0,
xMouseOffset: 0,
parentElement: document.body,
},
onZoomStartFun: (event) => {
console.log('pan/zoom start', event)
},
onZoomFun: (event) => {
console.log('zoom', event)
},
onZoomEndFun: (event) => {
console.log('pan/zoom end', event)
},
})
| Property | Type | Default | Description |
|---|---|---|---|
| opts.legendDivId | string | ‘gvizLegend’ | The identifier of the element upon which the legend will be appended. |
| opts.selectionRectangleColor | string | ‘red’ | The colour of the outline when a cell is highlighted. |
| opts.selectionRectangleWidthPix | Function | (r,z) => 4 | A function specifying the thickness in pixels of the outline when a cell is highlighted. The function parameter r is the cell resolution. z is the zoom level. |
| opts.transparentbackground | boolean | false | Whether the background should be filled with colour (backgroundColor) or not. It is essentially the difference between using context.fillRect vs context.clearRect. |
| opts.backgroundColor | string | ‘white’ | The background color of the canvas when transparentBackground is set to false. |
| opts.disableZoom | Boolean | false | Disables d3 pan and zoom when set to true. |
| opts.onZoomStartFun | Function | null | Event handler for when a pan/zoom event is initiated. |
| opts.onZoomFun | Function | null | Event handler for when a pan/zoom event is occurring. |
| opts.onZoomEndFun | Function | null | Event handler for when a pan/zoom event has finished. |
| opts.tooltip | Object | undefined | See tooltip |
| opts.asyncRedraw | boolean | true | When true, redraw() draws once, at the next animation frame, however many times it is called before then. Set it to false for redraw() to draw at once. |
The map is redrawn with map.redraw(). By default it draws once at the next animation frame, however many times it is called before then; with asyncRedraw set to false it draws at once. map.redrawNow() draws at once in either case, and is the one to use before reading the canvas (to export an image, for example). map.destroy() removes the map’s event listeners and stops observing its container.
A gridviz dataset defines how to retrieve gridded data, as a list of grid cells. A grid cell is stored as a javascript object having a x and y property, which is usually the coordinates of the grid cell lower left corner in the grid coordinate reference system. The x and y values are usually multiples of the grid resolution value.
Gridviz proposed several types of datasets: Javascript, CSV, Parquet.
These datasets may be bundled into multi-resolution datasets, to be used for multi-scale maps:
Gridviz can also show tiled data. This ensures only the data within the viewshed are loaded and displayed. These tiled data should follow the tiled grid format.
For Parquet data support, see the gridviz-parquet extension.
For better efficiency, it is recommended to use multi-resolution tiled parquet data.
| Class | Constructor | Data |
|---|---|---|
JSGrid |
new gridviz.JSGrid(resolution, cells, opts) |
The cells, as an array of JavaScript objects with a x and a y property. |
CSVGrid |
new gridviz.CSVGrid(map, url, resolution, opts) |
A CSV file with a x and a y column, and the values of the cells. Options: preprocess, delimiter. |
TiledGrid |
new gridviz.TiledGrid(map, url, opts) |
A folder of CSV tiles, in the tiled grid format. Options: preprocess, onlyDrawWhenAllTilesReady. |
MultiResolutionDataset |
new gridviz.MultiResolutionDataset(resolutions, datasets, opts) |
Several datasets, one for each resolution: datasets is an array of datasets, or a function which makes the dataset of a resolution. Option: preprocess. |
const dataset = new gridviz.MultiResolutionDataset([1000, 2000, 5000], (resolution) => new gridviz.CSVGrid(map, resolution + 'm.csv', resolution), {
preprocess: (cell) => {
cell.population = +cell.population // the values of a CSV file are text
if (cell.population == 0) return false // a cell for which it returns false is not kept
},
})
x and y of a cell are in the coordinate system of the map, and the resolution is a distance in its unit.preprocess is called once for each cell, when it is loaded. It can change the cell (to convert or compute values), and it removes the cell by returning false.minPixelsPerCell pixels wide at the current zoom (see GridLayer).TiledGrid.retryFailedAfterMs milliseconds (30000 by default) for any other failure. With onlyDrawWhenAllTilesReady: true, the map is drawn only when all the tiles of the view are there.TiledParquetGrid.There are a few different types of layers that can be added to a gridviz map: Once you have constructed them, simply add them to the map like so:
map.layers = [yourLayer] // they will be drawn in order
new gridviz.GridLayer(dataset, [style], {
minPixelsPerCell: 12, //optional
})
| Option | Type | Default | Description |
|---|---|---|---|
minPixelsPerCell |
number | 3 |
With a multi-resolution dataset, the smallest size on the screen, in pixels, of the cells of the resolution shown. A higher value draws fewer, bigger cells. |
cellInfoHTML |
function(cell):string or 'none' |
the list of the cell properties | The text of the tooltip of a cell, as HTML. 'none' for no tooltip. |
visible |
boolean or function(z) |
true |
Whether the layer is drawn, according to the zoom level. |
alpha |
function(z) |
opaque | The opacity of the layer. |
blendOperation |
function(z) |
'source-over' |
How the layer is blended with the layers below it. See transparency. |
const backgroundLayer = new gridviz.BackgroundLayer({
url: 'https://raw.githubusercontent.com/jgaffuri/mbxyz/main/pub/elevation_shading/',
resolutions: Array.from({ length: 9 }, (_, i) => 28.00132289714475 * Math.pow(2, 10 - i)),
origin: [0, 6000000],
filterColor: (z) => '#ffffff77',
})
const backgroundLayer = new gridviz.BackgroundLayerImage({
//the image URL
url: 'https://raw.githubusercontent.com/jgaffuri/mbxyz/main/pub/img/reunion_relief_100k.png',
//the georeferencing information:
// - geo coordinates of the top left corner
// - the image width and heigth in geo unit (meters). It is the image width/heigth in pixel multiplied by the resolution (meters/pixel)
xMin: 314686,
yMax: 7691260,
width: 64590.2,
height: 57178.2,
})
const backgroundLayer = new gridviz.BackgroundLayerWMS({
url: 'yourWMSserver?&service=WMS&request=GetMap&layers=yourLayers&styles=&format=image%2Fjpeg',
})
const geojsonLayer = new gridviz.GeoJSONLayer({
url: 'https://raw.githubusercontent.com/eurostat/gridviz/master/examples/basics/geojson_test.json',
shape: (f, z) => (f.properties.name == 'Fox' ? 'circle' : 'square'),
size: (f, z) => Math.max(15, 10 / z),
strokeStyle: (f, z) => 'black',
lineWidth: (f, z) => Math.max(3, 30 / z),
fillStyle: (f, z) => 'red',
})
const labelLayer = new gridviz.LabelLayer({
url: 'https://raw.githubusercontent.com/eurostat/euronym/main/pub/v3/UTF_LATIN/50/EUR.csv', //The URL of the label data, as CSV file.
preprocess: (label) => {
//project from geo coordinates to ETRS89-LAEA
const p = proj([label.lon, label.lat])
label.x = p[0]
label.y = p[1]
delete label.lon
delete label.lat
},
style: (label, zoom) => {
if (label.rs < 0.9 * zoom) return
if (label.r1 < 0.9 * zoom) return '1em Arial'
return '1.5em Arial'
},
haloColor: () => 'white',
textAlign: 'center', //Where the text is drawn from the label position: 'start' (default), 'end', 'left', 'right' or 'center'.
})
The gridded data may be pre-processed after loading, and filtered:
Official statistics often have missing values, or values of a lesser quality (estimated, imputed, or modified for statistical secrecy). They should not be mixed up with the real values on the map, and they should not get a color of the color scale. The way to do it is to give them a color of their own, outside of the scale, and to show it in the legend.
+'' is 0, which is a value, and +':' is NaN: test the text first (c.value === '', c.flag === 'e', isNaN(+c.value)…), in the preprocess function of the dataset for example, to give the cell a clear marker (c.value = undefined, or a c.missing property). Do not let a missing value be drawn as a zero.ShapeColorSizeStyle), the color function returns the color of the missing values: color: (c) => (c.missing ? '#8f9ba8' : ramp(c.value)).SquareColorWebGLStyle), a cell for which tFun returns undefined is not drawn. Draw the missing values with a second style of the layer, which selects them with its filter option.ColorCategoryLegend of one entry next to the color legend of the scale (style.legends = [colorLegend, missingLegend]).const valueStyle = new gridviz.SquareColorWebGLStyle({
tFun: (c) => (c.share === undefined ? undefined : c.share / 0.3), // not drawn when undefined
color: (t) => d3.interpolateYlOrRd(t),
})
const missingStyle = new gridviz.ShapeColorSizeStyle({
color: () => '#8f9ba8',
filter: (c) => c.share === undefined, // only the cells without value
})
missingStyle.legends = [new gridviz.ColorCategoryLegend({ colorLabel: [['#8f9ba8', 'No value']], shape: 'square' })]
All the styles are classes of the gridviz module, which are given to a GridLayer as a list. Each one of the sections below tells the class of its style, and the options it reads. The options which all the styles share are:
| Option | Type | Default | Description |
|---|---|---|---|
visible |
boolean or function(z) |
true |
Whether the style is drawn, according to the zoom level z. |
alpha |
function(z) |
opaque | The opacity of the style. |
blendOperation |
function(z) |
'source-over' |
How the style is blended with what is below: any canvas composite operation, such as 'multiply'. |
filter |
function(cell):boolean |
all the cells | The cells for which it returns false are not drawn. |
offset |
function(cell, resolution, z) |
no offset | Moves the symbols, in geographical unit: returns {dx, dy}. |
viewScale |
function | - | A scale computed from the cells in the view, given to the other functions of the style. See view scale. |
filterColor, filterBlendOperation |
function(z) |
- | A color drawn over the style (with this blend operation), for example to fade it. |
The legends of a style are set after its creation: style.legends = [legend1, legend2]. See legends.
This style is a generic style which allows to define the shape, color and size of each grid cell, independantly according to 3 different variables. Three shapes are currently available: square, circle, triangle (up, down, left or right) and donut (a disk with a hole of changing size). To show grid cells as small squares with only changing color, one of the styles based on web GL here or here should rather be used, for efficiency reasons. Likewise, to show many circles, the circle style based on web GL is much faster.
Class: gridviz.ShapeColorSizeStyle. Options, plus the options common to all the styles:
| Option | Type | Default | Description |
|---|---|---|---|
color |
string or function(cell, resolution, z, viewScale) |
'#EA6BAC' |
The color of the cell: any CSS color. A cell without color (or 'none') is not drawn. |
size |
number or function(cell, resolution, z, viewScale) |
the resolution of the grid | The size of the symbol, in geographical unit (not in pixels). A cell without size (0) is not drawn. |
shape |
string or function(cell, resolution, z, viewScale) |
'square' |
One of 'square', 'circle', 'diamond', 'donut', 'triangle_up', 'triangle_down', 'triangle_left', 'triangle_right', 'none'. |
donutOuterSize |
number or function(cell, resolution, z, viewScale) |
the resolution of the grid | For the 'donut' shape, its outer diameter, in geographical unit. The size of a donut is then the part of this diameter it fills: a full disk when it equals the outer diameter, a thin ring when it is small. |
A donut with a smaller outer diameter can be a ring around another symbol: a pie chart of a composition style, a circle, etc. Draw the two with two styles of the same layer, and choose their sizes so that they fit: the hole of a donut of outer diameter D and size s has a diameter of D - s.
Class: gridviz.SquareColorWebGLStyle. Options, plus the options common to all the styles:
| Option | Type | Default | Description |
|---|---|---|---|
tFun |
function(cell, resolution, z, viewScale) |
- | The position of the cell on the color ramp: a number between 0 (first color) and 1 (last color). Values out of this range are brought back to it. A cell for which it returns undefined or null is not drawn. |
color |
function(t) |
- | The color ramp: a function from a number between 0 and 1 to a color, such as a d3 interpolator (d3.interpolateYlOrRd). It is sampled at 0, 0.2, 0.4, 0.6, 0.8 and 1, and the GPU interpolates between the samples. |
colors |
array of colors | a blue-green-yellow-red ramp | The colors of the ramp, evenly spread on [0,1], when color is not given. One color or more: the GPU interpolates linearly between them. |
stretching |
{ fun, alpha } |
none | A stretching of t, computed by the GPU. See below. |
opacity |
function(resolution, z) |
- | The opacity of the cells, between 0 and 1. When it is defined, the opacity of the colors of the ramp is ignored. |
size |
function(resolution, z) |
the resolution plus 0.2 pixel | The size of the squares, in geographical unit. All the squares have the same size. By default, they are a little larger than the cells to avoid thin gaps between them. |
This style displays each cell as a square, with a changing color. This style uses webGL and should thus be used to display grid cells at detailed resolutions. The colors are computed by the GPU, from t: the style is fast, and a bit less flexible than a style with a color function, which can return any color for any cell.
A few things to know:
The tFun function and the stretching apply to t, not to the values: compute t from the value (for example with a viewScale which gives the minimum and maximum of the cells in the view), then let stretching change its distribution.
Without stretching, the color ramp is spread linearly on t: when a few cells have very high values, most of the cells get the first colors of the ramp. The stretching option changes this distribution, with the same functions as the stretching functions of the other styles, computed by the GPU: stretching: { fun: 'log', alpha: -7 }.
fun |
Same as | alpha |
|---|---|---|
'pow' |
powerScale(alpha) |
The exponent: below 1 gives more of the ramp to the low values (0.4 is a good start for a population), above 1 gives more to the high values. No change: 1. |
'powInv' |
powerInverseScale(alpha) |
The exponent. The mirror image of 'pow': 1 - (1 - t)^(1/alpha). No change: 1. |
'exp' |
exponentialScale(alpha) |
The base. No change: 0. |
'log' |
logarithmicScale(alpha) |
The base: a negative base gives more of the ramp to the low values, which is the usual choice for a population (-7 is a good start). No change: 0. |
'circle' |
circularScale(alpha) |
The circularity, between 0 (no stretching) and 1 (a quarter of circle). |
'circleInv' |
circularInverseScale(alpha) |
The circularity, between 0 (no stretching) and 1. |
The stretching can be changed at any time (style.stretching = { fun: 'pow', alpha: 0.4 }, then map.redraw()), as in this example (code), which shows how each function changes the same map. A color legend can write the value of a position t of its bar with the invert function of the stretching function (gridviz.logarithmicScale(-7).invert(t), in the textScale option of the legend).
Class: gridviz.SquareColorCategoryWebGLStyle. Options, plus the options common to all the styles:
| Option | Type | Default | Description |
|---|---|---|---|
code |
function(cell, resolution, z, viewScale) |
- | The category of the cell: a key of color. A cell without category is not drawn. |
color |
object | - | The color of each category: { category1: 'red', category2: '#00ff00' }. |
size |
function(resolution, z) |
the resolution plus 0.2 pixel | The size of the squares, in geographical unit. All the squares have the same size. |
This style displays each cell as a square, with a changing color based on a categorical variable. This style uses webGL and should thus be used to display grid cells at detailed resolutions. As for the Square color WebGL style, the squares are drawn as triangles when they are large, so that there are no gaps in the grid when zoomed in.
This style displays each cell as a circle, with a changing color and size. It does the same as the circle shape of the Shape/Color/Size style, but with webGL: all the circles of the style are drawn at once by the GPU, and copied on the map in a single operation. It should be used rather than the Shape/Color/Size style when there are many circles (tens of thousands or more), for example on a big screen or at detailed resolutions, and when the style has a blendOperation such as 'multiply': it is then applied once for the style instead of once for each circle. It needs webGL 2. Without it, the circles are drawn one by one, as the Shape/Color/Size style does.
new gridviz.CircleColorSizeWebGLStyle({
color: (cell, resolution, z, viewScale) => 'rgb(0,200,235)', // the color of the circle
size: (cell, resolution, z, viewScale) => resolution * 0.5, // its diameter, in geographical unit. 0 to not draw it
alpha: () => 0.85,
blendOperation: () => 'multiply',
})
| Option | Type | Default | Description |
|---|---|---|---|
color |
string or function(cell, resolution, z, viewScale) |
'#EA6BAC' |
The color of the circle of a cell: any CSS color, with its opacity if it has one. A cell without color (or 'none') is not drawn. |
size |
number or function(cell, resolution, z, viewScale) |
the resolution of the grid | The diameter of the circle, in geographical unit (not in pixels). A cell without size (0) is not drawn. |
viewScale |
function | - | As for the other styles: a scale computed from the cells in the view, given to color and size. |
filter |
function(cell) |
- | A cell for which it returns false is not drawn. |
offset |
function(cell, resolution, z) |
no offset | Moves the circles, in geographical unit: {dx, dy}. |
alpha |
function(z) |
opaque | The opacity of the style, applied once to all its circles. |
blendOperation |
function(z) |
'source-over' |
How the style is blended with what is below, applied once to all its circles: 'multiply', 'screen'… |
visible |
boolean or function(z) |
true |
Whether the style is drawn, at a zoom level. |
A few things to know:
size function if it should stay visible.Legends are added as for the other styles, with style.legends = [...]. The styles of this kind on a page share one webGL 2 context, so they do not use up the contexts of the browser.
Class: gridviz.CompositionStyle. Options: color, type, size, stripesOrientation, offsetAngle, agePyramidHeight, pieChartInternalRadiusFactor, plus the options common to all the styles.
This style shows a composition at cell level in various different ways: Flags, pie charts, rings, segments, radar, age pyramid and halftone.
Class: gridviz.SegmentStyle. Options: color, width, length, orientation, plus the options common to all the styles.
This style displays each cell as a segment with a changeable color, length, width and orientation.
Class: gridviz.StrokeStyle. Options: strokeColor, size, strokeWidth, shape, plus the options common to all the styles.
This style shows the stroke of each cell with different colors, widths, shapes and sizes. This style can be used in addition to others to show the cell strokes on top of those other styles.
Class: gridviz.DotDensityStyle. Options: dotNumber, color, dotSize, sigma, plus the options common to all the styles.
This style displays each cell as randomly located points, with changeable density and color.
Class: gridviz.PillarStyle. Options: height, color, width, simple, viewHeightFactor, viewSX, viewSY, shadowDirection, shadowFactor, shadowColor, outlineCol, outlineWidthPix, plus the options common to all the styles.
This style shows the grid cells as 3D pillars or, with changeable height, width and color.
There is no style of its own: the cells are drawn with a Shape/Color/Size style whose color comes from a ternary classifier, and the gridviz.TernaryLegend shows the colors (see the ternary color legend).
Ternary maps use color to show a composition according to three categories. Three different color hue are defined, that correspond to each of the three categories. The cells color is then selected according to the relative importance of the three categories. When two of the three categories are more important that the third, a color mix is used. A central class may be defined to show cases where the three categories are relativelly well balanced.
Note that this style is not really a new style - it relies on a specific classifier.
Class: gridviz.TextStyle. Options: text, color, fontSize, fontFamily, fontWeight, plus the options common to all the styles.
This style shows the grid cells as text labels. The text, its color and font size can be set according to some cell values.
Class: gridviz.ImageStyle. Options: image, size, plus the options common to all the styles.
This style shows the grid cells as an image. The image and its size can be set according to some cell values.
Class: gridviz.TimeSeriesStyle. Options: ts, noData, offsetX, width, offsetY, height, anchorModeY, lineWidth (function(cell, resolution, z, viewScale), 1.5 pixel by default), color, plus the options common to all the styles.
This style shows the grid cells as a time series chart. It is particulary suitable to show data that has high temporal granularity and low geographical granurality (variation across time rather than space). The time series charts can be colored and sized according to other variables.
The side styles are special:They do not display the cells, but their sides. They can be used to show discontinuities between cell values with, for example, some shadow effect.
Class: gridviz.SideStyle. Options: color, width, length, diamond, plus the options common to all the styles.
This style displays the sides of the cells as segments with different colors and widths, depending on the values of the 2 adjacent cells.
Class: gridviz.SideCategoryStyle, which extends the side style. Options: code, color, plus the options common to all the styles.
This style displays the sides of the cells as segments with different colors depending on the categories of the 2 adjacent cells.
Class: gridviz.SideTanakaStyle, with the same color for all the lines (see the Tanaka style for its options).
This style displays the sides of the cells depending on discontinuities between the 2 adjacent cells, like contour lines. For this style, the Tanaka style is simply reused with the same color for all lines.
Class: gridviz.IsoFenceStyle. Options: color, height, angle, cornerLineStrokeColor, cornerLineWidth, sVert, sHor, plus the options common to all the styles.
This style shows the composition of a total quantity into categories as vertical cross-sections oriented toward North-South and East-West. It is an alternative to composition style. It may also be seen as a bi-directional joyplot style showing categories - note that when angle value is set to 90°, the style is equivalent to a joyplot. This style was inspired by the USGS geologic isometric fence diagrams (1953).
This style shows the relief of an elevation grid as hillshading. It is based on the side style: for each side between two adjacent cells, it draws a segment which is light when the side faces the top left and dark when it faces the bottom right, with an opacity proportional to the elevation difference between the two cells (relative to the biggest difference in the view). Use it over a hypsometric colour style to give an impression of relief.
new gridviz.ShadingStyle({
elevation: 'v', // the name of the elevation property of the cells
scale: gridviz.exponentialScale(-1), // optional: stretches the elevation differences
colorTopLeft: '255,155,155', // 'r,g,b'
colorBottomRight: '0,0,100',
})
| Option | Type | Default | Description |
|---|---|---|---|
elevation |
string | - | The name of the cell property with the elevation. Required. A side next to a cell without elevation (or with a zero one) is not drawn. |
colorTopLeft |
string | '255,255,255' |
The color of the sides which face the top left, as 'r,g,b'. |
colorBottomRight |
string | '0,0,0' |
The color of the sides which face the bottom right, as 'r,g,b'. |
revert |
boolean | false |
Swaps the two colors, to show depressions as hills. |
scale |
function(number):number |
linear | Stretches the opacity, from a value within [0,1] (the elevation difference relative to the biggest one in the view) to a value within [0,1]. See stretching. |
width |
number | 2 pixels | The width of the segments, in geographical unit. By default 2 pixels, and at most a third of the resolution. |
diamond |
boolean | false |
Draws the sides as diamonds, as the side style does. |
The other options of the side style and of the styles in general (filter, alpha, blendOperation, visible…) can be used too.
Class: gridviz.JoyPlotStyle. Options: height, lineColor, lineWidth, fillColor, plus the options common to all the styles.
This style shows cell rows in the form of a ‘joyplot’ - named after Joy Division’s “Unknown Pleasures” album cover. For joyplot style showing composition by categories, or for various orientations and perspective angles, see isometric fence style.
Class: gridviz.MosaicStyle. Options: color, mosaicFactor, shadowFactor, shadowColor, plus the options common to all the styles.
This style shows the cell as pseudo-irregular square shapes giving a mosaic effect. The cells are colored depending on a variable.
Class: gridviz.NinjaStarStyle. Options: color, size, shape, plus the options common to all the styles.
This style shows the cell as a star polygon whose compacity depends on a variable. The higher the value, the more compact the star: Maximum values correspond to a square, and minimum values correspond to a thin star. The shapes in between correspond to 4 branches stars looking like a ninja star.
Class: gridviz.SideTanakaStyle. Options: classifier, width, length, colorDark, colorBright, revert, diamond, limit, plus the options common to all the styles.
This style shows the grid cells in a Tanaka style, that is with discrete colors and a shadow effect.
Class: gridviz.LegoStyle. It makes a list of styles, one for each color of the bricks: gridviz.LegoStyle.get(value, breaks, colors, opts), where value is a function of a cell, breaks the class limits and colors the color of each class (opts: colDark and colBright, the colors of the sides and of the top of the bricks, and filter). There is one more color than breaks: with the breaks [100, 200], the colors are those of the values under 100, from 100 to 200, and over 200.
This style shows the grid cells as lego bricks with changeable colors and height based on a quantitative variable.
Migrating from version 2. The tFun option of version 2, which gave the position of a cell on the color ramp (for example tFun: (v, r, s, zf) => sExpRev((v - s.min) / (s.max - s.min), -7)), does not exist anymore: a brick has the color of its class. To get the same colors for the same values, take the classes the stretching would give: gridviz.stretchedBreaks(min, max, classNumber, stretching) returns the class limits which a stretching function maps to the limits between the classes of the color ramp. Then take a color for each class.
const classNumber = 8
// the stretching of version 2, sExpRev(t, -7), is now gridviz.logarithmicScale(-7)
const breaks = gridviz.stretchedBreaks(0, 1400000, classNumber, gridviz.logarithmicScale(-7))
const colors = Array.from({ length: classNumber }, (_, i) => d3.interpolateYlOrRd((i + 0.5) / classNumber))
const styles = gridviz.LegoStyle.get((cell) => +cell.population, breaks, colors)
The breaks are fixed: unlike with tFun, the minimum and maximum are not taken from the cells in the view. Give the values of the data (or the ones you want for the whole map) for min and max.
Class: gridviz.LegoStyle, with gridviz.LegoStyle.getCategory(code, color, opts): code is a function of a cell which returns its category and color the color of each category.
This style shows the grid cells as lego bricks with changeable colors based on a categorical variable.
This style draws the shadows which the relief casts on the ground, for a given position of the sun. For each cell, a ray is cast towards the sun across the elevation grid: the cell is in the shadow when the relief hides the sun from it. The cells in the shadow are drawn as squares of a single color, usually black with some transparency, above a hypsometric colour style.
const shadows = new gridviz.ShadingRayStyle({
elevation: (cell) => cell.v, // the elevation of a cell
sunAzimuth: () => 2.356, // radians, clockwise from north: here, the sun is in the south-east
sunAltitude: () => 0.2, // radians, above the horizon
color: () => 'black', // the color of the shadows
alpha: () => 0.4, // as any style: the opacity of the shadows
})
| Option | Type | Default | Description |
|---|---|---|---|
elevation |
function(cell):number |
- | The elevation of a cell. Required. |
sunAzimuth |
function(resolution, z, viewScale):number |
() => 2.356 |
The direction of the sun, in radians, clockwise from the north (0 is north, π/2 east, π south). The default is 135°: south-east. |
sunAltitude |
function(resolution, z, viewScale):number |
() => 0.2 |
The height of the sun above the horizon, in radians (0.2 is about 11°). The lower the sun, the longer the shadows. |
color |
function(resolution, z, viewScale):string |
() => 'black' |
The color of the shadows. |
undefinedValue |
number | 0 |
The elevation to use for the cells without elevation (such as the sea). |
The shadows are computed from the cells of the view, each time the map is drawn. Their computation is heavy when there are many cells, so use a rather high minPixelsPerCell for the layer (the example uses 2). The styles options (filter, alpha, blendOperation, visible…) can be used too, to change them from a user interface for example.
This style allows applying a gaussian kernel smoothing to the input grid. Other styles can then be used on the smoothed grid - this style is thus more a ‘filter’ than a proper style.
Note that this style is available within the gridviz-smoothing extension which need to be added as: <script src="https://cdn.jsdelivr.net/npm/gridviz-smoothing"></script>.
The kernel smoothing computation relies on the fast-kde library, which produces smoothing approximation very fast. Note that the approximation degrades significantly for weak smoothing (for low sigma values).
The Interpolator computes new values for the cells in between the cells of a grid, to show a coarse grid as a smooth surface. Like the kernel smoothing, it is more a ‘filter’ than a proper style: it does not draw anything by itself, it makes a finer grid by bilinear interpolation and draws it with the styles it is given.
const interpolator = new gridviz.Interpolator({
value: (cell) => cell.v, // the value to interpolate
targetResolution: (resolution, z) => resolution / 5, // the resolution of the interpolated cells
interpolatedProperty: 'v', // the cells of the interpolated grid have their value under this property
})
// the styles which draw the interpolated cells, as the ones of a layer would
interpolator.styles.push(new gridviz.SquareColorWebGLStyle({ tFun: (cell) => cell.v / 4000 }))
const layer = new gridviz.GridLayer(dataset, [interpolator])
| Option | Type | Default | Description |
|---|---|---|---|
value |
function(cell):number |
- | The value to interpolate. Required. |
targetResolution |
function(resolution, z):number |
(r, z) => r / 5 |
The resolution of the interpolated cells. The ratio between the resolution of the grid and this one is rounded to an integer, so make sure it is one. |
interpolatedProperty |
string | 'value' |
The property of the interpolated cells which holds the interpolated value. The styles read the value from it. |
nodataHandling |
'zero' or 'average' |
'zero' |
What to do with the neighbour cells without value: take zero, or the average of the surrounding cells. |
styles |
array of styles | [] |
The styles which draw the interpolated cells. They are drawn at the target resolution, with their own alpha, blendOperation and visible. |
The cells with a zero value after interpolation are not drawn. Since there are many more interpolated cells than cells, using the WebGL styles to draw them is recommended.
A category (a land cover, for example) can not be interpolated like a number: there is nothing between a forest and a field. The RandomWalkInterpolator makes a finer grid from a grid of categories, with the random walk interpolator of Spatial interpolators in Observable Plot (VISU 2023). It is used as the Interpolator is, and its styles draw the finer grid. Each cell of the finer grid takes the category of the first cell of the original grid which a random walk, starting from it, reaches: the cells of the original grid are points, at their center, and a cell takes most of the time the category of its closest neighbors. The limits between the categories become irregular, with fine details, instead of the squares of the grid.
const interpolator = new gridviz.RandomWalkInterpolator({
value: (cell) => cell.clc, // the category of the cell. A cell for which it returns undefined is not interpolated.
targetResolution: (resolution, z) => resolution / 5, // the resolution of the finer grid
interpolatedProperty: 'clc', // the cells of the finer grid have their category under this property
})
// the styles which draw the finer grid
interpolator.styles.push(new gridviz.SquareColorCategoryWebGLStyle({ code: (cell) => cell.clc, color: colors }))
const layer = new gridviz.GridLayer(dataset, [interpolator])
| Option | Type | Default | Description |
|---|---|---|---|
value |
function(cell) |
- | The category of the cell, a string or a number. Required. |
targetResolution |
function(resolution, z):number |
(r, z) => r / 5 |
The resolution of the finer grid. The ratio between the resolution of the grid and this one is rounded to an integer. |
interpolatedProperty |
string | 'value' |
The property of the cells of the finer grid which holds the category. The styles read the category from it. |
maxSteps |
function(factor):number |
(f) => 6 * f * f |
The maximum number of steps of a random walk, from the ratio between the resolutions. A longer walk makes smoother limits, and takes more time. A walk which has not reached a cell takes the category of the cell it is in. |
seed |
number | 0 |
A number to change the random walks. Only the cells at the limits between categories change with it, so the effect is small. |
styles |
array of styles | [] |
The styles which draw the cells of the finer grid. |
The random walks start from the position of each cell of the finer grid: the result does not change when the map is panned or drawn again, only with the seed. A factor of 4 to 6 gives a good result in a fraction of a second for the cells of a screen: the cost grows with the square of the factor, and with the number of cells.
A style is an instance of gridviz.Style, which can be freely defined through the drawFun. It specifies how to draw the list of cells within the view on the map canvas:
new gridviz.Style({
drawFun: (cells, geoCanvas, resolution) => {
const ctx = geoCanvas.offscreenCtx // draw here, in geographical coordinates
for (const cell of cells) ctx.fillRect(cell.x, cell.y, resolution, resolution)
},
})
The options common to all the styles can be used. Two helpers are exported for custom styles: gridviz.nice(v), which rounds a value down to a round number (a power of ten, or a multiple of it), and gridviz.cellsToMatrix(cells, resolution, valueFunction), which puts the cells in a matrix (a list of rows, from top to bottom), to compute on neighbour cells.
Background image layers may be defined:
Foreground layers may be defined such as:
To handle layer and style transparency, blending modes and alpha values may be defined at layer or style level. These values may be set according to the zoom level.
A tooltip shows information about the grid cell under the mouse pointer. By default, it lists the properties of the cell.
cellInfoHTML option of the GridLayer: a function of the cell which returns HTML, or 'none' for no tooltip. See this example (code).tooltip option of the map:new gridviz.Map(document.getElementById('map'), {
tooltip: { maxWidth: 'none', fontSize: '0.9rem' },
})
| Option | Default | Description |
|---|---|---|
maxWidth |
'20em' |
The widest the tooltip can be. What does not fit is clipped: use 'none' for a tooltip with long lines. |
fontSize, font-family |
'1rem', 'Helvetica Neue', Arial, Helvetica, sans-serif |
The text. |
color, lineHeight |
'#171a22', '1.5' |
The color of the text and the height of its lines. |
background, padding |
'white', '4px' |
The inside of the tooltip. |
border, border-radius |
'1px solid #d5d5d5', '6px' |
Its outline. |
box-shadow |
'0px 4px 6px rgba(0, 0, 0, 0.1), 0px 1px 3px rgba(0, 0, 0, 0.08)' |
Its shadow. |
xOffset, yOffset |
30, 20 |
Its distance from the pointer, in pixels. xMouseOffset and yMouseOffset shift the point where the mouse is taken, for example so that the cursor does not cover the cell which is highlighted (default 0). |
transitionDuration |
100 |
The duration of its fade in and out, in milliseconds. |
parentElement, tooltipElement |
the page body, a new element | Where the tooltip is added, and an element of the page to use as the tooltip instead of a new one. |
The defaults are the look of the tooltips of the statistical atlas. The tooltip has the class gridviz-tooltip, so that a stylesheet can restyle it (the inline styles need !important to be overridden).
The map has a zoom button and a full screen button, added with two methods which can be chained:
const map = new gridviz.Map(document.getElementById('map'), { x: 4500000, y: 2900000, z: 3000 }).addZoomButtons().addFullscreenButton()
addZoomButtons({ id, class, x, y, onZoom, delta }): the two buttons “+” and “−”. delta is the change of zoom at each click (0.2 by default), and onZoom a function called after it. By default the buttons are 10 pixels from the right and from the top.addFullscreenButton({ id, class, x, y }): by default 10 pixels from the right and 90 pixels from the top.x and y are the distances, in pixels, of the button from the left and from the top of the map. class adds your own CSS classes.See this example (code). The look of the buttons is the one of the map controls of the statistical atlas, and can be changed with CSS variables: see styling the rest of the map.
For some predefined style parameters, viewscale parameter allows defining styling parameters based on the cells within the map view only. This parameter is an object computed only once from the cells within the view. It may be used for example to compute the minimum and maximum values of these cells and adapt a color scale to this for a better contrast. It should generally be used to compute scales that are view dependant - hence the name viewscale.
A style has one viewScale, but it can be an object: a view scale can compute the scale of the color and the scale of the size at once, for a style whose color and size follow two variables. gridviz.viewScaleCombination makes it from one view scale for each:
const style = new gridviz.ShapeColorSizeStyle({
shape: () => 'circle',
size: (c, r, z, viewScale) => viewScale.size(+c.population),
color: (c, r, z, viewScale) => viewScale.color(+c.change),
viewScale: gridviz.viewScaleCombination({
size: gridviz.viewScale({ valueFunction: (c) => +c.population, stretching: gridviz.logarithmicScale(-8) }),
color: gridviz.viewScaleColor({ valueFunction: (c) => +c.change, colorScale: d3.interpolateRdBu }),
}),
})
The legends take what they need from this object, so that each variable has its legend:
textScale option: textScale: (t, viewScale) => viewScale?.color?.invert(t).viewScaleFun option: gridviz.sizeLegendViewScale(value, { viewScaleFun: (viewScale) => viewScale.size }).Put them all in the legends of the style: style.legends = [colorLegend, sizeLegends].
Most of Gridviz styles rely on a continuous mapping from a statistical variable to a visual variable (color, size, etc.). The statistical distribution can be stretched with one of the stretching functions listed below can be used. These are continuous bijective functions defined from [0,1] to [0,1] intervals. They have different properties and should be chosen according to the data distribution. The amplitude of the stretching can be adjusted with a parameter.
| Stretching function | Description | Stretching parameter |
|---|---|---|
| powerScale | Polynomial function | Power exponent, from 0 to Infinity. No change: 1 |
| powerInverseScale | Polynomial inverse function | Power exponent, from 0 to Infinity. No change: 1 |
| logarithmicScale | Exponential function | Logarithmic base, from -Infinity to Infinity. No change: 0 |
| exponentialScale | Exponential | Logarithmic base, from -Infinity to Infinity. No change: 0 |
| circularScale | Circular | 0: no stretching. 1: perfect circle section |
| circularInverseScale | Circular | 0: no stretching. 1: perfect circle section |
For more information on these functions and an overview of how they differ, see:
Gridviz offers several types of legends that are suited to different cartographic styles.
The legend elements are added within a default HTML element. To define where the legend elements should be added, see this example (code).
Each legend can be customised using the ‘D3-like’ style() function after constructing the legend, like so:
new gridviz.SizeLegend({
title: 'Number of inhabitants',
exaggerationFactor: 0.8,
shape: 'circle',
fillColor: '#3E5791',
}).style('padding', '0px 5px')
labelsAsHTML: true on a legend makes its title and, for ColorCategoryLegend, its labels HTML instead of plain text, to italicise a word for example. It is off by default, and the text is not escaped, so only use it for text you trust.onLegendUpdate, a function given to the Map (or set on it afterwards), is called with the legend container each time the map has been drawn and its legends are in the container, for a host that adjusts them. Together with the legendContainer option, it lets an application render the legends straight into its own panel.gridviz-legend and one for its type (gridviz-legend--discrete, --color, --category, --ternary, --size, --orientation). The parts have gridviz-legend-title, -label, -swatch, -tick and, for a row of a category, size or orientation legend, -category. The drawing of a legend is an svg with gridviz-legend-graphic (inside a gridviz-legend-symbol-wrapper in a category row), the shapes of a size or orientation legend have gridviz-legend-symbol, the colour bar’s group has gridviz-legend-bar and the ternary triangle’s gridviz-legend-triangle. A swatch being hovered also has gridviz-legend-swatch--active (a category row gridviz-legend-category--active). Add your own class to a legend with the className option, for example to style one legend, like a “not available” entry, differently.!important: --gridviz-legend-font-family, --gridviz-legend-title-font-size, --gridviz-legend-title-font-weight, --gridviz-legend-label-font-size, --gridviz-legend-label-color, --gridviz-legend-padding. An option given to the legend (labelFontSize, padding…) still wins. The default values are those of the legends of the statistical atlas: a title of 15px with a weight of 500, labels of 14px in #333, and the font stack of the tooltip.width: 'fill' on a ColorLegend or a ColorDiscreteLegend draws it at the width of the element the legends are in (the map’s legendContainer), less its padding, each time the legend is drawn. A number of pixels is used as before.The other elements gridviz creates have classes too, so that a page can restyle them (inline styles set by gridviz need !important to be overridden):
gridviz-map: the element the map is drawn in. gridviz-canvas: the map’s canvas.gridviz-legends: the element the legends are in, when gridviz makes it (not when you give a legendContainer).gridviz-tooltip: the tooltip, also when you give your own tooltipElement.gridviz-button on every button, with gridviz-zoom-buttons (and gridviz-zoom-button--in / --out on the two links inside it) or gridviz-fullscreen-button (its icon is gridviz-fullscreen-icon). The class option adds your own classes.!important: --gridviz-button-color (#0e47cb, the symbol), --gridviz-button-border-color (#0e47cb), --gridviz-button-background (#ffffff), --gridviz-button-hover-background (#f4f4f4), --gridviz-button-radius (10px) and --gridviz-button-size (38px, the width and height of a button, border included).Hovering a swatch of a ColorDiscreteLegend, ColorCategoryLegend or TernaryLegend shows only the cells drawn in that colour on the map, and hovering out shows them all again. With a VennLegend, hovering a part of the diagram shows the cells of the colors of the circles at this place. This works for the styles that draw cells in a colour per class: ShapeColorSizeStyle, CircleColorSizeWebGLStyle and SquareColorCategoryWebGLStyle. It matches the colour the style draws with against the colour of the swatch, so the two should be the same colour. Set interactive: false on a legend to turn it off.
A custom style can take part too: skip the cells for which this.isHighlighted(color) is false. Custom legends can call this.bindHover(selection, color) on each swatch. A legend which stands for several styles (like the VennLegend) overrides highlightedStyles() to return them, and calls this.highlight(colors) with the colors to show.



Class: gridviz.OrientationLegend.





A legend for the colors of a map which shows two or three variables as overlapping layers, each in its own color, blended by multiplication (see the circle style based on web GL, with a blendOperation: () => 'multiply'). It is a Venn diagram: a circle for each variable, in its color, and the overlaps have the colors of the mix of the circles.
// one style for each variable, with its color (see the example)
styles[0].legends = [
new gridviz.VennLegend({
title: 'Permanent crops',
items: [
{ label: 'Fruit trees', color: 'rgb(0,255,255)' },
{ label: 'Olive groves', color: 'rgb(245,210,0)' },
{ label: 'Vineyards', color: 'rgb(255,20,147)' },
],
}),
]
| Option | Type | Default | Description |
|---|---|---|---|
items |
array of {label, color} |
- | The two or three variables. The label is written beside the circle (on the left, on the right and below, for the first, second and third one). The color is the one the style which draws the variable uses. Required. |
radius |
number | 45 |
The radius of the circles, in pixels. |
opacity |
number | 1 |
The opacity of the circles, within [0,1]. |
styles |
array of styles | the styles of the layer | The styles which are highlighted when the diagram is hovered, which should be the ones which draw the variables. |
The common options of the legends (title, labelFontSize, titleFontSize, padding, className, interactive…) can be used too.
The legend is interactive, like the other ones. When the pointer is over a part of the diagram, only the cells of the colors of the circles at this place are shown on the map: the cells of one variable on a part of one circle, and the cells of all the variables of the circles which overlap on an overlap (all of them in the center, for three variables). The circles which are not involved fade in the legend. Hovering the label of a variable shows its cells. Set interactive: false to turn it off.
For this, the legend highlights all the styles of the layer it is in, not only the one it is added to (the others are hidden for the colors which are not highlighted). Give the styles option if some of the styles of the layer should not be affected.
Gridviz can be used with leaflet by using the leaflet-gridviz plugin
See this example (code) to limit the panning and zooming to some limit values, in order to prevent the user to move toward undesired positions and zoom levels. Note that the panning limit applies to the map center, not the map borders. The panning limit is specified as an array [xMin, yMin, xMax, yMax].

A mixed-resolution grid is a grid which contains cells with different sizes.
Note that most pre-defined styles of GridViz may not apply for mixed-resolution grids. Custom styles can be defined.
Anything unclear or missing? Feel free to ask !