-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
charts: color are theme dependent #88126
Conversation
❌ 114 Tests Failed:
View the top 3 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
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.
is the plan to remove those entirely? I guess you just couldn’t do it right now because there are still more usages?
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.
yeah, we have a ton more. I'm going to make another pass, but I need to first figure out how this broke chartcuterie
@@ -274,8 +276,10 @@ class Chart extends Component<ChartProps, State> { | |||
); | |||
} | |||
const chartColors = timeseriesData.length | |||
? (colors?.slice(0, series.length) ?? | |||
getChartColorPalette(timeseriesData.length - 2 - (hasOther ? 1 : 0)).slice()) | |||
? ((colors as string[])?.slice(0, series.length) ?? |
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 don’t understand this type assertion. It seems that we’ve widened the type of colors
to also be potentially a function, but now, we are asserting here that it is a string. Couldn’t this fail at runtime if we pass a function as colors
?
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'm going to try and remove these before merging.
colors?: | ||
| string[] | ||
| readonly string[] | ||
| ReturnType<Theme['chart']['getColorPalette']> | ||
| ((theme: Theme) => string[] | ReturnType<Theme['chart']['getColorPalette']>); |
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.
we should probably extract this to a type Colors
visualMap: options.options?.visualMap, | ||
backgroundColor: theme.background, | ||
}; | ||
} | ||
type FunctionRegressionChartData = { | ||
evidenceData: NormalizedTrendsTransaction; | ||
rawResponse: any; |
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.
seems like if we make this unknown
, everything still compiles. Feels like a better default than any
:
rawResponse: any; | |
rawResponse: unknown; |
@@ -48,7 +47,7 @@ export function PerformanceScoreChart({ | |||
: projectScore.totalScore | |||
: undefined; | |||
|
|||
let ringSegmentColors = getChartColorPalette(3).slice() as string[]; | |||
let ringSegmentColors = theme.chart.getColorPalette(3) as unknown as string[]; |
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.
Those type assertions indicate that the type we return from getColorPalette
is too narrow. In fact, we seem to basically return CHART_PALETTE[index]
, which means we return a reference to the array inside CHART_PALETTE
, which is why it is readonly
.
So doing a type assertion to a string[]
means it becomes mutable, at which point re-assignments are possible and would have a huge impact, because it would mutate the overall CHART_PALETTE
. That feels like it can lead to hard to track bugs that will only occur in certain sencarios.
Now here we don’t actually push to ringSegmentColors
(we reassign it), but I still think it’s dangerous territory.
So I think we should either:
- not do a type assertion, and refactor this into an immutable way, e.g. like this:
const getRingSegmentColors = () => {
const ringSegmentColors = theme.chart.getColorPalette(3);
const ringBackgroundColors = ringSegmentColors.map(color => `${color}50`);
if (webVital) {
const index = ORDER.indexOf(webVital);
return {
ringSegmentColors: ringSegmentColors.map((color, i) => {
return i === index ? color : theme.gray200;
}),
ringBackgroundColors: ringBackgroundColors.map((color, i) => {
return i === index ? color : `${theme.gray200}33`;
}),
};
}
return {ringSegmentColors, ringBackgroundColors};
};
- embrace that everybody works in mutable ways, and just have
getColorPalette
return astring[]
by creating a copy of what it returns internally so that no one will accidentally mutate the global palette ?
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.
Let me do a second pass on this, as this isn't the only place that does this :/
68e9063
to
0c1d376
Compare
First pass of making colors theme dependent - we need this to be able to toggle between the correct themes for UI2. We should generally disallow direct theme imports as using them results in light/dark mode to be broken.
First pass of making colors theme dependent - we need this to be able to toggle between the correct themes for UI2. We should generally disallow direct theme imports as using them results in light/dark mode to be broken.