{
"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"autosize": "pad",
"padding": 5,
"data": [
{
"name": "brush_store"
},
{
"name": "matrix_data",
"url": "https://data.hkvservices.nl/dataservices/data.asmx/read?database=PR2877_20&key=som",
"format": {
"type": "csv",
"parse": {
"XY": "number",
"X": "number",
"Y": "number",
"U-matrix": "number",
"aanlegmoment": "number",
"datum": "number",
"helling buitentalud": "number",
"helling strand": "number",
"korreldiameter": "number",
"m3 aanzanding in duingebied": "number",
"oriëntatie": "number",
"strandbreedte": "number",
"number of transects": "number"
}
},
"transform": [
{
"type": "filter",
"expr": "datum['U-matrix'] <= filter_u_matrix"
}
]
},
{
"name": "map_data",
"url": "https://data.hkvservices.nl/dataservices/data.asmx/read?database=PR2877_20&key=transects",
"format": {
"type": "json",
"property": "features"
}
},
{"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": "descending"
}
}
]
},
{
"name": "data_1",
"source": "matrix_data",
"transform": [
{
"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": "descending"
}
}
]
},
{
"name": "map_outline",
"url": "https://raw.githubusercontent.com/mattijn/datasets/master/provinces_NL.json",
"format": {"type": "json", "property": "features"}
}
],
"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": "aanlegmoment",
"bind": {
"input": "select",
"options": [
"U-matrix",
"aanlegmoment",
"datum",
"helling buitentalud",
"helling strand",
"korreldiameter",
"m3 aanzanding in duingebied",
"oriëntatie",
"strandbreedte",
"number of transects"
]
}
},
{
"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": 280000,
"rotate": [
0,
0,
0
],
"center": [
4.645169,
52.748243
],
"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 Hondsbossche Dunes using variables representing the geographical characteristics of their growth",
"orient": "top",
"anchor": "start"
},
"marks": [
{
"type": "group",
"name": "matrix_group",
"style": "cell",
"title": {
"text": "matrix element: create box to filter locations",
"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": "white"
}
}
},
"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_static",
"type": "symbol",
"from": {
"data": "data_1"
},
"encode": {
"update": {
"fill": {
"value": "gray"
},
"size": {
"value": 40
},
"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
}
}
}
},
{
"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": [
50,
1500
]
},
{
"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
}
}
}