{
"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"autosize": "pad",
"padding": 5,
"data": [
{
"name": "brush_store"
},
{
"name": "matrix_data",
"url": "https://rawgit.com/mattijn/datasets/master/eu_extreme_discharge_som.csv",
"format": {
"type": "csv",
"parse": {
"X": "number",
"Y": "number",
"U-matrix": "number",
"Annual maxima of daily discharge": "number",
"Annual maxima of daily precipitation": "number",
"Annual maxima of daily precipitation and snowmelt": "number",
"Annual maxima of daily snowmelt": "number",
"Annual maxima of daily total runoff coefficient": "number",
"Annual mean of daily discharge": "number",
"Annual mean of daily near-surface air temperature": "number",
"Annual mean of daily precipitation": "number",
"Annual mean of daily total runoff coefficient": "number",
"Area": "number",
"Average elevation": "number",
"Average water capacity": "number",
"Build-up areas": "number",
"Circularity": "number",
"Clay": "number",
"Confidence": "number",
"Eolian deposits": "number",
"Forests": "number",
"Glaciers": "number",
"Gravel": "number",
"Irrigated agriculture": "number",
"Lakes": "number",
"Marshes": "number",
"Peat": "number",
"River network density": "number",
"River slopeness": "number",
"Sand": "number",
"Silt": "number",
"Slopeness (average)": "number",
"Soil sealing": "number",
"Soil texture (dimensionless index from 1 to 13)": "number",
"Steepness (equation)": "number",
"Time of concentration": "number",
"Total area": "number",
"Unconsolidated deposits": "number",
"Total events in node": "number"
}
},
"transform": [
{
"type": "filter",
"expr": "datum['U-matrix'] <= filter_u_matrix"
}
]
},
{
"name": "map_data",
"url": "https://rawgit.com/mattijn/datasets/master/eu_extreme_discharge_locations.json",
"format": {
"type": "json",
"property": "features"
},
"transform": []
},
{"name":"matrix_data_static",
"source":"matrix_data"},
{
"name": "data_0",
"source": "matrix_data",
"transform": [
{
"type": "filter",
"expr": "!(length(data(\"brush_store\"))) || (vlInterval(\"brush_store\", datum))"
},
{
"type": "lookup",
"from": "map_data",
"key": "properties.som_key",
"fields": [
"XY"
],
"as": [
"geo"
]
},
{
"type": "filter",
"expr": "datum.geo"
},
{
"type": "formula",
"expr": "geoCentroid('projection', datum.geo)",
"as": "centroid"
},
{
"type": "filter",
"expr": "datum['U-matrix'] <= filter_u_matrix"
},
{
"type": "collect",
"sort": {
"field": {
"signal": "variable"
},
"order": "ascending"
}
}
]
},
{
"name": "map_outline",
"url": "https://rawgit.com/mattijn/datasets/master/europe.topojson",
"format": {
"type": "topojson",
"feature": "europe"
}
}
],
"signals": [
{
"name": "matrix_x_step",
"value": 10
},
{
"name": "matrix_width",
"value": 600
},
{
"name": "matrix_y_step",
"value": 10
},
{
"name": "matrix_height",
"value": 500
},
{
"name": "matrix_x",
"value": 0
},
{
"name": "matrix_y",
"value": 0
},
{
"name": "map_width",
"value": 600
},
{
"name": "map_height",
"value": 500
},
{
"name": "variable",
"value": "Annual mean of daily precipitation",
"bind": {
"input": "select",
"options": [
"U-matrix",
"Annual maxima of daily discharge",
"Annual maxima of daily precipitation",
"Annual maxima of daily precipitation and snowmelt",
"Annual maxima of daily snowmelt",
"Annual maxima of daily total runoff coefficient",
"Annual mean of daily discharge",
"Annual mean of daily near-surface air temperature",
"Annual mean of daily precipitation",
"Annual mean of daily total runoff coefficient",
"Area",
"Average elevation",
"Average water capacity",
"Build-up areas",
"Circularity",
"Clay",
"Confidence",
"Eolian deposits",
"Forests",
"Glaciers",
"Gravel",
"Irrigated agriculture",
"Lakes",
"Marshes",
"Peat",
"River network density",
"River slopeness",
"Sand",
"Silt",
"Slopeness (average)",
"Soil sealing",
"Soil texture (dimensionless index from 1 to 13)",
"Steepness (equation)",
"Time of concentration",
"Total area",
"Unconsolidated deposits",
"Total events in node"
]
}
},
{
"name": "filter_u_matrix",
"value": 9.2,
"bind": {
"input": "range",
"min": 0.2,
"max": 9.2,
"step": 0.2
}
},
{
"name": "unit",
"value": {},
"on": [
{
"events": [
{
"type": "mousemove"
},
{
"type": "touchmove"
}
],
"update": "isTuple(group()) ? group() : unit"
}
]
}
],
"projections": [
{
"name": "projection",
"type": "mercator",
"scale": 450,
"rotate": [
0,
0,
0
],
"center": [
7,
56
],
"translate": [
{
"signal": "map_width / 2"
},
{
"signal": "map_height / 2"
}
]
}
],
"layout": {
"padding": {
"row": 10,
"column": 10
},
"offset": 10,
"columns": 2,
"bounds": "full",
"align": "none"
},
"title": {
"text": "A self-organizing map of European rivers using variables representing the geographical characteristics of their catchments",
"orient": "top",
"anchor": "start"
},
"marks": [
{
"type": "group",
"name": "matrix_group",
"style": "cell",
"title": {
"text": "matrix element: create box to filter locations (use scroll to change box-size)",
"anchor": "start",
"orient": "bottom"
},
"encode": {
"update": {
"x": {
"signal": "matrix_x"
},
"y": {
"signal": "matrix_y"
},
"width": {
"signal": "matrix_width"
},
"height": {
"signal": "matrix_height"
}
}
},
"signals": [
{
"name": "brush_x",
"value": [],
"on": [
{
"events": [
{
"source": "scope",
"type": "mousedown",
"filter": [
"!event.item || event.item.mark.name !== \"brush_brush\"",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)"
]
},
{
"source": "scope",
"type": "touchstart",
"filter": [
"!event.item || event.item.mark.name !== \"brush_brush\"",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)"
]
}
],
"update": "[x(unit), x(unit)]"
},
{
"events": [
{
"source": "window",
"type": "mousemove",
"consume": true,
"between": [
{
"source": "scope",
"type": "mousedown",
"filter": [
"!event.item || event.item.mark.name !== \"brush_brush\"",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)"
]
},
{
"source": "window",
"type": "mouseup"
}
]
},
{
"source": "window",
"type": "touchmove",
"consume": true,
"between": [
{
"source": "scope",
"type": "touchstart",
"filter": [
"!event.item || event.item.mark.name !== \"brush_brush\"",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)"
]
},
{
"source": "window",
"type": "touchend"
}
]
}
],
"update": "[brush_x[0], clamp(x(unit), 0, matrix_width)]"
},
{
"events": {
"signal": "brush_scale_trigger"
},
"update": "[0, 0]"
},
{
"events": {
"signal": "brush_translate_delta"
},
"update": "clampRange(panLinear(brush_translate_anchor.extent_x, brush_translate_delta.x / span(brush_translate_anchor.extent_x)), 0, matrix_width)"
},
{
"events": {
"signal": "brush_zoom_delta"
},
"update": "clampRange(zoomLinear(brush_x, brush_zoom_anchor.x, brush_zoom_delta), 0, matrix_width)"
}
]
},
{
"name": "brush_X",
"on": [
{
"events": {
"signal": "brush_x"
},
"update": "brush_x[0] === brush_x[1] ? null : invert(\"matrix_x\", brush_x)"
}
]
},
{
"name": "brush_y",
"value": [],
"on": [
{
"events": [
{
"source": "scope",
"type": "mousedown",
"filter": [
"!event.item || event.item.mark.name !== \"brush_brush\"",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)"
]
},
{
"source": "scope",
"type": "touchstart",
"filter": [
"!event.item || event.item.mark.name !== \"brush_brush\"",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)"
]
}
],
"update": "[y(unit), y(unit)]"
},
{
"events": [
{
"source": "window",
"type": "mousemove",
"consume": true,
"between": [
{
"source": "scope",
"type": "mousedown",
"filter": [
"!event.item || event.item.mark.name !== \"brush_brush\"",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)"
]
},
{
"source": "window",
"type": "mouseup"
}
]
},
{
"source": "window",
"type": "touchmove",
"consume": true,
"between": [
{
"source": "scope",
"type": "touchstart",
"filter": [
"!event.item || event.item.mark.name !== \"brush_brush\"",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)",
"inScope(event.item)"
]
},
{
"source": "window",
"type": "touchend"
}
]
}
],
"update": "[brush_y[0], clamp(y(unit), 0, matrix_height)]"
},
{
"events": {
"signal": "brush_scale_trigger"
},
"update": "[0, 0]"
},
{
"events": {
"signal": "brush_translate_delta"
},
"update": "clampRange(panLinear(brush_translate_anchor.extent_y, brush_translate_delta.y / span(brush_translate_anchor.extent_y)), 0, matrix_height)"
},
{
"events": {
"signal": "brush_zoom_delta"
},
"update": "clampRange(zoomLinear(brush_y, brush_zoom_anchor.y, brush_zoom_delta), 0, matrix_height)"
}
]
},
{
"name": "brush_Y",
"on": [
{
"events": {
"signal": "brush_y"
},
"update": "brush_y[0] === brush_y[1] ? null : invert(\"matrix_y\", brush_y)"
}
]
},
{
"name": "brush_scale_trigger",
"update": "(!isArray(brush_X) || (invert(\"matrix_x\", brush_x)[0] === brush_X[0] && invert(\"matrix_x\", brush_x)[1] === brush_X[1])) && (!isArray(brush_Y) || (invert(\"matrix_y\", brush_y)[0] === brush_Y[0] && invert(\"matrix_y\", brush_y)[1] === brush_Y[1])) ? brush_scale_trigger : {}"
},
{
"name": "brush_tuple",
"on": [
{
"events": [
{
"signal": "brush_X"
},
{
"signal": "brush_Y"
}
],
"update": "brush_X && brush_Y ? {unit: \"matrix_layer\", intervals: [{encoding: \"x\", field: \"X\", extent: brush_X}, {encoding: \"y\", field: \"Y\", extent: brush_Y}]} : null"
}
]
},
{
"name": "brush_translate_anchor",
"value": {},
"on": [
{
"events": [
{
"source": "scope",
"type": "mousedown",
"markname": "brush_brush"
},
{
"source": "scope",
"type": "touchstart",
"markname": "brush_brush"
}
],
"update": "{x: x(unit), y: y(unit), extent_x: slice(brush_x), extent_y: slice(brush_y)}"
}
]
},
{
"name": "brush_translate_delta",
"value": {},
"on": [
{
"events": [
{
"source": "window",
"type": "mousemove",
"consume": true,
"between": [
{
"source": "scope",
"type": "mousedown",
"markname": "brush_brush"
},
{
"source": "window",
"type": "mouseup"
}
]
},
{
"source": "window",
"type": "touchmove",
"consume": true,
"between": [
{
"source": "scope",
"type": "touchstart",
"markname": "brush_brush"
},
{
"source": "window",
"type": "touchend"
}
]
}
],
"update": "{x: brush_translate_anchor.x - x(unit), y: brush_translate_anchor.y - y(unit)}"
}
]
},
{
"name": "brush_zoom_anchor",
"on": [
{
"events": [
{
"source": "scope",
"type": "wheel",
"consume": true,
"markname": "brush_brush"
},
{
"source": "scope",
"type": "touchstart",
"filter": "event.touches.length===2",
"consume": true,
"markname": "brush_brush"
}
],
"update": "{x: x(unit), y: y(unit)}"
}
]
},
{
"name": "brush_zoom_delta",
"on": [
{
"events": [
{
"source": "scope",
"type": "wheel",
"consume": true,
"markname": "brush_brush"
}
],
"force": true,
"update": "pow(1.001, event.deltaY * pow(16, event.deltaMode))"
},
{
"events": {
"signal": "dist2"
},
"force": true,
"update": "dist1 / dist2"
}
]
},
{
"name": "brush_modify",
"on": [
{
"events": {
"signal": "brush_tuple"
},
"update": "modify(\"brush_store\", brush_tuple, true)"
}
]
},
{
"name": "dist2",
"value": 0,
"on": [
{
"events": {
"type": "touchstart",
"filter": "event.touches.length===2"
},
"update": "pinchDistance(event)"
},
{
"events": {
"signal": "dist1"
},
"update": "dist1"
}
]
},
{
"name": "dist1",
"value": 0,
"on": [
{
"events": {
"type": "touchmove",
"consume": true,
"filter": "event.touches.length===2"
},
"update": "pinchDistance(event)"
}
]
}
],
"marks": [
{
"name": "brush_brush_bg",
"type": "rect",
"clip": true,
"encode": {
"enter": {
"fill": {
"value": "#333"
},
"fillOpacity": {
"value": 0.125
}
},
"update": {
"x": [
{
"test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"matrix_layer\"",
"signal": "brush_x[0]"
},
{
"value": 0
}
],
"y": [
{
"test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"matrix_layer\"",
"signal": "brush_y[0]"
},
{
"value": 0
}
],
"x2": [
{
"test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"matrix_layer\"",
"signal": "brush_x[1]"
},
{
"value": 0
}
],
"y2": [
{
"test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"matrix_layer\"",
"signal": "brush_y[1]"
},
{
"value": 0
}
]
}
}
},
{
"name": "matrix_layer_marks",
"type": "rect",
"style": [
"rect"
],
"from": {
"data": "matrix_data"
},
"encode": {
"update": {
"x": {
"scale": "matrix_x",
"field": "X"
},
"width": {
"scale": "matrix_x",
"band": 1,
"offset": -0.25
},
"y": {
"scale": "matrix_y",
"field": "Y"
},
"height": {
"scale": "matrix_y",
"band": 1,
"offset": -0.25
},
"fill": {
"scale": "color",
"field": {
"signal": "variable"
}
},
"fillOpacity": [
{
"test": "!(length(data(\"brush_store\"))) || (vlInterval(\"brush_store\", datum))",
"value": 1
},
{
"value": 0.25
}
],
"stroke": {
"value": "white"
},
"strokeWidth": {
"value": 0.25
}
},
"hover": {
"stroke": {
"value": "#000"
},
"strokeWidth": {
"value": 2
}
}
}
},
{
"name": "brush_brush",
"type": "rect",
"clip": true,
"encode": {
"enter": {
"fill": {
"value": "transparent"
},
"stroke": {
"value": "white"
}
},
"update": {
"x": [
{
"test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"matrix_layer\"",
"signal": "brush_x[0]"
},
{
"value": 0
}
],
"y": [
{
"test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"matrix_layer\"",
"signal": "brush_y[0]"
},
{
"value": 0
}
],
"x2": [
{
"test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"matrix_layer\"",
"signal": "brush_x[1]"
},
{
"value": 0
}
],
"y2": [
{
"test": "data(\"brush_store\").length && data(\"brush_store\")[0].unit === \"matrix_layer\"",
"signal": "brush_y[1]"
},
{
"value": 0
}
]
}
}
}
],
"axes": [
{
"scale": "matrix_x",
"orient": "bottom",
"labels": false,
"tickCount": 5,
"offset": 0,
"zindex": 1,
"encode": {
"domain": {
"update": {
"strokeWidth": {
"value": 0
}
}
},
"ticks": {
"update": {
"strokeWidth": {
"value": 0
}
}
}
}
},
{
"scale": "matrix_y",
"offset": 0,
"orient": "left",
"zindex": 1,
"labels": false,
"encode": {
"domain": {
"update": {
"strokeWidth": {
"value": 0
}
}
},
"ticks": {
"update": {
"strokeWidth": {
"value": 0
}
}
}
}
}
]
},
{
"type": "group",
"name": "map_group",
"style": "cell",
"title": {
"text": "map element",
"anchor": "start",
"orient": "top"
},
"encode": {
"update": {
"width": {
"signal": "map_width"
},
"height": {
"signal": "map_height"
},
"clip": {
"value": true
},
"fill": {
"value": "#3D3D3D"
}
}
},
"marks": [
{
"type": "shape",
"from": {
"data": "map_outline"
},
"encode": {
"enter": {
"stroke": {
"value": "#3D3D3D"
},
"strokeWidth": {
"value": 1
},
"fill": {
"value": "#030303"
}
}
},
"transform": [
{
"type": "geoshape",
"projection": "projection"
}
]
},
{
"name": "circles",
"type": "symbol",
"from": {
"data": "data_0"
},
"encode": {
"update": {
"fill": {
"scale": "color",
"field": {
"signal": "variable"
}
},
"size": {
"scale": "size",
"field": {
"signal": "variable"
}
},
"stroke": {
"value": "white"
},
"strokeWidth": {
"value": 0.2
},
"x": {
"field": "centroid[0]"
},
"y": {
"field": "centroid[1]"
},
"zindex": {
"value": 2
}
},
"hover": {
"strokeWidth": {
"value": 1.5
},
"stroke": {
"value": "black"
},
"zindex": {
"value": 3
}
}
}
}
]
}
],
"scales": [
{
"name": "size",
"domain": {
"fields": [
{
"data": "matrix_data",
"field": {
"signal": "variable"
}
}
],
"sort": true
},
"range": [
30,
160
]
},
{
"name": "color",
"type": "sequential",
"domain": {
"fields": [
{
"data": "matrix_data",
"field": {
"signal": "variable"
}
}
],
"sort": true
},
"range": [
"#3D3D3D",
"#F0F8FF",
"cornflowerblue",
"mediumseagreen",
"#FFEE00",
"darkorange",
"firebrick"
],
"nice": false,
"zero": false
},
{
"name": "matrix_x",
"type": "band",
"domain": {
"data": "matrix_data_static",
"field": "X",
"sort": true
},
"range": {
"step": {
"signal": "matrix_x_step"
}
},
"paddingInner": 0,
"paddingOuter": 0
},
{
"name": "matrix_y",
"type": "band",
"domain": {
"data": "matrix_data_static",
"field": "Y",
"sort": true
},
"range": {
"step": {
"signal": "matrix_y_step"
}
},
"paddingInner": 0,
"paddingOuter": 0
}
],
"legends": [
{
"fill": "color",
"encode": {
"title": {
"update": {
"fontSize": {
"value": 14
},
"limit": {
"value": 400
}
}
}
},
"title": {
"signal": "variable"
},
"type": "gradient"
}
],
"config": {
"axisY": {
"minExtent": 30
},
"style": {
"text": {
"baseline": "middle"
}
},
"legend": {
"offset": 30,
"orient": "bottom"
},
"title": {
"offset": 10,
"fontSize": 18
}
}
}