@@ -33,8 +33,17 @@ import type {
3333 MarkerTiming ,
3434 MarkerTimingAndBuckets ,
3535 MarkerIndex ,
36+ MarkerSchemaByName ,
37+ GraphColor ,
3638} from 'firefox-profiler/types' ;
3739import { getStartEndRangeForMarker } from 'firefox-profiler/utils' ;
40+ import {
41+ getStrokeColor ,
42+ getFillColor ,
43+ getDotColor ,
44+ isValidGraphColor ,
45+ } from 'firefox-profiler/profile-logic/graph-color' ;
46+ import { getSchemaFromMarker } from 'firefox-profiler/profile-logic/marker-schema' ;
3847
3948import type {
4049 ChartCanvasScale ,
@@ -59,6 +68,7 @@ type OwnProps = {
5968 readonly rowHeight : CssPixels ;
6069 readonly getMarker : ( param : MarkerIndex ) => Marker ;
6170 readonly getMarkerLabel : ( param : MarkerIndex ) => string ;
71+ readonly markerSchemaByName : MarkerSchemaByName ;
6272 readonly markerListLength : number ;
6373 readonly threadsKey : ThreadsKey ;
6474 readonly updatePreviewSelection : WrapFunctionInDispatch < UpdatePreviewSelection > ;
@@ -82,10 +92,64 @@ const TEXT_OFFSET_START = 3;
8292const MARKER_DOT_RADIUS = 0.25 ;
8393const LABEL_PADDING = 5 ;
8494const MARKER_BORDER_COLOR = '#2c77d1' ;
95+ const DEFAULT_FILL_COLOR = '#8ac4ff' ; // Light blue for non-highlighted
8596
8697class MarkerChartCanvasImpl extends React . PureComponent < Props > {
8798 _textMeasurement : TextMeasurement | null = null ;
8899
100+ /**
101+ * Get the fill and stroke colors for a marker based on its schema and data.
102+ * If the marker schema has a colorField, use that field's value.
103+ * Fall back to default blue if no color is specified.
104+ */
105+ _getMarkerColors (
106+ markerIndex : MarkerIndex ,
107+ isHighlighted : boolean
108+ ) : {
109+ fillColor : string ;
110+ strokeColor : string ;
111+ } {
112+ const { getMarker, markerSchemaByName } = this . props ;
113+ const marker = getMarker ( markerIndex ) ;
114+
115+ let color : GraphColor | null = null ;
116+
117+ // Try to get color from the marker schema's colorField
118+ const schema = getSchemaFromMarker ( markerSchemaByName , marker . data ) ;
119+
120+ if (
121+ schema &&
122+ schema . colorField &&
123+ marker . data &&
124+ typeof marker . data === 'object'
125+ ) {
126+ // Use type assertion to safely access dynamic property
127+ const fieldValue = ( marker . data as any ) [ schema . colorField ] ;
128+ // Validate that the field value is a valid GraphColor
129+ if ( typeof fieldValue === 'string' && isValidGraphColor ( fieldValue ) ) {
130+ color = fieldValue as GraphColor ;
131+ }
132+ }
133+
134+ if ( color ) {
135+ if ( isHighlighted ) {
136+ return {
137+ fillColor : getStrokeColor ( color ) ,
138+ strokeColor : getDotColor ( color ) ,
139+ } ;
140+ }
141+ return {
142+ fillColor : getFillColor ( color ) ,
143+ strokeColor : getStrokeColor ( color ) ,
144+ } ;
145+ }
146+ // Fall back to default blue colors
147+ return {
148+ fillColor : isHighlighted ? BLUE_60 : DEFAULT_FILL_COLOR ,
149+ strokeColor : isHighlighted ? BLUE_80 : MARKER_BORDER_COLOR ,
150+ } ;
151+ }
152+
89153 drawCanvas = (
90154 ctx : CanvasRenderingContext2D ,
91155 scale : ChartCanvasScale ,
@@ -232,7 +296,7 @@ class MarkerChartCanvasImpl extends React.PureComponent<Props> {
232296 isHighlighted : boolean = false
233297 ) {
234298 if ( isInstantMarker ) {
235- this . drawOneInstantMarker ( ctx , x , y , h , isHighlighted ) ;
299+ this . drawOneInstantMarker ( ctx , x , y , h , markerIndex , isHighlighted ) ;
236300 } else {
237301 this . drawOneIntervalMarker ( ctx , x , y , w , h , markerIndex , isHighlighted ) ;
238302 }
@@ -248,14 +312,18 @@ class MarkerChartCanvasImpl extends React.PureComponent<Props> {
248312 isHighlighted : boolean
249313 ) {
250314 const { marginLeft, getMarkerLabel } = this . props ;
315+ const { fillColor, strokeColor } = this . _getMarkerColors (
316+ markerIndex ,
317+ isHighlighted
318+ ) ;
251319
252320 if ( w <= 2 ) {
253321 // This is an interval marker small enough that if we drew it as a
254322 // rectangle, we wouldn't see any inside part. With a width of 2 pixels,
255323 // the rectangle-with-borders would only be borders. With less than 2
256324 // pixels, the borders would collapse.
257325 // So let's draw it directly as a rect.
258- ctx . fillStyle = isHighlighted ? BLUE_80 : MARKER_BORDER_COLOR ;
326+ ctx . fillStyle = strokeColor ;
259327
260328 // w is rounded in the caller, but let's make sure it's at least 1.
261329 w = Math . max ( w , 1 ) ;
@@ -264,8 +332,8 @@ class MarkerChartCanvasImpl extends React.PureComponent<Props> {
264332 // This is a bigger interval marker.
265333 const textMeasurement = this . _getTextMeasurement ( ctx ) ;
266334
267- ctx . fillStyle = isHighlighted ? BLUE_60 : '#8ac4ff' ;
268- ctx . strokeStyle = isHighlighted ? BLUE_80 : MARKER_BORDER_COLOR ;
335+ ctx . fillStyle = fillColor ;
336+ ctx . strokeStyle = strokeColor ;
269337
270338 ctx . beginPath ( ) ;
271339
@@ -312,10 +380,15 @@ class MarkerChartCanvasImpl extends React.PureComponent<Props> {
312380 x : CssPixels ,
313381 y : CssPixels ,
314382 h : CssPixels ,
383+ markerIndex : MarkerIndex ,
315384 isHighlighted : boolean
316385 ) {
317- ctx . fillStyle = isHighlighted ? BLUE_60 : '#8ac4ff' ;
318- ctx . strokeStyle = isHighlighted ? BLUE_80 : MARKER_BORDER_COLOR ;
386+ const { fillColor, strokeColor } = this . _getMarkerColors (
387+ markerIndex ,
388+ isHighlighted
389+ ) ;
390+ ctx . fillStyle = fillColor ;
391+ ctx . strokeStyle = strokeColor ;
319392
320393 // We're drawing a diamond shape, whose height is h - 2, and width is h / 2.
321394 ctx . beginPath ( ) ;
0 commit comments