@preschen/gen-vis 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +241 -0
- package/dist/gen-vis.js +1127 -0
- package/package.json +31 -21
- package/schema.json +370 -0
- package/dist/index.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# gen-vis
|
|
2
|
+
|
|
3
|
+
A declarative d3 visualisation library: a chart is described by a JSON
|
|
4
|
+
definition (the *def*) and a CSV or JSON data file. Line, point, bar, stacked
|
|
5
|
+
bar and area charts with legends, hover, facets and form elements are
|
|
6
|
+
supported.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
### Standalone script
|
|
11
|
+
|
|
12
|
+
`npm run lib` builds `dist-lib/gen-vis-<version>.js`. It includes Vue, d3 and
|
|
13
|
+
the styles, and provides two global functions:
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<div class="genVis" data-def-file="/data/bev/def.json"></div>
|
|
17
|
+
|
|
18
|
+
<script src="gen-vis-0.5.0.js"></script>
|
|
19
|
+
<script>mountGenVisByClass('genVis')</script>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`mountGenVisByClass(className)` mounts all elements with the class which are
|
|
23
|
+
not mounted yet, `mountGenVisElement(element)` mounts a single element. The
|
|
24
|
+
props are taken from the `data-` attributes, see below.
|
|
25
|
+
|
|
26
|
+
### Vue component
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
import GenVis from '@preschen/gen-vis';
|
|
30
|
+
|
|
31
|
+
app.use(GenVis);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<GenVis def-file="/data/bev/def.json"/>
|
|
36
|
+
<GenVis :def="def" :data="rows"/>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`import { GenVis } from '@preschen/gen-vis'` registers the component
|
|
40
|
+
locally instead. `vue` is a peer dependency, the package uses the Vue of the
|
|
41
|
+
application. `mountGenVisElement` and `mountGenVisByClass` are exported as
|
|
42
|
+
well.
|
|
43
|
+
|
|
44
|
+
### Props
|
|
45
|
+
|
|
46
|
+
| Prop | Attribute | Description |
|
|
47
|
+
|------------|-----------------|-------------|
|
|
48
|
+
| `defFile` | `data-def-file` | url of the definition |
|
|
49
|
+
| `def` | `data-def` | the definition, an object or a JSON string |
|
|
50
|
+
| `data` | `data-data` | the data as rows or a CSV/JSON string, if not given it is loaded from the `data` url of the definition |
|
|
51
|
+
| `debug` | `data-debug` | shows the prepared definition |
|
|
52
|
+
|
|
53
|
+
Every visualisation has its own state, several of them can be used on a page.
|
|
54
|
+
If the props change, the visualisation is loaded again. Errors are shown in
|
|
55
|
+
place of the visualisation.
|
|
56
|
+
|
|
57
|
+
## Definition
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"parent": "../shared/def.json",
|
|
62
|
+
"data": "data.csv",
|
|
63
|
+
"options": { ... },
|
|
64
|
+
"globals": { ... },
|
|
65
|
+
"mapping": { ... },
|
|
66
|
+
"plot": [ ... ],
|
|
67
|
+
"facets": { ... },
|
|
68
|
+
"formElements": [ ... ]
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Relative urls are resolved against the definition referencing them, e.g.
|
|
73
|
+
`data.csv` is next to the definition file. A definition is deep merged into
|
|
74
|
+
its `parent` (and its parent into its own parent), arrays are replaced, not
|
|
75
|
+
merged. The merged definition is checked for common mistakes, e.g. unknown
|
|
76
|
+
plot types, the findings are logged as warnings in the console.
|
|
77
|
+
|
|
78
|
+
The package contains a JSON Schema of the definitions, `schema.json`. With
|
|
79
|
+
`"$schema"` in a definition, editors like VS Code complete and check it:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"$schema": "https://unpkg.com/@preschen/gen-vis/schema.json",
|
|
84
|
+
...
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
or with a local path, e.g. `"./node_modules/@preschen/gen-vis/schema.json"`.
|
|
89
|
+
The schema also allows parts of definitions, e.g. definitions with a `parent`.
|
|
90
|
+
|
|
91
|
+
### `options`
|
|
92
|
+
|
|
93
|
+
`title`, `subtitle`, `footer` (HTML), `width` (the width of the container if
|
|
94
|
+
not given), `height` and `margins` (`{"top", "right", "bottom", "left"}` in
|
|
95
|
+
pixels). `height` can be a prop based on `totalWidth`, see [props](#props-1).
|
|
96
|
+
|
|
97
|
+
`locale` sets the number and date formats of the axes and the hover, also of
|
|
98
|
+
axes without `format`: `de` (the default) or `en`, or an object with a `base`
|
|
99
|
+
locale and the parts which are changed, see d3's
|
|
100
|
+
[formatLocale](https://d3js.org/d3-format#formatLocale) and
|
|
101
|
+
[timeFormatLocale](https://d3js.org/d3-time-format#timeFormatLocale):
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
"locale": { "base": "de", "number": { "currency": ["", " EUR"] } }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`timeTicks` of the object are the tick formats of time axes without `format`,
|
|
108
|
+
by the interval of the date (`millisecond`, `second`, `minute`, `hour`, `day`,
|
|
109
|
+
`week`, `month`, `year`).
|
|
110
|
+
|
|
111
|
+
`fontFamily` sets the font, by default the css variable
|
|
112
|
+
`--gen-vis-font-family` or Century Gothic, so the font of all visualisations of
|
|
113
|
+
a page can be set with css:
|
|
114
|
+
|
|
115
|
+
```css
|
|
116
|
+
.vis { --gen-vis-font-family: Arial, sans-serif; }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### `mapping`
|
|
120
|
+
|
|
121
|
+
Maps columns of the data to named dimensions, the plots and all other parts of
|
|
122
|
+
the definition refer to these names.
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
"y": {
|
|
126
|
+
"column": "value",
|
|
127
|
+
"type": "numeric",
|
|
128
|
+
"stacked": false,
|
|
129
|
+
"scale": { "type": "linear", "orientation": "vertical", "domain": [0, null] },
|
|
130
|
+
"axis": { "position": "left", "ticks": 8, "format": ".1f", "grid": true, "title": { "name": "€/l", "offset": 50 } },
|
|
131
|
+
"hover": { "format": ".2f" }
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
- `type`: `numeric`, `date` or `categorical`. Numeric and date values which
|
|
136
|
+
are missing or invalid are `null`: they are gaps in lines and areas, points
|
|
137
|
+
and bars are not drawn, and they are not shown in the hover. Dates are
|
|
138
|
+
parsed with `Date.parse` or are timestamps.
|
|
139
|
+
- `scale`: `type` is a d3 scale (`linear`, `time`, `log`, `point`, `band`,
|
|
140
|
+
...), continuous scales need a `numeric` or `date` type, `point` and `band`
|
|
141
|
+
a `categorical` one. `orientation` (`horizontal` or `vertical`) places the
|
|
142
|
+
scale on the plot. `domain` fixes the domain, `null` entries are taken from
|
|
143
|
+
the data. `domainRel` (relative to the domain) and `domainAbs` (absolute)
|
|
144
|
+
extend it. `padding` for categorical scales.
|
|
145
|
+
- `axis`: `position` (`top`, `bottom`, `left`, `right`), `ticks`, `values`
|
|
146
|
+
(fixed ticks), `format` (d3 number or time format), `rotate` (the angle of
|
|
147
|
+
the labels in degrees, positive counterclockwise, negative clockwise), `grid`
|
|
148
|
+
(lines at the ticks), `title` (`{"name", "offset"}`) and `padding`.
|
|
149
|
+
- `hover`: the hover shows the values of the vertical axis at the position of
|
|
150
|
+
the mouse. On touch devices it is shown by a tap and stays until a tap
|
|
151
|
+
outside of the plot, horizontal swipes move it, vertical ones scroll the
|
|
152
|
+
page. `format` of the horizontal and vertical axis, it defaults to the
|
|
153
|
+
axis format. For categorical mappings `props` are the columns of the entries,
|
|
154
|
+
`name` by default.
|
|
155
|
+
- `props`: the categories and their props, e.g. colors. `common` props are
|
|
156
|
+
used for all `manual` entries, `name` and `visible` are set by default. Only
|
|
157
|
+
visible categories are shown.
|
|
158
|
+
- `legend`: a toggle for every category, `symbol` draws svg `elements` (with
|
|
159
|
+
props) of the given `size` before the name.
|
|
160
|
+
- `stacked`: stacks the values of a vertical axis, see `stackedBar`.
|
|
161
|
+
|
|
162
|
+
### `plot`
|
|
163
|
+
|
|
164
|
+
A plot or a list of plots, drawn in order:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"type": "svg:path",
|
|
169
|
+
"categories": ["nuts"],
|
|
170
|
+
"props": {
|
|
171
|
+
"stroke": "@color",
|
|
172
|
+
"fill": "none",
|
|
173
|
+
"d": { "x": "@x:scaled", "y": "@y:scaled" },
|
|
174
|
+
"highlight-stroke-width": "@highlight-stroke-width"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
- `type`: `svg:path` (a line per group, `d` with `x` and `y`), `base:area`
|
|
180
|
+
(an area per group, `d` with `x`, `y0` and `y1`), `svg:circle`, `svg:rect`,
|
|
181
|
+
`svg:line`, `svg:text` (an element per row), `bar` (props `cx` and
|
|
182
|
+
`height`, `width` defaults to the step of a categorical scale) and
|
|
183
|
+
`stackedBar` (props `x`, `y` and `width`).
|
|
184
|
+
- `categories`: the rows are grouped by these mappings, the props of their
|
|
185
|
+
categories are available in the plot props.
|
|
186
|
+
- `props`: svg attributes (and `text`). Props starting with `highlight-` are
|
|
187
|
+
used for the elements of the category under the mouse or the legend entry.
|
|
188
|
+
|
|
189
|
+
### Props
|
|
190
|
+
|
|
191
|
+
Most values of a definition can be props:
|
|
192
|
+
|
|
193
|
+
- fixed values, e.g. `3` or `"none"`
|
|
194
|
+
- references `"@name"`: in a plot a column of the row (e.g. `@x`), the scaled
|
|
195
|
+
value (`@x:scaled`, `@x:scaled:0` for the position of 0, `@y:st:e:scaled`
|
|
196
|
+
for the end of a stacked value), a prop of the categories (e.g. `@color`) or
|
|
197
|
+
the size of the plot (`@width`, `@innerWidth`, `@height`, `@innerHeight`)
|
|
198
|
+
- `{"prop": "relative", "ref": "innerWidth", "ratio": 0.01}`: a ratio of a
|
|
199
|
+
reference
|
|
200
|
+
- `{"prop": "steps", "ref": "totalWidth", "steps": [{"cut": 0, "value": 220}, {"cut": 550, "value": 250}]}`:
|
|
201
|
+
the value of the last step with a cut below the reference
|
|
202
|
+
|
|
203
|
+
Objects without `prop` are nested props, e.g. `d` of a path.
|
|
204
|
+
|
|
205
|
+
### `facets`
|
|
206
|
+
|
|
207
|
+
A plot for every category of `dim` (the name of a mapping with `props`), in
|
|
208
|
+
`cols` columns. The mappings listed in `scales` share their scale across all facets.
|
|
209
|
+
`cols` can be a prop based on `totalWidth`, `scales` a reference to `globals`.
|
|
210
|
+
|
|
211
|
+
### `formElements` and `globals`
|
|
212
|
+
|
|
213
|
+
Form elements change `globals`, e.g. the shared scales of the facets. An entry
|
|
214
|
+
with a `mapping` also patches the mappings while it is selected, e.g. to switch
|
|
215
|
+
the column of an axis:
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
"globals": { "column": "value" },
|
|
219
|
+
"formElements": [{
|
|
220
|
+
"id": "column", "name": "Wert", "ref": "column", "type": "switch",
|
|
221
|
+
"values": [
|
|
222
|
+
{ "id": "value", "name": "Wert", "value": "value" },
|
|
223
|
+
{ "id": "share", "name": "Anteil", "value": "share", "mapping": { "y": { "column": "share" } } }
|
|
224
|
+
]
|
|
225
|
+
}]
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Development
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
npm install
|
|
232
|
+
npm run dev # dev server, the definition shown by dev.html is set in src/globals.js
|
|
233
|
+
npm test # unit tests, rendering and schema check of all definitions in data/
|
|
234
|
+
npm run build # es module for bundlers in dist/
|
|
235
|
+
npm run watch # rebuilds dist/ on changes, e.g. for `npm link`
|
|
236
|
+
npm run lib # standalone script in dist-lib/
|
|
237
|
+
npm run deploy # builds and uploads the standalone script
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
`lib.html` shows the embedding with the dev server. The examples in `data/`
|
|
241
|
+
are rendered by the tests, so they have to stay valid.
|