Skip to content

Commit

Permalink
feat: support auto color generation for panelColors array. #132
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Nov 8, 2024
1 parent 3578b49 commit 4d46dbf
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 27 deletions.
70 changes: 50 additions & 20 deletions core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ import HeatMap from '@uiw/react-heat-map';
const value = [
{ date: '2016/01/11', count:2 },
{ date: '2016/04/12', count:2 },
{ date: '2016/05/01', count:5 },
{ date: '2016/05/01', count:17 },
{ date: '2016/05/02', count:5 },
{ date: '2016/05/03', count:1 },
{ date: '2016/05/03', count:27 },
{ date: '2016/05/04', count:11 },
{ date: '2016/05/08', count:32 },
];
Expand All @@ -88,18 +88,48 @@ const Demo = () => {
startDate={new Date('2016/01/01')}
panelColors={{
0: '#f4decd',
2: '#e4b293',
4: '#d48462',
10: '#c2533a',
20: '#ad001d',
30: '#000',
7: '#e4b293',
14: '#d48462',
21: '#c2533a',
28: '#ad001d',
35: '#6c0012'
}}
/>
)
};
export default Demo
```

Dynamic color based on maximum value

```jsx mdx:preview
import React from 'react';
import HeatMap from '@uiw/react-heat-map';

const value = [
{ date: '2016/01/11', count:2 },
{ date: '2016/04/12', count:2 },
{ date: '2016/05/01', count:17 },
{ date: '2016/05/02', count:5 },
{ date: '2016/05/03', count:27 },
{ date: '2016/05/04', count:11 },
{ date: '2016/05/08', count:32 },
];

const Demo = () => {
return (
<HeatMap
value={value}
width={600}
style={{ color: '#ad001d', '--rhm-rect-active': 'red' }}
startDate={new Date('2016/01/01')}
panelColors={['#f4decd', '#e4b293', '#d48462', '#c2533a', '#ad001d', '#6c0012']}
/>
)
};
export default Demo
```

## Set Rect Style

Set the radius of the rect.
Expand Down Expand Up @@ -271,19 +301,19 @@ export default Demo

| Property | Description | Type | Default |
| ---- | ---- | ---- | ---- |
| value | Data to be displayed, **required** | Array | `[]` |
| rectSize | Grid size | number | `11` |
| legendCellSize | Size of the legend cells, in pixel. Value equal to `0` hide legend. | number | `11` |
| startDate | Start date | Date | `new Date()` |
| endDate | End date | Date | - |
| space | Interval between grid sizes | number | `2`
| monthPlacement | position of month labels | `'top' | 'bottom'` | `top`
| rectProps | Grid node attribute settings | `React.SVGProps<SVGRectElement>` | `2` |
| weekLabels | Week display | string[] | `['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']`
| monthLabels | Month display | string[] | `['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']`
| panelColors | Backgroud color of active colors | `Record<number, string>` | `{ 0: '#EBEDF0', 8: '#7BC96F', 4: '#C6E48B', 12: '#239A3B', 32: '#196127' }`
| rectRender | Single `day` block re-render | `<E = SVGRectElement>(data: E & { key: number }, valueItem: HeatMapValue & { date: string, column: number, row: number, index: number }) => React.ReactElement` | - |
| legendRender | Single `legend` block re-render | `(props: React.SVGProps<SVGRectElement>) => React.ReactNode` | - |
| `value` | Data to be displayed, **required** | Array | `[]` |
| `rectSize` | Grid size | number | `11` |
| `legendCellSize` | Size of the legend cells, in pixel. Value equal to `0` hide legend. | number | `11` |
| `startDate` | Start date | Date | `new Date()` |
| `endDate` | End date | Date | - |
| `space` | Interval between grid sizes | number | `2`
| `monthPlacement` | position of month labels | `'top' | 'bottom'` | `top`
| `rectProps` | Grid node attribute settings | `React.SVGProps<SVGRectElement>` | `2` |
| `weekLabels` | Week display | string[] | `['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']`
| `monthLabels` | Month display | string[] | `['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']`
| `panelColors` | Backgroud color of active colors | `Record<number, string>` | `['var(--rhm-rect, #EBEDF0)','#C6E48B','#7BC96F', '#239A3B', '#196127']`
| `rectRender` | Single `day` block re-render | `<E = SVGRectElement>(data: E & { key: number }, valueItem: HeatMapValue & { date: string, column: number, row: number, index: number }) => React.ReactElement` | - |
| `legendRender` | Single `legend` block re-render | `(props: React.SVGProps<SVGRectElement>) => React.ReactNode` | - |

## Development

Expand Down
14 changes: 9 additions & 5 deletions core/src/SVG.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { CSSProperties, useEffect, useMemo, useState } from 'react';
import { LabelsWeek } from './LabelsWeek';
import { LabelsMonth } from './LabelsMonth';
import { RectProps } from './Rect';
import { isValidDate, oneDayTime } from './utils';
import { isValidDate, oneDayTime, convertPanelColors } from './utils';
import Legend, { LegendProps } from './Legend';
import { Day } from './Day';

Expand Down Expand Up @@ -33,7 +33,7 @@ export interface SVGProps extends React.SVGProps<SVGSVGElement> {
monthLabels?: string[] | false;
/** position of month labels @default `top` */
monthPlacement?: 'top' | 'bottom';
panelColors?: Record<number, string>;
panelColors?: Record<number, string> | string[];
}

export default function SVG(props: SVGProps) {
Expand All @@ -50,10 +50,14 @@ export default function SVG(props: SVGProps) {
value = [],
weekLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
monthLabels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
panelColors = { 0: 'var(--rhm-rect, #EBEDF0)', 8: '#7BC96F', 4: '#C6E48B', 12: '#239A3B', 32: '#196127' },
panelColors = ['var(--rhm-rect, #EBEDF0)','#C6E48B','#7BC96F', '#239A3B', '#196127'],
style,
...other
} = props || {};

const maxCount = Math.max(...value.map(item => item.count), 0);
const panelColorsObject = Array.isArray(panelColors) ? convertPanelColors(panelColors, maxCount) : panelColors;
console.log("panelColorsObject", panelColorsObject)
const [gridNum, setGridNum] = useState(0);
const [leftPad, setLeftPad] = useState(!!weekLabels ? 28 : 5);

Expand Down Expand Up @@ -95,7 +99,7 @@ export default function SVG(props: SVGProps) {
{legendCellSize !== 0 && (
<Legend
legendRender={legendRender}
panelColors={panelColors}
panelColors={panelColorsObject}
rectSize={rectSize}
rectY={legendTopPad}
legendCellSize={legendCellSize}
Expand All @@ -122,7 +126,7 @@ export default function SVG(props: SVGProps) {
rectProps={rectProps}
rectSize={rectSize}
rectRender={rectRender}
panelColors={panelColors}
panelColors={panelColorsObject}
value={value}
space={space}
/>
Expand Down
9 changes: 9 additions & 0 deletions core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,12 @@ export function existColor(num: number = 0, nums: number[], panelColors: Record<
}
return color;
}

export const convertPanelColors = (colors: string[], maxCount: number): Record<number, string> => {
const step = Math.ceil(maxCount / (colors.length - 1));
const panelColors: Record<number, string> = {};
colors.forEach((color, index) => {
panelColors[index * step] = color;
});
return panelColors;
};
4 changes: 2 additions & 2 deletions www/src/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ export default function Example() {
setSelectDate((e.target as any).dataset.date);
},
}}
legendRender={(props) => <rect {...props} rx={!enableCircle ? 0 : 5} />}
legendRender={(props) => <rect {...props} key={props.key} rx={!enableCircle ? 0 : 5} />}
rectRender={(props, data) => {
// if (!data.count) return <rect {...props} />;
return (
<Tooltip placement="top" content={`count: ${data.count || 0}`}>
<Tooltip placement="top" key={data.index} content={`count: ${data.count || 0}`}>
<rect {...props} />
</Tooltip>
);
Expand Down

0 comments on commit 4d46dbf

Please sign in to comment.