UNPKG

gobierto-vizzs

Version:

Shared data visualizations for Gobierto projects

653 lines (553 loc) 20.5 kB
# gobierto-vizzs Reusable visualizations used in Gobierto. Check out [the demo](https://populatetools.github.io/gobierto-vizzs/)! # API * [BeeSwarm](#beeswarm) + [BeeSwarm examples](#beeswarm-examples) * [TreeMap](#treemap) + [TreeMap examples](#treemap-examples) * [Gantt](#gantt) + [Gantt examples](#gantt-examples) * [BarChartStacked](#barchartstacked) + [BarChartStacked examples](#barchartstacked-examples) * [BarChartSplit](#barchartsplit) + [BarChartSplit examples](#barchartsplit-examples) * [Helpers](#helpers) + [toJSON](#tojson) * [Styling](#styling) * [Development](#development) ## BeeSwarm ```js import { BeeSwarm } from "gobierto-vizzs" const bee = new BeeSwarm(chart, data, options) // ...update data bee.setData(newData) ``` **chart** _(HTMLElement)_: DOM node where put the visualization **data** _(Array)_: Elements to display **options** _(Object)_: To custom the defaults presets. Optional. All properties come with setters, that is, once you have the object you can change any property using `setPROP(VALUE)`, i.e. `setX("prop")`, `setMargin({ left: 30 })`, `setOnClick(() => {})` etc... | name | type | default | description | |---|---|---|---| | **x** | _String_ | "date" | Property name of the X-axis. It must contain a date-like value. | | **y** | _String_ | "group" | Property name of the Y-axis. Categories to be grouped by. | | **value** | _String_ | "value" | Property name of the radius. Quantitative value. | | **id** | _String_ | "id" | Property name of the id or title. Better if unique. | | **relation** | _String_ | - | Property name of the relationship. In order to display some internal relationships between circles of different categories. Only make sense on mouse over. | | **margin** | _Object_ | `{ top: 50, bottom: 50, left: 120, right: 30 }` | Set the margin around the chart. You can pass the properties you want. | | **locale** | _String_ | `window.navigator.language` | 4-letters specification of the locale. | | **minBlockSize** | _Number_ | 100 | Height of each category. If there are many elements, it's strongly recommended it to increase this value. | | **circleSize** | _Array_ | `[2, 20]` | Minimum and maximum circle radius size, respectively. | | **onClick** | _Function_ | - | Circle click callback handler. It receives the `event` and the `datum`. | | **tooltip** | _Function_ | [<sup>1</sup>](#1) | Custom HTML content to render in the tooltip on mouseenter. | <span id="1"></span> ```js defaultTooltip(d) { return ` <div class="beeswarm-tooltip-id">${d[this.idProp]}</div> <div class="beeswarm-tooltip-values"> <span class="beeswarm-tooltip-date">${d[this.xAxisProp].toLocaleDateString()}</span> &nbsp; <span class="beeswarm-tooltip-radius">${d[this.rAxisProp].toLocaleString()}</span> </div> `; } ``` ### BeeSwarm examples If your data array have the expected keys, you can simply do: ```js import { BeeSwarm } from "gobierto-vizzs" const chart = document.body const data = [ { "date": "2020-10-26T13:04:51.746Z", "value": 8600, "group": "Mayotte", "relation": "Ford", "id": 0 }, { "date": "2021-04-03", "value": 169, "group": "Rwanda", "relation": "Polestar", "id": 1 }, ... ] const bee = new BeeSwarm(chart, data) ``` But if not, you can easily parse them using the options setup: ```js import { BeeSwarm } from "gobierto-vizzs" const chart = document.body const data = [ { "imported_date": "2020-10-26T13:04:51.746Z", "amount": 8600, "category": "Mayotte", "event": "Ford", "title": 0 }, { "imported_date": "2021-04-03", "amount": 169, "category": "Rwanda", "event": "Polestar", "title": 1 }, ... ] const bee = new BeeSwarm(chart, data, { x: "imported_date", y: "category", value: "amount", relation: "event", id: "title" }) ``` Tooltip can be configured with a custom function. The return will be parsed as HTML. Function argument is the current element data. ```js const tooltip = (data) => `<strong>${data.title}</strong>` const bee = new BeeSwarm(chart, data, { tooltip }) ``` Set a custom callback when clicking into the circles ```js const bee = new BeeSwarm(chart, data, { onClick: (event, datum) => /* custom function */ }) ``` If your dataset is quite large and the groups are too close each other, try to increase the minBlockSize property. Similarly, you can change the maximum/minimum size of the circles. ```js const bee = new BeeSwarm(chart, data, { minBlockSize: 200, circleSize: [3, 30] }) ``` In order to render the chart locale-sensitive stuff, enforce the graph language (List of available [locales](https://unpkg.com/browse/d3-time-format/locale/)) ```js const bee = new BeeSwarm(chart, data, { locale: "it-IT" }) ``` ## TreeMap ```js import { TreeMap } from "gobierto-vizzs" const tree = new TreeMap(chart, data, options) // ...update data tree.setData(newData) ``` **chart** _(HTMLElement)_: DOM node where put the visualization **data** _(Array)_: Elements to display **options** _(Object)_: To custom the defaults presets. Optional. All properties come with setters, that is, once you have the object you can change any property using `setPROP(VALUE)`, i.e. `setGroup("another_group")`, `setMargin({ bottom: 0 })`, `setTooltip(() => {})`, etc... | name | type | default | description | |---|---|---|---| | **group** | _String_, _Array<_String_>_ | "group" | Property/ies name/s of the different levels of the tree. | | **value** | _String_ | - | Property name of the aggregator. The tree will be adding such value for each item in each category. If none is passed, the treemap will group by number of children. | | **id** | _String_ | "id" | Property name to build the tree object. It works as a title for the different groups. | | **rootTitle** | _String_ | "root" | Display name of the first level of the tree. | | **margin** | _Object_ | `{ top: 30, bottom: 0, left: 0, right: 0 }` | Set the margin around the chart. You can pass the properties you want. | | **locale** | _String_ | `window.navigator.language` | 4-letters specification of the locale. | | **onLeafClick** | _Function_ | - | Leaf (no children node) click callback handler. It receives the `event` and the `datum`. | | **tooltip** | _Function_ | [<sup>1</sup>](#1) | Custom HTML content to render in the tooltip on mouseenter. | | **breadcrumb** | _Function_ | [<sup>2</sup>](#2) | Custom HTML content to render in the breadcrumb. It's clickable to change groups. | | **itemTemplate** | _Function_ | [<sup>3</sup>](#3) | Custom HTML content to render in the item. | <span id="1"></span> ```js defaultTooltip(d) { return d.children && d.data.children.map(x => ` <div class="treemap-tooltip-block"> ${[ `<div class="treemap-tooltip-id">${x[this.idProp]}</div>`, x[this.valueProp] && `<div class="treemap-tooltip-values">${x[this.valueProp].toLocaleString()}</div>` ].join("")} </div> `).join(""); } ``` <span id="2"></span> ```js defaultBreadcrumb(d) { return d.map((pathName) => `<span>${pathName}</span>`).join("&nbsp;/&nbsp;"); } ``` <span id="3"></span> ```js defaultItemTemplate(d) { return [ `<div><strong>${d.data[this.idProp]}</strong></div>`, `<div>${d.value.toLocaleString()}</div>`, d.children && `<div>${d.children?.length}</div>`, ].join(""); } ``` ### TreeMap examples If your data array have the expected keys, you can simply do to display a one level depth treemap, arranged by `group` property ```js import { TreeMap } from "gobierto-vizzs" const chart = document.body const data = [ { "id": "id nobis possimus incidunt dolorum", "group": "Lebanon", }, { "id": "adipisci fugiat quidem alias molestiae", "group": "Ireland", }, ... ] const tree = new TreeMap(chart, data) ``` Instead of the children, if you want to sum the values of a different property, you can set the `value` prop accordingly ```js import { TreeMap } from "gobierto-vizzs" const chart = document.body const data = [ { "id": "id nobis possimus incidunt dolorum", "group": "Lebanon", "population": 6e6 }, { "id": "adipisci fugiat quidem alias molestiae", "group": "Ireland", "population": 5e6 }, ... ] const tree = new TreeMap(chart, data, { value: "population" }) ``` But if you want more depth levels, and use different keys, try this instead ```js import { TreeMap } from "gobierto-vizzs" const chart = document.body const data = [ { "amount": 8600, "category": "Mayotte", "category1": "Madagascar", "category2": "Mozambique", "category3": "Ford", "title": 0 }, { "amount": 169, "category": "Rwanda", "category1": "Madagascar", "category2": "Mozambique", "category3": "Polestar", "title": 1 }, ... ] const tree = new TreeMap(chart, data, { group: ["category", "category1", "category2", "category3"], value: "amount", id: "title" }) ``` Tooltip, breadcrumb and item template can be configured with a custom functions. The return will be parsed as HTML. - In the tooltip, the argument is the current tree data. - In the breadcrumb, the argument is the array of `id` selected (path names). - In the item template, the argument is the current tree data. ```js const tooltip = (data) => `<strong>${data.title}</strong>` const breadcrumb = (data) => data.map(d => `<em>${d.id}</em>`).join(">") const itemTemplate = (data) => `<div>${d.value.toLocaleString()}</div>` const tree = new TreeMap(chart, data, { tooltip, breadcrumb, itemTemplate }) ``` Set a custom callback when clicking into a leaf (a node with no children) ```js const tree = new TreeMap(chart, data, { onClick: (event, datum) => /* custom function */ }) ``` Instead of display _root_ as the first item, you may edit the text ```js const tree = new TreeMap(chart, data, { rootTitle: "Entities" }) ``` In order to render the chart locale-sensitive stuff, enforce the graph language (List of available [locales](https://unpkg.com/browse/d3-time-format/locale/)) ```js const tree = new TreeMap(chart, data, { locale: "it-IT" }) ``` ## Gantt ```js import { Gantt } from "gobierto-vizzs" const gantt = new Gantt(chart, data, options) // ...update data gantt.setData(newData) ``` **chart** _(HTMLElement)_: DOM node where put the visualization **data** _(Array)_: Elements to display **options** _(Object)_: To custom the defaults presets. Optional. All properties come with setters, that is, once you have the object you can change any property using `setPROP(VALUE)`, i.e. `setX("prop")`, `setMargin({ left: 30 })`, `setOnClick(() => {})` etc... | name | type | default | description | |---|---|---|---| | **x** | _String_ | "phase" | Property name of the categories along the X-axis. Legend will be depicted by these values | | **y** | _String_ | "group" | Property name of the Y-axis. Categories to be grouped by. | | **from** | _String_ | "from" | Property name of the initial range. Date-like value. | | **to** | _String_ | "to" | Property name of the end range. Date-like value. | | **id** | _String_ | "id" | Property name of the id or title. Better if unique. | | **margin** | _Object_ | `{ top: 30, bottom: 0, left: 0, right: 0 }` | Set the margin around the chart. You can pass the properties you want. | | **locale** | _String_ | `window.navigator.language` | 4-letters specification of the locale. | | **barHeight** | _Number_ | 10 | Height of each category. | | **onClick** | _Function_ | - | Circle click callback handler. It receives the `event` and the `datum`. | | **tooltip** | _Function_ | [<sup>1</sup>](#1) | Custom HTML content to render in the tooltip on mouseenter. | <span id="1"></span> ```js defaultTooltip(d) { return ` <div class="gantt-tooltip-id">${d[this.yAxisProp]}</div> <div class="gantt-tooltip-values"> <span>${d[this.xAxisProp]}:</span> <span>${d[this.fromProp].toLocaleDateString()} - ${d[this.toProp].toLocaleDateString()}</span> </div> `; } ``` ### Gantt examples If your data array have the expected keys, you can simply do: ```js import { Gantt } from "gobierto-vizzs" const chart = document.body const data = [ { "id": "id nobis possimus incidunt dolorum", "group": "Lebanon", "phase": "Step 1", "from": "2020-01-01", "to": "2020-03-01", }, { "id": "adipisci fugiat quidem alias molestiae", "phase": "Step 2", "group": "Lebanon", "from": "2020-03-01", "to": "2020-06-01", }, ... ] const gantt = new Gantt(chart, data) ``` But if not, you can easily parse them using the options setup: ```js import { BeeSwarm } from "gobierto-vizzs" const chart = document.body const data = [ { "start_date": "2020-10-26T13:04:51.746Z", "end_date": "2020-12-26T13:04:51.746Z", "amount": 8600, "category": "Mayotte", "event": "#1", "title": 0 }, { "start_date": "2021-04-03", "end_date": "2021-04-03", "amount": 169, "category": "Mayotte", "event": "#2", "title": 1 }, ... ] const gantt = new Gantt(chart, data, { from: "start_date", to: "end_date", x: "event", y: "category", id: "title" }) ``` Set a custom callback when clicking into a leaf (a node with no children) ```js const gantt = new Gantt(chart, data, { onClick: (event, datum) => /* custom function */ }) ``` In order to render the chart locale-sensitive stuff, enforce the graph language (List of available [locales](https://unpkg.com/browse/d3-time-format/locale/)) ```js const gantt = new Gantt(chart, data, { locale: "it-IT" }) ``` ## BarChartStacked ```js import { BarChartStacked } from "gobierto-vizzs" const barChartStacked = new BarChartStacked(chart, data, options) // ...update data barChartStacked.setData(newData) ``` **chart** _(HTMLElement)_: DOM node where put the visualization **data** _(Array)_: Elements to display **options** _(Object)_: To custom the defaults presets. Optional. All properties come with setters, that is, once you have the object you can change any property using `setPROP(VALUE)`, i.e. `setX("prop")`, `setMargin({ left: 30 })`, `setOnClick(() => {})` etc... | name | type | default | description | |---|---|---|---| | **x** | _String_ | "phase" | Property name of the categories along the X-axis | | **y** | _String_ | "group" | Property name of the groups along the Y-axis. Legend will be depicted by these values | | **count** | _String_ | - | Property name of a numeric value to sum Y-axis groups. If not specified, it uses the length of each group | | **ratio** | _String_ | "absolute|percentage" | Display the bars as percentage. Implies full-height. | | **showLegend** | _Boolean_ | false | Show the legend. | | **sortStack** | _Boolean_ | false | Sort the legend. | | **orientationLegend** | _String_ | "left" | Positioning of legends, supports left and right. | | **xTickFormat** | _Function_ | - | Function to format ticks from X-axis. | | **yTickFormat** | _Function_ | - | Function to format ticks from Y-axis. | | **xTickValues** | _Array_ | - | Elements with a tick for the X-axis. | | **yTickValues** | _Array_ | - | Elements with a tick for the Y-axis. | | **categories** | _Array_ | - | Set the X-axis categories manually. | | **series** | _Array_ | - | Set the Y-axis series manually. | | **margin** | _Object_ | `{ top: 30, bottom: 0, left: 0, right: 0 }` | Set the margin around the chart. You can pass the properties you want. | | **onClick** | _Function_ | - | Rect click callback handler. It receives the `event` and the `datum`. | | **locale** | _String_ | `window.navigator.language` | 4-letters specification of the locale. | | **tooltip** | _Function_ | [<sup>1</sup>](#1) | Custom HTML content to render in the tooltip on mouseenter. | <span id="1"></span> ```js defaultTooltip(d) { const tooltipContent = Array.from(d.data[1]).map(([key, values]) => { const agg = values.reduce((acc, item) => acc + item[this.countProp], 0) return ` <div class="tooltip-barchart-stacked-grid"> <span style="background-color: ${this.scaleColor(key)}" class="tooltip-barchart-stacked-grid-key-color"></span> <span class="tooltip-barchart-stacked-grid-key">${key}:</span> <span class="tooltip-barchart-stacked-grid-value">${agg}</span> </div>` }); return ` <span class="tooltip-barchart-stacked-title">${this.xTickFormat(d.data[0])}</span> ${tooltipContent.join("")} `; } ``` ### BarChartStacked examples ```js import { BarChartStacked } from "gobierto-vizzs" const chart = document.body const data = [ { "year": "2010", "month": "enero", "value":"44.6132", }, { "year": "2010", "month":"febrero", "value":"7.2782", }, ... ] const bar_chart_stacked = new BarChartStacked(chart, data, { x: "year", y: "month", count: "value" }) ``` Set a custom callback when clicking into a leaf (a node with no children) ```js const bar_chart_stacked = new BarChartStacked(chart, data, { onClick: (event, datum) => /* custom function */ }) ``` In order to render the chart locale-sensitive stuff, enforce the graph language (List of available [locales](https://unpkg.com/browse/d3-time-format/locale/)) ```js const bar_chart_stacked = new BarChartStacked(chart, data, { locale: "it-IT" }) ``` ## BarChartSplit ```js import { BarChartSplit } from "gobierto-vizzs" const bar_chart_split = new BarChartSplit(chart, data, options) // ...update data bar_chart_split.setData(newData) ``` **chart** _(HTMLElement)_: DOM node where put the visualization **data** _(Array)_: Elements to display **options** _(Object)_: To custom the defaults presets. Optional. All properties come with setters, that is, once you have the object you can change any property using `setPROP(VALUE)`, i.e. `setX("prop")`, `setMargin({ left: 30 })`, `setOnClick(() => {})` etc... | name | type | default | description | |---|---|---|---| | **x** | _String_ | "phase" | Property name of the categories along the X-axis. Legend will be depicted by these values | | **y** | _String_ | Property name of the categories along the Y-axis. | | **count** | _String_ | Property name of the width of the bars. Quantitative value. | | **margin** | _Object_ | `{ top: 30, bottom: 0, left: 0, right: 0 }` | Set the margin around the chart. You can pass the properties you want. | | **moveLabels** | _Boolean_ | false | Shows the values of the bars on the left. | | **yTickFormat** | _Function_ | - | Function to format ticks from Y-axis. | | **yTickValues** | _Array_ | - | Elements with a tick for the Y-axis. | | **categories** | _Array_ | - | Set the Y-axis categories manually. | | **locale** | _String_ | `window.navigator.language` | 4-letters specification of the locale. | ### BarChartStacked examples ```js import { BarChartSplit } from "gobierto-vizzs" const chart = document.body const data = [ { "amount": 67, "category": "Spain", "group": "Toyota" }, { "amount": 45, "category": "Spain", "group": "Seat" }, { "amount": 56, "category": "Spain", "group": "Renault" }, { "amount": 13, "category": "France", "group": "Toyota" }, { "amount": 68, "category": "France", "group": "Seat" }, { "amount": 35, "category": "France", "group": "Renault" }, { "amount": 87, "category": "Germany", "group": "Toyota" }, { "amount": 90, "category": "Germany", "group": "Seat" }, { "amount": 39, "category": "Germany", "group": "Renault" }, ... ] const bar_chart_split = new BarChartSplit(chart, data, { x: "category", y: "group", count: "amount" }) ``` ## Helpers ### toJSON Convenience method to transform a CSV text into a JSON structure, assuming the CSV separator is a comma `,` ```js import { toJSON } from "gobierto-vizzs" const data = toJSON(CSV_STRING) ``` You can use a different separator as well ```js import { toJSON } from "gobierto-vizzs" const data = toJSON(CSV_STRING, ";") ``` ## Styling All charts uses CSS custom variables to define the palette, you may overwrite them: ```css :root { --gv-color-1: #008e9c; --gv-color-2: #12365b; --gv-color-3: #ff776d; --gv-color-4: #f8b205; --gv-color-5: #a6cee3; --gv-color-6: #1f78b4; --gv-color-7: #b2df8a; --gv-color-8: #33a02c; --gv-color-9: #fb9a99; --gv-color-10: #e31a1c; --gv-color-11: #fdbf6f; --gv-color-12: #ff7f00; } ``` ## Development You can try the demos, running the examples: ```sh cd examples npm install npm start ```