Skip to content

Commit

Permalink
Fix values in array column and use correct labels (#211)
Browse files Browse the repository at this point in the history
* add `heatmap` to renderer

* add property `labels` and assign `years`

in order to avoid labels `Column 0`, ...

* use `getRawNumbers()` instead of `getLabels`

and use `getNumberFormat()` instead of `DEFAULT_FORMATTER`

* set `raw` to true to get the correct numbers

* set `style.left` to 0 if `leftWhisker` is negative

* use `getRawValue()` instead of `getValues()`

in order to retrieve the correct values

* add the property `labels` to `BooleanColumn`

* use correct labels in `UpSetCellRenderer`

* use `getRawNumbers()` instead of `getNumbers()`

in order to retrieve the right values

* remove `=` from comparision

* adapt `whiskers.style.left`

if the summary visualization is rendered, the originally used
value is assigned, otherwise it is set to 0 in order to avoid
misplacing

* remove multiplication with `width` for `outliers`

in order to avoid displaying them outside the column

* revert changes for outliers

* adapt styling of outliers

if they are placed outside the column

* revert changes for outliers

because they affect the boxplot

* rename variable

Co-Authored-By: Holger Stitz <holger.stitz@datavisyn.io>

* rename  variable

* set default value for `raw` as `true`

instead of setting the flag in the function

* add boxplot example

* revert deprecated solution for boxplot calc

* split `renderDOMBoxPlot()'

- create `renderItemDOMBoxPlot()` and
`renderSummaryDOMBoxPlot()'
- add `scaleLinear` for `summaryRenderer' because the
calculations base on a range from 0 to 1 and without the
mapping, the wrong values are used

* Moved comments to corresponding datasets

* Correct some expected boxplot values

The calculated and visualized boxplot values by LineUp are matching with the expected. I checked the values using this page: https://goodcalculators.com/box-plot-maker/

* Fix NumberColumnBuilder for linear mapping

Before the `mapping()` returned `undefined` incase of a linear mapping. Now it returns the builder instance.

* Set boxplot renderer and add inverted mapping

* remove `renderSummaryDOMBoxPlot' and scaleLinear

fix problem with labels and inverted data by setting the raw
flag in `createSummary` and change the function according
to `createGroup`; use `mappedSummary` and `rawSummary`

* revert setting default value for `raw`

* remove unused `!` from variable `data.outlier`

* Revert some code and code formatting

* Revert to col.getLabels()

* Fix tslint

* Revert getRawNumbers() in HistogramCellRenderer

* Revert label in UpSetCellRenderer

The UpSet renderer is mainly used for categorical or set columns. Categorical arrays is a corner case. So it seems like that the category generation might be wrong but imo the UpSet renderer should be just based on categories.
  • Loading branch information
dvvanessastoiber authored and sgratzl committed Dec 18, 2019
1 parent 8f6010d commit 16df0a0
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 10 deletions.
108 changes: 108 additions & 0 deletions demo/boxplot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html>

<head lang="en">
<meta charset="UTF-8">
<title>LineUp Boxplot Test</title>

<link href="./LineUpJS.css" rel="stylesheet">
<link href="./demo.css" rel="stylesheet">
<!--source of data-->
<link href="https://courses.lumenlearning.com/introstats1/chapter/box-plots/">
<link href="http://www.real-statistics.com/descriptive-statistics/box-plots-with-outliers/">
</head>

<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="./LineUpJS.js"></script>

<script>
window.onload = function () {
const arr = [];

/*
* expected values for data1:
* min = 59
* q1 = 64.75
* q2/median = 66
* q3 = 70
* max = 77
* mean = 67.175
*
*/
const data1 = [59, 60, 61, 62, 62, 63, 63, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 67, 67, 68, 68, 69, 70, 70, 70, 70, 70, 71, 71, 72, 72, 73, 74, 74, 75, 77];

/*
* expected values for data2:
* min = 32
* q1 = 56
* q2/median = 74.5
* q3 = 81.75
* max = 99
* mean = 69.4
*/
const data2 = [99, 56, 78, 55.5, 32, 90, 80, 81, 56, 59, 45, 77, 84.5, 84, 70, 72, 68, 32, 79, 90];

/*
* expected values for data3:
* min = 25.5
* q1 = 78
* q2/median = 81
* q3 = 88.75
* max = 98
* mean = 79.0455
*/
const data3 = [98, 78, 68, 83, 81, 89, 88, 76, 65, 45, 98, 90, 80, 84.5, 85, 79, 78, 98, 90, 79, 81, 25.5];

/*
* expected values for dataWithOutlier:
* min = 300
* q1 = 485
* q2/median = 705
* q3 = 825
* max = 1850
* mean = 756
*/
const dataWithOutlier = [840, 940, 780, 650, 720, 430, 1850, 300, 360, 690];

for (let i = 0; i < data1.length; ++i) {
arr.push({
a: data1[i],
b: data2[i],
c: data3[i],
d: dataWithOutlier[i],
cat: 'A'
})
}

const builder = LineUpJS.builder(arr)
.deriveColors()
.column(LineUpJS.buildCategoricalColumn('cat'))

.column(LineUpJS.buildNumberColumn('a').label('A').renderer('number', 'boxplot', 'boxplot'))
.column(LineUpJS.buildNumberColumn('a').label('A inverted').mapping('linear', [Math.min(...data1), Math.max(...data1)], [1, 0]).renderer('number', 'boxplot', 'boxplot'))

.column(LineUpJS.buildNumberColumn('b').label('B').renderer('number', 'boxplot', 'boxplot'))
.column(LineUpJS.buildNumberColumn('b').label('B inverted').mapping('linear', [Math.min(...data2), Math.max(...data2)], [1, 0]).renderer('number', 'boxplot', 'boxplot'))

.column(LineUpJS.buildNumberColumn('c').renderer('number', 'boxplot', 'boxplot'))
.column(LineUpJS.buildNumberColumn('c').label('C inverted').mapping('linear', [Math.min(...data3), Math.max(...data3)], [1, 0]).renderer('number', 'boxplot', 'boxplot'))

.column(LineUpJS.buildNumberColumn('d').renderer('number', 'boxplot', 'boxplot'))
.column(LineUpJS.buildNumberColumn('d').label('D inverted').mapping('linear', [Math.min(...dataWithOutlier), Math.max(...dataWithOutlier)], [1, 0]).renderer('number', 'boxplot', 'boxplot'));

const ranking = LineUpJS.buildRanking()
.supportTypes()
.allColumns() // add all columns
.groupBy('cat');

builder
.ranking(ranking);

builder.buildTaggle(document.body);
};
</script>

</body>

</html>
8 changes: 5 additions & 3 deletions demo/multivalue.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@
// {label: 'Region', type: 'categorical', column: 'region', categories: Array.from(new Set(data.map((d) => d.region)))},
// {label: 'PI Region', type: 'categorical', column: 'piregion', categories: Array.from(new Set(data.map((d) => d.piregion)))},
].concat(...groups.slice(0, 1).map((group, i) => {
return ['boxplot', 'threshold', 'sparkline', 'numbers', 'verticalbar', 'table'].map((renderer) => ({
return ['boxplot', 'threshold', 'sparkline', 'numbers', 'verticalbar', 'table', 'heatmap'].map((renderer) => ({
label: group,
type: 'numbers',
dataLength: years.length,
renderer,
column: group,
domain: d3.extent([].concat(...data.map((d) => d[group])))
domain: d3.extent([].concat(...data.map((d) => d[group]))),
labels: years
}));
}));

Expand All @@ -46,7 +47,8 @@
type: 'booleans',
column: groups[0],
dataLength: years.length,
accessor: (row) => (row.v[groups[0]] || []).map((d) => d >= 0)
accessor: (row) => (row.v[groups[0]] || []).map((d) => d >= 0),
labels: years
});

const p = new LineUpJS.LocalDataProvider(data, desc);
Expand Down
2 changes: 1 addition & 1 deletion src/builder/column/NumberColumnBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default class NumberColumnBuilder extends ColumnBuilder<INumberColumnDesc
if (range) {
this.desc.range = range;
}
return;
return this;
}
this.desc.map = {
type, domain, range: range || [0, 1]
Expand Down
2 changes: 1 addition & 1 deletion src/model/NumbersColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export default class NumbersColumn extends ArrayColumn<number> implements INumbe
}

getLabels(row: IDataRow) {
return this.getValues(row).map(this.numberFormat);
return this.getRawValue(row).map(this.numberFormat);
}

getSortMethod() {
Expand Down
10 changes: 5 additions & 5 deletions src/renderer/BoxplotCellRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,13 @@ export default class BoxplotCellRenderer implements ICellRendererFactory {
return {
template: isMapAbleColumn(col) ? MAPPED_BOXPLOT : BOXPLOT,
update: (n: HTMLElement) => {
return context.tasks.summaryBoxPlotStats(col).then((data) => {
return tasksAll([context.tasks.summaryBoxPlotStats(col, false), context.tasks.summaryBoxPlotStats(col, true)]).then((data) => {
if (typeof data === 'symbol') {
return;
}
const {summary} = data;
if (summary == null) {
const mappedSummary = data[0].summary;
const rawSummary = data[1].summary;
if (mappedSummary == null) {
n.classList.add(cssClass('missing'));
return;
}
Expand All @@ -127,7 +128,7 @@ export default class BoxplotCellRenderer implements ICellRendererFactory {
Array.from(n.getElementsByTagName('span')).forEach((d: HTMLElement, i) => d.textContent = range[i]);
}

renderDOMBoxPlot(col, n, summary, summary, sort, colorOf(col, null, imposer), isMapAbleColumn(col));
renderDOMBoxPlot(col, n, mappedSummary, rawSummary, sort, colorOf(col, null, imposer), isMapAbleColumn(col));
});
}
};
Expand Down Expand Up @@ -179,7 +180,6 @@ function renderDOMBoxPlot(col: INumberColumn, n: HTMLElement, data: IBoxPlotData
outliers.unshift(p);
whiskers.insertAdjacentElement('afterend', p);
}

data.outlier.forEach((v, i) => {
delete outliers[i].dataset.sort;
outliers[i].style.left = `${round(v * 100, 2)}%`;
Expand Down

0 comments on commit 16df0a0

Please sign in to comment.