Assets/vega.dsm.matrix.json
{ "data": [ { "name": "nodes", "transform": [{"type": "formula", "as": "order", "expr": "datum.index"}], "values": [] }, { "name": "edges", "transform": [ { "type": "lookup", "from": "nodes", "key": "index", "fields": ["source"], "as": ["sourceNode"] }, { "type": "lookup", "from": "nodes", "key": "index", "fields": ["target"], "as": ["targetNode"] }, { "type": "formula", "as": "sourceCluster", "expr": "datum.sourceNode.group" }, { "type": "formula", "as": "targetCluster", "expr": "datum.targetNode.group" }, { "type": "formula", "as": "clusterKey", "expr": "datum.sourceCluster * groupBase + datum.targetCluster" }, { "type": "formula", "as": "clusterLabel", "expr": "toString(datum.sourceCluster) + '-' + toString(datum.targetCluster)" } ], "values": [] }, { "name": "children", "transform": [ { "type": "filter", "expr": "datum.sourceNode.index === rowClick.index || datum.targetNode.index === columnClick.index" }, { "type": "formula", "as": "targetNodeName", "expr": "datum.targetNode.name" }, { "type": "formula", "as": "sourceNodeName", "expr": "datum.sourceNode.name" } ], "source": "edges" }, { "name": "groupStats", "source": "nodes", "transform": [ { "type": "aggregate", "ops": ["max"], "fields": ["group"], "as": ["groupMax"] } ] }, { "name": "pairs", "source": "edges", "transform": [{"type": "aggregate", "groupby": ["clusterKey"]}] } ], "marks": [ { "from": {"data": "nodes"}, "type": "rect", "encode": { "update": { "fill": {"value": "#cccccc"}, "fillOpacity": {"value": 0.45}, "height": {"band": 1, "offset": -1, "scale": "position"}, "width": {"band": 1, "offset": -1, "scale": "position"}, "x": {"scale": "position", "field": "order"}, "y": {"scale": "position", "field": "order"} } }, "zindex": 0 }, { "from": {"data": "edges"}, "type": "rect", "encode": { "update": { "fill": [ { "test": "rowClick && rowClick.index != null && datum.sourceNode.index === rowClick.index", "value": "red" }, { "test": "columnClick && columnClick.index != null && datum.targetNode.index === columnClick.index", "value": "red" }, {"scale": "color", "field": "clusterKey"} ], "height": {"band": 1, "offset": -1, "scale": "position"}, "width": {"band": 1, "offset": -1, "scale": "position"}, "x": {"mult": {"signal": "cellSize"}, "field": "y"}, "y": {"mult": {"signal": "cellSize"}, "field": "x"} } }, "zindex": 10 }, { "from": {"data": "nodes"}, "type": "rect", "encode": { "update": { "fill": [ { "test": "rowClick && rowClick.index != null && datum.index === rowClick.index", "value": "lightsteelblue" } ], "fillOpacity": {"value": 0.3}, "height": {"band": 1, "scale": "position"}, "width": {"signal": "width"}, "x": {"value": 0}, "y": {"scale": "position", "field": "order"} } }, "name": "rowHighlight" }, { "from": {"data": "nodes"}, "type": "rect", "encode": { "update": { "fill": [ { "test": "rowClick && rowClick.index != null && indata('children', 'target', datum.index)", "value": "lightsteelblue" } ], "fillOpacity": {"value": 0.3}, "height": {"signal": "height"}, "width": {"band": 1, "scale": "position"}, "x": {"scale": "position", "field": "order"}, "y": {"value": 0} } }, "name": "colHighlight" }, { "from": {"data": "nodes"}, "type": "rect", "encode": { "update": { "fill": [ { "test": "columnClick && columnClick.index != null && datum.index === columnClick.index", "value": "lightsteelblue" } ], "fillOpacity": {"value": 0.3}, "height": {"signal": "width"}, "width": {"band": 1, "scale": "position"}, "x": {"scale": "position", "field": "order"}, "y": {"value": 0} } }, "name": "colHighlightOnColumnClick" }, { "from": {"data": "nodes"}, "type": "rect", "encode": { "update": { "fill": [ { "test": "columnClick && indata('children', 'source', datum.index)", "value": "lightsteelblue" } ], "fillOpacity": {"value": 0.3}, "height": {"band": 1, "scale": "position"}, "width": {"signal": "height"}, "x": {"value": 0}, "y": {"scale": "position", "field": "order"} } }, "name": "rowHighlightOnColumnClick" }, { "from": {"data": "nodes"}, "type": "text", "encode": { "update": { "align": {"value": "left"}, "angle": {"value": -90}, "baseline": {"value": "middle"}, "fill": [ { "test": "rowClick && indata('children', 'targetNodeName', datum.name)", "value": "red" }, {"value": "black"} ], "fontSize": {"value": 10}, "text": {"field": "name"}, "x": {"band": 0.5, "scale": "position", "field": "order"}, "y": {"offset": -2} } }, "name": "columns" }, { "from": {"data": "nodes"}, "type": "text", "encode": { "update": { "align": {"value": "right"}, "baseline": {"value": "middle"}, "fill": [ {"test": "datum === rowClick", "value": "steelblue"}, { "test": "columnClick && indata('children', 'sourceNodeName', datum.name)", "value": "red" }, {"value": "black"} ], "fontSize": {"value": 10}, "text": {"field": "name"}, "x": {"offset": -2}, "y": {"band": 0.5, "scale": "position", "field": "order"} } }, "name": "rows" } ], "scales": [ { "domain": {"data": "nodes", "field": "order", "sort": true}, "name": "position", "type": "band", "range": {"step": {"signal": "cellSize"}} }, { "name": "color", "type": "ordinal", "domain": {"data": "edges", "field": "clusterKey", "sort": true}, "range": { "scheme": {"signal": "colorSchemeName"}, "count": {"signal": "schemeCount"} } } ], "signals": [ { "name": "columnClick", "on": [ { "events": {"markname": "columns", "type": "mouseover"}, "update": "datum" }, {"events": "mouseout", "update": "{}"} ], "value": {} }, { "name": "rowClick", "on": [ { "events": {"markname": "rows", "type": "mouseover"}, "update": "datum" }, {"events": "mouseout", "update": "{}"} ], "value": {} }, {"name": "pairsCount", "update": "length(data('pairs'))"}, { "name": "colorSchemeName", "update": "pairsCount <= 10 ? 'tableau10' : (pairsCount <= 12 ? 'set3' : 'category20')" }, {"name": "schemeCount", "update": "min(pairsCount, 20)"}, {"name": "groupBase", "update": "data('groupStats')[0].groupMax + 1"}, {"name": "cellSize", "value": 10}, {"name": "count", "update": "length(data('nodes'))"}, {"name": "width", "update": "span(range('position'))"}, {"name": "height", "update": "width"} ], "legends": [ { "fill": "color", "title": "Cluster pairs (src→dst)", "encode": { "labels": { "update": { "text": { "signal": "floor(datum.value / groupBase) + '-' + (datum.value % groupBase)" } } } } } ], "$schema": "https://vega.github.io/schema/vega/v6.json", "description": "A re-orderable DSM matrix.", "height": 1000, "padding": 2, "width": 1000 } |