UNPKG

27.8 kBMarkdownView Raw
1LineUp.js: Visual Analysis of Multi-Attribute Rankings
2======================================================
3[![License][bsd-image]][bsd-url] [![NPM version][npm-image]][npm-url] [![CircleCI][ci-image]][ci-url] [![CircleCI][ci-image-dev]][ci-url-dev] <sup>(dev)</sup>
4
5LineUp is an interactive technique designed to create, visualize and explore rankings of items based on a set of heterogeneous attributes.
6
7Key Features
8-----------
9 * scalable (~1M rows)
10 * heterogenous attribute types (string, numerical, categorical, boolean, date)
11 * composite column types (weighted sum, min, max, mean, median, impose, nested, ...)
12 * array (multi value) and map column types (strings, stringMap, numbers, numberMap, ...)
13 * filtering capabilities
14 * hierarchical sorting (sort by more than one sorting criteria)
15 * hierarchical grouping (split rows in multiple separate groups)
16 * group aggregations (show a whole group as a single group row)
17 * numerous visualizations for summaries, cells, and group aggregations
18 * side panel for easy filtering and column management
19 * [React](#react), [Angular](#angular), [Vue.js](#vue), [Polymer](#polymer), [RShiny](#rshiny), [Juypter](#jupyter), [ObservableHQ](#observablehq), and [Power BI](#powerbi) wrapper
20 * [Demo Application](#demo) with CSV import and export capabilities
21 * [API Documentation](#api) based on generated TypeDoc documenation
22
23Usage
24-----
25
26**Installation**
27
28```bash
29npm install --save lineupjs
30```
31
32```html
33<link href="https://unpkg.com/lineupjs/build/LineUpJS.css" rel="stylesheet">
34<script src="https://unpkg.com/lineupjs/build/LineUpJS.js"></script>
35```
36
37**Minimal Usage Example**
38
39```javascript
40// generate some data
41const arr = [];
42const cats = ['c1', 'c2', 'c3'];
43for (let i = 0; i < 100; ++i) {
44 arr.push({
45 a: Math.random() * 10,
46 d: 'Row ' + i,
47 cat: cats[Math.floor(Math.random() * 3)],
48 cat2: cats[Math.floor(Math.random() * 3)]
49 })
50}
51```
52```javascript
53const lineup = LineUpJS.asLineUp(document.body, arr);
54```
55
56[CodePen](https://codepen.io/sgratzl/pen/Ozzbqp)
57
58[![Minimal Result](https://user-images.githubusercontent.com/4129778/34654173-32180ff8-f3f8-11e7-8469-229fa34a65dc.png)](https://codepen.io/sgratzl/pen/Ozzbqp)
59
60
61<a id="advanced_usage_example"></a>
62
63**Advanced Usage Example**
64
65```javascript
66// arr from before
67const builder = LineUpJS.builder(arr);
68
69// manually define columns
70builder
71 .column(LineUpJS.buildStringColumn('d').label('Label').width(100))
72 .column(LineUpJS.buildCategoricalColumn('cat', cats).color('green'))
73 .column(LineUpJS.buildCategoricalColumn('cat2', cats).color('blue'))
74 .column(LineUpJS.buildNumberColumn('a', [0, 10]).color('blue'));
75
76// and two rankings
77const ranking = LineUpJS.buildRanking()
78 .supportTypes()
79 .allColumns() // add all columns
80 .impose('a+cat', 'a', 'cat2'); // create composite column
81 .groupBy('cat')
82 .sortBy('a', 'desc')
83
84
85builder
86 .defaultRanking()
87 .ranking(ranking);
88
89const lineup = builder.build(document.body);
90```
91
92[CodePen](https://codepen.io/sgratzl/pen/vppyML)
93
94[![Advanced Result](https://user-images.githubusercontent.com/4129778/34654174-3235f784-f3f8-11e7-9361-44f5fa068bb9.png)](https://codepen.io/sgratzl/pen/vppyML)
95
96
97Supported Browsers
98------------------
99
100 * Chrome 64+ (best performance)
101 * Firefox 57+
102 * Edge 16+
103
104<a id="demo"></a>
105
106Demo Application
107----------------
108
109A demo application is located at [lineup_app](https://github.com/lineupjs/lineup_app). It support CSV Import, CSV Export, JSON Export, CodePen Export, nad local data management.
110
111The application is deployed at [https://lineup.js.org/app](https://lineup.js.org/app)
112
113[![Screenshot](https://user-images.githubusercontent.com/4129778/36336600-8590a932-1389-11e8-8de0-269079efc37b.png)](https://lineup.js.org/app)
114
115
116<a id="api"></a>
117
118API Documentation
119-----------------
120
121LineUp is implemented in clean TypeScript in an object oriented manner. A fully generated API documentation based on [TypeDoc](http://typedoc.org) is available at https://lineup.js.org/master/docs
122
123LineUp can be build manually or using via the builder design pattern (see [Advanced Usage Example](#advanced_usage_example)). The builder design pattern in the more common way.
124
125### LineUp Builder
126
127The simplest methods to create a new instance are:
128 * [asLineUp](https://lineup.js.org/master/docs/modules/_builder_index_.html#aslineup) returning a ready to use [LineUp](https://lineup.js.org/master/docs/classes/_ui_lineup_.lineup.html) instance
129 ```ts
130 asLineUp(node: HTMLElement, data: any[], ...columns: string[]): LineUp
131 ```
132 * [asTaggle](https://lineup.js.org/master/docs/modules/_builder_index_.html#astaggle) returning a ready to use [Taggle](https://lineup.js.org/master/docs/classes/_ui_taggle_taggle_.taggle.html) instance
133 ```ts
134 asTaggle(node: HTMLElement, data: any[], ...columns: string[]): Taggle
135 ```
136 * [builder](https://lineup.js.org/master/docs/modules/_builder_databuilder_.html#builder) returning a new [DataBuilder](https://lineup.js.org/master/docs/classes/_builder_databuilder_.databuilder.html)
137 ```ts
138 builder(arr: any[]): DataBuilder`
139 ```
140
141The `DataBuilder` allows on the one hand to specify the individual columns more specificly and the creation of custom rankings.
142
143Builder factory functions for creating column descriptions include:
144 * [buildStringColumn](https://lineup.js.org/master/docs/modules/_builder_column_stringcolumnbuilder_.html#buildstringcolumn) returning a new [StringColumnBuilder](https://lineup.js.org/master/docs/classes/_builder_column_stringcolumnbuilder_.stringcolumnbuilder.html)
145 ```ts
146 buildStringColumn(column: string): StringColumnBuilder
147 ```
148 * [buildNumberColumn](https://lineup.js.org/master/docs/modules/_builder_column_numbercolumnbuilder_.html#buildnumbercolumn) returning a new [NumberColumnBuilder](https://lineup.js.org/master/docs/classes/_builder_column_numbercolumnbuilder_.numbercolumnbuilder.html)
149 ```ts
150 buildNumberColumn(column: string, domain?: [number, number]): NumberColumnBuilder
151 ```
152 * [buildCategoricalColumn](https://lineup.js.org/master/docs/modules/_builder_column_categoricalcolumnbuilder_.html#buildcategoricalcolumn) returning a new [CategoricalColumnBuilder](https://lineup.js.org/master/docs/classes/_builder_column_categoricalcolumnbuilder_.categoricalcolumnbuilder.html)
153 ```ts
154 buildCategoricalColumn(column: string, categories?: (string | Partial<ICategory>)[]): CategoricalColumnBuilder
155 ```
156 * [buildHierarchicalColumn](https://lineup.js.org/master/docs/modules/_builder_column_hierarchycolumnbuilder_.html#buildhierarchicalcolumn) returning a new [HierarchyColumnBuilder](https://lineup.js.org/master/docs/classes/_builder_column_hierarchycolumnbuilder_.hierarchycolumnbuilder.html)
157 ```ts
158 buildHierarchicalColumn(column: string, hierarchy?: IPartialCategoryNode): HierarchyColumnBuilder
159 ```
160 * [buildDateColumn](https://lineup.js.org/master/docs/modules/_builder_column_datecolumnbuilder_.html#builddatecolumn) returning a new [DateColumnBuilder](https://lineup.js.org/master/docs/classes/_builder_column_datecolumnbuilder_.datecolumnbuilder.html)
161 ```ts
162 buildDateColumn(column: string): DateColumnBuilder
163 ```
164 * [buildActionsColumn]( https://lineup.js.org/master/docs/modules/_builder_column_actionscolumnbuilder_.html#buildactionscolumn) returning a new [ActionsColumnBuilder](https://lineup.js.org/master/docs/classes/_builder_column_actionscolumnbuilder_.actionscolumnbuilder.html)
165 ```ts
166 buildActionsColumn(): ActionsColumnBuilder
167 ```
168
169In order to build custom rankings within the `DataBuilder` the [buildRanking]( https://lineup.js.org/master/docs/modules/_builder_rankingbuilder_.html#buildranking) returning a new [RankingBuilder](https://lineup.js.org/master/docs/classes/_builder_rankingbuilder_.rankingbuilder.html) is used.
170```ts
171buildRanking(): RankingBuilder
172```
173
174### LineUp classes and manual creation
175
176The relevant classes for creating a LineUp instance manually are [LineUp](https://lineup.js.org/master/docs/classes/_ui_lineup_.lineup.html), [Taggle](https://lineup.js.org/master/docs/classes/_ui_taggle_taggle_.taggle.html), and [LocalDataProvider](https://lineup.js.org/master/docs/classes/_provider_localdataprovider_.localdataprovider.html). A `LocalDataProvider` is an sub class of `ADataProvider` implementing the data model management based on a local JavaScript array. `LineUp` and `Taggle` are the visual interfaces to the `LocalDataProvider`.
177
178The classes can be instantiated either using the factory pattern or via their regular class constructors:
179
180```ts
181createLineUp(container: HTMLElement, data: ADataProvider, config?: Partial<ILineUpOptions>): LineUp
182
183createTaggle(container: HTMLElement, data: ADataProvider, config?: Partial<ITaggleOptions>): Taggle
184
185createLocalDataProvider(data: any[], columns: IColumnDesc[], options?: Partial<ILocalDataProviderOptions>): LocalDataProvider
186```
187```ts
188new LineUp(node: HTMLElement, data: DataProvider, options?: Partial<ILineUpOptions>): LineUp
189new Taggle(node: HTMLElement, data: DataProvider, options?: Partial<ITaggleOptions>): Taggle
190new LocalDataProvider(data: any[], columns?: IColumnDesc[], options?: Partial<ILocalDataProviderOptions & IDataProviderOptions>): LocalDataProvider
191```
192
193Both `LineUp` and `Taggle` are sub classes of [ALineUp](https://lineup.js.org/master/docs/classes/_ui_alineup_.alineup.html). The most important functions of this class include:
194
195 * [`getHighlight(): number`](https://lineup.js.org/master/docs/classes/_ui_alineup_.alineup.html#gethighlight) / [`setHighlight(dataIndex: number): void`](https://lineup.js.org/master/docs/classes/_ui_alineup_.alineup.html#sethighlight)
196 to get and set the highlighted row identified by its index in the data. If none is highlighted `-1` is returned.
197 * [`getSelection(): number[]`](
198https://lineup.js.org/master/docs/classes/_ui_lineup_.lineup.html#getselection) / [`setSelection(dataIndices: number[]): void`](https://lineup.js.org/master/docs/classes/_ui_alineup_.alineup.html#setselection)
199 to get and set the selected rows identified by their indices in the data
200 * [`on(type: string, listener: IEventListener | null): this`](https://lineup.js.org/master/docs/classes/_ui_alineup_.alineup.html#on) to listen to highlight and selection events. LineUp.js event mechanism is based on [d3 dispatch](https://github.com/d3/d3-dispatch), thus instead of and `off` method `null` is passed to disable listening to the event. The following events are sent out:
201 * [`highlightChanged(dataIndex: number): void`](https://lineup.js.org/master/docs/classes/_ui_alineup_.alineup.html#highlightchanged)
202 * [`selectionChanged(dataIndices: number[]): void`](https://lineup.js.org/master/docs/classes/_ui_alineup_.alineup.html#selectionchanged)
203
204
205
206<a id="react"></a>
207
208React Support (LineUp.jsx)
209--------------------------
210
211A [React](https://reactjs.org/) wrapper is located at [lineupjsx](https://github.com/lineupjs/lineupjsx).
212
213
214**Installation**
215
216```bash
217npm install --save lineupjsx
218```
219
220```html
221<link href="https://unpkg.com/lineupjsx/build/LineUpJSx.css" rel="stylesheet">
222<script src="https://unpkg.com/lineupjsx/build/LineUpJSx.js"></script>
223```
224
225**Minimal Usage Example**
226
227```javascript
228// generate some data
229const arr = [];
230const cats = ['c1', 'c2', 'c3'];
231for (let i = 0; i < 100; ++i) {
232 arr.push({
233 a: Math.random() * 10,
234 d: 'Row ' + i,
235 cat: cats[Math.floor(Math.random() * 3)],
236 cat2: cats[Math.floor(Math.random() * 3)]
237 })
238}
239```
240```jsx
241<LineUp data={arr}/>
242```
243
244[CodePen](https://codepen.io/sgratzl/pen/mXEpMP)
245
246Result is same as the builder minimal example
247
248**Advanced Usage Example**
249
250```jsx
251// arr from before
252<LineUp data={arr} defaultRanking>
253 <LineUpStringColumnDesc column="d" label="Label" width={100} />
254 <LineUpCategoricalColumnDesc column="cat" categories={cats} color="green" />
255 <LineUpCategoricalColumnDesc column="cat2" categories={cats} color="blue" />
256 <LineUpNumberColumnDesc column="a" domain={[0, 10]} color="blue" />
257
258 <LineUpRanking groupBy="cat" sortBy="a:desc">
259 <LineUpSupportColumn type="*" />
260 <LineUpColumn column="*" />
261 <LineUpImposeColumn label="a+cat" column="a" categeoricalColumn="cat2" />
262 </LineUpRanking>
263</LineUp>;
264```
265
266[CodePen](https://codepen.io/sgratzl/pen/yvJpWQ)
267
268Result is same as the builder advanced example
269
270
271<a id="angular"></a>
272
273Angular 6 Support (nglineup)
274----------------------------
275
276An [Angular](https://angular.io/) wrapper is located at [nglineup](https://github.com/lineupjs/nglineup).
277
278
279**Installation**
280
281```bash
282npm install --save nglineup
283```
284
285**Minimal Usage Example**
286
287`app.module.ts`:
288```ts
289import { BrowserModule } from '@angular/platform-browser';
290import { NgModule } from '@angular/core';
291import { LineUpModule } from '../lib/lineup.module';
292
293import { AppComponent } from './app.component.1';
294
295@NgModule({
296 declarations: [
297 AppComponent
298 ],
299 imports: [
300 BrowserModule,
301 LineUpModule
302 ],
303 providers: [],
304 bootstrap: [AppComponent]
305})
306export class AppModule { }
307```
308
309`app.component.ts`:
310```ts
311import { Component } from '@angular/core';
312
313@Component({
314 selector: 'app-root',
315 templateUrl: './app.component.html'
316})
317export class AppComponent {
318 readonly data = <any[]>[];
319
320 readonly cats = ['c1', 'c2', 'c3'];
321
322 constructor() {
323 const cats = this.cats;
324 for (let i = 0; i < 100; ++i) {
325 this.data.push({
326 a: Math.random() * 10,
327 d: 'Row ' + i,
328 cat: cats[Math.floor(Math.random() * 3)],
329 cat2: cats[Math.floor(Math.random() * 3)]
330 });
331 }
332 }
333}
334```
335
336`app.component.html`:
337```html
338<lineup-lineup [data]="data"></lineup-lineup>
339```
340
341
342[CodePen](https://codepen.io/sgratzl/pen/QxYgzN)
343
344Result is same as the builder minimal example
345
346
347**Advanced Usage Example**
348
349`app.component.html`:
350```html
351<lineup-lineup [data]="data" [defaultRanking]="true" style="height: 800px;">
352 <lineup-string-column-desc column="d" label="Label" [width]="100"></lineup-string-column-desc>
353 <lineup-categorical-column-desc column="cat" [categories]="cats" color="green"></lineup-categorical-column-desc>
354 <lineup-categorical-column-desc column="cat2" [categories]="cats" color="blue"></lineup-categorical-column-desc>
355 <lineup-number-column-desc column="a" [domain]="[0, 10]" color="blue"></lineup-number-column-desc>
356
357 <lineup-ranking groupBy="cat" sortBy="a:desc">
358 <lineup-support-column type="*"></lineup-support-column>
359 <lineup-column column="*"></lineup-column>
360 <lineup-impose-column label="a+cat" column="a" categoricalColumn="cat2"></lineup-impose-column>
361 </lineup-ranking>
362</lineup-lineup>
363```
364
365
366[CodePen](https://codepen.io/sgratzl/pen/BVMdZL)
367
368Result is same as the builder advanced example
369
370
371<a id="vue"></a>
372
373Vue.js Support (vue-lineup)
374--------------------------
375
376A [Vue.js](https://vuejs.org) wrapper is located at [vue-lineup](https://github.com/lineupjs/vue-lineup).
377
378
379**Installation**
380
381```bash
382npm install --save vue-lineup
383```
384
385**Minimal Usage Example**
386
387```ts
388const cats = ['c1', 'c2', 'c3'];
389const data = [];
390for (let i = 0; i < 100; ++i) {
391 data.push({
392 a: Math.random() * 10,
393 d: 'Row ' + i,
394 cat: cats[Math.floor(Math.random() * 3)],
395 cat2: cats[Math.floor(Math.random() * 3)],
396 });
397}
398
399// enable plugin to register components
400Vue.use(VueLineUp);
401
402const app = new Vue({
403 el: '#app',
404 template: `<LineUp v-bind:data="data" />`,
405 data: {
406 cats,
407 data
408 }
409});
410```
411
412[CodePen](https://codepen.io/sgratzl/pen/pKGmvK)
413
414Result is same as the builder minimal example
415
416
417**Advanced Usage Example**
418
419```ts
420const app = new Vue({
421 el: '#app',
422 template: `<LineUp v-bind:data="data" defaultRanking="true" style="height: 800px">
423 <LineUpStringColumnDesc column="d" label="Label" v-bind:width="100" />
424 <LineUpCategoricalColumnDesc column="cat" v-bind:categories="cats" color="green" />
425 <LineUpCategoricalColumnDesc column="cat2" v-bind:categories="cats" color="blue" />
426 <LineUpNumberColumnDesc column="a" v-bind:domain="[0, 10]" color="blue" />
427 <LineUpRanking groupBy="cat" sortBy="a:desc">
428 <LineUpSupportColumn type="*" />
429 <LineUpColumn column="*" />
430 </LineUpRanking>
431 </LineUp>`,
432 data: {
433 cats,
434 data
435 }
436});
437```
438
439[CodePen](https://codepen.io/sgratzl/pen/vrboWB)
440
441Result is same as the builder advanced example
442
443
444<a id="polymer"></a>
445
446Polymer Support (LineUp-Element)
447--------------------------------
448
449A [Polymer 2.0](https://www.polymer-project.org/) web component wrapper is located at [lineup-element](https://github.com/lineupjs/lineup-element).
450
451
452**Installation**
453
454```bash
455bower install https://github.com/lineupjs/lineup-element
456```
457
458```html
459<link rel="import" href="bower_components/lineup-element/lineup-element.html">
460```
461
462**Minimal Usage Example**
463
464```javascript
465// generate some data
466const arr = [];
467const cats = ['c1', 'c2', 'c3'];
468for (let i = 0; i < 100; ++i) {
469 arr.push({
470 a: Math.random() * 10,
471 d: 'Row ' + i,
472 cat: cats[Math.floor(Math.random() * 3)],
473 cat2: cats[Math.floor(Math.random() * 3)]
474 })
475}
476conat data = { arr, cats };
477```
478```jsx
479<lineup-element data="[[data.arr]]"></lineup-element>
480```
481
482TODO
483[CodePen]()
484
485Result is same as the builder minimal example
486
487**Advanced Usage Example**
488
489```jsx
490// arr from before
491<lineup-element data="[[data.arr]]" side-panel side-panel-collapsed default-ranking="true">
492 <lineup-string-desc column="d" label="Label" width="100" ></lineup-string-desc>
493 <lineup-categorical-desc column="cat" categories="[[cats]]" color="green" ></lineup-categorical-desc>
494 <lineup-categorical-desc column="cat2" categories="[[cats]]" color="blue" ></lineup-categorical-desc>
495 <lineup-number-desc column="a" domain="[0, 10]" color="blue" ></lineup-number-desc>
496 <lineup-ranking group-by="cat" sort-by="a:desc">
497 <lineup-support-column type="*" ></lineup-support-column>
498 <lineup-column column="*" ></lineup-column>
499 </lineup-ranking>
500</lineup-element>
501```
502
503TODO
504[CodePen]()
505
506Result is same as the builder advanced example
507
508
509<a id="rshiny"></a>
510
511R, RShiny, and R Markdown Support
512---------------------------------
513
514A [HTMLWidget](http://www.htmlwidgets.org/) wrapper for R is located at [lineup_htmlwidget](https://github.com/lineupjs/lineup_htmlwidget).
515It can be used within standalone [R Shiny](https://shiny.rstudio.com/) apps or [R Markdown](http://rmarkdown.rstudio.com/) files. Integrated plotting does not work due to an outdated integrated Webkit version in RStudio.
516[Crosstalk](https://rstudio.github.io/crosstalk/) is supported for synching selections and filtering among widgets.
517
518**Installation**
519
520```R
521devtools::install_github("rstudio/crosstalk")
522devtools::install_github("lineupjs/lineup_htmlwidget")
523library(lineupjs)
524```
525
526**Examples**
527
528```R
529lineup(iris)
530```
531
532![iris output](https://user-images.githubusercontent.com/4129778/34919941-fec50232-f96a-11e7-95be-9eefb213e3d6.png)
533
534
535<a id="jupyter"></a>
536
537Jupyter Widget (to be released)
538--------------
539
540A [Jupyter Widget](https://jupyter.org/widgets.html) wrapper for Python is located at [lineup_widget](https://github.com/lineupjs/lineup_widget).
541
542**Installation**
543
544```bash
545pip install -e git+https://github.com/lineupjs/lineup_widget.git#egg=lineup_widget
546jupyter nbextension enable --py [--sys-prefix|--user|--system] lineup_widget
547```
548
549Or, if you use jupyterlab:
550
551```bash
552pip install -e git+https://github.com/lineupjs/lineup_widget.git#egg=lineup_widget
553jupyter labextension install @jupyter-widgets/jupyterlab-manager
554```
555
556**Examples**
557
558[![Launch Binder][binder-image]][binder-url]
559
560[binder-image]: https://camo.githubusercontent.com/70c5b4d050d4019f4f20b170d75679a9316ac5e5/687474703a2f2f6d7962696e6465722e6f72672f62616467652e737667
561[binder-url]: http://mybinder.org/repo/lineupjs/lineup_widget/examples
562
563
564```python
565import lineup_widget
566import pandas as pd
567import numpy as np
568
569df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
570
571w = lineup_widget.LineUpWidget(df)
572w.on_selection_changed(lambda selection: print(selection))
573w
574```
575
576![simple usage](https://user-images.githubusercontent.com/4129778/35321859-7925d3a6-00e8-11e8-9884-bcbc76ae51c9.png)
577
578```python
579from __future__ import print_function
580from ipywidgets import interact, interactive, interact_manual
581
582def selection_changed(selection):
583 return df.iloc[selection]
584
585interact(selection_changed, selection=lineup_widget.LineUpWidget(df));
586```
587
588![interact example](https://user-images.githubusercontent.com/4129778/35321846-6c5b07cc-00e8-11e8-9388-0acb65cbb509.png)
589
590<a id="observablehq"></a>
591
592Observable HQ
593-------------
594
595A [ObservableHQ](https://observablehq.com/) wrapper is located at [lineup-js-observable](https://observablehq.com/@sgratzl/lineup-js-observable-library).
596
597
598```js
599data = {
600 const arr = [];
601 const cats = ['c1', 'c2', 'c3'];
602 for (let i = 0; i < 100; ++i) {
603 arr.push({
604 a: Math.random() * 10,
605 d: 'Row ' + i,
606 cat: cats[Math.floor(Math.random() * 3)],
607 cat2: cats[Math.floor(Math.random() * 3)]
608 })
609 }
610 return arr;
611}
612```
613```js
614import { asLineUp } from '@sgratzl/lineup-js-observable-library'
615```
616```js
617viewof selection = asLineUp(arr)
618```
619
620[ObservableHQ](https://observablehq.com/@sgratzl/lineup-simple-example-with-observable-base)
621
622[![Minimal Result](https://user-images.githubusercontent.com/4129778/75078130-cd276d80-54d2-11ea-9496-0cc685e826ee.png)](https://observablehq.com/@sgratzl/lineup-simple-example-with-observable-base)
623
624
625### Advanced Usage Example
626
627```js
628// arr from before
629viewof selection = {
630 const b = builder(data);
631 b.column(
632 LineUpJS.buildStringColumn('d')
633 .label('Label')
634 .width(100)
635 )
636 .column(LineUpJS.buildCategoricalColumn('cat', cats).color('green'))
637 .column(LineUpJS.buildCategoricalColumn('cat2', cats).color('blue'))
638 .column(LineUpJS.buildNumberColumn('a', [0, 10]).color('blue'));
639
640 // and two rankings
641 const ranking = LineUpJS.buildRanking()
642 .supportTypes()
643 .allColumns() // add all columns
644 .impose('a+cat', 'a', 'cat2') // create composite column
645 .groupBy('cat')
646 .sortBy('a', 'desc');
647
648 b.defaultRanking().ranking(ranking);
649 return b.build();
650}
651```
652
653[ObservableHQ](https://observablehq.com/@sgratzl/lineup-advanced-example)
654
655[![Advanced Result](https://user-images.githubusercontent.com/4129778/75078499-bfbeb300-54d3-11ea-92aa-b9ab0d2af043.png)](https://observablehq.com/@sgratzl/lineup-advanced-example)
656
657
658<a id="powerbi"></a>
659
660PowerBI Custom Visual (under development)
661----------------------------------------
662
663A [PowerBI Visual](https://github.com/Microsoft/PowerBI-Visuals) wrapper is located at [lineup_powerbi](https://github.com/lineupjs/lineup_powerbi).
664
665**Installation**
666
667TODO
668
669**Examples**
670
671TODO
672
673
674API Documentation
675-----------------
676
677See [API documentation](https://lineup.js.org/master/docs) and [Develop API documentation](https://lineup.js.org/develop/docs)
678
679
680Demos
681-----
682
683See [Demos](https://lineup.js.org/master), [Develop Demos](https://lineup.js.org/develop), and [R Demos](https://lineup.js.org/R)
684
685
686Related Publications
687---------------------
688
689**LineUp: Visual Analysis of Multi-Attribute Rankings** [Paper](http://data.caleydo.org/papers/2013_infovis_lineup.pdf) [Paper Website](http://caleydo.org/publications/2013_infovis_lineup/)
690
691Samuel Gratzl, Alexander Lex, Nils Gehlenborg, Hanspeter Pfister, and Marc Streit <br>
692IEEE Transactions on Visualization and Computer Graphics (InfoVis '13), 19(12), pp. 2277–2286, [doi:10.1109/TVCG.2013.173](https://dx.doi.org/10.1109/TVCG.2013.173), 2013.
693
694:trophy: [IEEE VIS](http://ieeevis.org) InfoVis 2013 Best Paper Award
695
696**Taggle: Scalable Visualization of Tabular Data through Aggregation** [Paper Preprint](http://data.caleydo.org/papers/2019_sage_infovis_taggle.pdf) [Paper Website](http://caleydo.org/publications/2019_sage_infovis_taggle/)
697
698Katarina Furmanova, Samuel Gratzl, Holger Stitz, Thomas Zichner, Miroslava Jaresova, Martin Ennemoser, Alexander Lex, and Marc Streit <br>
699Information Visualization, 19(2): 114-136, [doi:10.1177/1473871619878085](https://dx.doi.org/10.1177/1473871619878085), 2019.
700
701Dependencies
702------------
703
704LineUp.js depends on
705 * [LineUpEngine](https://github.com/lineupjs/lineupengine) table rendering engine
706 * [D3](http://d3js.org) utilities: scales, format, dragging
707 * [Popper.js](https://popper.js.org) dialogs
708
709
710**Development Dependencies**
711
712[Webpack](https://webpack.github.io) is used as build tool. LineUp itself is written in [TypeScript](https://www.typescriptlang.org) and [SASS](https://sass-lang.com).
713
714
715Development Environment
716-----------------------
717
718Try the Gitpod online IDE and start coding instantly in your browser.
719
720[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/lineupjs/lineupjs)
721
722Otherwise follow the steps to setup a local development environment.
723
724**Installation**
725
726```bash
727git clone https://github.com/lineupjs/lineupjs.git -b develop
728cd lineupjs
729npm install
730```
731
732**Build distribution packages**
733
734```bash
735npm run build
736```
737
738**Run Linting**
739
740```bash
741npm run lint
742```
743
744**Run Unit Tests**
745
746```bash
747npm test
748```
749
750**Serve integrated webserver**
751
752```bash
753npm start
754```
755
756**Run E2E Tests**
757
758via cypress.io
759
760Variant 1: with prebuilt LineUp
761
762```sh
763npm run compile
764npm run build:prod
765npm run cy:open
766```
767
768Variant 2: with webpack-dev-server
769
770first shell:
771```sh
772npm start
773```
774
775second shell:
776```sh
777npm run cy:start
778```
779
780**Link develop version**
781
782In order to use the library during development in another repository, one need to build and watch the library and produce development typings.
783
784```bash
785ln -s . <target_project>/node_modules/lineupjs
786npm run compile:dev
787npm run watch
788```
789
790The development typings are needed cause during production the are located at `/src`. That causes problems cause during compilation of a dependent project the Typescript compiler will first find the original TypeScript file e.g. `config.ts` before looking for `config.d.ts`, will complain that the library owner should deliver JavaScript files and won't compile the file. Thus the typings have to lie at a different location in this scenario.
791
792Authors
793-------
794
795 * Samuel Gratzl (@sgratzl)
796 * Holger Stitz (@thinkh)
797 * The Caleydo Team (@caleydo)
798 * datavisyn GmbH (@datavisyn)
799
800***
801
802<a href="http://caleydo.org"><img src="https://user-images.githubusercontent.com/4129778/34663868-5455cb76-f459-11e7-95db-f80db24026dc.png" align="left" width="200px" hspace="10" vspace="6"></a>
803This repository was created as part of the **[The Caleydo Project](http://caleydo.org/)**.
804
805[npm-image]: https://badge.fury.io/js/lineupjs.svg
806[npm-url]: https://npmjs.org/package/lineupjs
807[bsd-image]: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
808[bsd-url]: https://opensource.org/licenses/BSD-3-Clause
809[ci-image]: https://circleci.com/gh/lineupjs/lineupjs.svg?style=shield
810[ci-url]: https://circleci.com/gh/lineupjs/lineupjs
811[ci-image-dev]: https://circleci.com/gh/lineupjs/lineupjs/tree/develop.svg?style=shield
812[ci-url-dev]: https://circleci.com/gh/lineupjs/lineupjs/tree/develop
813
814
815