Skip to main content

Node attribute-based layout

Rather than positioning nodes with a force-based layout, let's position them based on the value of two of their attributes - their overall number of followers, and number of followers on #EuroVis2019.


{

We import data and construct the network as before


"data": [
{
"name": "data",
"url": "/data/eurovis-twitter/Eurovis2019Network.json"
}
],

"networks": [
{
"name": "network",
"nodes": "data.nodes",
"links": "data.links",
"directed": true,
"source_node": [ "id", "source" ],
"target_node": [ "id", "target" ],

"transform": [
{"type": "metric", "metric": "degree"},
{"type": "filterNodes", "expression": "datum.degree > 250 "}
]
}
],

construct 2 linear scales


"scales": [
{"name": "x", "type": "linear", "domain": [0, 42884], "range": [0, 1000]},
{"name": "y", "type": "linear", "domain": [0, 40], "range": [0, 1000]}
],

We use these scales to define a layout


"layouts": [
{
"name": "layout",
"pattern": "cartesian",
"network": "network",
"x": [{"field": "followers_count", "scale": "x"}],
"y": [{"field": "count_followers_in_query", "scale": "y"}]
}
],

We use the same visual encoding as previously


"vis": [
{
"entries": "network.links",
"layout": "layout",
"mark": {
"type": "linkpath",
"start": "source",
"end": "target"
"tooltip": {"field": "screen_name"}
}
},

{
"entries": "network.nodes",
"layout": "layout",
"mark": {
"type": "circle",
"area": 70,
"fill": "steelblue",
"stroke": "grey",
}
}
]


]
}