Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ dist
/src/test-utils/selectors/**/*.ts
!/src/test-utils/selectors/index.ts
.DS_STORE
.idea
.vscode
82 changes: 81 additions & 1 deletion pages/01-cartesian-chart/axes-and-thresholds.page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { useState } from "react";
import { range } from "lodash";

import Button from "@cloudscape-design/components/button";
import SpaceBetween from "@cloudscape-design/components/space-between";

const addDays = (date: Date, days: number) => {
const result = new Date(date);
result.setDate(result.getDate() + days);
Expand All @@ -15,7 +19,7 @@ const subYears = (date: Date, years: number) => {
return result;
};

import { CartesianChart } from "../../lib/components";
import { CartesianChart, CartesianChartProps } from "../../lib/components";
import { dateFormatter } from "../common/formatters";
import { useChartSettings } from "../common/page-settings";
import { Page, PageSection } from "../common/templates";
Expand Down Expand Up @@ -77,6 +81,12 @@ export default function () {
<CategoryDatetime />
</PageSection>
</div>
<PageSection title="Datetime X, linear Y — Zoom (uncontrolled)">
<DatetimeLinearWithZoom />
</PageSection>
<PageSection title="Datetime X, linear Y — Zoom (controlled)">
<DatetimeLinearWithControlledZoom />
</PageSection>
</Page>
);
}
Expand Down Expand Up @@ -688,3 +698,73 @@ function CategoryDatetime() {
/>
);
}

const zoomSeriesData = range(0, 100).map((i) => ({
x: addDays(new Date(), i).getTime(),
y: Math.floor((pseudoRandom() + i / 50) * 100),
}));

const zoomSeries: CartesianChartProps.SeriesOptions[] = [
{ type: "area", name: "Requests", data: zoomSeriesData },
{
type: "spline",
name: "Avg latency",
data: zoomSeriesData.map((d) => ({ x: d.x, y: d.y * 0.6 + Math.floor(pseudoRandom() * 20) })),
},
{ type: "y-threshold", name: "SLA limit", value: 150 },
];

// Uncontrolled zoom: two accessible interaction methods are available out of the box —
// (1) drag-to-zoom with the mouse, and (2) the "Zoom" button that enters a unified zoom mode.
// In zoom mode a vertical cursor is moved with the mouse OR the Left/Right arrow keys (and UAP
// direction buttons for touch); a single click / Enter / Space sets the start point, and a second
// click / Enter / Space sets the end point to zoom — a single-pointer, no-modifier interaction that
// satisfies WCAG 2.5.7 (Dragging Movements). Escape or "Exit zoom" cancels. The cursor position is
// announced to screen readers as it moves. Zoom state is managed internally; a "Reset" button
// appears once zoomed. While zoomed, a persistent affordance marks the active range: a vertical
// boundary line at each edge with a subtle band tint between them. The "Zoom" button stays visible
// alongside "Reset" while zoomed, so a narrower range can be selected without resetting first.
function DatetimeLinearWithZoom() {
const { chartProps } = useChartSettings();
return (
<CartesianChart
{...chartProps.cartesian}
chartHeight={400}
legend={{ enabled: true }}
zoom={{ enabled: true }}
series={zoomSeries}
xAxis={{ title: "Time", type: "datetime", valueFormatter: dateFormatter }}
yAxis={{ title: "Count", type: "linear" }}
/>
);
}

// Controlled zoom: the consumer owns the zoom range via `zoomRange` + `onZoomRangeChange`.
// Here we hide the built-in buttons and drive zoom entirely through custom UI and ref methods.
function DatetimeLinearWithControlledZoom() {
const { chartProps } = useChartSettings();
const [zoomRange, setZoomRange] = useState<CartesianChartProps.ZoomRange | null>(null);
const start = zoomSeriesData[20].x;
const end = zoomSeriesData[60].x;
return (
<SpaceBetween size="s">
<SpaceBetween size="xs" direction="horizontal">
<Button onClick={() => setZoomRange({ x: { startValue: start, endValue: end } })}>Zoom to middle range</Button>
<Button onClick={() => setZoomRange(null)} disabled={!zoomRange}>
Reset zoom
</Button>
</SpaceBetween>
<CartesianChart
{...chartProps.cartesian}
chartHeight={400}
legend={{ enabled: true }}
zoom={{ enabled: true, hideButtons: true }}
zoomRange={zoomRange}
onZoomRangeChange={({ detail }) => setZoomRange(detail.zoomRange)}
series={zoomSeries}
xAxis={{ title: "Time", type: "datetime", valueFormatter: dateFormatter }}
yAxis={{ title: "Count", type: "linear" }}
/>
</SpaceBetween>
);
}
8 changes: 7 additions & 1 deletion pages/common/use-highcharts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ export function useHighcharts({
solidgauge = false,
boost = false,
heatmap = false,
}: { more?: boolean; xrange?: boolean; solidgauge?: boolean; boost?: boolean; heatmap?: boolean } = {}) {
}: {
more?: boolean;
xrange?: boolean;
solidgauge?: boolean;
boost?: boolean;
heatmap?: boolean;
} = {}) {
const [highcharts, setHighcharts] = useState<null | typeof Highcharts>(null);

useEffect(() => {
Expand Down
Loading
Loading