Last active
January 26, 2021 09:43
-
-
Save nyurik/2729e86307fbc600d15c736c37392514 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"$schema": "https://vega.github.io/schema/vega/v3.0.json", | |
"data": [ | |
{ | |
"name": "data", | |
"values": { | |
"aggregations": { | |
"pairs": { | |
"buckets": [ | |
{"key": "aa:cc", "doc_count": 10}, | |
{"key": "aa:bb", "doc_count": 12}, | |
{"key": "bb:aa", "doc_count": 8}, | |
{"key": "bb:bb", "doc_count": 12}, | |
{"key": "cc:aa", "doc_count": 9}, | |
{"key": "cc:cc", "doc_count": 10} | |
] | |
} | |
} | |
}, | |
"format": {"property": "aggregations.pairs.buckets"}, | |
"transform": [ | |
{"type": "formula", "expr": "slice(datum.key, 0, 2)", "as": "src"}, | |
{"type": "formula", "expr": "slice(datum.key, 3, 5)", "as": "dst"} | |
] | |
}, | |
{ | |
"name": "nodes", | |
"source": "data", | |
"transform": [ | |
{ | |
"type": "filter", | |
"expr": "!groupSelector || groupSelector.src == datum.src || groupSelector.dst == datum.dst" | |
}, | |
{"type": "fold", "fields": ["src", "dst"], "as": ["stack", "cc"]}, | |
{ | |
"type": "formula", | |
"expr": "if(datum.stack == 'src', datum.src+datum.dst, datum.dst+datum.src)", | |
"as": "sortField" | |
}, | |
{ | |
"type": "stack", | |
"groupby": ["stack"], | |
"sort": {"field": "sortField"}, | |
"field": "doc_count" | |
}, | |
{"type": "formula", "expr": "(datum.y0+datum.y1)/2", "as": "yc"} | |
] | |
}, | |
{ | |
"name": "groups", | |
"source": "nodes", | |
"transform": [ | |
{ | |
"type": "aggregate", | |
"groupby": ["stack", "cc"], | |
"fields": ["doc_count"], | |
"ops": ["sum"], | |
"as": ["total"] | |
}, | |
{"type": "stack", "groupby": ["stack"], "sort": {"field": "cc"}, "field": "total"}, | |
{"type": "formula", "expr": "scale('y', datum.y0)", "as": "scaledY0"}, | |
{"type": "formula", "expr": "scale('y', datum.y1)", "as": "scaledY1"}, | |
{"type": "formula", "expr": "datum.stack == 'src'", "as": "rightLabel"}, | |
{"type": "formula", "expr": "datum.total/domain('y')[1]", "as": "percentage"} | |
] | |
}, | |
{ | |
"name": "destinationNodes", | |
"source": "nodes", | |
"transform": [{"type": "filter", "expr": "datum.stack == 'dst'"}] | |
}, | |
{ | |
"name": "edges", | |
"source": "nodes", | |
"transform": [ | |
{"type": "filter", "expr": "datum.stack == 'src'"}, | |
{ | |
"type": "lookup", | |
"from": "destinationNodes", | |
"key": "key", | |
"fields": ["key"], | |
"as": ["target"] | |
}, | |
{ | |
"type": "linkpath", | |
"orient": "horizontal", | |
"shape": {"signal": "'diagonal'"}, | |
"sourceY": {"expr": "scale('y', datum.yc)"}, | |
"sourceX": {"expr": "scale('x', 'src') + bandwidth('x')"}, | |
"targetY": {"expr": "scale('y', datum.target.yc)"}, | |
"targetX": {"expr": "scale('x', 'dst')"} | |
}, | |
{ | |
"type": "formula", | |
"expr": "range('y')[0]-scale('y', datum.doc_count)", | |
"as": "strokeWidth" | |
}, | |
{"type": "formula", "expr": "datum.doc_count/domain('y')[1]", "as": "percentage"} | |
] | |
} | |
], | |
"scales": [ | |
{ | |
"name": "x", | |
"type": "band", | |
"range": "width", | |
"domain": ["src", "dst"], | |
"paddingOuter": 0.05, | |
"paddingInner": 0.95 | |
}, | |
{ | |
"name": "y", | |
"type": "linear", | |
"range": "height", | |
"domain": {"data": "nodes", "field": "y1"} | |
}, | |
{ | |
"name": "color", | |
"type": "ordinal", | |
"range": "category", | |
"domain": {"data": "data", "field": "src"} | |
} | |
], | |
"axes": [{"orient": "bottom", "scale": "x"}, {"orient": "left", "scale": "y"}], | |
"marks": [ | |
{ | |
"type": "path", | |
"name": "edgeMark", | |
"from": {"data": "edges"}, | |
"encode": { | |
"update": { | |
"stroke": [ | |
{ | |
"test": "groupSelector && groupSelector.stack=='src'", | |
"scale": "color", | |
"field": "dst" | |
}, | |
{"scale": "color", "field": "src"} | |
], | |
"strokeWidth": {"field": "strokeWidth"}, | |
"path": {"field": "path"}, | |
"strokeOpacity": { | |
"signal": "if(!groupSelector && (groupHover.src == datum.src || groupHover.dst == datum.dst), 0.6, 0.2)" | |
}, | |
"tooltip": { | |
"signal": "datum.src + ' → ' + datum.dst + ' ' + format(datum.doc_count, ',.0f') + ' (' + format(datum.percentage, '.1%') + ')'" | |
} | |
}, | |
"hover": {"strokeOpacity": {"value": 1}} | |
} | |
}, | |
{ | |
"type": "rect", | |
"name": "nodeMark", | |
"from": {"data": "groups"}, | |
"encode": { | |
"enter": {"fill": {"scale": "color", "field": "cc"}, "width": {"scale": "x", "band": 1}}, | |
"update": { | |
"x": {"scale": "x", "field": "stack"}, | |
"y": {"field": "scaledY0"}, | |
"y2": {"field": "scaledY1"}, | |
"fillOpacity": {"signal": "if(groupSelector, 1, 0.6)"}, | |
"tooltip": { | |
"signal": "datum.cc + ' ' + format(datum.total, ',.0f') + ' (' + format(datum.percentage, '.1%') + ')'" | |
} | |
}, | |
"hover": {"fillOpacity": {"value": 1}} | |
} | |
}, | |
{ | |
"type": "text", | |
"from": {"data": "groups"}, | |
"interactive": false, | |
"encode": { | |
"update": { | |
"x": { | |
"signal": "scale('x', datum.stack) + if(datum.rightLabel, bandwidth('x') + 5, -5)" | |
}, | |
"yc": {"signal": "(datum.scaledY0 + datum.scaledY1)/2"}, | |
"align": {"signal": "if(datum.rightLabel, 'left', 'right')"}, | |
"baseline": {"value": "middle"}, | |
"fontWeight": {"value": "bold"}, | |
"text": {"signal": "if(abs(datum.scaledY0-datum.scaledY1) > 13, datum.cc, '')"} | |
} | |
} | |
}, | |
{ | |
"type": "group", | |
"data": [ | |
{ | |
"name": "dataForShowAll", | |
"values": [{}], | |
"transform": [{"type": "filter", "expr": "groupSelector"}] | |
} | |
], | |
"encode": { | |
"enter": { | |
"xc": {"signal": "width/2"}, | |
"y": {"value": 30}, | |
"width": {"value": 80}, | |
"height": {"value": 30} | |
} | |
}, | |
"marks": [ | |
{ | |
"type": "group", | |
"name": "groupReset", | |
"from": {"data": "dataForShowAll"}, | |
"encode": { | |
"enter": { | |
"opacity": {"value": 1}, | |
"cornerRadius": {"value": 6}, | |
"fill": {"value": "#f5f5f5"}, | |
"stroke": {"value": "#c1c1c1"}, | |
"strokeWidth": {"value": 2}, | |
"height": {"signal": "item.mark.group.height"}, | |
"width": {"signal": "item.mark.group.width"} | |
}, | |
"hover": {"opacity": {"value": 0.7}} | |
}, | |
"marks": [ | |
{ | |
"type": "text", | |
"interactive": false, | |
"encode": { | |
"enter": { | |
"xc": {"signal": "item.mark.group.width/2"}, | |
"yc": {"signal": "item.mark.group.height/2 + 2"}, | |
"align": {"value": "center"}, | |
"baseline": {"value": "middle"}, | |
"fontWeight": {"value": "bold"}, | |
"text": {"value": "Show All"} | |
} | |
} | |
} | |
] | |
} | |
] | |
} | |
], | |
"signals": [ | |
{ | |
"name": "groupHover", | |
"value": {}, | |
"on": [ | |
{ | |
"events": "@nodeMark:mouseover", | |
"update": "{src:datum.stack=='src' && datum.cc, dst:datum.stack=='dst' && datum.cc}" | |
}, | |
{"events": "mouseout", "update": "{}"} | |
] | |
}, | |
{ | |
"name": "groupSelector", | |
"value": false, | |
"on": [ | |
{ | |
"events": "@nodeMark:click!", | |
"update": "{stack:datum.stack, src:datum.stack=='src' && datum.cc, dst:datum.stack=='dst' && datum.cc}" | |
}, | |
{"events": [{"type": "click", "markname": "groupReset"}], "update": "false"} | |
] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment