{ "$schema": "https://vega.github.io/schema/vega/v5.json", "padding": 10, "config": { "axis": { "tickColor": "#ccc" } }, "signals": [ { "name": "chartSize", "value": 120 }, { "name": "chartPad", "value": 20 }, { "name": "chartStep", "update": "chartSize + chartPad" }, { "name": "width", "update": "chartStep * 4" }, { "name": "height", "update": "chartStep * 4" }, { "name": "cell", "value": null, "on": [ { "events": "@cell:mousedown", "update": "group()" }, { "events": "@cell:mouseup", "update": "!span(brushX) && !span(brushY) ? null : cell" } ] }, { "name": "brushX", "value": 0, "on": [ { "events": "@cell:mousedown", "update": "[x(cell), x(cell)]" }, { "events": "[@cell:mousedown, window:mouseup] > window:mousemove", "update": "[brushX[0], clamp(x(cell), 0, chartSize)]" }, { "events": {"signal": "delta"}, "update": "clampRange([anchorX[0] + delta[0], anchorX[1] + delta[0]], 0, chartSize)" } ] }, { "name": "brushY", "value": 0, "on": [ { "events": "@cell:mousedown", "update": "[y(cell), y(cell)]" }, { "events": "[@cell:mousedown, window:mouseup] > window:mousemove", "update": "[brushY[0], clamp(y(cell), 0, chartSize)]" }, { "events": {"signal": "delta"}, "update": "clampRange([anchorY[0] + delta[1], anchorY[1] + delta[1]], 0, chartSize)" } ] }, { "name": "down", "value": [0, 0], "on": [{"events": "@brush:mousedown", "update": "[x(cell), y(cell)]"}] }, { "name": "anchorX", "value": null, "on": [{"events": "@brush:mousedown", "update": "slice(brushX)"}] }, { "name": "anchorY", "value": null, "on": [{"events": "@brush:mousedown", "update": "slice(brushY)"}] }, { "name": "delta", "value": [0, 0], "on": [ { "events": "[@brush:mousedown, window:mouseup] > window:mousemove", "update": "[x(cell) - down[0], y(cell) - down[1]]" } ] }, { "name": "rangeX", "value": [0, 0], "on": [ { "events": {"signal": "brushX"}, "update": "invert(cell.datum.x.data + 'X', brushX)" } ] }, { "name": "rangeY", "value": [0, 0], "on": [ { "events": {"signal": "brushY"}, "update": "invert(cell.datum.y.data + 'Y', brushY)" } ] }, { "name": "cursor", "value": "'default'", "on": [ { "events": "[@cell:mousedown, window:mouseup] > window:mousemove!", "update": "'nwse-resize'" }, { "events": "@brush:mousemove, [@brush:mousedown, window:mouseup] > window:mousemove!", "update": "'move'" }, { "events": "@brush:mouseout, window:mouseup", "update": "'default'" } ] } ], "data": [ { "name": "penguins", "url": "data/penguins.json", "transform": [ {"type": "filter", "expr": "datum['Beak Length (mm)'] != null"} ] }, { "name": "fields", "values": [ "Beak Length (mm)", "Beak Depth (mm)", "Flipper Length (mm)", "Body Mass (g)" ] }, { "name": "cross", "source": "fields", "transform": [ { "type": "cross", "as": ["x", "y"] }, { "type": "formula", "as": "xscale", "expr": "datum.x.data + 'X'" }, { "type": "formula", "as": "yscale", "expr": "datum.y.data + 'Y'" } ] } ], "scales": [ { "name": "groupx", "type": "band", "range": "width", "domain": {"data": "fields", "field": "data"} }, { "name": "groupy", "type": "band", "range": [{"signal": "height"}, 0], "domain": {"data": "fields", "field": "data"} }, { "name": "color", "type": "ordinal", "domain": {"data": "penguins", "field": "Species"}, "range": "category" }, { "name": "Beak Length (mm)X", "zero": false, "nice": true, "domain": {"data": "penguins", "field": "Beak Length (mm)"}, "range": [0, {"signal": "chartSize"}] }, { "name": "Beak Depth (mm)X", "zero": false, "nice": true, "domain": {"data": "penguins", "field": "Beak Depth (mm)"}, "range": [0, {"signal": "chartSize"}] }, { "name": "Flipper Length (mm)X", "zero": false, "nice": true, "domain": {"data": "penguins", "field": "Flipper Length (mm)"}, "range": [0, {"signal": "chartSize"}] }, { "name": "Body Mass (g)X", "zero": false, "nice": true, "domain": {"data": "penguins", "field": "Body Mass (g)"}, "range": [0, {"signal": "chartSize"}] }, { "name": "Beak Length (mm)Y", "zero": false, "nice": true, "domain": {"data": "penguins", "field": "Beak Length (mm)"}, "range": [{"signal": "chartSize"}, 0] }, { "name": "Beak Depth (mm)Y", "zero": false, "nice": true, "domain": {"data": "penguins", "field": "Beak Depth (mm)"}, "range": [{"signal": "chartSize"}, 0] }, { "name": "Flipper Length (mm)Y", "zero": false, "nice": true, "domain": {"data": "penguins", "field": "Flipper Length (mm)"}, "range": [{"signal": "chartSize"}, 0] }, { "name": "Body Mass (g)Y", "zero": false, "nice": true, "domain": {"data": "penguins", "field": "Body Mass (g)"}, "range": [{"signal": "chartSize"}, 0] } ], "axes": [ { "orient": "left", "scale": "Beak Length (mm)Y", "minExtent": 25, "title": "Beak Length (mm)", "tickCount": 5, "domain": false, "position": {"signal": "3 * chartStep"} }, { "orient": "left", "scale": "Beak Depth (mm)Y", "minExtent": 25, "title": "Beak Depth (mm)", "tickCount": 5, "domain": false, "position": {"signal": "2 * chartStep"} }, { "orient": "left", "scale": "Flipper Length (mm)Y", "minExtent": 25, "title": "Flipper Length (mm)", "tickCount": 5, "domain": false, "position": {"signal": "1 * chartStep"} }, { "orient": "left", "scale": "Body Mass (g)Y", "minExtent": 25, "title": "Body Mass (g)", "tickCount": 5, "domain": false }, { "orient": "bottom", "scale": "Beak Length (mm)X", "title": "Beak Length (mm)", "tickCount": 5, "domain": false, "offset": {"signal": "-chartPad"} }, { "orient": "bottom", "scale": "Beak Depth (mm)X", "title": "Beak Depth (mm)", "tickCount": 5, "domain": false, "offset": {"signal": "-chartPad"}, "position": {"signal": "1 * chartStep"} }, { "orient": "bottom", "scale": "Flipper Length (mm)X", "title": "Flipper Length (mm)", "tickCount": 5, "domain": false, "offset": {"signal": "-chartPad"}, "position": {"signal": "2 * chartStep"} }, { "orient": "bottom", "scale": "Body Mass (g)X", "title": "Body Mass (g)", "tickCount": 5, "domain": false, "offset": {"signal": "-chartPad"}, "position": {"signal": "3 * chartStep"} } ], "legends": [ { "fill": "color", "title": "Species", "offset": 0, "encode": { "symbols": { "update": { "fillOpacity": {"value": 0.5}, "stroke": {"value": "transparent"} } } } } ], "marks": [ { "type": "rect", "encode": { "enter": { "fill": {"value": "#eee"} }, "update": { "opacity": {"signal": "cell ? 1 : 0"}, "x": {"signal": "cell ? cell.x + brushX[0] : 0"}, "x2": {"signal": "cell ? cell.x + brushX[1] : 0"}, "y": {"signal": "cell ? cell.y + brushY[0] : 0"}, "y2": {"signal": "cell ? cell.y + brushY[1] : 0"} } } }, { "name": "cell", "type": "group", "from": {"data": "cross"}, "encode": { "enter": { "x": {"scale": "groupx", "field": "x.data"}, "y": {"scale": "groupy", "field": "y.data"}, "width": {"signal": "chartSize"}, "height": {"signal": "chartSize"}, "fill": {"value": "transparent"}, "stroke": {"value": "#ddd"} } }, "marks": [ { "type": "symbol", "from": {"data": "penguins"}, "interactive": false, "encode": { "enter": { "x": { "scale": {"parent": "xscale"}, "field": {"datum": {"parent": "x.data"}} }, "y": { "scale": {"parent": "yscale"}, "field": {"datum": {"parent": "y.data"}} }, "fillOpacity": {"value": 0.5}, "size": {"value": 36} }, "update": { "fill": [ { "test": "!cell || inrange(datum[cell.datum.x.data], rangeX) && inrange(datum[cell.datum.y.data], rangeY)", "scale": "color", "field": "Species" }, {"value": "#ddd"} ] } } } ] }, { "type": "rect", "name": "brush", "encode": { "enter": { "fill": {"value": "transparent"} }, "update": { "x": {"signal": "cell ? cell.x + brushX[0] : 0"}, "x2": {"signal": "cell ? cell.x + brushX[1] : 0"}, "y": {"signal": "cell ? cell.y + brushY[0] : 0"}, "y2": {"signal": "cell ? cell.y + brushY[1] : 0"} } } } ] }