Template:Graph:US Map state highlight
Appearance
This graph's main version resides at Template:Graph:US Map state highlight. Please make or suggest all the changes there, and copy it everywhere else (until the copying is automated)
{{Graph:US Map state highlight | table=Bea.gov/GDP by state.tab |
---|
See or edit source data. |
<graph>
{
//
// ATTENTION: This code is maintained at https://www.mediawiki.org/wiki/Template:Graph:US_Map_state_highlight
// Please do not modify it anywhere else, as it may get copied and override your changes.
// Suggestions can be made at https://www.mediawiki.org/wiki/Template_talk:Graph:US_Map_state_highlight
//
"version": 2,
"width": 300,
"height": 265,
"signals": [
// TODO: should be last available
{ "name": "initYear", "init": 2016 },
{ "name": "gapHeight", "init": 26 },
{
// Hide overview if total height is too small
"name": "showOverview",
"init": {"expr": "true || height < (gapHeight + 100)" }
},
{ "name": "overviewHeight", "init": {"expr": "showOverview ? 40 : 0" } },
{ "name": "detailHeight", "init": {"expr": "height - (showOverview ? overviewHeight + gapHeight : 0)" } },
{ "name": "overviewYPos", "init": {"expr": "height - overviewHeight" } },
{
"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:///{{{table}}}",
"format": {"type": "json", "property": "data"},
},{
"name": "totals",
"source": "data",
"transform": [
{ "type": "formula", "field": "date", "expr": "datetime(datum.year, 0, 1)" },
// TODO: We shouldn't list each field this way... nasty
{ "type": "formula", "field": "total", "expr": "datum.AL+datum.AK+datum.AZ+datum.AR+datum.CA+datum.CO+datum.CT+datum.DE+datum.DC+datum.FL+datum.GA+datum.HI+datum.ID+datum.IL+datum.IN+datum.IA+datum.KS+datum.KY+datum.LA+datum.ME+datum.MD+datum.MA+datum.MI+datum.MN+datum.MS+datum.MO+datum.MT+datum.NE+datum.NV+datum.NH+datum.NJ+datum.NM+datum.NY+datum.NC+datum.ND+datum.OH+datum.OK+datum.OR+datum.PA+datum.RI+datum.SC+datum.SD+datum.TN+datum.TX+datum.UT+datum.VT+datum.VA+datum.WA+datum.WV+datum.WI+datum.WY" },
]
},{
// Select just the source data for the starting year
"name": "firstYearData",
"source": "data",
"transform": [{
"type": "filter", "test": "datum.year === fromYear"
},{
// TODO: autogenerate this list
"type": "fold",
"fields": ["AL","AK","AZ","AR","CA","CO","CT","DE","DC","FL","GA","HI","ID","IL","IN","IA","KS","KY","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","RI","SC","SD","TN","TX","UT","VT","VA","WA","WV","WI","WY"]
}]
},{
// Select just the source data for the ending year
"name": "yearData",
"source": "data",
"transform": [{
"type": "filter", "test": "datum.year === toYear"
},{
"type": "fold",
// TODO: autogenerate this list
"fields": ["AL","AK","AZ","AR","CA","CO","CT","DE","DC","FL","GA","HI","ID","IL","IN","IA","KS","KY","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","RI","SC","SD","TN","TX","UT","VT","VA","WA","WV","WI","WY"]
},{
"type": "lookup",
"on": "firstYearData",
"onKey": "key",
"keys": ["key"],
"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/US_states.map",
"format": {"type": "json", "property": "data.features"},
"transform": [{
"type": "geopath",
"projection": "albersUsa",
"scale": 500,
"translate": [200, 100]
},{
"type": "lookup",
"on": "yearData",
"onKey": "key",
"keys": ["id"],
"as": ["lookup"],
"default": null
}]
},{
"name": "dummyValue",
"values": [{}]
}],
"scales": [{
"name": "color",
"type": "linear",
"domain": {"data": "yearData", "field": "calc"},
"range": ["#f1f1f0", "#08306b"],
"zero": false
},{
"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
},{
"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"}
]} } }]
},{
"type": "group",
"name": "overview",
"from": {
"data": "dummyValue",
// HACK: brush_end is needed to fool optimizer, because otherwise legend doesn't auto-update
"transform": [{"type": "filter", "test": "(brush_end && 0) || showOverview"}]
},
"properties": {
"enter": {
"x": {"value": 0},
"y": {"signal": "overviewYPos"},
"height": {"signal": "overviewHeight"},
"width": {"signal": "width"},
"fill": {"value": "transparent"}
} },
"axes": [
{"type": "x", "scale": "xOverview"}
],
"marks": [{
// Draw scale for a single year (I wish we could dynamically pick which scale to use for the legend)
"type": "group",
// HACK: brush_end is needed to fool optimizer, because otherwise legend doesn't auto-update
"from": { "data": "dummyValue", "transform": [{"type": "filter", "test": "(brush_end && 0) || !isRange"}] },
"properties": { "enter": { "width": {"signal": "width"} } },
"legends": [{
"fill": "color",
"offset": 20,
"properties": {"legend": {"y": {"value": 30} } }
}]},{
// Draw scale for a range (I wish we could dynamically pick which scale to use for the legend)
"type": "group",
"from": { "data": "dummyValue", "transform": [{"type": "filter", "test": "isRange"}] },
"properties": { "enter": { "width": {"signal": "width"} } },
"legends": [{
"fill": "diffColor",
"offset": 20,
"properties": {
"legend": {"y": {"value": 30} },
"labels": {
"text": [
{"test": "datum.data===0", "value": "0"},
{"test": "(datum.data%1)===0", "template": "\u007b{datum.data|number:'.0%'}\u007d"},
{"value": ""}
]} } }]},{
"name": "yearLabel",
"type": "text",
"from": {
"data": "dummyValue",
"transform": [
{"type": "formula", "field": "text", "expr": "if(isRange,fromYear + '-' + toYear, fromYear)"},
{"type": "formula", "field": "fontSize", "expr": "if(isRange,22,32)"},
]},
"properties": {
"enter": {
"x": {"signal": "width", "offset": 72},
"y": {"value": 20},
"fontWeight": {"value": "bold"},
"align": {"value": "center"},
"baseline": {"value": "middle"},
"fill": {"value": "#08306b"}
},
"update": {
"fontSize": {"field": "fontSize"},
"text": {"field": "text"}
} } },{
"type": "line",
"from": { "data": "totals" },
"properties": {
"update": {
"x": {"scale": "xOverview", "field": "date"},
"y": {"scale": "yOverview", "field": "total"},
"stroke": {"value": "#08306b"},
"strokeWidth": {"value": 2}
} } },{
"type": "rect",
"from": {
"data": "dummyValue",
"transform": [
{"type": "formula", "field": "fromDate", "expr": "datetime(fromYear, -6, 1)"},
{"type": "formula", "field": "toDate", "expr": "datetime(toYear, 6, 1)"},
]},
"properties": {
"enter": {
"y": {"value": 0},
"height": {"signal": "overviewHeight"},
"fill": {"value": "#333"},
"fillOpacity": {"value": 0.2},
"stroke": {"value": "#f00"},
"strokeDash": {"value": [4]},
},
"update": {
"x": {"scale": "xOverview", "field": "fromDate"},
"x2": {"scale": "xOverview", "field": "toDate"}
} } }]},
{
"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": "lookupYear", "expr": "datetime(fromYear, 0, 1)"},
{
"type": "lookup",
"on": "totals",
"onKey": "lookupYear",
"keys": ["date"],
"as": ["totals"],
"default": null
},
{"type": "formula", "field": "relGrowth", "expr": "tooltip.datum.calc/datum.totals.total"},
]},
"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": "\u007b{tooltip.datum.key}\u007d"},
"fill": {"value": "black"},
"fontWeight": {"value": "bold"}
} } },
{
"type": "text",
"properties": {
"update": {
"x": {"value": 6}, "y": {"value": 29},
"text": [
{"test": "isRange", "template": "Growth:\t\u007b{tooltip.datum.calc|number:'.1%'}\u007d"},
{"template": "State GDP:\t\u007b{tooltip.datum.calc|number:',.0f'}\u007d"},
],
"fill": {"value": "black"},
} } },
{
"type": "text",
"properties": {
"update": {
"x": {"value": 6}, "y": {"value": 44},
"text": [
{"test": "isRange", "template": ""},
{"template": "Percent of total:\t\u007b{parent.relGrowth|number:'.1%'}\u007d"},
],
"fill": {"value": "black"},
} } },
]}
]
}
</graph>