Usage

This template creates an interactive world choropleth map, indicating some statistical value with different colors for different countries. A tooltip with country data is shown when the mouse is over a country.

Example

{{Choropleth world map

| title=Net official development assistance and official aid (ODA) received in 2019
| table=OdaReceived2019.tab
| column=oda_received
| columnName= ODA received
| year=2019
}}

<graph mode="interactive"> {

 //TODO remove the year variables, which are a hangover from the source version which generated a slider for seeing multiple year values
 "width": 600,
 "height": 250,
 "signals": [
   { "name": "initYear", "init": 2019 },
   { "name": "gapHeight", "init": 0 },
   {
     // Hide overview if total height is too small
     "name": "showOverview",
     "init": {"expr": "true || height < (gapHeight + 0)" }
   },
   { "name": "overviewHeight", "init": {"expr": "showOverview ? 0 : 0" } },
   { "name": "detailHeight", "init": {"expr": "height - (showOverview ? overviewHeight + gapHeight : 0)" } },
   { "name": "overviewYPos", "init": {"expr": "height - overviewHeight" } },
   { "name": "mapXC", "init": {"expr": "width/2"} },
   { "name": "mapYC", "init": {"expr": "overviewYPos/2"} },
   {
     "name": "brush_start",
     "streams": [{
       "type": "@overview:mousedown, @overview:touchstart", 
       "expr": "clamp(eventX(), 0, width)",
       "scale": {"name": "xOverview", "invert": true}
     }]
   },
   {
     "name": "brush_end",
     "streams": [{
       "type": "@overview:mousedown, [@overview:mousedown, window:mouseup] > window:mousemove, @overview:mouseup, @overview:touchstart, [@overview:touchstart, window:touchend] > window:touchmove, @overview:touchend",
       "expr": "clamp(eventX(), 0, width)",
       "scale": {"name": "xOverview", "invert": true}
     }]
   },
   {
     "name": "fromYear", 
     "init": {"expr": "initYear"},
     "expr": "year(min(brush_start, brush_end))"
   },
   {
     "name": "toYear",
     "init": {"expr": "initYear"},
     "expr": "year(max(brush_start, brush_end))"
   },
   {
     "name": "isRange", 
     "init": {"expr": "false"},
     "expr": "fromYear !== toYear"
   },
   {
     "name": "tooltip",
     "init": {"expr": "{x: 0, y: 0, datum: false }"}, 
     "streams": [
       {"type": "@map:mouseout, @map:touchstart", "expr": "{x: 0, y: 0, datum: false }" },
       {"type": "@map:mouseover, @map:touchstart", "expr": "{x: eventX(), y: eventY(), datum: eventItem().datum.lookup}" }
     ]
   }
 ],
 "data": [{
   "name": "data",
   "url": "tabular:///Sandbox/mrmedley/OdaReceived2019.tab",
   "format": {"type": "json", "property": "data"},
   "transform": [
     { "type": "formula", "field": "value", "expr": "datum.oda_received" }
   ]
 },{
   "name": "totals",
   "source": "data",
   "transform": [
     {
     	"type": "aggregate",
     	"groupby": ["year"],
       "summarize": [{"field": "value", "ops": ["sum"], "as": ["total"]}]
     },
     { "type": "formula", "field": "date", "expr": "datetime(datum.year, 0, 1)" }
   ]
 },{
   // Select just the source data for the starting year
   "name": "firstYearData",
   "source": "data",
   "transform": [{"type": "filter", "test": "datum.year === fromYear"}]
 },{
   // Select just the source data for the ending year
   "name": "yearData",
   "source": "data",
   "transform": [{
     "type": "filter", "test": "datum.year === toYear"
   },{
     "type": "sort", "by": ["-value"]
   },{
     "type": "rank", "field": "country"
   },{
     "type": "lookup",
     "on": "firstYearData",
     "onKey": "country",
     "keys": ["country"],
     "as": ["firstYear"],
     "default": null
   },{
     "type": "formula", "field": "calc", "expr": "if(isRange, (datum.value - datum.firstYear.value)/datum.firstYear.value, datum.value)"
   }]
 },{
   "name": "mapData",
   "url": "map:///Naturalearthdata.com/admin-0-countries-no-antarctica.map",
   "format": {"type": "json", "property": "data.features"},
   "transform": [{
     "type": "geopath",
     "projection": "equirectangular",
     "scale": 108,
     "translate": [{"expr": "mapXC"}, {"expr": "mapYC"}]
   },{
   	"type": "formula",
   	"field": "my_id",
   	"expr": "datum.properties.iso_a3 || datum.properties.adm0_a3"
   },{
     "type": "lookup",
     "on": "yearData",
     "onKey": "country",
     "keys": ["my_id"],
     "as": ["lookup"],
     "default": 100
   }]
 },{
   "name": "dummyValue",
   "values": [{}]
 }],
 "scales": [{
   "name": "color",
   "type": "sqrt",
   "domain": {"data": "yearData", "field": "calc"},
   "range": ["#eee", "#c00000"],
   "zero": false,
   "clamp": true
 },{
   "name": "diffColor",
   "type": "linear",
   "domain": [-1, -0.8, -0.6, -0.3, -0.1, 0, 0.1, 0.3, 0.6, 0.8, 1],
   "range": ["#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf", "#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026"],
   "zero": false,
   "clamp": true
 },{
     "name": "xOverview",
     "type": "time",
     "range": "width",
     "domain": {"data": "totals", "field": "date"}
 },{
     "name": "yOverview",
     "type": "linear",
     "rangeMin": {"signal": "overviewHeight"},
     "nice": true,
     "zero": false,
     "domain": {"data": "totals", "field": "total"}
 }],
 "marks": [{
   "type": "group",
   "name": "detail",
   "properties": {
     "enter": {
       "height": {"signal": "detailHeight"},
       "width": {"signal": "width"}
   } },
   "marks": [{
     "name": "map",
     "type": "path",
     "from": {"data": "mapData"},
     "properties": {
       "enter": {
         "stroke": {"value": "#fff"},
         "path": {"field": "layout_path"}
       },
       "update": {
         "fill": [
           {"test": "isRange", "field": "lookup.calc", "scale": "diffColor"},
           {"field": "lookup.calc", "scale": "color"}
         ],
         "stroke": {"value": "#fff"}
       },
       "hover": {"fill": {"value": "#989898"}, "stroke": {"value": "#000"} }
     }
   }]
 },

{

   "name": "tooltip",
     "type": "group",
     "from": {
       "data": "dummyValue",
       "transform": [
         {"type": "filter", "test": "tooltip.datum && tooltip.datum.calc"},
         {"type": "formula", "field": "offsetX", "expr": "5"},
         {"type": "formula", "field": "offsetY", "expr": "30"},
         {"type": "formula", "field": "tipWidth", "expr": "200"},
         {"type": "formula", "field": "tipHeight", "expr": "51"},
         {"type": "formula", "field": "alignLeft", "expr": "tooltip.x > width - datum.offsetX - datum.tipWidth"},
         {"type": "formula", "field": "alignTop", "expr": "tooltip.y > height - datum.offsetY - datum.tipHeight"},
         {"type": "formula", "field": "x", "expr": "max(0, tooltip.x + (datum.alignLeft ? -datum.offsetX-datum.tipWidth : datum.offsetX ))"},
         {"type": "formula", "field": "y", "expr": "tooltip.y + (datum.alignTop ? -1 : 1) * datum.offsetY"},
         {"type": "formula", "field": "lookupCountry", "expr": "tooltip.datum.country"},

{ "type": "lookup", "on": "mapData", "onKey": "my_id", "keys": ["lookupCountry"], "as": ["mapDataVal"], "default": null },

         {"type": "formula", "field": "name", "expr": "datum.mapDataVal ? datum.mapDataVal.properties.name : '?xyz?'"},

{ "type": "lookup", "on": "yearData", "onKey": "country", "keys": ["lookupCountry"], "as": ["yearDataVal"], "default": null },

         {"type": "formula", "field": "rank", "expr": "datum.yearDataVal ? datum.yearDataVal.rank : 1000"}
     ]},
     "properties": {
       "update": {
         "x": {"field": "x" }, "y": {"field": "y" },
         "width": {"field": "tipWidth" },
         "height": {"field": "tipHeight" },
         "fill": {"value": "#fff"},
         "fillOpacity": {"value": 0.85},
         "stroke": {"value": "#aaa"},
         "strokeWidth": {"value": 0.5}
     } },
     "marks": [
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 14},
             "text": {"template": "{{parent.name}}"},
             "fill": {"value": "black"},
             "fontWeight": {"value": "bold"}
       } } },
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 29},
             "text": [
               {"test": "isRange", "template": "Growth:\t{{tooltip.datum.calc|number:'.1%'}}"},
               {"template": "ODA received:\t{{tooltip.datum.calc|number:',.0f'}}"}
             ],
             "fill": {"value": "black"}
       } } },
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 44},
             "text": [
               {"test": "isRange", "template": ""},
               {"template": "Global position:\t#{{parent.rank|number:'.0f'}}"}
             ],
             "fill": {"value": "black"}
       } } },
   ]}
 ]

} </graph> See or edit source data.

{{Choropleth world map

| title=CO2 Per Capita
| table=CO2PerCapita.tab
| column=tonnes
| columnName=tonnes per Capita
| year=2017
}}

<graph mode="interactive"> {

 //TODO remove the year variables, which are a hangover from the source version which generated a slider for seeing multiple year values
 "width": 600,
 "height": 250,
 "signals": [
   { "name": "initYear", "init": 2017 },
   { "name": "gapHeight", "init": 0 },
   {
     // Hide overview if total height is too small
     "name": "showOverview",
     "init": {"expr": "true || height < (gapHeight + 0)" }
   },
   { "name": "overviewHeight", "init": {"expr": "showOverview ? 0 : 0" } },
   { "name": "detailHeight", "init": {"expr": "height - (showOverview ? overviewHeight + gapHeight : 0)" } },
   { "name": "overviewYPos", "init": {"expr": "height - overviewHeight" } },
   { "name": "mapXC", "init": {"expr": "width/2"} },
   { "name": "mapYC", "init": {"expr": "overviewYPos/2"} },
   {
     "name": "brush_start",
     "streams": [{
       "type": "@overview:mousedown, @overview:touchstart", 
       "expr": "clamp(eventX(), 0, width)",
       "scale": {"name": "xOverview", "invert": true}
     }]
   },
   {
     "name": "brush_end",
     "streams": [{
       "type": "@overview:mousedown, [@overview:mousedown, window:mouseup] > window:mousemove, @overview:mouseup, @overview:touchstart, [@overview:touchstart, window:touchend] > window:touchmove, @overview:touchend",
       "expr": "clamp(eventX(), 0, width)",
       "scale": {"name": "xOverview", "invert": true}
     }]
   },
   {
     "name": "fromYear", 
     "init": {"expr": "initYear"},
     "expr": "year(min(brush_start, brush_end))"
   },
   {
     "name": "toYear",
     "init": {"expr": "initYear"},
     "expr": "year(max(brush_start, brush_end))"
   },
   {
     "name": "isRange", 
     "init": {"expr": "false"},
     "expr": "fromYear !== toYear"
   },
   {
     "name": "tooltip",
     "init": {"expr": "{x: 0, y: 0, datum: false }"}, 
     "streams": [
       {"type": "@map:mouseout, @map:touchstart", "expr": "{x: 0, y: 0, datum: false }" },
       {"type": "@map:mouseover, @map:touchstart", "expr": "{x: eventX(), y: eventY(), datum: eventItem().datum.lookup}" }
     ]
   }
 ],
 "data": [{
   "name": "data",
   "url": "tabular:///CO2PerCapita.tab",
   "format": {"type": "json", "property": "data"},
   "transform": [
     { "type": "formula", "field": "value", "expr": "datum.tonnes" }
   ]
 },{
   "name": "totals",
   "source": "data",
   "transform": [
     {
     	"type": "aggregate",
     	"groupby": ["year"],
       "summarize": [{"field": "value", "ops": ["sum"], "as": ["total"]}]
     },
     { "type": "formula", "field": "date", "expr": "datetime(datum.year, 0, 1)" }
   ]
 },{
   // Select just the source data for the starting year
   "name": "firstYearData",
   "source": "data",
   "transform": [{"type": "filter", "test": "datum.year === fromYear"}]
 },{
   // Select just the source data for the ending year
   "name": "yearData",
   "source": "data",
   "transform": [{
     "type": "filter", "test": "datum.year === toYear"
   },{
     "type": "sort", "by": ["-value"]
   },{
     "type": "rank", "field": "country"
   },{
     "type": "lookup",
     "on": "firstYearData",
     "onKey": "country",
     "keys": ["country"],
     "as": ["firstYear"],
     "default": null
   },{
     "type": "formula", "field": "calc", "expr": "if(isRange, (datum.value - datum.firstYear.value)/datum.firstYear.value, datum.value)"
   }]
 },{
   "name": "mapData",
   "url": "map:///Naturalearthdata.com/admin-0-countries-no-antarctica.map",
   "format": {"type": "json", "property": "data.features"},
   "transform": [{
     "type": "geopath",
     "projection": "equirectangular",
     "scale": 108,
     "translate": [{"expr": "mapXC"}, {"expr": "mapYC"}]
   },{
   	"type": "formula",
   	"field": "my_id",
   	"expr": "datum.properties.iso_a3 || datum.properties.adm0_a3"
   },{
     "type": "lookup",
     "on": "yearData",
     "onKey": "country",
     "keys": ["my_id"],
     "as": ["lookup"],
     "default": 100
   }]
 },{
   "name": "dummyValue",
   "values": [{}]
 }],
 "scales": [{
   "name": "color",
   "type": "sqrt",
   "domain": {"data": "yearData", "field": "calc"},
   "range": ["#eee", "#c00000"],
   "zero": false,
   "clamp": true
 },{
   "name": "diffColor",
   "type": "linear",
   "domain": [-1, -0.8, -0.6, -0.3, -0.1, 0, 0.1, 0.3, 0.6, 0.8, 1],
   "range": ["#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf", "#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026"],
   "zero": false,
   "clamp": true
 },{
     "name": "xOverview",
     "type": "time",
     "range": "width",
     "domain": {"data": "totals", "field": "date"}
 },{
     "name": "yOverview",
     "type": "linear",
     "rangeMin": {"signal": "overviewHeight"},
     "nice": true,
     "zero": false,
     "domain": {"data": "totals", "field": "total"}
 }],
 "marks": [{
   "type": "group",
   "name": "detail",
   "properties": {
     "enter": {
       "height": {"signal": "detailHeight"},
       "width": {"signal": "width"}
   } },
   "marks": [{
     "name": "map",
     "type": "path",
     "from": {"data": "mapData"},
     "properties": {
       "enter": {
         "stroke": {"value": "#fff"},
         "path": {"field": "layout_path"}
       },
       "update": {
         "fill": [
           {"test": "isRange", "field": "lookup.calc", "scale": "diffColor"},
           {"field": "lookup.calc", "scale": "color"}
         ],
         "stroke": {"value": "#fff"}
       },
       "hover": {"fill": {"value": "#989898"}, "stroke": {"value": "#000"} }
     }
   }]
 },

{

   "name": "tooltip",
     "type": "group",
     "from": {
       "data": "dummyValue",
       "transform": [
         {"type": "filter", "test": "tooltip.datum && tooltip.datum.calc"},
         {"type": "formula", "field": "offsetX", "expr": "5"},
         {"type": "formula", "field": "offsetY", "expr": "30"},
         {"type": "formula", "field": "tipWidth", "expr": "200"},
         {"type": "formula", "field": "tipHeight", "expr": "51"},
         {"type": "formula", "field": "alignLeft", "expr": "tooltip.x > width - datum.offsetX - datum.tipWidth"},
         {"type": "formula", "field": "alignTop", "expr": "tooltip.y > height - datum.offsetY - datum.tipHeight"},
         {"type": "formula", "field": "x", "expr": "max(0, tooltip.x + (datum.alignLeft ? -datum.offsetX-datum.tipWidth : datum.offsetX ))"},
         {"type": "formula", "field": "y", "expr": "tooltip.y + (datum.alignTop ? -1 : 1) * datum.offsetY"},
         {"type": "formula", "field": "lookupCountry", "expr": "tooltip.datum.country"},

{ "type": "lookup", "on": "mapData", "onKey": "my_id", "keys": ["lookupCountry"], "as": ["mapDataVal"], "default": null },

         {"type": "formula", "field": "name", "expr": "datum.mapDataVal ? datum.mapDataVal.properties.name : '?xyz?'"},

{ "type": "lookup", "on": "yearData", "onKey": "country", "keys": ["lookupCountry"], "as": ["yearDataVal"], "default": null },

         {"type": "formula", "field": "rank", "expr": "datum.yearDataVal ? datum.yearDataVal.rank : 1000"}
     ]},
     "properties": {
       "update": {
         "x": {"field": "x" }, "y": {"field": "y" },
         "width": {"field": "tipWidth" },
         "height": {"field": "tipHeight" },
         "fill": {"value": "#fff"},
         "fillOpacity": {"value": 0.85},
         "stroke": {"value": "#aaa"},
         "strokeWidth": {"value": 0.5}
     } },
     "marks": [
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 14},
             "text": {"template": "{{parent.name}}"},
             "fill": {"value": "black"},
             "fontWeight": {"value": "bold"}
       } } },
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 29},
             "text": [
               {"test": "isRange", "template": "Growth:\t{{tooltip.datum.calc|number:'.1%'}}"},
               {"template": "tonnes per Capita:\t{{tooltip.datum.calc|number:',.0f'}}"}
             ],
             "fill": {"value": "black"}
       } } },
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 44},
             "text": [
               {"test": "isRange", "template": ""},
               {"template": "Global position:\t#{{parent.rank|number:'.0f'}}"}
             ],
             "fill": {"value": "black"}
       } } },
   ]}
 ]

} </graph> See or edit source data.

{{Choropleth world map

| title=Share of the population infected with HIV
| table=HIV_rates.tab
| column=HIV_rate
| columnName=Percent of people with HIV
| year=2017
}}

<graph mode="interactive"> {

 //TODO remove the year variables, which are a hangover from the source version which generated a slider for seeing multiple year values
 "width": 600,
 "height": 250,
 "signals": [
   { "name": "initYear", "init": 2017 },
   { "name": "gapHeight", "init": 0 },
   {
     // Hide overview if total height is too small
     "name": "showOverview",
     "init": {"expr": "true || height < (gapHeight + 0)" }
   },
   { "name": "overviewHeight", "init": {"expr": "showOverview ? 0 : 0" } },
   { "name": "detailHeight", "init": {"expr": "height - (showOverview ? overviewHeight + gapHeight : 0)" } },
   { "name": "overviewYPos", "init": {"expr": "height - overviewHeight" } },
   { "name": "mapXC", "init": {"expr": "width/2"} },
   { "name": "mapYC", "init": {"expr": "overviewYPos/2"} },
   {
     "name": "brush_start",
     "streams": [{
       "type": "@overview:mousedown, @overview:touchstart", 
       "expr": "clamp(eventX(), 0, width)",
       "scale": {"name": "xOverview", "invert": true}
     }]
   },
   {
     "name": "brush_end",
     "streams": [{
       "type": "@overview:mousedown, [@overview:mousedown, window:mouseup] > window:mousemove, @overview:mouseup, @overview:touchstart, [@overview:touchstart, window:touchend] > window:touchmove, @overview:touchend",
       "expr": "clamp(eventX(), 0, width)",
       "scale": {"name": "xOverview", "invert": true}
     }]
   },
   {
     "name": "fromYear", 
     "init": {"expr": "initYear"},
     "expr": "year(min(brush_start, brush_end))"
   },
   {
     "name": "toYear",
     "init": {"expr": "initYear"},
     "expr": "year(max(brush_start, brush_end))"
   },
   {
     "name": "isRange", 
     "init": {"expr": "false"},
     "expr": "fromYear !== toYear"
   },
   {
     "name": "tooltip",
     "init": {"expr": "{x: 0, y: 0, datum: false }"}, 
     "streams": [
       {"type": "@map:mouseout, @map:touchstart", "expr": "{x: 0, y: 0, datum: false }" },
       {"type": "@map:mouseover, @map:touchstart", "expr": "{x: eventX(), y: eventY(), datum: eventItem().datum.lookup}" }
     ]
   }
 ],
 "data": [{
   "name": "data",
   "url": "tabular:///HIV_rates.tab",
   "format": {"type": "json", "property": "data"},
   "transform": [
     { "type": "formula", "field": "value", "expr": "datum.HIV_rate" }
   ]
 },{
   "name": "totals",
   "source": "data",
   "transform": [
     {
     	"type": "aggregate",
     	"groupby": ["year"],
       "summarize": [{"field": "value", "ops": ["sum"], "as": ["total"]}]
     },
     { "type": "formula", "field": "date", "expr": "datetime(datum.year, 0, 1)" }
   ]
 },{
   // Select just the source data for the starting year
   "name": "firstYearData",
   "source": "data",
   "transform": [{"type": "filter", "test": "datum.year === fromYear"}]
 },{
   // Select just the source data for the ending year
   "name": "yearData",
   "source": "data",
   "transform": [{
     "type": "filter", "test": "datum.year === toYear"
   },{
     "type": "sort", "by": ["-value"]
   },{
     "type": "rank", "field": "country"
   },{
     "type": "lookup",
     "on": "firstYearData",
     "onKey": "country",
     "keys": ["country"],
     "as": ["firstYear"],
     "default": null
   },{
     "type": "formula", "field": "calc", "expr": "if(isRange, (datum.value - datum.firstYear.value)/datum.firstYear.value, datum.value)"
   }]
 },{
   "name": "mapData",
   "url": "map:///Naturalearthdata.com/admin-0-countries-no-antarctica.map",
   "format": {"type": "json", "property": "data.features"},
   "transform": [{
     "type": "geopath",
     "projection": "equirectangular",
     "scale": 108,
     "translate": [{"expr": "mapXC"}, {"expr": "mapYC"}]
   },{
   	"type": "formula",
   	"field": "my_id",
   	"expr": "datum.properties.iso_a3 || datum.properties.adm0_a3"
   },{
     "type": "lookup",
     "on": "yearData",
     "onKey": "country",
     "keys": ["my_id"],
     "as": ["lookup"],
     "default": 100
   }]
 },{
   "name": "dummyValue",
   "values": [{}]
 }],
 "scales": [{
   "name": "color",
   "type": "sqrt",
   "domain": {"data": "yearData", "field": "calc"},
   "range": ["#eee", "#c00000"],
   "zero": false,
   "clamp": true
 },{
   "name": "diffColor",
   "type": "linear",
   "domain": [-1, -0.8, -0.6, -0.3, -0.1, 0, 0.1, 0.3, 0.6, 0.8, 1],
   "range": ["#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf", "#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026"],
   "zero": false,
   "clamp": true
 },{
     "name": "xOverview",
     "type": "time",
     "range": "width",
     "domain": {"data": "totals", "field": "date"}
 },{
     "name": "yOverview",
     "type": "linear",
     "rangeMin": {"signal": "overviewHeight"},
     "nice": true,
     "zero": false,
     "domain": {"data": "totals", "field": "total"}
 }],
 "marks": [{
   "type": "group",
   "name": "detail",
   "properties": {
     "enter": {
       "height": {"signal": "detailHeight"},
       "width": {"signal": "width"}
   } },
   "marks": [{
     "name": "map",
     "type": "path",
     "from": {"data": "mapData"},
     "properties": {
       "enter": {
         "stroke": {"value": "#fff"},
         "path": {"field": "layout_path"}
       },
       "update": {
         "fill": [
           {"test": "isRange", "field": "lookup.calc", "scale": "diffColor"},
           {"field": "lookup.calc", "scale": "color"}
         ],
         "stroke": {"value": "#fff"}
       },
       "hover": {"fill": {"value": "#989898"}, "stroke": {"value": "#000"} }
     }
   }]
 },

{

   "name": "tooltip",
     "type": "group",
     "from": {
       "data": "dummyValue",
       "transform": [
         {"type": "filter", "test": "tooltip.datum && tooltip.datum.calc"},
         {"type": "formula", "field": "offsetX", "expr": "5"},
         {"type": "formula", "field": "offsetY", "expr": "30"},
         {"type": "formula", "field": "tipWidth", "expr": "200"},
         {"type": "formula", "field": "tipHeight", "expr": "51"},
         {"type": "formula", "field": "alignLeft", "expr": "tooltip.x > width - datum.offsetX - datum.tipWidth"},
         {"type": "formula", "field": "alignTop", "expr": "tooltip.y > height - datum.offsetY - datum.tipHeight"},
         {"type": "formula", "field": "x", "expr": "max(0, tooltip.x + (datum.alignLeft ? -datum.offsetX-datum.tipWidth : datum.offsetX ))"},
         {"type": "formula", "field": "y", "expr": "tooltip.y + (datum.alignTop ? -1 : 1) * datum.offsetY"},
         {"type": "formula", "field": "lookupCountry", "expr": "tooltip.datum.country"},

{ "type": "lookup", "on": "mapData", "onKey": "my_id", "keys": ["lookupCountry"], "as": ["mapDataVal"], "default": null },

         {"type": "formula", "field": "name", "expr": "datum.mapDataVal ? datum.mapDataVal.properties.name : '?xyz?'"},

{ "type": "lookup", "on": "yearData", "onKey": "country", "keys": ["lookupCountry"], "as": ["yearDataVal"], "default": null },

         {"type": "formula", "field": "rank", "expr": "datum.yearDataVal ? datum.yearDataVal.rank : 1000"}
     ]},
     "properties": {
       "update": {
         "x": {"field": "x" }, "y": {"field": "y" },
         "width": {"field": "tipWidth" },
         "height": {"field": "tipHeight" },
         "fill": {"value": "#fff"},
         "fillOpacity": {"value": 0.85},
         "stroke": {"value": "#aaa"},
         "strokeWidth": {"value": 0.5}
     } },
     "marks": [
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 14},
             "text": {"template": "{{parent.name}}"},
             "fill": {"value": "black"},
             "fontWeight": {"value": "bold"}
       } } },
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 29},
             "text": [
               {"test": "isRange", "template": "Growth:\t{{tooltip.datum.calc|number:'.1%'}}"},
               {"template": "Percent of people with HIV:\t{{tooltip.datum.calc|number:',.0f'}}"}
             ],
             "fill": {"value": "black"}
       } } },
       {
         "type": "text",
         "properties": {
           "update": {
             "x": {"value": 6}, "y": {"value": 44},
             "text": [
               {"test": "isRange", "template": ""},
               {"template": "Global position:\t#{{parent.rank|number:'.0f'}}"}
             ],
             "fill": {"value": "black"}
       } } },
   ]}
 ]

} </graph> See or edit source data.


Dataset format

The dataset should be stored at Wikimedia commons, in the Data namespace, as a tabular data (.tab) file. Currently, the file format should be JSON, representing a three column table, where the first column is the three-letter ISO country code, the second is the year and the third is the value. In the future, CSV-files may be possible.

Steps:

  • Download a .csv file, for example from https://ourworldindata.org
  • Trim to three columns in a spreadsheet program
  • Upload it at https://www.csvjson.com/csv2json . Select "parse numbers".
  • Copy the json output and paste it into Notepad. Find and replace { with [, and "Country:" with nothing
  • Paste this data below the heading data, at for example [:commons:Data:Child Mortality.tab]

Be aware of some minor bugs.

See also