33
44import type Highcharts from "highcharts" ;
55
6+ import { colors } from "../internal/chart-styles" ;
67import { ChartSeriesMarkerType } from "../internal/components/series-marker" ;
78import { getChartSeries } from "../internal/utils/chart-series" ;
89import { getFormatter } from "./formatters" ;
910import { ChartLabels } from "./i18n-utils" ;
10- import { Rect } from "./interfaces" ;
11+ import { CoreChartProps , Rect } from "./interfaces" ;
1112
1213export interface LegendItemSpec {
1314 id : string ;
@@ -17,6 +18,16 @@ export interface LegendItemSpec {
1718 visible : boolean ;
1819}
1920
21+ export function isLegendItemsEqual ( a : CoreChartProps . LegendItem , b : CoreChartProps . LegendItem ) {
22+ return (
23+ a . id === b . id &&
24+ a . name === b . name &&
25+ a . marker === b . marker &&
26+ a . visible === b . visible &&
27+ a . highlighted === b . highlighted
28+ ) ;
29+ }
30+
2031// The below functions extract unique identifier from series, point, or options. The identifier can be item's ID or name.
2132// We expect that items requiring referencing (e.g. in order to control their visibility) have the unique identifier defined.
2233// Otherwise, we return a randomized id that is to ensure no accidental matches.
@@ -29,7 +40,7 @@ export function getPointId(point: Highcharts.Point): string {
2940export function getOptionsId ( options : { id ?: string ; name ?: string } ) : string {
3041 return options . id ?? options . name ?? noIdPlaceholder ( ) ;
3142}
32- function noIdPlaceholder ( ) : string {
43+ export function noIdPlaceholder ( ) : string {
3344 const rand = ( Math . random ( ) * 1_000_000 ) . toFixed ( 0 ) . padStart ( 6 , "0" ) ;
3445 return "awsui-no-id-placeholder-" + rand ;
3546}
@@ -83,7 +94,22 @@ export function getSeriesMarkerType(series?: Highcharts.Series): ChartSeriesMark
8394 if ( "dashStyle" in series . options && series . options . dashStyle ) {
8495 return "dashed" ;
8596 }
86- switch ( series . type ) {
97+ return getMarkerType ( series . type , seriesSymbol ) ;
98+ }
99+
100+ export function getSeriesOptionsMarkerType ( series ?: Highcharts . SeriesOptionsType ) : ChartSeriesMarkerType {
101+ if ( ! series ) {
102+ return "large-square" ;
103+ }
104+ const seriesSymbol = "symbol" in series && typeof series . symbol === "string" ? series . symbol : "circle" ;
105+ if ( "dashStyle" in series && series . dashStyle ) {
106+ return "dashed" ;
107+ }
108+ return getMarkerType ( series . type , seriesSymbol ) ;
109+ }
110+
111+ function getMarkerType ( seriesType : string , seriesSymbol : string ) {
112+ switch ( seriesType ) {
87113 case "area" :
88114 case "areaspline" :
89115 return "hollow-square" ;
@@ -121,6 +147,15 @@ export function getSeriesColor(series?: Highcharts.Series): string {
121147export function getPointColor ( point ?: Highcharts . Point ) : string {
122148 return typeof point ?. color === "string" ? point . color : "black" ;
123149}
150+ export function getPointOptionsColor ( point ?: Highcharts . PointOptionsObject ) : string | null {
151+ return typeof point ?. color === "string" ? point . color : null ;
152+ }
153+ export function getSeriesOptionsColor ( series : Highcharts . SeriesOptionsType ) : string | null {
154+ if ( "color" in series ) {
155+ return typeof series ?. color === "string" ? series . color : null ;
156+ }
157+ return null ;
158+ }
124159
125160// The custom legend implementation does not rely on the Highcharts legend. When Highcharts legend is disabled,
126161// the chart object does not include information on legend items. Instead, we collect series and pie segments
@@ -170,6 +205,60 @@ export function getChartLegendItems(chart: Highcharts.Chart): readonly LegendIte
170205 return legendItems ;
171206}
172207
208+ export function getChartLegendItemsFromSeriesOptions (
209+ series : Highcharts . SeriesOptionsType [ ] ,
210+ ) : readonly LegendItemSpec [ ] {
211+ const legendItems : LegendItemSpec [ ] = [ ] ;
212+ const addSeriesItem = ( series : Highcharts . SeriesOptionsType , markerType : ChartSeriesMarkerType ) => {
213+ if ( series . type === "pie" ) {
214+ return ;
215+ }
216+ if ( series . type === "errorbar" ) {
217+ return ;
218+ }
219+ if ( series . showInLegend !== false ) {
220+ legendItems . push ( {
221+ id : getOptionsId ( series ) ,
222+ name : series . name ?? "fallbackName" ,
223+ markerType,
224+ color : getSeriesOptionsColor ( series ) ?? colors [ legendItems . length % colors . length ] ,
225+ visible : series . visible ?? true ,
226+ } ) ;
227+ }
228+ } ;
229+ const addPointItem = (
230+ point : NonNullable < Highcharts . SeriesPieOptions [ "data" ] > [ number ] ,
231+ markerType : ChartSeriesMarkerType ,
232+ ) => {
233+ if ( point === null ) {
234+ return ;
235+ }
236+ if ( typeof point === "number" ) {
237+ console . log ( point ) ;
238+ return ;
239+ }
240+ if ( point instanceof Array ) {
241+ console . log ( point ) ;
242+ return ;
243+ }
244+ legendItems . push ( {
245+ id : getOptionsId ( point ) ,
246+ name : point . name ?? "fallbackName" ,
247+ markerType,
248+ color : getPointOptionsColor ( point ) ?? colors [ legendItems . length % colors . length ] ,
249+ visible : true ,
250+ } ) ;
251+ } ;
252+ for ( const s of series ) {
253+ const markerType = getSeriesOptionsMarkerType ( s ) ;
254+ addSeriesItem ( s , markerType ) ;
255+ if ( s . type === "pie" ) {
256+ s . data ?. forEach ( ( p ) => addPointItem ( p , markerType ) ) ;
257+ }
258+ }
259+ return legendItems ;
260+ }
261+
173262export function hasVisibleLegendItems ( options : Highcharts . Options ) {
174263 return ! ! options . series ?. some ( ( series ) => {
175264 // The pie series is not shown in the legend, but their segments are always shown.
0 commit comments