Skip to content

Commit 33dfc5f

Browse files
committed
Basic color range works
1 parent 46cf10c commit 33dfc5f

File tree

7 files changed

+100
-16
lines changed

7 files changed

+100
-16
lines changed

__fixtures__/ColorScale.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ import { createFixture } from "react-cosmos";
22
import Spreadsheet, {
33
createEmptyMatrix
44
} from "../src/SpreadsheetStateProvider";
5-
import ColorScaleDataViewer from "../src/ColorScaleDataViewer";
5+
import createColorScaleDataViewer from "../src/ColorScaleDataViewer";
66
import "./index.css";
77

88
const initialData = createEmptyMatrix(4, 4);
99

1010
for (let i = 0; i < 4; i++) {
1111
initialData[i][0] = {
12-
DataViewer: ColorScaleDataViewer,
12+
DataViewer: createColorScaleDataViewer({
13+
minPoint: { type: "maximum", color: "#57BB8A" },
14+
maxPoint: { type: "minimum", color: "#FFFFFF" }
15+
}),
1316
value: i + 1
1417
};
1518
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"classnames": "^2.2.6",
2424
"clipboard-polyfill": "^2.4.7",
2525
"fbjs": "^1.0.0",
26+
"gradstop": "^2.2.3",
2627
"hot-formula-parser": "^3.0.0",
2728
"unistore": "^3.4.1"
2829
},

src/ColorScaleDataViewer.js

Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,101 @@
11
// @flow
22

33
import React from "react";
4+
import { connect } from "unistore/react";
5+
import gradstop from "gradstop";
46
import DataViewer from "./DataViewer";
57
import type { Props as DataViewerProps } from "./DataViewer";
6-
import { connect } from "unistore/react";
78

89
type ColorScalePoint =
910
| { color: string, type: "number", value: number }
1011
| { color: string, type: "percent", value: number }
1112
| { color: string, type: "percentile", value: number };
1213

14+
type MinPoint = ColorScalePoint | { type: "minimum", color: string };
15+
type MidPoint = ColorScalePoint | null;
16+
type MaxPoint = ColorScalePoint | { type: "maximum", color: string };
17+
1318
type Props = DataViewerProps & {
14-
columnMaxValue: ColorScalePoint | { type: "minimum", color: string },
15-
columnMinValue: ColorScalePoint | { type: "maximum", color: string },
16-
maxPoint: {}
19+
columnMaxValue: number,
20+
columnMinValue: number,
21+
columnSize: number,
22+
minPoint: ColorScalePoint | { type: "minimum", color: string },
23+
midPoint: ColorScalePoint,
24+
maxPoint: ColorScalePoint | { type: "maximum", color: string }
25+
};
26+
27+
const resolveColor = (props: Props): ?string => {
28+
const {
29+
columnMaxValue,
30+
columnMinValue,
31+
minPoint,
32+
midPoint,
33+
maxPoint,
34+
columnSize,
35+
cell
36+
} = props;
37+
if (!cell || !cell.value) {
38+
return null;
39+
}
40+
const { value } = cell;
41+
/** @todo handle midPoint */
42+
const gradient = gradstop({
43+
stops: columnSize,
44+
inputFormat: "hex",
45+
colorArray: midPoint
46+
? [minPoint.color, midPoint.color, maxPoint.color]
47+
: [minPoint.color, maxPoint.color]
48+
});
49+
const relativeValue =
50+
(value - columnMinValue) / (columnMaxValue - columnMinValue);
51+
const index = Math.floor(relativeValue * (columnSize - 1));
52+
return gradient[index];
1753
};
1854

1955
const ColorScaleDataViewer = (props: Props) => {
20-
console.log(props.cell.value, props.columnMaxValue, props.columnMinValue);
21-
return <DataViewer {...props} />;
56+
const color = resolveColor(props);
57+
return (
58+
<div style={{ backgroundColor: color }}>
59+
<DataViewer {...props} />
60+
</div>
61+
);
2262
};
2363

2464
const mapStateToProps = (state, props) => {
25-
let columnMaxValue: number = 0;
26-
let columnMinValue: number = 0;
65+
let columnMaxValue: number;
66+
let columnMinValue: number;
2767
for (const row of state.data) {
2868
const cell = row[props.column];
29-
columnMaxValue = Math.max(cell.value, columnMaxValue);
30-
columnMinValue = Math.min(cell.value, columnMinValue);
69+
const value = cell && cell.value;
70+
if (!value) {
71+
continue;
72+
}
73+
columnMaxValue = columnMaxValue ? Math.max(value, columnMaxValue) : value;
74+
columnMinValue = columnMinValue ? Math.min(value, columnMinValue) : value;
3175
}
32-
return { columnMaxValue, columnMinValue };
76+
return { columnMaxValue, columnMinValue, columnSize: state.data.length };
77+
};
78+
79+
const createColorScaleDataViewer = ({
80+
minPoint,
81+
maxPoint,
82+
midPoint = null
83+
}: {
84+
minPoint: MinPoint,
85+
maxPoint: MaxPoint,
86+
midPoint: MidPoint
87+
}) => {
88+
const BoundScaleDataViewer = props => {
89+
return (
90+
<ColorScaleDataViewer
91+
{...props}
92+
minPoint={minPoint}
93+
midPoint={midPoint}
94+
maxPoint={maxPoint}
95+
/>
96+
);
97+
};
98+
return connect(mapStateToProps)(BoundScaleDataViewer);
3399
};
34100

35-
export default connect(mapStateToProps)(ColorScaleDataViewer);
101+
export default createColorScaleDataViewer;

src/DataViewer.css

Whitespace-only changes.

src/DataViewer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React from "react";
44
import type { ComponentType, Node } from "react";
55
import type { Parser as FormulaParser } from "hot-formula-parser";
66
import * as Types from "./types";
7+
import './DataViewer.css';
78

89
type Cell = {
910
component?: ComponentType<{
@@ -33,7 +34,7 @@ const DataViewer = ({ getValue, cell, column, row, formulaParser }: Props) => {
3334
const { result, error } = formulaParser.parse(rawValue.slice(1));
3435
return error || toView(result);
3536
}
36-
return toView(rawValue);
37+
return <div className="DataViewer">{toView(rawValue)}</div>;
3738
};
3839

3940
export default DataViewer;

src/Spreadsheet.css

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,21 @@
3232
outline: none;
3333
}
3434

35+
.Spreadsheet td {
36+
padding: 0;
37+
}
38+
39+
.Spreadsheet .DataViewer,
40+
.Spreadsheet th {
41+
padding: 4px;
42+
}
43+
3544
.Spreadsheet td,
3645
.Spreadsheet th {
3746
min-width: 6em;
3847
min-height: 1.9em;
3948
height: 1.9em;
4049
max-height: 1.9em;
41-
padding: 4px;
4250
border: 1px solid rgb(231, 231, 231);
4351
overflow: hidden;
4452
word-break: keep-all;

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4148,6 +4148,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
41484148
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
41494149
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
41504150

4151+
gradstop@^2.2.3:
4152+
version "2.2.3"
4153+
resolved "https://registry.yarnpkg.com/gradstop/-/gradstop-2.2.3.tgz#b60922677d31cef479587f976f97f43222e80a5a"
4154+
integrity sha512-omtiHZCI/vykWcXNDYdrHhe7VUnnZvya94wAHRLI8ciDkAviXYrT+pwP7ybYqK7uwYir59auBCY5ggwBlVSmsg==
4155+
41514156
"growl@~> 1.10.0":
41524157
version "1.10.5"
41534158
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"

0 commit comments

Comments
 (0)