gobierto-vizzs
Version:
Shared data visualizations for Gobierto projects
653 lines (553 loc) • 20.5 kB
Markdown
# 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>
<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(" / ");
}
```
<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
```