Skip to content

Commit

Permalink
[Chart] Sort Feature (#29)
Browse files Browse the repository at this point in the history
* preserve order for categorical data
* y-axis min val is 0 unless specified
#29
  • Loading branch information
meowcodes authored May 4, 2020
1 parent aa5956f commit fb16f48
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 16 deletions.
3 changes: 3 additions & 0 deletions datahub/config/datadoc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ cell_types:
scale: ''
min: 0
max: 0
sort:
idx: 0
asc: true
y_axis:
label: ''
scale: ''
Expand Down
1 change: 1 addition & 0 deletions datahub/webapp/components/AppAdmin/AppAdmin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
flex-grow: 1;
text-align: left;
overflow-y: hidden;
overflow-x: hidden;
.AdminForm-button-box {
display: flex;
justify-content: center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ export const DataDocChartCell: React.FunctionComponent<IProps> = ({
formatSeriesCol,
formatValueCols,
aggSeries,
sortIndex,
sortAsc,
xAxisIdx,
} = getDataTransformationOptions(meta);

return transformData(
Expand All @@ -138,7 +141,10 @@ export const DataDocChartCell: React.FunctionComponent<IProps> = ({
formatAggCol,
formatSeriesCol,
formatValueCols,
aggSeries
aggSeries,
sortIndex,
sortAsc,
xAxisIdx
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import { Level, LevelItem } from 'ui/Level/Level';
import { SimpleReactSelect } from 'ui/SimpleReactSelect/SimpleReactSelect';
import { getDefaultScaleType } from 'lib/chart/chart-utils';
import { NumberField } from 'ui/FormikField/NumberField';
import { CheckboxField } from 'ui/FormikField/CheckboxField';
import { ReactSelectField } from 'ui/FormikField/ReactSelectField';
import { FormWrapper } from 'ui/Form/FormWrapper';
import { SimpleField } from 'ui/FormikField/SimpleField';
Expand Down Expand Up @@ -109,7 +108,10 @@ const DataDocChartComposerComponent: React.FunctionComponent<
values.formatAggCol,
values.formatSeriesCol,
values.formatValueCols,
values.aggSeries
values.aggSeries,
values.sortIndex,
values.sortAsc,
values.xIndex
)
: null;
}, [
Expand All @@ -121,6 +123,9 @@ const DataDocChartComposerComponent: React.FunctionComponent<
values.formatValueCols,
values.aggType,
values.aggSeries,
values.sortIndex,
values.sortAsc,
values.xIndex,
]);

// getting redux state
Expand Down Expand Up @@ -619,10 +624,40 @@ const DataDocChartComposerComponent: React.FunctionComponent<
);
}

const sortDOM = (
<>
<FormSectionHeader>Sort</FormSectionHeader>
<SimpleField
stacked
type="react-select"
options={xAxisOptions}
name="sortIndex"
label="Sort Index"
onChange={(val) => {
setFieldValue('sortIndex', val);
if (val != null) {
setTableTab('transformed');
}
}}
/>
<SimpleField
stacked
type="react-select"
options={[
{ value: true, label: 'Ascending' },
{ value: false, label: 'Descending' },
]}
name="sortAsc"
label="Sort Direction"
/>
</>
);

const chartTabDOM = (
<>
{chartOptionsDOM}
{axesDOM}
{sortDOM}
</>
);

Expand Down Expand Up @@ -722,7 +757,7 @@ const DataDocChartComposerComponent: React.FunctionComponent<
let dataDOM: JSX.Element;
let dataSwitch: JSX.Element;
if (chartData && showTable) {
if (values.aggregate || values.switch) {
if (values.aggregate || values.switch || values.sortIndex != null) {
dataSwitch = (
<div className="toggleTableDataSwitch">
<Tabs
Expand Down Expand Up @@ -757,7 +792,6 @@ const DataDocChartComposerComponent: React.FunctionComponent<
<LevelItem>{dataSwitch}</LevelItem>
<LevelItem>{hideTableButtonDOM}</LevelItem>
</Level>

{dataDOM}
</div>
);
Expand Down Expand Up @@ -877,12 +911,18 @@ function formValsToMeta(vals: IChartFormValues, meta: IDataChartCellMeta) {
for (const [field, val] of Object.entries(vals.xAxis)) {
draft.chart.x_axis[field] = val;
}
draft.chart.y_axis.stack = vals.stack;
if (vals.sortIndex != null) {
draft.chart.x_axis.sort = {
idx: vals.sortIndex,
asc: vals.sortAsc,
};
}

// Y Axes
for (const [field, val] of Object.entries(vals.yAxis)) {
draft.chart.y_axis[field] = val;
}
draft.chart.y_axis.stack = vals.stack;

const seriesObj = {};
if (vals.hiddenSeries.length) {
Expand Down
6 changes: 6 additions & 0 deletions datahub/webapp/const/dataDocChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export interface IChartAxisMeta {

export interface IChartXAxisMeta extends IChartAxisMeta {
col_idx: number;
sort?: {
idx: number;
asc: boolean;
};
}

export interface IChartYAxisMeta extends IChartAxisMeta {
Expand Down Expand Up @@ -144,6 +148,8 @@ export interface IChartFormValues {

xAxis: IChartAxisMeta;
xIndex: number;
sortIndex: number | undefined;
sortAsc: boolean;
yAxis: IChartAxisMeta;
stack: boolean;
hiddenSeries: number[];
Expand Down
2 changes: 1 addition & 1 deletion datahub/webapp/lib/chart/chart-data-processing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function processChartJSData(

const xAxisIdx = chartMeta.x_axis.col_idx;
const seriesNames: string[] = data[0];
const dataRows = sortTable(data.slice(1), xAxisIdx);
const dataRows = data.slice(1);

// hide hidden series
const hiddenSeriesIndices = new Set();
Expand Down
46 changes: 40 additions & 6 deletions datahub/webapp/lib/chart/chart-data-transformation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { cloneDeep, range } from 'lodash';
import { ChartDataAggType } from 'const/dataDocChart';
import { sortTable, getValueDataType } from './chart-utils';

const emptyCellValue = 'No Value';

Expand Down Expand Up @@ -227,6 +228,27 @@ function aggregateData(
return aggregatedData;
}

export function sortTableWithDefaultIdx(
data: any[][],
idx: number,
ascending: boolean,
xIdx: number
) {
if (idx != null) {
// if idx is provided then call sortTable as is
return sortTable(data, idx, ascending);
} else {
// if idx is not provided then default idx to the xIndex of the table
// only sort if the column type for that index is either 'date' 'datetime' or 'number'
const valType = getValueDataType(data[0][xIdx]);
if (valType === 'string' || valType === null) {
return data;
} else {
return sortTable(data, xIdx, ascending);
}
}
}

export function transformData(
data: any[][],
isAggregate: boolean = false,
Expand All @@ -236,16 +258,16 @@ export function transformData(
formatValueCols: number[] = [2],
aggSeries: {
[seriesIdx: number]: ChartDataAggType;
} = {}
} = {},
// tslint:disable-next-line: no-unnecessary-initializer
sortIdx: number = undefined,
sortAsc: boolean = true,
xAxisIdx: number = 0
) {
if (data?.length < 2) {
return null;
}

if (!isAggregate && !isSwitch) {
return data;
}

let transformedData = cloneDeep(data);

if (isAggregate) {
Expand All @@ -258,9 +280,21 @@ export function transformData(
);
}

if (transformedData == null) {
return null;
}

if (isSwitch) {
transformedData = switchData(transformedData);
}

return transformedData;
return [
transformedData[0],
...sortTableWithDefaultIdx(
transformedData.slice(1),
sortIdx,
sortAsc,
xAxisIdx
),
];
}
11 changes: 11 additions & 0 deletions datahub/webapp/lib/chart/chart-meta-processing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ export function getDataTransformationOptions(meta: IDataChartCellMeta) {
switch: Boolean(transformations.switch),
aggSeries,
aggType,
sortIndex: meta.chart.x_axis.sort?.idx,
sortAsc: meta.chart.x_axis.sort?.asc ?? true,
xAxisIdx: meta.chart.x_axis.col_idx,
};
}

Expand Down Expand Up @@ -106,6 +109,8 @@ export function mapMetaToFormVals(
// axes
xAxis: getAxisOptions(meta.chart.x_axis),
xIndex: meta.chart.x_axis.col_idx,
sortIndex: meta.chart.x_axis.sort?.idx,
sortAsc: meta.chart.x_axis.sort?.asc ?? true,

yAxis: getAxisOptions(meta.chart.y_axis),
stack: Boolean(meta.chart.y_axis.stack),
Expand Down Expand Up @@ -299,6 +304,12 @@ function computeScaleOptions(
...axis.ticks,
min: axisMeta.min,
};
} else {
// default min to 0 unless specified
axis.ticks = {
...axis.ticks,
min: 0,
};
}
}

Expand Down
12 changes: 9 additions & 3 deletions datahub/webapp/lib/chart/chart-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ export function getDefaultScaleType(value: any): ChartScaleType {

export function sortTable(
tableRows: any[][],
columnIndex: number = 0
columnIndex: number = 0,
ascending: boolean = true
): any[][] {
// Check if string are numbers, if so use number sort
// otherwise use default sort
Expand All @@ -57,10 +58,15 @@ export function sortTable(
return tableRows;
}

const reverseMultiplier = ascending ? 1 : -1;

if (!isNaN(tableRows[0][columnIndex] as number)) {
return tableRows.sort(
(a, b) => a[columnIndex] - b[columnIndex]
(a, b) => (a[columnIndex] - b[columnIndex]) * reverseMultiplier
) as any[];
}
return tableRows.sort((a, b) => (a[columnIndex] > b[columnIndex] ? 1 : -1));

return tableRows.sort(
(a, b) => (a[columnIndex] > b[columnIndex] ? 1 : -1) * reverseMultiplier
);
}

0 comments on commit fb16f48

Please sign in to comment.