Skip to main content

Representing time with node position

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.

As an alternative to positioning nodes based on their attributes, we could instead position them using a force-based layout, and represent the attributes using a glyph.


{

"data": [
{
"name": "data",

We import data for a different file...


"url": "/data/eurovis-twitter/Eurovis2019_rt_network.json",


}
],

"networks": [
{
"name": "network",
"nodes": "data.nodes",
"links": "data.links",
"directed": true,

...which has a different name for the node id column.


"source_node": [ "id_str", "source" ],
"target_node": [ "id_str", "target" ],



"transform": [
{"type": "metric", "metric": "degree"},

We apply a calculate transform to convert the timestamp of each tweet from a string to a Date() object.


{"type": "calculate", "for": "nodes", "as": "date", "calculate": "utcParse(datum.created_at, '%a %b %e %H:%M:%S %Z %Y')" }


]
}
],

We define a time scale (the domain is in unix time)


"scales": [
{
"name": "time",
"type": "time",
"range": [0, 500],
"domain": [1559176363000, 1560117923000 ]
}
],

We define a cartesian layout, which distributes nodes along the x-axis using the time scale.


"layouts": [
{
"name": "l",
"network": "network",
"pattern": "cartesian",
"x": [{"field": "date", "scale": "time"}],
"y": [{"value": 0}],
"transform": [
{"type": "set", "field": "width", "value": 20},
{"type": "set", "field": "height", "value": 20},

And apply a beeswarm transform to reposition nodes to avoid overlaps.

The gravityY is 0, as we aren't trying to control the y-coordinates.


{"type": "beeswarm", "gravityY": 0 }


]
},

],

We render nodes and links as for the force-directed example.


"vis": [
{
"entries": "network.links",
"layout": "l",
"mark": {
"type": "linkpath",
"start": "source",
"end": "target"
}
},
{
"entries": "network.nodes",
"layout": "l",
"mark": {
"type": "circle",
"area": 70,
"fill": "steelblue"
}
}
]


}