1 | LineUp.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 |
|
5 | LineUp is an interactive technique designed to create, visualize and explore rankings of items based on a set of heterogeneous attributes.
|
6 |
|
7 | Key Features
|
8 | -----------
|
9 | * scalable (~100k 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), 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 |
|
23 | Usage
|
24 | -----
|
25 |
|
26 | **Installation**
|
27 |
|
28 | ```bash
|
29 | npm 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
|
41 | const arr = [];
|
42 | const cats = ['c1', 'c2', 'c3'];
|
43 | for (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
|
53 | const 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
|
67 | const builder = LineUpJS.builder(arr);
|
68 |
|
69 | // manually define columns
|
70 | builder
|
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
|
77 | const 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 |
|
85 | builder
|
86 | .defaultRanking()
|
87 | .ranking(ranking);
|
88 |
|
89 | const 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 |
|
97 | Supported Browsers
|
98 | ------------------
|
99 |
|
100 | * Chrome 64+ (best performance)
|
101 | * Firefox 57+
|
102 | * Edge 16+
|
103 |
|
104 | <a id="demo"></a>
|
105 |
|
106 | Demo Application
|
107 | ----------------
|
108 |
|
109 | A demo application is located at [lineup_app](https://github.com/sgratzl/lineup_app). It support CSV Import, CSV Export, JSON Export, CodePen Export, and Github Gist Export.
|
110 |
|
111 | The 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 |
|
118 | API Documentation
|
119 | -----------------
|
120 |
|
121 | LineUp 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 |
|
123 | LineUp 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 |
|
127 | The 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 |
|
141 | The `DataBuilder` allows on the one hand to specify the individual columns more specificly and the creation of custom rankings.
|
142 |
|
143 | Builder 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 |
|
169 | In 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
|
171 | buildRanking(): RankingBuilder
|
172 | ```
|
173 |
|
174 | ### LineUp classes and manual creation
|
175 |
|
176 | The 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 |
|
178 | The classes can be instantiated either using the factory pattern or via their regular class constructors:
|
179 |
|
180 | ```ts
|
181 | createLineUp(container: HTMLElement, data: ADataProvider, config?: Partial<ILineUpOptions>): LineUp
|
182 |
|
183 | createTaggle(container: HTMLElement, data: ADataProvider, config?: Partial<ITaggleOptions>): Taggle
|
184 |
|
185 | createLocalDataProvider(data: any[], columns: IColumnDesc[], options?: Partial<ILocalDataProviderOptions>): LocalDataProvider
|
186 | ```
|
187 | ```ts
|
188 | new LineUp(node: HTMLElement, data: DataProvider, options?: Partial<ILineUpOptions>): LineUp
|
189 | new Taggle(node: HTMLElement, data: DataProvider, options?: Partial<ITaggleOptions>): Taggle
|
190 | new LocalDataProvider(data: any[], columns?: IColumnDesc[], options?: Partial<ILocalDataProviderOptions & IDataProviderOptions>): LocalDataProvider
|
191 | ```
|
192 |
|
193 | Both `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[]`](
|
198 | https://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 |
|
208 | React Support (LineUp.jsx)
|
209 | --------------------------
|
210 |
|
211 | A [React](https://reactjs.org/) wrapper is located at [lineupjsx](https://github.com/datavisyn/lineupjsx).
|
212 |
|
213 |
|
214 | **Installation**
|
215 |
|
216 | ```bash
|
217 | npm 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
|
229 | const arr = [];
|
230 | const cats = ['c1', 'c2', 'c3'];
|
231 | for (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 |
|
246 | Result 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 |
|
268 | Result is same as the builder advanced example
|
269 |
|
270 |
|
271 | <a id="angular"></a>
|
272 |
|
273 | Angular 6 Support (nglineup)
|
274 | --------------------------
|
275 |
|
276 | An [Angular](https://angular.io/) wrapper is located at [nglineup](https://github.com/datavisyn/nglineup).
|
277 |
|
278 |
|
279 | **Installation**
|
280 |
|
281 | ```bash
|
282 | npm install --save nglineup
|
283 | ```
|
284 |
|
285 | **Minimal Usage Example**
|
286 |
|
287 | `app.module.ts`:
|
288 | ```ts
|
289 | import { BrowserModule } from '@angular/platform-browser';
|
290 | import { NgModule } from '@angular/core';
|
291 | import { LineUpModule } from '../lib/lineup.module';
|
292 |
|
293 | import { 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 | })
|
306 | export class AppModule { }
|
307 | ```
|
308 |
|
309 | `app.component.ts`:
|
310 | ```ts
|
311 | import { Component } from '@angular/core';
|
312 |
|
313 | @Component({
|
314 | selector: 'app-root',
|
315 | templateUrl: './app.component.html'
|
316 | })
|
317 | export 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 |
|
344 | Result 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 |
|
368 | Result is same as the builder advanced example
|
369 |
|
370 |
|
371 | <a id="vue"></a>
|
372 |
|
373 | Vue.js Support (vue-lineup)
|
374 | --------------------------
|
375 |
|
376 | A [Vue.js](https://vuejs.org) wrapper is located at [vue-lineup](https://github.com/datavisyn/vue-lineup).
|
377 |
|
378 |
|
379 | **Installation**
|
380 |
|
381 | ```bash
|
382 | npm install --save vue-lineup
|
383 | ```
|
384 |
|
385 | **Minimal Usage Example**
|
386 |
|
387 | ```ts
|
388 | const cats = ['c1', 'c2', 'c3'];
|
389 | const data = [];
|
390 | for (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
|
400 | Vue.use(VueLineUp);
|
401 |
|
402 | const 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 |
|
414 | Result is same as the builder minimal example
|
415 |
|
416 |
|
417 | **Advanced Usage Example**
|
418 |
|
419 | ```ts
|
420 | const 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 |
|
441 | Result is same as the builder advanced example
|
442 |
|
443 |
|
444 | <a id="polymer"></a>
|
445 |
|
446 | Polymer Support (LineUp-Element)
|
447 | --------------------------------
|
448 |
|
449 | A [Polymer 2.0](https://www.polymer-project.org/) web component wrapper is located at [lineup-element](https://github.com/datavisyn/lineup-element).
|
450 |
|
451 |
|
452 | **Installation**
|
453 |
|
454 | ```bash
|
455 | bower install https://github.com/datavisyn/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
|
466 | const arr = [];
|
467 | const cats = ['c1', 'c2', 'c3'];
|
468 | for (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 | }
|
476 | conat data = { arr, cats };
|
477 | ```
|
478 | ```jsx
|
479 | <lineup-element data="[[data.arr]]"></lineup-element>
|
480 | ```
|
481 |
|
482 | TODO
|
483 | [CodePen]()
|
484 |
|
485 | Result 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 |
|
503 | TODO
|
504 | [CodePen]()
|
505 |
|
506 | Result is same as the builder advanced example
|
507 |
|
508 |
|
509 | <a id="rshiny"></a>
|
510 |
|
511 | R, RShiny, and R Markdown Support
|
512 | ---------------------------------
|
513 |
|
514 | A [HTMLWidget](http://www.htmlwidgets.org/) wrapper for R is located at [lineup_htmlwidget](https://github.com/datavisyn/lineup_htmlwidget).
|
515 | It 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
|
521 | devtools::install_github("rstudio/crosstalk")
|
522 | devtools::install_github("datavisyn/lineup_htmlwidget")
|
523 | library(lineup)
|
524 | ```
|
525 |
|
526 | **Examples**
|
527 |
|
528 | ```R
|
529 | lineup(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 |
|
537 | Jupyter Widget (to be released)
|
538 | --------------
|
539 |
|
540 | A [Jupyter Widget](https://jupyter.org/widgets.html) wrapper for Python is located at [lineup_widget](https://github.com/datavisyn/lineup_widget).
|
541 |
|
542 | **Installation**
|
543 |
|
544 | ```bash
|
545 | pip install -e git+https://github.com/datavisyn/lineup_widget.git#egg=lineup_widget
|
546 | jupyter nbextension enable --py [--sys-prefix|--user|--system] lineup_widget
|
547 | ```
|
548 |
|
549 | Or, if you use jupyterlab:
|
550 |
|
551 | ```bash
|
552 | pip install -e git+https://github.com/datavisyn/lineup_widget.git#egg=lineup_widget
|
553 | jupyter 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/datavisyn/lineup_widget/examples
|
562 |
|
563 |
|
564 | ```python
|
565 | import lineup_widget
|
566 | import pandas as pd
|
567 | import numpy as np
|
568 |
|
569 | df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
|
570 |
|
571 | w = lineup_widget.LineUpWidget(df)
|
572 | w.on_selection_changed(lambda selection: print(selection))
|
573 | w
|
574 | ```
|
575 |
|
576 | ![simple usage](https://user-images.githubusercontent.com/4129778/35321859-7925d3a6-00e8-11e8-9884-bcbc76ae51c9.png)
|
577 |
|
578 | ```python
|
579 | from __future__ import print_function
|
580 | from ipywidgets import interact, interactive, interact_manual
|
581 |
|
582 | def selection_changed(selection):
|
583 | return df.iloc[selection]
|
584 |
|
585 | interact(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 |
|
591 |
|
592 | <a id="powerbi"></a>
|
593 |
|
594 | PowerBI Custom Visual (under development)
|
595 | ----------------------------------------
|
596 |
|
597 | A [PowerBI Visual](https://github.com/Microsoft/PowerBI-Visuals) wrapper is located at [lineup_powerbi](https://github.com/datavisyn/lineup_powerbi).
|
598 |
|
599 | **Installation**
|
600 |
|
601 | TODO
|
602 |
|
603 | **Examples**
|
604 |
|
605 | TODO
|
606 |
|
607 |
|
608 | API Documentation
|
609 | -----------------
|
610 |
|
611 | See [API documentation](https://lineup.js.org/master/docs) and [Develop API documentation](https://lineup.js.org/develop/docs)
|
612 |
|
613 |
|
614 | Demos
|
615 | -----
|
616 |
|
617 | See [Demos](https://lineup.js.org/master), [Develop Demos](https://lineup.js.org/develop), and [R Demos](https://lineup.js.org/R)
|
618 |
|
619 |
|
620 | Related Publications
|
621 | ---------------------
|
622 |
|
623 | **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/)
|
624 |
|
625 | Samuel Gratzl, Alexander Lex, Nils Gehlenborg, Hanspeter Pfister, and Marc Streit <br>
|
626 | IEEE Transactions on Visualization and Computer Graphics (InfoVis '13), 19(12), pp. 2277–2286, doi:10.1109/TVCG.2013.173, 2013.
|
627 |
|
628 | :trophy: [IEEE VIS](http://ieeevis.org) InfoVis 2013 Best Paper Award
|
629 |
|
630 | **Taggle: Scalable Visualization of Tabular Data through Aggregation** [Paper Preprint](http://sci.utah.edu/~vdl/papers/2017_preprint_taggle.pdf) [Paper Website](http://vdl.sci.utah.edu/publications/2017_preprint_taggle/)
|
631 |
|
632 | Katarina Furmanova, Samuel Gratzl, Holger Stitz, Thomas Zichner, Miroslava Jaresova, Martin Ennemoser, Alexander Lex, and Marc Streit <br>
|
633 | arXiv preprint, 2017.
|
634 |
|
635 | Dependencies
|
636 | ------------
|
637 |
|
638 | LineUp.js depends on
|
639 | * [LineUpEngine](https://github.com/sgratzl/lineupengine) table rendering engine
|
640 | * [D3](http://d3js.org) utilities: scales, format, dragging
|
641 | * [Popper.js](https://popper.js.org) dialogs
|
642 |
|
643 |
|
644 | **Development Dependencies**
|
645 |
|
646 | [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).
|
647 |
|
648 |
|
649 | Development Environment
|
650 | -----------------------
|
651 |
|
652 | **Installation**
|
653 |
|
654 | ```bash
|
655 | git clone https://github.com/datavisyn/lineupjs.git -b develop
|
656 | cd lineupjs
|
657 | npm install
|
658 | ```
|
659 |
|
660 | **Build distribution packages**
|
661 |
|
662 | ```bash
|
663 | npm run build
|
664 | ```
|
665 |
|
666 | **Run Linting**
|
667 |
|
668 | ```bash
|
669 | npm run lint
|
670 | ```
|
671 |
|
672 |
|
673 | **Serve integrated webserver**
|
674 |
|
675 | ```bash
|
676 | npm run start
|
677 | ```
|
678 |
|
679 | **Link develop version**
|
680 |
|
681 | In order to use the library during development in another repository, one need to build and watch the library and produce development typings.
|
682 |
|
683 | ```bash
|
684 | ln -s . <target_project>/node_modules/lineupjs
|
685 | npm run compile:dev
|
686 | npm run watch
|
687 | ```
|
688 |
|
689 | The 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.
|
690 |
|
691 | Authors
|
692 | -------
|
693 |
|
694 | * Samuel Gratzl (@sgratzl)
|
695 | * Holger Stitz (@thinkh)
|
696 | * The Caleydo Team (@caleydo)
|
697 | * Datavisyn GmbH (@datavisyn)
|
698 |
|
699 | ***
|
700 |
|
701 | <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>
|
702 | This repository was created as part of the **[The Caleydo Project](http://caleydo.org/)**.
|
703 |
|
704 | [npm-image]: https://badge.fury.io/js/lineupjs.svg
|
705 | [npm-url]: https://npmjs.org/package/lineupjs
|
706 | [bsd-image]: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
|
707 | [bsd-url]: https://opensource.org/licenses/BSD-3-Clause
|
708 | [ci-image]: https://circleci.com/gh/datavisyn/lineupjs.svg?style=shield
|
709 | [ci-url]: https://circleci.com/gh/datavisyn/lineupjs
|
710 | [ci-image-dev]: https://circleci.com/gh/datavisyn/lineupjs/tree/develop.svg?style=shield
|
711 | [ci-url-dev]: https://circleci.com/gh/datavisyn/lineupjs/tree/develop
|
712 |
|
713 |
|
714 |
|