diff --git a/pages/03-core/heatmap.page.tsx b/pages/03-core/heatmap.page.tsx
new file mode 100644
index 00000000..22af22f3
--- /dev/null
+++ b/pages/03-core/heatmap.page.tsx
@@ -0,0 +1,125 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+import CoreChart from "../../lib/components/internal-do-not-use/core-chart";
+import { Page } from "../common/templates";
+import { useHighcharts } from "../common/use-highcharts";
+import pseudoRandom from "../utils/pseudo-random";
+
+const INSTANCE_COUNT = 10;
+const PERIOD = 60000; // 1 minute in ms
+const POINTS_PER_INSTANCE = 100;
+const START_TIME = Date.now() - POINTS_PER_INSTANCE * PERIOD;
+
+function generateHeatmapData() {
+ const instances = Array.from({ length: INSTANCE_COUNT }, (_, i) => `i-${String(i).padStart(16, "0")}`);
+
+ const series = instances.map((name, yIndex) => {
+ const baseValue = 0.5 + pseudoRandom() * 2.5;
+ const data: [number, number, number][] = [];
+ for (let x = 0; x < POINTS_PER_INSTANCE; x++) {
+ const timestamp = START_TIME + x * PERIOD;
+ const value = baseValue + (pseudoRandom() - 0.5) * 0.5;
+ data.push([timestamp, yIndex, value]);
+ }
+ return {
+ name,
+ type: "heatmap" as const,
+ data,
+ borderWidth: 0,
+ borderRadius: 0,
+ pointPadding: 0,
+ showInLegend: false,
+ colsize: PERIOD,
+ };
+ });
+
+ return { series, instances };
+}
+
+const { series, instances } = generateHeatmapData();
+
+export default function () {
+ const highcharts = useHighcharts({ heatmap: true });
+
+ return (
+
+
+
+ );
+}
diff --git a/pages/common/use-highcharts.ts b/pages/common/use-highcharts.ts
index d665197c..2f0bb0dd 100644
--- a/pages/common/use-highcharts.ts
+++ b/pages/common/use-highcharts.ts
@@ -11,7 +11,8 @@ export function useHighcharts({
xrange = false,
solidgauge = false,
boost = false,
-}: { more?: boolean; xrange?: boolean; solidgauge?: boolean; boost?: boolean } = {}) {
+ heatmap = false,
+}: { more?: boolean; xrange?: boolean; solidgauge?: boolean; boost?: boolean; heatmap?: boolean } = {}) {
const [highcharts, setHighcharts] = useState(null);
useEffect(() => {
@@ -33,6 +34,9 @@ export function useHighcharts({
if (boost) {
await import("highcharts/modules/boost");
}
+ if (heatmap) {
+ await import("highcharts/modules/heatmap");
+ }
if (isDevelopment) {
await import("highcharts/modules/debugger");
@@ -42,7 +46,7 @@ export function useHighcharts({
};
load();
- }, [more, xrange, solidgauge, boost]);
+ }, [more, xrange, solidgauge, boost, heatmap]);
return highcharts;
}
diff --git a/src/core/chart-api/chart-extra-tooltip.tsx b/src/core/chart-api/chart-extra-tooltip.tsx
index dedaed34..d9c8cce2 100644
--- a/src/core/chart-api/chart-extra-tooltip.tsx
+++ b/src/core/chart-api/chart-extra-tooltip.tsx
@@ -149,8 +149,10 @@ export class ChartExtraTooltip extends AsyncStore {
const pointRect = point ? getPointRect(point) : getGroupRect(group.slice(0, 1));
const groupRect = getGroupRect(group);
// The cursor is not shown when column series are present (a UX decision).
- const hasColumnSeries = getChartSeries(this.context.chart()).some((s) => s.type === "column");
- this.cursor.create(groupRect, point, group, !hasColumnSeries);
+ const hideCursorLine = getChartSeries(this.context.chart()).some(
+ (s) => s.type === "column" || s.type === "heatmap",
+ );
+ this.cursor.create(groupRect, point, group, !hideCursorLine);
this.targetTrack.rect(this.context.chart().renderer, { ...pointRect, ...this.commonTrackAttrs });
this.groupTrack.rect(this.context.chart().renderer, { ...groupRect, ...this.commonTrackAttrs });
};
@@ -238,7 +240,8 @@ class HighlightCursorCartesian {
isPointVisible(point) &&
!isXThreshold(point.series) &&
point.series.type !== "column" &&
- point.series.type !== "errorbar"
+ point.series.type !== "errorbar" &&
+ point.series.type !== "heatmap"
);
};
}