diff --git a/pages/05-demos/with-split-panel.page.tsx b/pages/05-demos/with-split-panel.page.tsx new file mode 100644 index 00000000..5cd84398 --- /dev/null +++ b/pages/05-demos/with-split-panel.page.tsx @@ -0,0 +1,111 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { useState } from "react"; + +import Button from "@cloudscape-design/components/button"; +import ColumnLayout from "@cloudscape-design/components/column-layout"; +import Container from "@cloudscape-design/components/container"; +import Link from "@cloudscape-design/components/link"; +import SplitPanel from "@cloudscape-design/components/split-panel"; + +import { CartesianChart, PieChart } from "../../lib/components"; +import { moneyFormatter } from "../common/formatters"; +import { PageSettings, useChartSettings } from "../common/page-settings"; +import { Page } from "../common/templates"; + +interface ThisPageSettings extends PageSettings { + visibleItems: string; +} + +const categories = ["Jun 2019", "Jul 2019", "Aug 2019", "Sep 2019", "Oct 2019", "Nov 2019", "Dec 2019"]; + +export default function () { + const [splitPanelContent, setSplitPanelContent] = useState(""); + const chartSplitPanelProps = { + onToggle: (content: string) => setSplitPanelContent((prev) => (prev === content ? "" : content)), + }; + return ( + {splitPanelContent}} + splitPanelOpen={splitPanelContent !== ""} + splitPanelPreferences={{ position: "side" }} + onSplitPanelToggle={() => setSplitPanelContent((prev) => (prev ? "" : "generic content"))} + > + + + + + + + + ); +} + +function LineChartDemo({ splitPanel }: { splitPanel: { onToggle: (content: string) => void } }) { + const { chartProps } = useChartSettings(); + return ( + { + return { + key: item.series.name, + value: ( + + {item.y !== null ? moneyFormatter(item.y) : null} + + ), + }; + }, + footer: (detail) => ( + + ), + }} + xAxis={{ title: "", type: "category", categories }} + yAxis={{ title: "" }} + /> + ); +} + +function PieChartDemo({ splitPanel }: { splitPanel: { onToggle: (content: string) => void } }) { + const { chartProps } = useChartSettings(); + return ( + ""} + tooltip={{ + footer: (detail) => ( + + ), + }} + series={{ + name: "Resource count", + type: "pie", + data: [ + { name: "Running", y: 60 }, + { name: "Failed", y: 30 }, + { name: "In-progress", y: 10 }, + ], + }} + /> + ); +} diff --git a/pages/common/templates.tsx b/pages/common/templates.tsx index 17f07d9c..84903905 100644 --- a/pages/common/templates.tsx +++ b/pages/common/templates.tsx @@ -50,6 +50,10 @@ export function Page({ children, screenshotArea = true, iframe, + splitPanel, + splitPanelOpen, + splitPanelPreferences, + onSplitPanelToggle, }: { title: React.ReactNode; subtitle?: React.ReactNode; @@ -57,6 +61,10 @@ export function Page({ children: React.ReactNode; screenshotArea?: boolean; iframe?: { id?: string }; + splitPanel?: React.ReactNode; + splitPanelOpen?: boolean; + splitPanelPreferences?: AppLayoutProps.SplitPanelPreferences; + onSplitPanelToggle?: () => void; }) { const { urlParams } = useContext(AppContext); const [toolsOpen, setToolsOpen] = useState(!urlParams.screenshotMode); @@ -93,6 +101,10 @@ export function Page({ activeDrawerId={toolsOpen ? "settings" : null} onDrawerChange={({ detail }) => setToolsOpen(!!detail.activeDrawerId)} drawers={drawers} + splitPanelOpen={splitPanelOpen} + onSplitPanelToggle={onSplitPanelToggle} + splitPanelPreferences={splitPanelPreferences} + splitPanel={splitPanel} content={iframe ? content} /> : content} /> ); diff --git a/src/core/chart-api/chart-extra-tooltip.tsx b/src/core/chart-api/chart-extra-tooltip.tsx index 98ff1828..b1799d1d 100644 --- a/src/core/chart-api/chart-extra-tooltip.tsx +++ b/src/core/chart-api/chart-extra-tooltip.tsx @@ -52,6 +52,10 @@ export class ChartExtraTooltip extends AsyncStore { private targetTrack = new SVGRendererSingle(); private groupTrack = new SVGRendererSingle(); + // Cached coordinates to update cursor's position on re-render. + private lastPoint: null | Highcharts.Point = null; + private lastGroup: null | readonly Highcharts.Point[] = null; + constructor(context: ChartExtraContext) { super({ visible: false, pinned: false, point: null, group: [] }); this.context = context; @@ -65,6 +69,12 @@ export class ChartExtraTooltip extends AsyncStore { return (this.groupTrack.element?.element ?? null) as null | SVGElement; }; + public onChartRender() { + if (this.lastGroup && this.get().visible) { + this.updateTooltipCursor({ point: this.lastPoint, group: this.lastGroup }); + } + } + public onChartDestroy() { this.cursor.destroy(); this.targetTrack.destroy(); @@ -113,6 +123,9 @@ export class ChartExtraTooltip extends AsyncStore { } private updateTooltipCursor = (props: { point: null | Highcharts.Point; group: readonly Highcharts.Point[] }) => { + this.lastPoint = props.point; + this.lastGroup = props.group; + const chartType = this.context.chart().series.find((s) => s.type === "pie" || s.type === "solidgauge")?.type ?? "cartesian"; if (chartType === "pie") { diff --git a/src/core/chart-api/index.tsx b/src/core/chart-api/index.tsx index 95a0cbde..6ad64a9c 100644 --- a/src/core/chart-api/index.tsx +++ b/src/core/chart-api/index.tsx @@ -111,6 +111,7 @@ export class ChartAPI { chartAPI.chartExtraLegend.onChartRender(); chartAPI.chartExtraNodata.onChartRender(); chartAPI.chartExtraAxisTitles.onChartRender(); + chartAPI.chartExtraTooltip.onChartRender(); chartAPI.handleDestroyedPoints(); chartAPI.resetColorCounter(); chartAPI.showMarkersForIsolatedPoints();