Skip to content

Commit

Permalink
Improve styles and edges resolution (plotly#465)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marc-Andre-Rivet committed Jun 13, 2019
1 parent 90ac7b6 commit 92e78bb
Show file tree
Hide file tree
Showing 17 changed files with 470 additions and 510 deletions.
26 changes: 25 additions & 1 deletion packages/dash-table/src/core/math/matrixZipMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@ import * as R from 'ramda';

type Matrix<T> = T[][];

export const shallowClone: <T>(
m: Matrix<T>
) => Matrix<T> = R.map(row => row.slice(0));

export const traverse2 = <T1, T2, TR>(
a1: T1[],
a2: T2[],
fn: (d1: T1, d2: T2, i1: number, i2: number) => TR
) => R.addIndex<T1>(R.forEach)((d1, i1) =>
R.addIndex<T2>(R.forEach)((d2, i2) =>
fn(d1, d2, i1, i2),
a2),
a1);

export const traverseMap2 = <T1, T2, TR>(
a1: T1[],
a2: T2[],
fn: (d1: T1, d2: T2, i1: number, i2: number) => TR
): Matrix<TR> => R.addIndex<T1, TR[]>(R.map)((d1, i1) =>
R.addIndex<T2, TR>(R.map)((d2, i2) =>
fn(d1, d2, i1, i2),
a2),
a1);

export function matrixMap<T1, TR>(
m1: Matrix<T1>,
cb: (d1: T1, i: number, j: number) => TR
Expand Down Expand Up @@ -102,7 +126,7 @@ export function matrixMapN<TR>(
[
ijValue,
m1[i][j],
...matrices.map(m => m ? m[i][j] : undefined)
...matrices.map(m => m ? m[i][j] : undefined)
]
),
iRow
Expand Down
89 changes: 69 additions & 20 deletions packages/dash-table/src/dash-table/components/CellFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import { ICellFactoryProps } from 'dash-table/components/Table/props';
import derivedCellWrappers from 'dash-table/derived/cell/wrappers';
import derivedCellContents from 'dash-table/derived/cell/contents';
import derivedCellOperations from 'dash-table/derived/cell/operations';
import derivedCellStyles, { derivedDataOpStyles } from 'dash-table/derived/cell/wrapperStyles';
import { derivedDataOpStyles, derivedDataStyles, derivedPartialDataStyles } from 'dash-table/derived/cell/wrapperStyles';
import derivedDropdowns from 'dash-table/derived/cell/dropdowns';
import { derivedRelevantCellStyles } from 'dash-table/derived/style';
import { IEdgesMatrices } from 'dash-table/derived/edges/type';
import { memoizeOne } from 'core/memoizer';
import memoizerCache from 'core/cache/memoizer';

export default class CellFactory {

Expand All @@ -25,7 +26,8 @@ export default class CellFactory {
private readonly cellContents = derivedCellContents(propsFn),
private readonly cellDropdowns = derivedDropdowns(),
private readonly cellOperations = derivedCellOperations(),
private readonly cellStyles = derivedCellStyles(),
private readonly dataPartialStyles = derivedPartialDataStyles(),
private readonly dataStyles = derivedDataStyles(),
private readonly dataOpStyles = derivedDataOpStyles(),
private readonly cellWrappers = derivedCellWrappers(propsFn),
private readonly relevantStyles = derivedRelevantCellStyles()
Expand Down Expand Up @@ -59,10 +61,15 @@ export default class CellFactory {
style_data_conditional
);

const cellStyles = this.cellStyles(
const partialCellStyles = this.dataPartialStyles(
columns,
relevantStyles,
virtualized.data,
virtualized.offset
);

const cellStyles = this.dataStyles(
partialCellStyles,
virtualized.offset,
selected_cells
);
Expand Down Expand Up @@ -93,15 +100,29 @@ export default class CellFactory {
setProps
);

const cellWrappers = this.cellWrappers(
active_cell,
const partialCellWrappers = this.cellWrappers.partialGet(
columns,
virtualized.data,
virtualized.offset
);

const cellWrappers = this.cellWrappers.get(
partialCellWrappers,
virtualized.offset,
active_cell,
selected_cells
);

const cellContents = this.cellContents(
const partialCellContents = this.cellContents.partialGet(
columns,
virtualized.data,
virtualized.offset,
!!is_focused,
dropdowns
);

const cellContents = this.cellContents.get(
partialCellContents,
active_cell,
columns,
virtualized.data,
Expand Down Expand Up @@ -138,22 +159,52 @@ export default class CellFactory {
(o, c) => o.length ? o.concat(c) : c
));

getDataOpCell = memoizerCache<[number, number]>()((
operation: JSX.Element,
style: CSSProperties | undefined,
borderBottom: any,
borderLeft: any,
borderRight: any,
borderTop: any
) => {
return React.cloneElement(operation, {
style: R.mergeAll([
{ borderBottom, borderLeft, borderRight, borderTop },
style,
operation.props.style
])
});
});

getDataOpCells = memoizeOne((
ops: JSX.Element[][],
styles: (CSSProperties | undefined)[][],
edges: IEdgesMatrices | undefined
) => matrixMap2(
ops,
styles,
(o, s, i, j) => React.cloneElement(o, {
style: R.mergeAll([
edges && edges.getStyle(i, j),
s,
o.props.style
])
})
(o, s, i, j) => {
const edge = edges && edges.getStyle(i, j);

return this.getDataOpCell.get(i, j)(o, s, edge && edge.borderBottom, edge && edge.borderLeft, edge && edge.borderRight, edge && edge.borderTop);
}
));

getDataCell = memoizerCache<[number, number]>()((
wrapper: JSX.Element,
content: JSX.Element | undefined,
style: CSSProperties | undefined,
borderBottom: any,
borderLeft: any,
borderRight: any,
borderTop: any
) => {
return React.cloneElement(wrapper, {
children: [content],
style: R.merge(style, { borderBottom, borderLeft, borderRight, borderTop })
});
});

getDataCells = memoizeOne((
wrappers: JSX.Element[][],
contents: JSX.Element[][],
Expand All @@ -163,12 +214,10 @@ export default class CellFactory {
wrappers,
styles,
contents,
(w, s, c, i, j) => React.cloneElement(w, {
children: [c],
style: R.mergeAll([
s,
edges && edges.getStyle(i, j)
])
})
(w, s, c, i, j) => {
const edge = edges && edges.getStyle(i, j);

return this.getDataCell.get(i, j)(w, c, s, edge && edge.borderBottom, edge && edge.borderLeft, edge && edge.borderRight, edge && edge.borderTop);
}
));
}
39 changes: 37 additions & 2 deletions packages/dash-table/src/dash-table/conditional/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { ColumnId, Datum, ColumnType } from 'dash-table/components/Table/props';
import * as R from 'ramda';

import { ColumnId, Datum, ColumnType, IVisibleColumn } from 'dash-table/components/Table/props';
import { QuerySyntaxTree } from 'dash-table/syntax-tree';
import { IConvertedStyle } from 'dash-table/derived/style';

export interface IConditionalElement {
filter_query?: string;
Expand Down Expand Up @@ -82,4 +85,36 @@ export function ifEditable(condition: IEditableElement | undefined, isEditable:
return true;
}
return isEditable === condition.column_editable;
}
}

export type Filter<T> = (s: T[]) => T[];

export const matchesDataCell = (datum: Datum, i: number, column: IVisibleColumn): Filter<IConvertedStyle> => R.filter<IConvertedStyle>((style =>
style.matchesRow(i) &&
style.matchesColumn(column) &&
style.matchesFilter(datum)
));

export const matchesFilterCell = (column: IVisibleColumn): Filter<IConvertedStyle> => R.filter<IConvertedStyle>((style =>
style.matchesColumn(column)
));

export const matchesHeaderCell = (i: number, column: IVisibleColumn): Filter<IConvertedStyle> => R.filter<IConvertedStyle>((style =>
style.matchesRow(i) &&
style.matchesColumn(column)
));

export const matchesDataOpCell = (datum: Datum, i: number): Filter<IConvertedStyle> => R.filter<IConvertedStyle>((style =>
!style.checksColumn() &&
style.matchesRow(i) &&
style.matchesFilter(datum)
));

export const getFilterOpStyles: Filter<IConvertedStyle> = R.filter<IConvertedStyle>((style =>
!style.checksColumn()
));

export const getHeaderOpStyles = (i: number): Filter<IConvertedStyle> => R.filter<IConvertedStyle>((style =>
style.matchesRow(i) &&
!style.checksColumn()
));
Loading

0 comments on commit 92e78bb

Please sign in to comment.