-
Notifications
You must be signed in to change notification settings - Fork 81
[FEATURE] Add horizontal crosshair option to TimeSeriesChart plugin #809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "kind": "TimeSeriesChart", | ||
| "spec": { | ||
| "tooltip": { | ||
| "axisPointer": { | ||
| "type": "shadow" | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "kind": "TimeSeriesChart", | ||
| "spec": { | ||
| "tooltip": { | ||
| "enablePinning": true, | ||
| "axisPointer": { | ||
| "type": "cross" | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,9 @@ spec: close({ | |
|
|
||
| #tooltip: { | ||
| enablePinning?: bool | ||
| axisPointer?: { | ||
| type?: "cross" | ||
| } | ||
| } | ||
|
|
||
| #palette: { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,6 +67,7 @@ import type { MouseEvent } from 'react'; | |
| import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; | ||
|
|
||
| import { AnnotationTooltip, buildAnnotationSeries } from './annotations/AnnotationTooltip'; | ||
| import type { TooltipAxisPointerOptions } from './time-series-chart-model'; | ||
| import type { TimeSeriesAnnotation } from './utils/annotation'; | ||
| import { createTimezoneAwareAxisFormatter } from './utils/timezone-formatter'; | ||
|
|
||
|
|
@@ -99,6 +100,7 @@ export interface TimeChartProps { | |
| seriesFormatMap?: Map<string, FormatOptions>; | ||
| grid?: GridComponentOption; | ||
| tooltipConfig?: TooltipConfig; | ||
| axisPointer?: TooltipAxisPointerOptions; | ||
| noDataVariant?: 'chart' | 'message'; | ||
| syncGroup?: string; | ||
| isStackedBar?: boolean; | ||
|
|
@@ -120,6 +122,7 @@ export const TimeSeriesChartBase = forwardRef<ChartInstance, TimeChartProps>(fun | |
| grid, | ||
| isStackedBar = false, | ||
| tooltipConfig = DEFAULT_TOOLTIP_CONFIG, | ||
| axisPointer, | ||
| noDataVariant = 'message', | ||
| syncGroup, | ||
| onDataZoom, | ||
|
|
@@ -133,6 +136,7 @@ export const TimeSeriesChartBase = forwardRef<ChartInstance, TimeChartProps>(fun | |
| const isPinningEnabled = tooltipConfig.enablePinning && enablePinning; | ||
| const chartRef = useRef<EChartsInstance>(); | ||
| const [showTooltip, setShowTooltip] = useState<boolean>(true); | ||
| const [isHovered, setIsHovered] = useState<boolean>(false); | ||
| const [tooltipPinnedCoords, setTooltipPinnedCoords] = useState<CursorCoordinates | null>(null); | ||
| const [pinnedCrosshair, setPinnedCrosshair] = useState<LineSeriesOption | null>(null); | ||
| const [isDragging, setIsDragging] = useState(false); | ||
|
|
@@ -252,6 +256,8 @@ export const TimeSeriesChartBase = forwardRef<ChartInstance, TimeChartProps>(fun | |
|
|
||
| const { noDataOption } = chartsTheme; | ||
|
|
||
| const axisPointerType = axisPointer?.type; | ||
|
|
||
| const option: EChartsCoreOption = useMemo(() => { | ||
| // The "chart" `noDataVariant` is only used when the `timeSeries` is an | ||
| // empty array because a `null` value will throw an error. | ||
|
|
@@ -273,6 +279,16 @@ export const TimeSeriesChartBase = forwardRef<ChartInstance, TimeChartProps>(fun | |
| ? [...seriesMapping, pinnedCrosshair, ...annotationSeries] | ||
| : [...seriesMapping, ...annotationSeries]; | ||
|
|
||
| const tooltip: TooltipComponentOption = { | ||
| show: true, | ||
| // ECharts tooltip content hidden by default since we use custom tooltip instead. | ||
| // Stacked bar uses ECharts tooltip so subgroup data shows correctly. | ||
| showContent: isStackedBar, | ||
| trigger: isStackedBar ? 'item' : 'axis', | ||
| appendToBody: isStackedBar, | ||
| ...(axisPointerType && isHovered ? { axisPointer: { type: axisPointerType, label: { show: false } } } : {}), | ||
| }; | ||
|
|
||
| const option: EChartsCoreOption = { | ||
| dataset: dataset, | ||
| series: updatedSeriesMapping, | ||
|
|
@@ -291,14 +307,7 @@ export const TimeSeriesChartBase = forwardRef<ChartInstance, TimeChartProps>(fun | |
| // If yAxis is already an array (multiple Y axes), use it directly; otherwise use getFormattedAxis | ||
| yAxis: Array.isArray(yAxis) ? yAxis : getFormattedAxis(yAxis, format), | ||
| animation: false, | ||
| tooltip: { | ||
| show: true, | ||
| // ECharts tooltip content hidden by default since we use custom tooltip instead. | ||
| // Stacked bar uses ECharts tooltip so subgroup data shows correctly. | ||
| showContent: isStackedBar, | ||
| trigger: isStackedBar ? 'item' : 'axis', | ||
| appendToBody: isStackedBar, | ||
| }, | ||
| tooltip, | ||
| // https://echarts.apache.org/en/option.html#axisPointer | ||
| axisPointer: { | ||
| type: 'line', | ||
|
|
@@ -338,6 +347,8 @@ export const TimeSeriesChartBase = forwardRef<ChartInstance, TimeChartProps>(fun | |
| enablePinning, | ||
| pinnedCrosshair, | ||
| getTimezoneAwareAxisFormatter, | ||
| axisPointerType, | ||
| isHovered, | ||
| ]); | ||
|
|
||
| // Update adjacent charts so tooltip is unpinned when current chart is clicked. | ||
|
|
@@ -481,6 +492,7 @@ export const TimeSeriesChartBase = forwardRef<ChartInstance, TimeChartProps>(fun | |
| setShowTooltip(true); | ||
| }} | ||
| onMouseLeave={() => { | ||
| setIsHovered(false); | ||
| if (tooltipPinnedCoords === null) { | ||
| setShowTooltip(false); | ||
|
Comment on lines
+495
to
497
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in the description. I distinguish hovered and showing tooltips because, tooltips might be pinned, but i might not hover anymore. Please advice if that distinction make sense to you. |
||
| } | ||
|
|
@@ -491,6 +503,7 @@ export const TimeSeriesChartBase = forwardRef<ChartInstance, TimeChartProps>(fun | |
| } | ||
| }} | ||
| onMouseEnter={() => { | ||
| setIsHovered(true); | ||
| setShowTooltip(true); | ||
| if (chartRef.current !== undefined) { | ||
| enableDataZoom(chartRef.current); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,8 +66,13 @@ export interface TimeSeriesChartYAxisOptions { | |
| logBase?: LOG_BASE; | ||
| } | ||
|
|
||
| export interface TooltipAxisPointerOptions { | ||
| type?: 'cross'; | ||
| } | ||
|
|
||
| export interface TooltipSpecOptions { | ||
| enablePinning: boolean; | ||
| axisPointer?: TooltipAxisPointerOptions; | ||
|
Comment on lines
74
to
+75
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The required |
||
| } | ||
|
|
||
| export interface TimeSeriesChartPaletteOptions { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to do this as a follow up. I first want to get the spec and behaviour correct, before also changing SDK.