diff --git a/packages/heatmap/src/HeatMap.js b/packages/heatmap/src/HeatMap.js
index b55463e688..1bfa5a9d2e 100644
--- a/packages/heatmap/src/HeatMap.js
+++ b/packages/heatmap/src/HeatMap.js
@@ -63,7 +63,7 @@ const HeatMap = ({
yScale,
offsetX,
offsetY,
- setCurrentCell,
+ setCurrentCellId,
getCellBorderColor,
getLabelTextColor,
} = useHeatMap({
@@ -91,19 +91,19 @@ const HeatMap = ({
const handleCellHover = useCallback(
(cell, event) => {
- setCurrentCell(cell)
+ setCurrentCellId(cell.id)
showTooltipFromEvent(
,
event
)
},
- [setCurrentCell, showTooltipFromEvent, tooltipFormat, tooltip]
+ [setCurrentCellId, showTooltipFromEvent, tooltipFormat, tooltip]
)
const handleCellLeave = useCallback(() => {
- setCurrentCell(null)
+ setCurrentCellId(null)
hideTooltip()
- }, [setCurrentCell, hideTooltip])
+ }, [setCurrentCellId, hideTooltip])
let cellComponent
if (cellShape === 'rect') {
diff --git a/packages/heatmap/src/HeatMapCanvas.js b/packages/heatmap/src/HeatMapCanvas.js
index a3320192ce..a4f5b76a5e 100644
--- a/packages/heatmap/src/HeatMapCanvas.js
+++ b/packages/heatmap/src/HeatMapCanvas.js
@@ -60,26 +60,28 @@ const HeatMapCanvas = ({
partialMargin
)
- const { cells, xScale, yScale, offsetX, offsetY, currentCell, setCurrentCell } = useHeatMap({
- data,
- keys,
- indexBy,
- minValue,
- maxValue,
- width: innerWidth,
- height: innerHeight,
- padding,
- forceSquare,
- sizeVariation,
- colors,
- nanColor,
- cellOpacity,
- cellBorderColor,
- labelTextColor,
- hoverTarget,
- cellHoverOpacity,
- cellHoverOthersOpacity,
- })
+ const { cells, xScale, yScale, offsetX, offsetY, currentCellId, setCurrentCellId } = useHeatMap(
+ {
+ data,
+ keys,
+ indexBy,
+ minValue,
+ maxValue,
+ width: innerWidth,
+ height: innerHeight,
+ padding,
+ forceSquare,
+ sizeVariation,
+ colors,
+ nanColor,
+ cellOpacity,
+ cellBorderColor,
+ labelTextColor,
+ hoverTarget,
+ cellHoverOpacity,
+ cellHoverOthersOpacity,
+ }
+ )
const theme = useTheme()
@@ -145,24 +147,24 @@ const HeatMapCanvas = ({
event => {
const [x, y] = getRelativeCursor(canvasEl.current, event)
- const cell = cells.find(node =>
+ const cell = cells.find(c =>
isCursorInRect(
- node.x + margin.left + offsetX - node.width / 2,
- node.y + margin.top + offsetY - node.height / 2,
- node.width,
- node.height,
+ c.x + margin.left + offsetX - c.width / 2,
+ c.y + margin.top + offsetY - c.height / 2,
+ c.width,
+ c.height,
x,
y
)
)
if (cell !== undefined) {
- setCurrentCell(cell)
+ setCurrentCellId(cell.id)
showTooltipFromEvent(
,
event
)
} else {
- setCurrentCell(null)
+ setCurrentCellId(null)
hideTooltip()
}
},
@@ -172,7 +174,7 @@ const HeatMapCanvas = ({
margin,
offsetX,
offsetY,
- setCurrentCell,
+ setCurrentCellId,
showTooltipFromEvent,
hideTooltip,
tooltip,
@@ -180,17 +182,18 @@ const HeatMapCanvas = ({
)
const handleMouseLeave = useCallback(() => {
- setCurrentCell(null)
+ setCurrentCellId(null)
hideTooltip()
- }, [setCurrentCell, hideTooltip])
+ }, [setCurrentCellId, hideTooltip])
const handleClick = useCallback(
event => {
- if (currentCell === null) return
+ if (currentCellId === null) return
- onClick(currentCell, event)
+ const currentCell = cells.find(cell => cell.id === currentCellId)
+ currentCell && onClick(currentCell, event)
},
- [currentCell, onClick]
+ [cells, currentCellId, onClick]
)
return (
diff --git a/packages/heatmap/src/HeatMapCells.js b/packages/heatmap/src/HeatMapCells.js
index 43c2fdc0ec..f5f36756f7 100644
--- a/packages/heatmap/src/HeatMapCells.js
+++ b/packages/heatmap/src/HeatMapCells.js
@@ -21,7 +21,7 @@ const HeatMapCells = ({
}) => {
return cells.map(cell =>
React.createElement(cellComponent, {
- key: cell.key,
+ key: cell.id,
data: cell,
value: cell.value,
x: cell.x,
diff --git a/packages/heatmap/src/hooks.js b/packages/heatmap/src/hooks.js
index cfdbf03c24..65c1d809ce 100644
--- a/packages/heatmap/src/hooks.js
+++ b/packages/heatmap/src/hooks.js
@@ -30,49 +30,35 @@ const computeCells = ({
colorScale,
nanColor,
getLabelTextColor,
- currentCell,
- hoverTarget,
- cellHoverOpacity,
- cellHoverOthersOpacity,
}) => {
- const isHoverTarget = isHoverTargetByType[hoverTarget]
-
- return data.reduce((acc, d) => {
+ const cells = []
+ data.forEach(datum => {
keys.forEach(key => {
- const width = sizeScale ? Math.min(sizeScale(d[key]) * cellWidth, cellWidth) : cellWidth
- const height = sizeScale
- ? Math.min(sizeScale(d[key]) * cellHeight, cellHeight)
- : cellHeight
+ const value = datum[key]
+ const index = getIndex(datum)
+ const sizeMultiplier = sizeScale ? sizeScale(value) : 1
+ const width = sizeMultiplier * cellWidth
+ const height = sizeMultiplier * cellHeight
const cell = {
- key: `${key}.${getIndex(d)}`,
+ id: `${key}.${index}`,
xKey: key,
- yKey: getIndex(d),
+ yKey: index,
x: xScale(key),
- y: yScale(getIndex(d)),
+ y: yScale(index),
width,
height,
- value: d[key],
- color: isNaN(d[key]) ? nanColor : colorScale(d[key]),
+ value,
+ color: isNaN(value) ? nanColor : colorScale(value),
+ opacity: cellOpacity,
}
+ cell.labelTextColor = getLabelTextColor(cell)
- let opacity = cellOpacity
- if (currentCell) {
- opacity = isHoverTarget(cell, currentCell)
- ? cellHoverOpacity
- : cellHoverOthersOpacity
- }
-
- acc.push(
- Object.assign(cell, {
- labelTextColor: getLabelTextColor(cell),
- opacity,
- })
- )
+ cells.push(cell)
})
+ })
- return acc
- }, [])
+ return cells
}
export const useHeatMap = ({
@@ -95,7 +81,7 @@ export const useHeatMap = ({
cellHoverOpacity,
cellHoverOthersOpacity,
}) => {
- const [currentCell, setCurrentCell] = useState(null)
+ const [currentCellId, setCurrentCellId] = useState(null)
const getIndex = useMemo(() => getAccessorFor(indexBy), [indexBy])
const indices = useMemo(() => data.map(getIndex), [data, getIndex])
@@ -161,11 +147,11 @@ export const useHeatMap = ({
}
}, [sizeVariation, values])
- const theme = useTheme()
const colorScale = useMemo(
() => guessQuantizeColorScale(colors).domain([values.min, values.max]),
[colors, values]
)
+ const theme = useTheme()
const getCellBorderColor = useInheritedColor(cellBorderColor, theme)
const getLabelTextColor = useInheritedColor(labelTextColor, theme)
@@ -184,10 +170,6 @@ export const useHeatMap = ({
colorScale,
nanColor,
getLabelTextColor,
- currentCell,
- hoverTarget,
- cellHoverOpacity,
- cellHoverOthersOpacity,
}),
[
data,
@@ -200,22 +182,37 @@ export const useHeatMap = ({
colorScale,
nanColor,
getLabelTextColor,
- currentCell,
- hoverTarget,
- cellHoverOpacity,
- cellHoverOthersOpacity,
]
)
+ const cellsWithCurrent = useMemo(() => {
+ if (currentCellId === null) return cells
+
+ const isHoverTarget = isHoverTargetByType[hoverTarget]
+ const currentCell = cells.find(cell => cell.id === currentCellId)
+
+ return cells.map(cell => {
+ const opacity = isHoverTarget(cell, currentCell)
+ ? cellHoverOpacity
+ : cellHoverOthersOpacity
+
+ if (opacity === cell.opacity) return cell
+
+ return {
+ ...cell,
+ opacity,
+ }
+ })
+ }, [cells, currentCellId, hoverTarget, cellHoverOpacity, cellHoverOthersOpacity])
+
return {
- cells,
+ cells: cellsWithCurrent,
getIndex,
xScale: scales.x,
yScale: scales.y,
...layoutConfig,
sizeScale,
- currentCell,
- setCurrentCell,
+ setCurrentCellId,
colorScale,
getCellBorderColor,
getLabelTextColor,