|
|
Line 1: |
Line 1: |
| <graph> | | <graph> |
| { | | { |
| "version": 2, | | "width": 400, |
| "width": 300, | | "height": 100, |
| "height": 300, | | "padding": {"top": 30, "left": 30, "bottom": 30, "right": 10}, |
| "data": [ | | "data": [ |
| { | | { |
| // Data is retrieved from the MediaWiki API. By default it uses current wiki's "Extension by category"
| | "name": "aggregate", |
| "name": "table", | | "values": [ |
| "url": "wikiapi:///?generator=categorymembers&gcmtitle=Category:Extensions+by+category&gcmtype=subcat&action=query&gcmlimit=max&prop=categoryinfo&formatversion=2&format=json", | | {"label": "Category A", "mean": 1, "lo": 0, "hi": 2}, |
| // We are only interested in the content of query.pages subelement.
| | {"label": "Category B", "mean": 2, "lo": 1.5, "hi": 2.5}, |
| "format": {"property": "query.pages","type": "json"},
| | {"label": "Category C", "mean": 3, "lo": 1.7, "hi": 4.3}, |
| "transform": [
| | {"label": "Category D", "mean": 4, "lo": 3, "hi": 5}, |
| // sort in descending order using category size as the sort key
| | {"label": "Category E", "mean": 5, "lo": 4.1, "hi": 5.9} |
| {"type": "sort","by": "-categoryinfo.size"}, | |
| // To visualize, use "pie" transformation to add layout_start, layout_end, and layout_mid fields to each page object | |
| // These fields contain angles at which to start and stop drawing arcs. First element's start will be 0, and last element's end will be 360 degrees (in radians)
| |
| {"type": "pie","field": "categoryinfo.size"} | |
| ] | | ] |
| } | | } |
| ], | | ], |
| // Scales are like functions -- marks use them to convert a data value into a visual value, like x or y coordinate on the graph, or a color value.
| |
| "scales": [ | | "scales": [ |
| { | | { |
| // This scale will be used to assign a color to each slice, using a palette of 10 colors | | "name": "y", |
| "name": "color", | | "type": "ordinal", |
| "domain": {"data": "table","field": "title"}, | | "range": "height", |
| "range": "category10", | | "domain": {"data": "aggregate", "field": "label"} |
| "type": "ordinal" | | }, |
| | { |
| | "name": "x", |
| | "type": "linear", |
| | "domain": {"data": "aggregate", "field": "hi"}, |
| | "range": [100, 400], |
| | "nice": true, |
| | "zero": true |
| } | | } |
| | ], |
| | "axes": [ |
| | {"type": "x", "scale": "x", "ticks": 6} |
| ], | | ], |
| "marks": [ | | "marks": [ |
| { | | { |
| // This mark draws the actual pie chart from the data source | | "type": "text", |
| // Each element is an arc between layout_start and layout_end angles (as calculated by the pie transformation)
| | "from": {"data": "aggregate"}, |
| // drawn with a given radius, stroke, and fill.
| |
| "from": {"data": "table"}, | |
| "type": "arc",
| |
| "properties": { | | "properties": { |
| "enter": { | | "enter": { |
| "fill": {"scale": "color","field": "title"}, | | "x": {"value": 0}, |
| "outerRadius": {"value": 200}, | | "y": {"scale": "y", "field": "label"}, |
| "startAngle": {"field": "layout_start"}, | | "baseline": {"value": "middle"}, |
| "endAngle": {"field": "layout_end"}, | | "fill": {"value": "#000"}, |
| "stroke": {"value": "white"}, | | "text": {"field": "label"}, |
| "strokeWidth": {"value": 1} | | "font": {"value": "Helvetica Neue"}, |
| | "fontSize": {"value": 13} |
| } | | } |
| } | | } |
| }, | | }, |
| { | | { |
| // This mark draws labels around the pie chart after the pie chart has been drawn
| | "type": "rect", |
| "type": "text", | | "from": {"data": "aggregate"}, |
| // Before drawing, we need to perform a number of calculations to figure out the exact location and orientation of the text
| | "properties": { |
| "from": { | | "enter": { |
| "data": "table",
| | "x": {"scale": "x", "field": "lo"}, |
| "transform": [
| | "x2": {"scale": "x", "field": "hi"}, |
| // For each data point (datum), each of these transformations will be ran in order.
| | "y": {"scale": "y", "field": "label", "offset": -1}, |
| // Formula transformation evaluates the expression and assigns result to the datapoint
| | "height": {"value": 1}, |
| // Size of the pie slice, in degrees: sliceSize = (end - start) * 180 / Pi
| | "fill": {"value": "#888"} |
| { "type": "formula", "field": "sliceSize", "expr": "(datum.layout_end - datum.layout_start)*180/PI" }, | | } |
| // Draw text only if the slice of the arc is more than 2 degrees to avoid overcrowding | | } |
| { "type": "filter", "test": "datum.sliceSize > 2" },
| | }, |
| // Remove namespace from the text - keeps only text after the first ':' symbol, limits to 40 chars.
| | { |
| { "type": "formula", "field": "title", "expr": "substring(datum.title, 1+indexof(datum.title,':'), 40)" },
| | "type": "symbol", |
| // Determine the side of the pie chart we are on - left or right.
| | "from": {"data": "aggregate"}, |
| { "type": "formula", "field": "invert", "expr": "datum.layout_mid*180/PI < 180 ? 1 : -1" },
| |
| // If on the left, the text should be right-aligned (go from the rim inward) | |
| { "type": "formula", "field": "align", "expr": "datum.invert < 0 ? 'left' : 'right'" },
| |
| // At what angle should the text be drawn relative to the point on the circle | |
| { "type": "formula", "field": "angle", "expr": "(datum.layout_mid*180/PI)-90*datum.invert" },
| |
| // Make font smaller for smaller pie slices
| |
| { "type": "formula", "field": "fontSize", "expr": "datum.sliceSize > 20 ? 15 : (datum.sliceSize > 10 ? 14 : 10)" },
| |
| // Make font bold for largest pie slices
| |
| { "type": "formula", "field": "fontWeight", "expr": "datum.sliceSize > 15 ? 'bold' : 'normal'" }
| |
| ]
| |
| },
| |
| "properties": { | | "properties": { |
| "enter": { | | "enter": { |
| // Use the fields calculated in the transformation to draw category names
| | "x": {"scale": "x", "field": "mean"}, |
| "align": {"field": "align"}, | | "y": {"scale": "y", "field": "label"}, |
| "angle": {"field": "angle"},
| | "size": {"value": 40}, |
| "baseline": {"value": "middle"},
| | "fill": {"value": "#000"} |
| "fill": {"value": "black"},
| |
| "fontSize": {"field": "fontSize"}, | |
| "fontWeight": {"field": "fontWeight"},
| |
| "radius": {"value": 270}, | |
| "text": {"field": "title"}, | |
| "theta": {"field": "layout_mid"}
| |
| } | | } |
| } | | } |