User:Yair rand/Wiki readership map

Data from 2021. Editor data not available for sister projects or certain countries.

The map can be zoomed and panned. Hovering over the pie slices or legend highlights relevant colors, and shows additional data on the text box in the top left. Radio buttons allow toggling between data sources.

{ "version": 2, "width": 1250, "height": 670, "padding": 0, "background": "#edf1f7", "description": "TODOs: maybe have", "description2":"options for click, dblclick, position tooltip? something for", "description3":"clicking pies and legend items", "description6":"Maybe rework zoom to be just magnif and offsets.", "description7":"Maybe loop map", "data": [ {     "name": "rawmap", "url": "wikiraw:///Extension:Graph/Demo/RawData:WorldMap-iso2-json", "format": {"type": "topojson","feature": "countries"} },   {      "name": "map", "source":"rawmap", "transform": [ {         "type": "geopath", "value": "data", "scale": {"signal":"mzoom"}, "center": [-180,125], "translate": [0,0], "projection": "equirectangular" }     ]    },    {      "name": "d_options", "values": [ {         "title": "Pageviews", "order": 0, "dtype": "pageviews", "c": "readercount", "ttext": "views", "mult": 1000, "mincount": 80 },       {          "title": "Active editors", "order": 1, "dtype": "aeditors", "c":"editorcount", "activity": "5..99", "ttext": "active editors (5-99 edits monthly)", "mult": 1, "mincount": 0 },       {          "title": "Very active editors", "order": 2, "dtype": "vaeditors", "activity": "100..", "ttext": "very active editors (100+ edits monthly)", "mult": 1, "mincount": 0 }     ]    },    {      "name": "raw_reader_data", "url": "tabular:///Pageviews-by-country-monthly-2021-01.tab", "format": { "":"wiki_db,country,count", "type":"json","property":"data" },     "transform": [ {         "type": "filter", "test": "datum.count > 1" }     ]    },    {      "name": "raw_editor_data", "url": "tabular:///Geoeditors-monthly-2021-12.tab", "format": { "":"wiki_db,country,count", "type":"json","property":"data" },     "transform": [ {         "type": "filter", "test": "datum.count > 1" },       {          "type": "formula", "field": "c_db", "expr": "datum.country + '_' + datum.wiki_db" },       {          "type": "formula", "field": "range_max", "expr": "datum.count" },       {          "type": "formula", "field": "range_min", "expr": "datum.count - 9" },       {          "type": "formula", "field": "count", "description": "rough estimates, smaller numbers more likely to be on the low end", "expr": "datum.count - ( datum.count === 10 ? 7 : datum.count < 50 ? 5 : 4.5 )" }     ]    },    {      "name": "raw_aeditor_data", "source": "raw_editor_data", "transform": [ {         "type": "filter", "test": "datum.count > 1" },       {          "type": "filter", "test": "datum.activity_level === active_dtype.activity" }     ]    },    {      "name": "source_data", "source":"raw_reader_data", "transform": [ {         "type": "formula", "field": "c_db", "expr": "datum.country + '_' + datum.wiki_db" },       {          "type": "lookup", "on": "raw_aeditor_data", "onKey": "c_db", "keys": ["c_db"], "as": ["e_d"], "default": {"count":0,"range_min":0,"range_max":0} },       {          "type": "formula", "field": "editorcount", "expr": "datum.e_d.count" },       {          "type": "formula", "field": "readercount", "expr": "datum.count" }     ]    },    {      "name": "source_run_data", "source":"source_data", "transform": [ {         "type":"formula", "field": "count", "expr": "active_dtype.dtype === 'pageviews' ? datum.readercount : datum.editorcount" }     ]    },    {      "name": "by_wiki", "source":"source_run_data", "transform": [ {         "type": "aggregate", "groupby": ["wiki_db"], "summarize": [ {"field":"count","ops":"sum"}, {"field":"readercount","ops":"sum"}, {"field":"e_d.range_min","ops":"sum","as":"sum_range_min"}, {"field":"e_d.range_max","ops":"sum","as":"sum_range_max"} ]       }      ]    },    {      "name": "top_wikis", "description":"List 48 largest wikis, for the colors (consistency). Formerly legend.", "source":"by_wiki", "transform": [ {         "type":"sort", "by": ["-sum_readercount"] },       {          "type":"rank" },       {          "type":"filter", "_test":"indexof(['enwiki','frwiki','dewiki','jawiki','eswiki'],datum.wiki_db)!=-1", "test":"datum.rank < 48" }     ]    },    {      "name": "by_country", "source":"source_run_data", "transform": [ {         "type": "aggregate", "groupby": ["country"], "summarize": {"count":"sum"} }     ]    },    {      "name":"country_coords", "url":"wikidatasparql:///?query=SELECT%20%3Fcode%20%3Fcoords%20WHERE%20%7B%0A%20%20%3Fq%20wdt%3AP297%20%3Fcode%3B%0A%20%20%20%20%20wdt%3AP625%20%3Fcoords%20.%0A%7D", "transform": [ {         "type": "geo", "projection": "equirectangular", "scale": 180, "center": [-180,125], "translate": [0,0], "lon": "coords[0]", "lat": "coords[1]" }     ]    },    {      "name": "scary_countries", "values": [ "AZ","BH","BY","CN","CU","DJ","EG","GQ","ER","ET","IR","KZ", "LA","LY","MM","KP","PK","RU","SA","SO","SD","SY","TH", "TR","TM","AE","UZ","VE","VN","YE" ],     "description":"Also RW,BI,SG,IQ,TJ in more recent data", "transform": [ {         "description": "Add icons for scary countries...", "type":"lookup", "on":"country_coords", "onKey":"code", "keys": ["data"], "as": ["coords_data"], "default": { "layout_x": 10, "layout_y": 10 }       }      ]    },    {      "name": "all_pies", "source":"source_run_data", "transform": [ {         "description":"Wiki totals", "type":"lookup", "on":"by_wiki", "onKey":"wiki_db", "keys": ["wiki_db"], "as": ["db_count"] },       {            "":"wiki_db,country,count", "type": "facet", "groupby": ["country"], "transform": [ {             "description": "Each pie chart starts with slices from bigger wikis", "type":"sort", "by":"-db_count.sum_count" },           {"type":"pie","field":"count"}, {             "type":"filter", "description":"For performance...", "test":"datum.count > active_dtype.mincount" }         ]        },        {          "description": "Add country location...", "type":"lookup", "on":"country_coords", "onKey":"code", "keys": ["country"], "as": ["coords_data"] },       {          "description":"Country totals, for the pie radius and top-bar text", "type":"lookup", "on":"by_country", "onKey":"country", "keys": ["country"], "as": ["big"] },       {          "type": "formula", "field": "country_count", "expr":"datum.big.sum_count" },       {          "type":"filter", "test":"datum.coords_data" },       {          "description": "Show smaller pies on top", "type":"sort", "by":"-country_count" }     ]    },    {      "name": "onscreens", "source": "source_run_data", "description": "For the legend, show visible wikis", "transform": [ {         "description": "Add country location...", "type":"lookup", "on":"country_coords", "onKey":"code", "keys": ["country"], "as": ["coords_data"] },       {          "type":"filter", "test":"datum.coords_data && datum.count > 0" },       {          "type": "filter", "test": "datum.coords_data.layout_x > xMin && datum.coords_data.layout_x < xMax" },       {          "type": "filter", "test": "datum.coords_data.layout_y > yMin && datum.coords_data.layout_y < yMax" },       {          "type": "aggregate", "groupby": ["wiki_db"], "summarize": [ {"field":"count","ops":"sum","as":"onscreen_count"} ]       },        {          "type":"sort", "by": ["-onscreen_count"], "description": "For rank purposes" },       {          "type":"rank" },       {          "type":"filter", "test":"datum.rank < 48" },       {          "description":"Wiki totals", "type":"lookup", "on":"by_wiki", "onKey":"wiki_db", "keys": ["wiki_db"], "as": ["db_count"] },       {          "type":"formula", "field": "sum_count", "expr": "datum.db_count.sum_count", "description": "Need to have the actual total counts available for the tooltip." }     ]    }  ],

"signals": [ {     "name": "tooltip", "init": {}, "streams": [ {         "type": "arc:mouseover", "expr": "{count:(datum.e_d.range_min&&datum.e_d.range_min<100000)?format(',',datum.e_d.range_min*active_dtype.mult)+' - '+format(',',datum.e_d.range_max*active_dtype.mult):format(',',datum.count*active_dtype.mult),wiki_db:datum.wiki_db,tc:format('.1%',datum.count/parent.country_count),pp:format('.1%',datum.count/datum.db_count.sum_count),country:datum.country}" },       {          "description":"duplicating above with different selector", "type": "@pietext:mouseover", "expr": "{count:(datum.e_d.range_min&&datum.e_d.range_min<100000)?format(',',datum.e_d.range_min*active_dtype.mult)+' - '+format(',',datum.e_d.range_max*active_dtype.mult):format(',',datum.count*active_dtype.mult),wiki_db:datum.wiki_db,tc:format('.1%',datum.count/parent.country_count),pp:format('.1%',datum.count/datum.db_count.sum_count),country:datum.country}" },       {          "type": "@legendItem:mouseover", "expr": "{'wiki_db':datum.wiki_db,'count':(datum.db_count&&datum.db_count.sum_range_min)?format(',',datum.db_count.sum_range_min*active_dtype.mult)+' - '+format(',',datum.db_count.sum_range_max*active_dtype.mult):format(',',datum.sum_count*active_dtype.mult)}", "_expr": "{'wiki_db':'viwiki'}", "_":",'wiki_db_':datum.label" },       {          "type": "@legendItemPiece:mouseover", "expr": "{'wiki_db':parent.wiki_db,'count':(parent.db_count.sum_range_min)?format(',',parent.db_count.sum_range_min*active_dtype.mult)+' - '+format(',',parent.db_count.sum_range_max*active_dtype.mult):format(',',parent.sum_count*active_dtype.mult)}" },       {          "type":"@scary_marker:mouseover", "expr":"{'scary':datum.data,'wiki_db':'null'}", "__expr":"{'wiki_db':'viwiki'}" },       {"type": "arc:mouseout", "expr": "{}"}, {"type": "@pietext:mouseout", "expr": "{}"}, {"type": "@legendItem:mouseout", "expr": "{}"}, {"type": "@scary_marker:mouseout", "expr": "{}"} ]   },    {      "name": "zoom", "init": 1, "verbose": true, "streams": [ {"type": "wheel", "expr": "pow(1.001, event.deltaY*pow(16, event.deltaMode))"} ]   },    {      "name": "czoom", "init": 1, "streams": { "type":"zoom", "expr": "czoom * zoom" }   },    {      "name": "mzoom", "init": 180, "streams": [ {"type": "czoom", "expr": "180 / czoom"} ]   },    {      "name": "circleMax", "init": 50, "streams": { "type":"czoom", "_expr": "if( czoom == 1, 50, 200 )", "expr": "50 / pow( czoom, 0.86 )" }   },    {      "name": "point", "init": 0, "streams": [{ "type": "mousedown", "expr": "{x: eventX, y: eventY}" }]   },    {      "name": "delta", "init": 0, "streams": [ {         "type": "[mousedown, window:mouseup] > window:mousemove", "expr": "{x: point.x - eventX, y: point.y - eventY}" }     ]    },    {      "name": "xAnchor", "init": 0, "streams": [{ "type": "mousemove", "expr": "eventX", "scale": {"name":"scx", "invert":true} }]   },    {      "name": "yAnchor", "init": 0, "streams": [{ "type": "mousemove", "expr": "eventY", "scale": {"name":"scy", "invert":true} }]   },    {      "name": "xs", "streams": [{ "type": "mousedown, mouseup, wheel", "expr": "{min: xMin, max: xMax}" }]   },    {      "name": "ys", "streams": [{ "type": "mousedown, mouseup, wheel", "expr": "{min: yMin, max: yMax}" }]   },    {      "name": "xMin", "init": 0, "streams": [ {"type": "delta", "expr": "xs.min + (xs.max-xs.min)*delta.x/width"}, {"type": "zoom", "expr": "(xs.min-xAnchor)*zoom + xAnchor"} ]   },    {      "name": "xMax", "init": 1250, "streams": [ {"type": "delta", "expr": "xs.max + (xs.max-xs.min)*delta.x/width"}, {"type": "zoom", "expr": "(xs.max-xAnchor)*zoom + xAnchor"} ]   },    {      "name": "yMin", "init": 0, "streams": [ {"type": "delta", "expr": "ys.min + (ys.max-ys.min)*delta.y/height"}, {"type": "zoom", "expr": "(ys.min-yAnchor)*zoom + yAnchor"} ]   },    {      "name": "yMax", "init": 670, "streams": [ {"type": "delta", "expr": "ys.max + (ys.max-ys.min)*delta.y/height"}, {"type": "zoom", "expr": "(ys.max-yAnchor)*zoom + yAnchor"} ]   },    {      "name": "active_dtype", "init": { "description": "duplicating d_options[ 0 ]", "title": "Pageviews", "order": 0, "dtype": "pageviews", "c": "readercount", "ttext": "page views", "mult": 1000, "mincount": 80 },     "streams": [ { "type": "@dtype_selector:click", "expr": "parent" }, { "type": "@dtype_selector_label:click", "expr": "parent" } ]   }  ],  "scales": [ {     "name": "color", "type": "ordinal", "_domain": {"data": "raw_reader_data", "field": "wiki_db"}, "__domain": {"data": "top_wikis", "field": "wiki_db"}, "___domain": {"data": "by_wiki", "reverse":false}, "domain": {"data": "top_wikis", "reverse":false}, "sort":false, "range": "category20", "_range": ["purple","orange","blue","red","green"] },   {      "name": "pie_size", "type": "sqrt", "domain": {"data": "by_country", "field": "sum_count"}, "_domain": [0,4000000], "rangeMin": 0, "rangeMax": { "signal": "circleMax" } },   {      "name": "legendY", "type": "linear", "_domain": { "data": "onscreens", "field": "rank" },     "domain": [1,48], "range": [10, 700] },   {      "name": "scx", "type": "linear", "range": "width", "zero": false, "domainMin": {"signal": "xMin"}, "domainMax": {"signal": "xMax"} },   {      "name": "scy", "type": "linear", "range": "height", "zero": false, "reverse":true, "domainMin": {"signal": "yMin"}, "domainMax": {"signal": "yMax"} } ],  "marks": [ {     "name": "map", "type": "path", "from": {"data": "map"}, "properties": { "update": { "x": {"value":"0","scale":"scx"}, "y": {"value":"0","scale":"scy"}, "_fill": {"value": "grey"}, "path": {"field": "layout_path"} },       "enter": { "fill": {"value": "grey"} }     }    },    {      "name": "pie_charts", "type": "group", "from": { "data": "all_pies" },     "properties": { "update": { "x": {"field": "coords_data.layout_x","scale":"scx"}, "y": {"field": "coords_data.layout_y","scale":"scy"} }     },      "marks": [ { "type": "arc", "properties": { "enter": { "stroke": {"value": "#fff"}, "fill": {"field": "wiki_db","scale":"color"} },         "hover": { "strokeWidth": {"value":1} },         "update": { "startAngle": {"field": "layout_start"}, "endAngle": {"field": "layout_end"}, "outerRadius": [ {"field": {"parent":"country_count"},"scale":"pie_size"} ],           "strokeWidth": [ { "test": "tooltip.wiki_db && tooltip.wiki_db == datum.wiki_db", "value": 0.5 },             {"value":0.25} ],           "opacity": [ { "test": "tooltip.wiki_db && tooltip.wiki_db != datum.wiki_db", "value": 0.1 },             {"value": 1} ]         }        }      }, {        "type": "text", "name": "pietext", "properties": { "enter": { "fill": [ { "value": "black" } ],           "baseline": {"value":"middle"}, "align": {"value":"center"} },         "update": { "text": [ { "field":"wiki_db", "test": "datum.count > iscale('pie_size',15)" }, { "value":"" } ],           "fontSize": [ { "value":10, "test": "datum.count > iscale('pie_size',15)" }, { "value":0 } ],           "radius": {"field": {"parent":"country_count"},"scale":"pie_size","mult":0.6}, "theta": {"field":"layout_mid"}, "_angle": {"field":"layout_mid","mult":57.3,"offset":90}, "opacity": [ { "test": "tooltip.wiki_db && tooltip.wiki_db != datum.wiki_db", "value": 0.1 },             {"value": 1} ]         }        }      } ]    },    {      "type": "text", "name": "scary_marker", "from": {"data":"scary_countries"}, "properties": { "enter": { "baseline": { "value": "middle" }, "align": {"value":"center"}, "text": {"value":"?"}, "_text": {"field":"data"}, "fill": {"value":"black"} },       "update": { "x": {"field": "coords_data.layout_x","scale":"scx"}, "y": {"field": "coords_data.layout_y","scale":"scy"}, "fontSize": [ {"test":"active_dtype.dtype !== 'pageviews'", "value":12}, {"value":0} ],         "opacity": [ {             "test": "tooltip.wiki_db && tooltip.scary !== datum.data", "value": 0.1 },           {"value": 1} ]       }      }    },    {      "description": "Legend outline box", "type":"group", "properties": { "enter": { "x": {"value": 37}, "y": {"value": 12}, "fill": {"value":"white"}, "width": {"value":110}, "height": {"value":700} }     },      "marks": [ {         "type":"text", "properties": { "enter": { "text": {"value":"Wikis:"}, "fontWeight": {"value":"bold"}, "fill": {"value":"black"}, "x": {"value":5}, "y": {"value":15} }         }        }      ]    },    {      "type":"group", "description":"legend contents", "from": { "data": "onscreens" },     "name":"legendItem", "properties": { "enter": { "width": {"value":100}, "height": {"value":14}, "x": {"value":42}, "fill": {"value":"white"} },       "update": { "y": {"scale":"legendY","field": "rank","offset":5} }     },      "marks": [ {         "type": "rect", "name":"legendItemPiece", "properties": { "enter": { "fill": {"field":{"parent": "wiki_db"},"scale":"color"}, "height": {"value":10}, "width": {"value":10}, "x": {"value":0}, "y": {"value":2} },           "update": { "opacity": [ {                 "test": "tooltip.wiki_db && tooltip.wiki_db != parent.wiki_db", "value": 0.25 },               {"value": 1} ]           }          }        },        {          "type": "text", "name":"legendItemPiece", "properties": { "enter": { "text": {"field":{"parent":"wiki_db"}}, "baseline": {"value":"top"}, "fill": {"value":"black"}, "_fill": {"scale":"color","field": "wiki_db"}, "fontSize": {"value":10}, "x": {"value":13}, "y2": {"value":1} },         "update": { "opacity": [ {                 "test": "tooltip.wiki_db && tooltip.wiki_db != parent.wiki_db", "value": 0.25 },               {"value": 1} ]           }          }        }      ]    },    {      "type":"group", "description": "Text box at the top with stats, displayed when hovering an item.", "properties": { "enter": { "x": {"value":167}, "y": {"value":32}, "height": {"value":16}, "fill": {"value":"#FFF"}, "opacity": {"value": 0.8} },       "update": { "width": [ {             "test": "!tooltip.wiki_db && !tooltip.scary", "value": 0 },           {"value":500} ]       }      },      "marks": [ {         "type":"text", "properties": { "enter": { "baseline": {"value":"top"}, "fill": {"value":"black"}, "x": {"value":2}, "y": {"value":1} },           "update": { "text": [ {"test":"tooltip.tc","template": "\u007b{tooltip.wiki_db}}: \u007b{tooltip.count}} \u007b{active_dtype.ttext}}, \u007b{tooltip.tc}} of country (\u007b{tooltip.country}}), \u007b{tooltip.pp}} of \u007b{tooltip.wiki_db}}"}, {"test":"tooltip.scary","template": "Editor data not available in \u007b{tooltip.scary}} due to privacy/security concerns"}, {"template": "\u007b{tooltip.wiki_db}}: \u007b{tooltip.count}} \u007b{active_dtype.ttext}} (all countries)"} ],             "opacity": [ {                 "test": "!tooltip.wiki_db", "value": 0 },               {"value": 1} ]           }          }        }      ]    },    {      "type": "group", "description": "", "from": {"data": "d_options" }, "properties": { "enter": { "y": {"value": 12 }, "x": {"value": 162 } }     },      "scales": [ { "name": "x", "type": "ordinal", "range": [ 0, 360 ], "domain": {"data":"d_options","field":"order" } } ],     "marks": [ {         "type": "rect", "name": "d_option_hoverarea", "properties": { "enter": { "width": {"value":120}, "height": {"value":20}, "fill": {"value":"green"}, "x": { "field": {"parent":"order"}, "scale": "x" } },           "update": { "fill": {"value":"transparent"}, "dot_fill": {"value":"orange"} },           "hover": { "fill": {"value":"transparent"}, "dot_fill": {"value":"lightblue"} }         }        },        {          "type": "symbol", "_from": {"mark":"d_option_hoverarea"}, "name": "dtype_selector", "properties": { "enter": { "size": { "value": 80 }, "endAngle": {"value":"7" }, "x": { "field": {"parent":"order"}, "scale": "x", "offset": 10 }, "y": { "value": 10 }, "stroke": { "value": "black" }, "strokeWidth": {"value":2} },           "hover": { "_fill": {"field":"dot_fill"}, "fill": {"value":"lightblue"} },           "update": { "_fill": {"field":"dot_fill"}, "fill": [ {"value":"blue","test":"active_dtype.dtype === parent.dtype" }, {"value":"white"} ]           }          }        },        {          "type": "text", "name": "dtype_selector_label", "properties": { "enter": { "baseline": { "value": "top" }, "x": { "field": {"parent":"order"}, "scale": "x", "offset": 20 }, "y": { "value": 3 }, "text": {"field": {"parent":"title"}}, "fill": {"value":"black"} }         }        }      ]    }  ] }