react-heat-map

repository·main·Indexed 42 days ago

https://github.com/uiwjs/react-heat-map

A lightweight, SVG-based React component for rendering calendar heatmaps to visualize time series data, similar to the GitHub contribution graph. Version 2.3.4 supports customizable colors, styles, and data representation via props like panelColors, rectRender, and legendRender.

Tokens
6.1K
Snippets
26
Records
27
Agent score
53%

What's inside react-heat-map

  1. Set HeatMap Colors

    main

    You can customize the color scheme of the heatmap using the panelColors prop and the style prop.

    Using an Object for panelColors

    Provide an object where keys are specific count thresholds and values are the colors for those levels.

    Using an Array for panelColors

    Provide an array of colors. The component will automatically distribute these colors dynamically based on the maximum value in your data.

    Styling

    You can use the style prop to pass CSS variables like --rhm-rect-active to control the active rectangle color.

    // Example with Object mapping
    <HeatMap
      value={value}
      panelColors={{
        0: '#f4decd',
        7: '#e4b293',
        14: '#d48462',
        21: '#c2533a',
        28: '#ad001d',
        35: '#6c0012'
      }}
      style={{ color: '#ad001d', '--rhm-rect-active': 'red' }}
    />
    
    // Example with Dynamic Array mapping
    <HeatMap
      value={value}
      panelColors={['#f4decd', '#e4b293', '#d48462', '#c2533a', '#ad001d', '#6c0012']}
      style={{ color: '#ad001d', '--rhm-rect-active': 'red' }}
    />
  2. Show or hide the HeatMap legend

    main

    The legend visibility is controlled by the legendCellSize prop. Setting legendCellSize to 0 will hide the legend.

    <HeatMap
      width={600}
      value={value}
      legendCellSize={0} // Set to 0 to hide
      startDate={new Date('2016/01/01')}
    />
  3. Basic Usage of HeatMap

    main

    To use the HeatMap component, provide a value array containing objects with date and count.

    Important Date Format Note: Use the YYYY/MM/DD format (e.g., 2016/01/11) to ensure compatibility with Safari.

    Props used in this example:

    • value: Array of { date: string, count: number, content?: string }.
    • weekLabels: Array of strings for day labels.
    • startDate: A Date object defining the beginning of the heatmap.
    • width: (Optional) The width of the heatmap.
    import React from 'react';
    import HeatMap from '@uiw/react-heat-map';
    
    const value = [
      { date: '2016/01/11', count: 2 },
      { date: '2016/01/12', count: 20 },
      { date: '2016/01/13', count: 10 },
      ...[...Array(17)].map((_, idx) => ({
        date: `2016/02/${idx + 10}`, count: idx, content: ''
      })),
      { date: '2016/04/11', count: 2 },
      { date: '2016/05/01', count: 5 },
      { date: '2016/05/02', count: 5 },
      { date: '2016/05/04', count: 11 },
    ];
    
    const Demo = () => {
      return (
        <div>
          <HeatMap
            value={value}
            weekLabels={['', 'Mon', '', 'Wed', '', 'Fri', '']}
            startDate={new Date('2016/01/01')}
          />
        </div>
      )
    };
    
    export default Demo;
  4. Add tooltips to HeatMap cells using rectRender

    main

    To add interactive elements like tooltips to individual cells, use the rectRender prop. This prop provides access to the cell's data (e.g., count) and SVG properties. You can wrap the returned <rect /> element with a tooltip component (like @uiw/react-tooltip).

    <HeatMap
      value={value}
      width={600}
      startDate={new Date('2016/01/01')}
      rectRender={(props, data) => {
        return (
          <Tooltip placement="top" content={`count: ${data.count || 0}`}>
            <rect {...props} />
          </Tooltip>
        );
      }}
    />
  5. Implement cell selection logic

    main

    You can implement selection behavior by using rectRender to intercept click events and modify the opacity of the rectangles based on whether their date matches a selected state.

    const [selected, setSelected] = useState('');
    
    <HeatMap
      width={600}
      value={value}
      startDate={new Date('2016/01/01')}
      rectRender={(props, data) => {
        if (selected !== '') {
          props.opacity = data.date === selected ? 1 : 0.45;
        }
        return (
          <rect {...props} onClick={() => {
            setSelected(data.date === selected ? '' : data.date);
          }} />
        );
      }}
    />
  6. Customize rectangle styles with rectProps and legendRender

    main

    You can customize the appearance of the grid rectangles (e.g., adding border radius) using the rectProps property. To customize the legend cells, use the legendRender property to provide a custom render function.

    Example of setting a border radius (rx) for both the grid rectangles and the legend cells:

    <HeatMap
      value={value}
      width={600}
      style={{ '--rhm-rect': '#b9b9b9' }}
      startDate={new Date('2016/01/01')}
      legendRender={(props) => <rect {...props} y={props.y + 10} rx={range} />}
      rectProps={{
        rx: range
      }}
    />
  7. Configure color scales with panelColors

    main

    The panelColors prop controls the color gradient of the heat map. It accepts two formats:

    1. An array of strings: Colors are mapped to the data intensity (count) based on the maximum count in the dataset.
    2. A Record<number, string>: Explicitly maps specific count values to specific colors.

    Default colors use CSS variables: var(--rhm-rect, #EBEDF0).

    // Using an array (gradient style)
    <SVG panelColors={['#f7fbff', '#6baed6', '#08306b']} />
    
    // Using a record (explicit mapping)
    <SVG panelColors={{ 0: '#eee', 10: '#ff0000' }} />
  8. Reference: HeatMap Props

    main

    The following properties are available for the HeatMap component:

    | 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>` \| `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` | -
  9. Use the LabelsMonth component

    main

    The LabelsMonth component is used to render month labels within a heat map. It calculates the appropriate positions for month text based on the heat map's grid structure (columns, rect size, and spacing).

    Props

    PropTypeDefaultDescription
    monthLabelsfalse | string[][]An array of month name strings. If false, labels are not rendered.
    rectSizenumber0The size of the rectangles in the heat map.
    spacenumber0The spacing between rectangles.
    leftPadnumber0The left padding of the heat map container.
    colNumnumber0The total number of columns in the heat map.
    rectYnumber15The Y-coordinate where the month labels are rendered.
    startDateDateRequiredThe start date of the heat map range.
    endDateDateundefinedThe end date of the heat map range.
    ...React.SVGProps<SVGTextElement>-Standard SVG text element attributes.

    Note: startDate is required for the component to calculate date offsets correctly.

    import { LabelsMonth } from '@uiw/react-heat-map';
    
    // Example usage within an SVG context
    <LabelsMonth
      monthLabels={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']}
      rectSize={15}
      space={2}
      leftPad={10}
      colNum={52}
      startDate={new Date('2023-01-01')}
    />
  10. Format heat map data with formatData

    main

    The formatData function transforms an array of heat map data items into a record object keyed by date strings. This is useful for normalizing input data where dates might be in various formats. Each entry in the resulting object uses the format YYYY/M/D as its key. If a date cannot be parsed, that item is skipped.

    import { formatData } from './utils';
    
    const rawData = [
      { date: '2023-01-01', value: 10 },
      { date: new Date(2023, 0, 2), value: 20 }
    ];
    
    const formatted = formatData(rawData);
    // Result: { '2023/1/1': { date: '2023/1/1', value: 10 }, '2023/1/2': { date: '2023/1/2', value: 20 } }
  11. Parse date strings or objects with parseDate

    main

    The parseDate function converts a string or Date object into a valid Date instance. It supports:

    • Date objects (returns a new copy).
    • Date strings in YYYY-MM-DD or YYYY/MM/DD format.
    • Standard ISO date strings via the Date constructor.

    Returns null if the input is an invalid date or an unparseable string.

    import { parseDate } from './utils';
    
    parseDate('2023-05-20'); // Returns Date object
    parseDate(new Date());   // Returns copy of Date
    parseDate('invalid');    // Returns null