[Charts] Use chartTheme hook everywhere (#217370)

## Summary

This PR fixes the existing usage of the chart themes by using the
provided `useElasticChartsTheme` hook that is color mode aware and theme
adaptive (borealis/amsterdam)

Some charts where using just the Light theme version or the legacy (aka
amsterdam theme), and I've applied the hook to pick up the correct
theme.

TO REVIEWERS: Please pull down the PR and check if the actual changed
charts looks correct with the new theme configuration.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Anton Dosov <anton.dosov@elastic.co>
This commit is contained in:
Marco Vettorello 2025-04-14 18:09:15 +02:00 committed by GitHub
parent 4cd9376422
commit a9c9354382
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
46 changed files with 157 additions and 205 deletions

View file

@ -9,29 +9,19 @@
import React, { type FC } from 'react';
import {
Chart,
Settings,
Axis,
BarSeries,
Position,
ScaleType,
LEGACY_LIGHT_THEME,
} from '@elastic/charts';
import { Chart, Settings, Axis, BarSeries, Position, ScaleType } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
interface BarChartRaceProps {
entities: Record<string, number>;
}
export const BarChartRace: FC<BarChartRaceProps> = ({ entities }) => {
const chartBaseTheme = useElasticChartsTheme();
return (
<div style={{ height: '300px' }}>
<Chart>
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
rotation={90}
/>
<Settings baseTheme={chartBaseTheme} rotation={90} />
<Axis id="entities" position={Position.Bottom} title="Commits" showOverlappingTicks />
<Axis id="left2" title="Developers" position={Position.Left} />

View file

@ -23,5 +23,6 @@
"@kbn/shared-ux-router",
"@kbn/ml-response-stream",
"@kbn/react-kibana-context-render",
"@kbn/charts-theme",
]
}

View file

@ -9,12 +9,12 @@ import { useElasticChartsTheme } from '@kbn/charts-theme';
import { Chart, Settings } from '@elastic/charts';
export function MyComponent() {
const baseTheme = useElasticChartsTheme();
const chartBaseTheme = useElasticChartsTheme();
return (
<Chart>
<Settings
baseTheme={baseTheme}
baseTheme={chartBaseTheme}
{/* ... */}
/>
{/* ... */}

View file

@ -22,18 +22,11 @@ import {
EuiSpacer,
EuiFlexItem,
} from '@elastic/eui';
import {
Chart,
Axis,
Position,
HistogramBarSeries,
ScaleType,
Settings,
LEGACY_LIGHT_THEME,
} from '@elastic/charts';
import { Chart, Axis, Position, HistogramBarSeries, ScaleType, Settings } from '@elastic/charts';
import numeral from '@elastic/numeral';
import type { FunctionComponent } from 'react';
import React from 'react';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { i18nTexts } from '../i18n_texts';
import { useFilesManagementContext } from '../context';
@ -43,6 +36,7 @@ interface Props {
export const DiagnosticsFlyout: FunctionComponent<Props> = ({ onClose }) => {
const { filesClient } = useFilesManagementContext();
const chartBaseTheme = useElasticChartsTheme();
const { status, refetch, data, isLoading, error } = useQuery(['filesDiagnostics'], async () => {
return filesClient.getMetrics();
});
@ -99,10 +93,7 @@ export const DiagnosticsFlyout: FunctionComponent<Props> = ({ onClose }) => {
<h3>{i18nTexts.diagnosticsBreakdownsStatus}</h3>
</EuiTitle>
<Chart size={{ height: 200, width: '100%' }}>
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
/>
<Settings baseTheme={chartBaseTheme} />
<Axis id="y" position={Position.Left} showOverlappingTicks />
<Axis id="x" position={Position.Bottom} showOverlappingTicks />
<HistogramBarSeries
@ -125,6 +116,7 @@ export const DiagnosticsFlyout: FunctionComponent<Props> = ({ onClose }) => {
<h3>{i18nTexts.diagnosticsBreakdownsExtension}</h3>
</EuiTitle>
<Chart size={{ height: 200, width: '100%' }}>
<Settings baseTheme={chartBaseTheme} />
<Axis id="y" position={Position.Left} showOverlappingTicks />
<Axis id="x" position={Position.Bottom} showOverlappingTicks />
<HistogramBarSeries

View file

@ -16,6 +16,7 @@
"@kbn/shared-ux-router",
"@kbn/content-management-table-list-view-common",
"@kbn/react-kibana-context-render",
"@kbn/charts-theme",
],
"exclude": [
"target/**/*",

View file

@ -18,11 +18,11 @@ import {
Settings,
Wordcloud,
RenderChangeListener,
LEGACY_LIGHT_THEME,
ElementClickListener,
WordCloudElementEvent,
} from '@elastic/charts';
import { EmptyPlaceholder } from '@kbn/charts-plugin/public';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { PaletteRegistry, PaletteOutput, getColorFactory } from '@kbn/coloring';
import { IInterpreterRenderHandlers, DatatableRow } from '@kbn/expressions-plugin/public';
import { getColorCategories, getOverridesFor } from '@kbn/chart-expressions-common';
@ -100,6 +100,7 @@ export const TagCloudChart = ({
}: TagCloudChartProps) => {
const [warning, setWarning] = useState(false);
const palettes = useKbnPalettes();
const chartBaseTheme = useElasticChartsTheme();
const { bucket, metric, scale, palette, showLabel, orientation, colorMapping } = visParams;
const bucketFormatter = useMemo(() => {
@ -239,8 +240,7 @@ export const TagCloudChart = ({
<div css={tgcChartCss.wrapper} ref={resizeRef} data-test-subj="tagCloudVisualization">
<Chart size="100%" {...getOverridesFor(overrides, 'chart')}>
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
onElementClick={handleWordClick}
onRenderChange={onRenderChange}
ariaLabel={visParams.ariaLabel}

View file

@ -30,6 +30,7 @@
"@kbn/data-plugin",
"@kbn/react-kibana-context-render",
"@kbn/palettes",
"@kbn/charts-theme",
],
"exclude": [
"target/**/*",

View file

@ -97,6 +97,7 @@ export function getBaseTheme(baseTheme: Theme, bgColor?: string | null): Theme {
}
const bgLuminosity = computeRelativeLuminosity(bgColor);
// TODO check if this still apply
const mainTheme = bgLuminosity <= 0.179 ? LEGACY_DARK_THEME : LEGACY_LIGHT_THEME;
const color = findBestContrastColor(
bgColor,

View file

@ -7,10 +7,11 @@
import React, { type FC } from 'react';
import { BarSeries, Chart, Settings, ScaleType, LEGACY_LIGHT_THEME } from '@elastic/charts';
import { BarSeries, Chart, Settings, ScaleType } from '@elastic/charts';
import { mathWithUnits, type UseEuiTheme, type EuiDataGridColumn } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import type { ChartData } from '../lib/field_histograms';
import { isUnsupportedChartData } from '../lib/field_histograms';
@ -62,7 +63,7 @@ export const ColumnChart: FC<Props> = ({
maxChartColumns,
}) => {
const { data, legendText } = useColumnChart(chartData, columnType, maxChartColumns);
const chartBaseTheme = useElasticChartsTheme();
return (
<div data-test-subj={dataTestSubj}>
{!isUnsupportedChartData(chartData) && data.length > 0 && (
@ -70,8 +71,7 @@ export const ColumnChart: FC<Props> = ({
<Chart>
<Settings
theme={columnChartTheme}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
locale={i18n.getLocale()}
/>
<BarSeries

View file

@ -34,5 +34,6 @@
"@kbn/field-formats-plugin",
"@kbn/ml-query-utils",
"@kbn/ml-date-utils",
"@kbn/charts-theme",
]
}

View file

@ -9,7 +9,8 @@ import type { FC } from 'react';
import React, { useMemo } from 'react';
import { EuiSpacer } from '@elastic/eui';
import { Axis, BarSeries, Chart, Settings, ScaleType, LEGACY_LIGHT_THEME } from '@elastic/charts';
import { Axis, BarSeries, Chart, Settings, ScaleType } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { FormattedMessage } from '@kbn/i18n-react';
import { roundToDecimalPlace } from '@kbn/ml-number-utils';
@ -48,7 +49,7 @@ const BOOLEAN_DISTRIBUTION_CHART_HEIGHT = 70;
export const BooleanContent: FC<FieldDataRowProps> = ({ config, onAddFilter }) => {
const barColor = useBarColor();
const chartBaseTheme = useElasticChartsTheme();
const fieldFormat = 'fieldFormat' in config ? config.fieldFormat : undefined;
const formattedPercentages = useMemo(() => getTFPercentage(config), [config]);
const theme = useDataVizChartTheme();
@ -84,8 +85,7 @@ export const BooleanContent: FC<FieldDataRowProps> = ({ config, onAddFilter }) =
/>
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
showLegend={false}
theme={theme}
locale={i18n.getLocale()}

View file

@ -8,17 +8,9 @@
import type { FC } from 'react';
import React from 'react';
import {
Axis,
BarSeries,
Chart,
LEGACY_LIGHT_THEME,
Position,
ScaleType,
Settings,
} from '@elastic/charts';
import { Axis, BarSeries, Chart, Position, ScaleType, Settings } from '@elastic/charts';
import type { EuiDataGridColumn } from '@elastic/eui';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { isUnsupportedChartData, type ChartData } from '@kbn/ml-data-grid';
import { i18n } from '@kbn/i18n';
@ -47,14 +39,13 @@ export const ColumnChart: FC<Props> = ({
}) => {
const { data, legendText } = useColumnChart(chartData, columnType, maxChartColumns, isNumeric);
const styles = useColumnChartStyles();
const chartBaseTheme = useElasticChartsTheme();
return (
<div data-test-subj={dataTestSubj} style={{ width: '100%' }}>
{!isUnsupportedChartData(chartData) && data.length > 0 && (
<Chart size={size}>
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
xDomain={Array.from({ length: maxChartColumns }, (_, i) => i)}
theme={{
chartMargins: zeroSize,

View file

@ -20,8 +20,8 @@ import {
ScaleType,
Settings,
Tooltip,
LEGACY_LIGHT_THEME,
} from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { MetricDistributionChartTooltipHeader } from './metric_distribution_chart_tooltip_header';
import { kibanaFieldFormat } from '../../../utils';
@ -67,6 +67,8 @@ export const MetricDistributionChart: FC<Props> = ({
const styles = useColumnChartStyles();
const chartBaseTheme = useElasticChartsTheme();
const headerFormatter: TooltipHeaderFormatter = (tooltipData) => {
const xValue = tooltipData.value;
const chartPoint: MetricDistributionChartData | undefined = chartData.find(
@ -86,12 +88,7 @@ export const MetricDistributionChart: FC<Props> = ({
<div data-test-subj="dataVisualizerFieldDataMetricDistributionChart" css={styles.histogram}>
<Chart size={{ width, height }}>
<Tooltip headerFormatter={headerFormatter} />
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
theme={theme}
locale={i18n.getLocale()}
/>
<Settings baseTheme={chartBaseTheme} theme={theme} locale={i18n.getLocale()} />
<Axis
id="bottom"
position={Position.Bottom}

View file

@ -10,12 +10,12 @@ import {
Axis,
Chart,
CurveType,
LEGACY_LIGHT_THEME,
Position,
ScaleType,
Settings,
Tooltip,
} from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { FIELD_FORMAT_IDS } from '@kbn/field-formats-plugin/common';
@ -38,6 +38,7 @@ export const OverlapDistributionComparison = ({
fieldType?: DataDriftField['type'];
fieldName?: DataDriftField['field'];
}) => {
const chartBaseTheme = useElasticChartsTheme();
const xAxisFormatter = useFieldFormatter(getFieldFormatType(secondaryType));
const yAxisFormatter = useFieldFormatter(FIELD_FORMAT_IDS.NUMBER);
if (data.length === 0) return <NoChartsData textAlign="left" />;
@ -61,8 +62,10 @@ export const OverlapDistributionComparison = ({
/>
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
theme={{
axes: { gridLine: { horizontal: { visible: false }, vertical: { visible: false } } }, // Hide grid lines
}}
showLegend={false}
locale={i18n.getLocale()}
/>

View file

@ -8,16 +8,8 @@
import React from 'react';
import type { SeriesColorAccessor } from '@elastic/charts/dist/chart_types/xy_chart/utils/specs';
import {
Axis,
BarSeries,
Chart,
LEGACY_LIGHT_THEME,
Position,
ScaleType,
Settings,
Tooltip,
} from '@elastic/charts';
import { Axis, BarSeries, Chart, Position, ScaleType, Settings, Tooltip } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { FIELD_FORMAT_IDS } from '@kbn/field-formats-plugin/common';
import type { Histogram } from '@kbn/ml-chi2test';
@ -44,6 +36,7 @@ export const SingleDistributionChart = ({
fieldType?: DataDriftField['type'];
domain?: Feature['domain'];
}) => {
const chartBaseTheme = useElasticChartsTheme();
const xAxisFormatter = useFieldFormatter(getFieldFormatType(secondaryType));
const yAxisFormatter = useFieldFormatter(FIELD_FORMAT_IDS.NUMBER);
@ -54,8 +47,10 @@ export const SingleDistributionChart = ({
<Tooltip body={DataComparisonChartTooltipBody} />
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
theme={{
axes: { gridLine: { horizontal: { visible: false }, vertical: { visible: false } } }, // Hide grid lines
}}
locale={i18n.getLocale()}
/>
<Axis

View file

@ -17,6 +17,7 @@ import {
TooltipType,
} from '@elastic/charts';
import { useEuiTheme } from '@elastic/eui';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { i18n } from '@kbn/i18n';
@ -35,6 +36,7 @@ interface Props {
export const EventRateChart: FC<Props> = ({ eventRateChartData, height, width }) => {
const { euiTheme } = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
const theme: PartialTheme = useMemo(
() => ({
scales: { histogramPadding: 0.2 },
@ -65,7 +67,7 @@ export const EventRateChart: FC<Props> = ({ eventRateChartData, height, width })
<Chart>
<Axes />
<Tooltip type={TooltipType.None} />
<Settings theme={theme} locale={i18n.getLocale()} />
<Settings theme={theme} locale={i18n.getLocale()} baseTheme={chartBaseTheme} />
<HistogramBarSeries
id="event_rate"

View file

@ -84,7 +84,8 @@
"@kbn/presentation-containers",
"@kbn/react-kibana-mount",
"@kbn/core-ui-settings-browser",
"@kbn/file-upload-common"
"@kbn/file-upload-common",
"@kbn/charts-theme"
],
"exclude": [
"target/**/*",

View file

@ -16,6 +16,7 @@ import {
} from '@elastic/eui';
import { ScaleType, Settings, Tooltip, Chart, BarSeries } from '@elastic/charts';
import { i18n } from '@kbn/i18n';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { Coordinate } from '../../../common/types';
export function SparkPlot({
@ -45,6 +46,7 @@ function SparkPlotItem({
series?: Coordinate[] | null;
}) {
const { euiTheme } = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
const chartSize = {
height: euiTheme.size.l,
width: '80px',
@ -73,7 +75,7 @@ function SparkPlotItem({
data-test-subj="datasetQualitySparkPlot"
>
<Chart size={chartSize}>
<Settings showLegend={false} locale={i18n.getLocale()} />
<Settings showLegend={false} locale={i18n.getLocale()} baseTheme={chartBaseTheme} />
<Tooltip type="none" />
<BarSeries
id="barseries"

View file

@ -57,7 +57,8 @@
"@kbn/field-utils",
"@kbn/logging",
"@kbn/ui-theme",
"@kbn/react-hooks"
"@kbn/react-hooks",
"@kbn/charts-theme"
],
"exclude": [
"target/**/*"

View file

@ -29,6 +29,7 @@ import { ExplorerChartLabel } from './components/explorer_chart_label';
import { CHART_TYPE } from '../explorer_constants';
import { SEARCH_QUERY_LANGUAGE } from '@kbn/ml-query-utils';
import { i18n } from '@kbn/i18n';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { FormattedMessage } from '@kbn/i18n-react';
import { MlTooltipComponent } from '../../components/chart_tooltip';
import { withKibana } from '@kbn/kibana-react-plugin/public';
@ -41,7 +42,7 @@ import { ExplorerChartsErrorCallOuts } from './explorer_charts_error_callouts';
import { addItemToRecentlyAccessed } from '../../util/recently_accessed';
import { EmbeddedMapComponentWrapper } from './explorer_chart_embedded_map';
import { useActiveCursor } from '@kbn/charts-plugin/public';
import { BarSeries, Chart, Settings, LEGACY_LIGHT_THEME } from '@elastic/charts';
import { BarSeries, Chart, Settings } from '@elastic/charts';
import { escapeKueryForFieldValuePair } from '../../util/string_utils';
import { useCssMlExplorerChartContainer } from './explorer_chart_styles';
@ -112,6 +113,8 @@ function ExplorerChartContainer({
},
} = useMlKibana();
const chartBaseTheme = useElasticChartsTheme();
const getMapsLink = useCallback(async () => {
const { queryString, query } = getEntitiesQuery(series);
const initialLayers = getInitialAnomaliesLayers(series.jobId);
@ -238,8 +241,7 @@ function ExplorerChartContainer({
<div style={{ width: 0, height: 0 }}>
<Chart ref={chartRef}>
<Settings
// TODO connect to charts.theme service see src/platform/plugins/shared/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
noResults={<div />}
width={0}
height={0}

View file

@ -19,7 +19,7 @@ import {
LineAnnotation,
AnnotationDomainType,
Tooltip,
LEGACY_LIGHT_THEME,
LIGHT_THEME,
} from '@elastic/charts';
import { EuiIcon } from '@elastic/eui';
import { FIELD_FORMAT_IDS } from '@kbn/field-formats-plugin/common';
@ -37,7 +37,7 @@ export const MemoryPreviewChart: FC<MemoryPreviewChartProps> = ({ memoryOverview
const {
services: { charts: chartsService },
} = useMlKibana();
const chartBaseTheme = chartsService.theme.useChartsBaseTheme();
const groups = useMemo(
() => ({
jvm: {
@ -123,8 +123,8 @@ export const MemoryPreviewChart: FC<MemoryPreviewChartProps> = ({ memoryOverview
}
/>
<Settings
theme={{ chartMargins: LEGACY_LIGHT_THEME.chartMargins }}
baseTheme={chartsService.theme.useChartsBaseTheme()}
theme={{ chartMargins: LIGHT_THEME.chartMargins }}
baseTheme={chartBaseTheme}
rotation={90}
locale={i18n.getLocale()}
/>

View file

@ -17,19 +17,11 @@ import {
EuiLoadingChart,
EuiPanel,
EuiSpacer,
useEuiTheme,
EuiIconTip,
EuiText,
} from '@elastic/eui';
import {
AreaSeries,
Axis,
BarSeries,
Chart,
DARK_THEME,
LIGHT_THEME,
Settings,
} from '@elastic/charts';
import { AreaSeries, Axis, BarSeries, Chart, Settings } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { useKibana } from '../../../hooks/use_kibana';
import { DataStreamStats } from './hooks/use_data_stream_stats';
import { formatBytes } from './helpers/format_bytes';
@ -149,7 +141,7 @@ function ChartAreaSeries({
isLoading: isLoadingIngestionRate,
error: ingestionRateError,
} = useIngestionRate({ definition, stats, timeRange });
const { colorMode } = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
return ingestionRateError ? (
'Failed to load ingestion rate'
@ -158,7 +150,7 @@ function ChartAreaSeries({
) : (
<>
<Chart size={{ height: 250 }}>
<Settings showLegend={false} baseTheme={colorMode === 'LIGHT' ? LIGHT_THEME : DARK_THEME} />
<Settings showLegend={false} baseTheme={chartBaseTheme} />
<AreaSeries
id="ingestionRate"
@ -215,7 +207,7 @@ function ChartBarSeries({
error: ingestionRateError,
} = useIngestionRatePerTier({ definition, stats, timeRange });
const { ilmPhases } = useIlmPhasesColorAndDescription();
const { colorMode } = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
return ingestionRateError ? (
'Failed to load ingestion rate'
@ -224,7 +216,7 @@ function ChartBarSeries({
) : (
<>
<Chart size={{ height: 250 }}>
<Settings showLegend={false} baseTheme={colorMode === 'LIGHT' ? LIGHT_THEME : DARK_THEME} />
<Settings showLegend={false} baseTheme={chartBaseTheme} />
{Object.entries(ingestionRate.buckets).map(([tier, buckets]) => (
<BarSeries
id={`ingestionRate-${tier}`}

View file

@ -17,11 +17,10 @@ import {
Settings,
Tooltip,
niceTimeFormatter,
LIGHT_THEME,
DARK_THEME,
DomainRange,
} from '@elastic/charts';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer, useEuiTheme } from '@elastic/eui';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { css } from '@emotion/css';
import { AbortableAsyncState } from '@kbn/react-hooks';
@ -75,7 +74,7 @@ export function ControlledEsqlChart<T extends string>({
const {
core: { uiSettings },
} = useKibana();
const { colorMode } = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
const allTimeseries = useMemo(
() =>
@ -158,7 +157,7 @@ export function ControlledEsqlChart<T extends string>({
legendPosition={Position.Bottom}
xDomain={xDomain}
locale={i18n.getLocale()}
baseTheme={colorMode === 'LIGHT' ? LIGHT_THEME : DARK_THEME}
baseTheme={chartBaseTheme}
/>
<Axis
id="x-axis"

View file

@ -14,15 +14,12 @@ import {
Chart,
ScaleType,
Settings,
LIGHT_THEME,
DARK_THEME,
niceTimeFormatter,
Tooltip,
TooltipStickTo,
type SettingsProps,
} from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { i18n } from '@kbn/i18n';
import { useEuiTheme } from '@elastic/eui';
import { useStreamsAppFetch } from '../../hooks/use_streams_app_fetch';
import { useKibana } from '../../hooks/use_kibana';
import { esqlResultToTimeseries } from '../../util/esql_result_to_timeseries';
@ -42,6 +39,7 @@ export function DocumentsColumn({
},
},
} = useKibana();
const chartBaseTheme = useElasticChartsTheme();
const { absoluteTimeRange } = useTimeFilter();
const minInterval = Math.floor((absoluteTimeRange.end - absoluteTimeRange.start) / numDataPoints);
@ -112,7 +110,10 @@ export function DocumentsColumn({
`}
>
<Chart size={{ width: '100%', height: euiThemeVars.euiSizeL }}>
<SettingsWithTheme
<Settings
locale={i18n.getLocale()}
baseTheme={chartBaseTheme}
theme={{ background: { color: 'transparent' } }}
xDomain={{ min: absoluteTimeRange.start, max: absoluteTimeRange.end, minInterval }}
noResults={<div />}
/>
@ -138,15 +139,3 @@ export function DocumentsColumn({
</EuiFlexGroup>
);
}
function SettingsWithTheme(props: SettingsProps) {
const { colorMode } = useEuiTheme();
return (
<Settings
locale={i18n.getLocale()}
baseTheme={colorMode === 'LIGHT' ? LIGHT_THEME : DARK_THEME}
theme={{ background: { color: 'transparent' } }}
{...props}
/>
);
}

View file

@ -66,6 +66,7 @@
"@kbn/core-analytics-browser",
"@kbn/index-management-shared-types",
"@kbn/ingest-pipelines-plugin",
"@kbn/deeplinks-observability"
"@kbn/deeplinks-observability",
"@kbn/charts-theme"
]
}

View file

@ -18,15 +18,9 @@ import {
EuiLoadingChart,
useEuiTheme,
} from '@elastic/eui';
import {
Axis,
BarSeries,
Chart,
CurveType,
LineSeries,
Settings,
LEGACY_LIGHT_THEME,
} from '@elastic/charts';
import { Axis, BarSeries, Chart, CurveType, LineSeries, Settings } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { assign, fill } from 'lodash';
import moment from 'moment';
import { formatMillisForDisplay } from '../../../lib/execution_duration_utils';
@ -61,6 +55,7 @@ export const ExecutionDurationChart: React.FunctionComponent<ComponentOpts> = ({
isLoading,
}: ComponentOpts) => {
const { euiTheme } = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
const paddedExecutionDurations = padOrTruncateDurations(
executionDuration.valuesWithTimestamp,
@ -122,8 +117,7 @@ export const ExecutionDurationChart: React.FunctionComponent<ComponentOpts> = ({
line: { stroke: euiTheme.colors.accent },
},
}}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
locale={i18n.getLocale()}
/>
<BarSeries

View file

@ -8,7 +8,7 @@ import React from 'react';
import type { Datum, PartialTheme } from '@elastic/charts';
import { Chart, Partition, PartitionLayout, Settings } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import {
EuiFlexItem,
euiPaletteColorBlindBehindText,
@ -49,6 +49,7 @@ export function SunburstChart({
fetchStatus: FETCH_STATUS;
chartWidth: number;
}) {
const chartBaseTheme = useElasticChartsTheme();
const colors = euiPaletteColorBlindBehindText({ sortBy: 'natural' });
const isDataAvailable = data && data.length > 0;
const isLoading = fetchStatus === FETCH_STATUS.LOADING;
@ -88,7 +89,7 @@ export function SunburstChart({
>
{isDataAvailable ? (
<Chart>
<Settings theme={theme} locale={i18n.getLocale()} />
<Settings theme={theme} locale={i18n.getLocale()} baseTheme={chartBaseTheme} />
<Partition
id={chartKey}
data={data}

View file

@ -6,7 +6,8 @@
*/
import React from 'react';
import type { MetricDatum } from '@elastic/charts';
import { Chart, Metric } from '@elastic/charts';
import { Chart, Metric, Settings } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { EuiSkeletonText, EuiPanel } from '@elastic/eui';
import { isEmpty } from 'lodash';
import { EuiErrorBoundary } from '@elastic/eui';
@ -22,6 +23,7 @@ export function MetricItem({
isLoading: boolean;
height?: string;
}) {
const chartBaseTheme = useElasticChartsTheme();
const hasData = !isEmpty(data);
return (
<div
@ -40,6 +42,7 @@ export function MetricItem({
) : (
<EuiErrorBoundary>
<Chart>
<Settings baseTheme={chartBaseTheme} />
<Metric id={`metric_${id}`} data={[data]} />
</Chart>
</EuiErrorBoundary>

View file

@ -6,7 +6,8 @@
*/
import React from 'react';
import type { Datum } from '@elastic/charts';
import { Chart, Partition, PartitionLayout } from '@elastic/charts';
import { Chart, Partition, PartitionLayout, Settings } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { euiPaletteColorBlind } from '@elastic/eui';
import { percentValueGetter } from '@elastic/charts/dist/chart_types/partition_chart/layout/config';
import { isEmpty } from 'lodash';
@ -29,10 +30,12 @@ export function TreemapChart({
id: string;
}) {
const colorPalette = euiPaletteColorBlind();
const chartBaseTheme = useElasticChartsTheme();
return (
<ChartContainer hasData={!isEmpty(data)} height={height} status={fetchStatus} id={id}>
<Chart>
<Settings baseTheme={chartBaseTheme} />
<Partition
data={data}
id="spec_1"

View file

@ -15,7 +15,7 @@ interface AlertStatusIndicatorProps {
alertStatus: AlertStatus;
textSize?: 'xs' | 's' | 'm' | 'inherit';
}
// TODO update these colors to a more appropriate EUI color token
export function AlertStatusIndicator({ alertStatus, textSize = 'xs' }: AlertStatusIndicatorProps) {
if (alertStatus === ALERT_STATUS_ACTIVE) {
return (

View file

@ -7,7 +7,6 @@
import React, { useMemo } from 'react';
import { niceTimeFormatter } from '@elastic/charts';
import { Theme, LEGACY_LIGHT_THEME, LEGACY_DARK_THEME } from '@elastic/charts';
import { i18n } from '@kbn/i18n';
import { EuiLoadingChart, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
@ -81,11 +80,6 @@ export const getDomain = (series: Series, stacked: boolean = false) => {
return { yMin: min || 0, yMax: max || 0, xMin: minTimestamp, xMax: maxTimestamp };
};
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
export const getChartTheme = (isDarkMode: boolean): Theme => {
return isDarkMode ? LEGACY_DARK_THEME : LEGACY_LIGHT_THEME;
};
export const EmptyContainer: React.FC<{ children?: React.ReactNode }> = ({ children }) => (
<div
style={{

View file

@ -6,7 +6,8 @@
*/
import type { Datum, FlameLayerValue, FlameSpec, PartialTheme } from '@elastic/charts';
import { Chart, Flame, Settings, Tooltip, LEGACY_LIGHT_THEME } from '@elastic/charts';
import { Chart, Flame, Settings, Tooltip } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import type { Maybe } from '@kbn/observability-plugin/common/typings';
@ -48,6 +49,8 @@ export function FlameGraph({
setShowInformationWindow((prev) => !prev);
}
const theme = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
const trackProfilingEvent = useUiTracker({ app: 'profiling' });
const columnarData = useMemo(() => {
@ -141,8 +144,7 @@ export function FlameGraph({
<Chart key={columnarData.key}>
<Settings
theme={chartTheme}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
onElementClick={(elements) => {
const selectedElement = elements[0] as Maybe<FlameLayerValue>;
if (Number.isNaN(selectedElement?.vmIndex)) {

View file

@ -56,7 +56,8 @@
"@kbn/react-kibana-context-render",
"@kbn/apm-data-access-plugin",
"@kbn/ebt-tools",
"@kbn/core-security-server"
"@kbn/core-security-server",
"@kbn/charts-theme"
// add references to other TypeScript projects the plugin depends on
// requiredPlugins from ./kibana.json

View file

@ -272,11 +272,12 @@ export function SloCardChart({
const { cardColor } = useSloCardColor(slo.summary.status);
const subTitle = getSubTitle(slo);
const { sliValue, sloTarget, sloDetailsUrl } = useSloFormattedSummary(slo);
const chartBaseTheme = charts.theme.useChartsBaseTheme();
return (
<Chart>
<Settings
baseTheme={charts.theme.useChartsBaseTheme()}
baseTheme={chartBaseTheme}
theme={{
metric: {
iconAlign: 'right',

View file

@ -81,6 +81,7 @@ export const MetricItem = ({
});
const { charts } = useKibana<ClientPluginsStart>().services;
const chartBaseTheme = charts.theme.useChartsBaseTheme();
const testInProgress = useSelector(manualTestRunInProgressSelector(monitor.configId));
const dispatch = useDispatch();
@ -138,7 +139,7 @@ export const MetricItem = ({
});
}
}}
baseTheme={charts.theme.useChartsBaseTheme()}
baseTheme={chartBaseTheme}
locale={i18n.getLocale()}
/>
<Metric

View file

@ -5,15 +5,7 @@
* 2.0.
*/
import {
Chart,
Datum,
LEGACY_LIGHT_THEME,
PartialTheme,
Partition,
PartitionLayout,
Settings,
} from '@elastic/charts';
import { Chart, Datum, PartialTheme, Partition, PartitionLayout, Settings } from '@elastic/charts';
import {
EuiFlexGroup,
EuiFlexItem,
@ -23,6 +15,7 @@ import {
EuiTitle,
useEuiTheme,
} from '@elastic/eui';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { formatMillisecond } from '../common/network_data/data_formatting';
@ -47,6 +40,7 @@ export const NetworkTimingsDonut = () => {
const networkTimings = useNetworkTimings();
const { euiTheme } = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
if (!networkTimings) {
return <EuiLoadingSpinner size="xl" />;
@ -70,8 +64,7 @@ export const NetworkTimingsDonut = () => {
<Chart size={{ height: 240 }}>
<Settings
theme={[themeOverrides]}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
showLegend={false}
locale={i18n.getLocale()}
/>

View file

@ -106,7 +106,6 @@ export const WaterfallBarChart = ({
showLegend={false}
rotation={90}
theme={{ tooltip: { maxWidth: 500 } }}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={baseChartTheme}
onProjectionClick={handleProjectionClick}
onElementClick={handleElementClick}

View file

@ -49,7 +49,6 @@ export const WaterfallChartFixedAxis = ({ tickFormat, domain, barStyleAccessor }
},
},
]}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={baseChartTheme}
locale={i18n.getLocale()}
/>

View file

@ -100,7 +100,6 @@ export const WaterfallBarChart = ({
<Settings
showLegend={false}
rotation={90}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={baseChartTheme}
onProjectionClick={handleProjectionClick}
onElementClick={handleElementClick}

View file

@ -31,7 +31,7 @@ interface Props {
}
export const WaterfallChartFixedAxis = ({ tickFormat, domain, barStyleAccessor }: Props) => {
const baseChartTheme = useElasticChartsTheme();
const chartBaseTheme = useElasticChartsTheme();
return (
<WaterfallChartFixedAxisContainer>
@ -40,8 +40,7 @@ export const WaterfallChartFixedAxis = ({ tickFormat, domain, barStyleAccessor }
<Settings
showLegend={false}
rotation={90}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={baseChartTheme}
baseTheme={chartBaseTheme}
locale={i18n.getLocale()}
/>

View file

@ -10,15 +10,7 @@ import React, { MouseEvent } from 'react';
import { parsePath } from 'history';
import { useValues } from 'kea';
import {
AreaSeries,
Chart,
CurveType,
ScaleType,
Settings,
Tooltip,
LEGACY_LIGHT_THEME,
} from '@elastic/charts';
import { AreaSeries, Chart, CurveType, ScaleType, Settings, Tooltip } from '@elastic/charts';
import {
EuiBadge,
EuiCard,
@ -29,8 +21,8 @@ import {
EuiLoadingChart,
useEuiTheme,
} from '@elastic/eui';
import { EuiThemeComputed } from '@elastic/eui/src/services/theme/types';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { i18n } from '@kbn/i18n';
@ -105,6 +97,7 @@ export const AnalyticsCollectionCard: React.FC<
AnalyticsCollectionCardProps & AnalyticsCollectionCardLensProps
> = ({ collection, isLoading, isCreatedByEngine, subtitle, data, metric, secondaryMetric }) => {
const { euiTheme } = useEuiTheme();
const chartBaseTheme = useElasticChartsTheme();
const { history, navigateToUrl } = useValues(KibanaLogic);
const cardStyles = AnalyticsCollectionCardStyles(euiTheme);
const status = getChartStatus(secondaryMetric);
@ -188,8 +181,7 @@ export const AnalyticsCollectionCard: React.FC<
css={cardStyles.chart}
>
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
theme={{
areaSeriesStyle: {
area: {

View file

@ -89,5 +89,6 @@
"@kbn/search-shared-ui",
"@kbn/file-upload-common",
"@kbn/search-indices",
"@kbn/charts-theme",
]
}

View file

@ -7,12 +7,12 @@
import { mount } from 'enzyme';
import React from 'react';
import { useEuiTheme } from '@elastic/eui';
import { renderHook } from '@testing-library/react';
import { matchers } from '@emotion/jest';
expect.extend(matchers);
import { useDarkMode } from '../../lib/kibana';
import type { ChartSeriesData } from './common';
import {
checkIfAllValuesAreZero,
@ -22,9 +22,15 @@ import {
WrappedByAutoSizer,
useThemes,
} from './common';
import { LEGACY_LIGHT_THEME, LEGACY_DARK_THEME } from '@elastic/charts';
import { LIGHT_THEME, DARK_THEME } from '@elastic/charts';
jest.mock('../../lib/kibana');
jest.mock('@elastic/eui', () => {
const actual = jest.requireActual('@elastic/eui');
return {
...actual,
useEuiTheme: jest.fn(),
};
});
describe('WrappedByAutoSizer', () => {
it('should render correct default height', () => {
@ -166,23 +172,33 @@ describe('checkIfAllValuesAreZero', () => {
describe('useThemes', () => {
it('should return custom spacing theme', () => {
(useEuiTheme as jest.Mock).mockReturnValue({
euiTheme: { themeName: 'borealis' },
colorMode: 'LIGHT',
});
const { result } = renderHook(() => useThemes());
expect(result.current.theme.chartMargins).toMatchObject({ top: 4, bottom: 0 });
});
it('should return light baseTheme when isDarkMode false', () => {
(useDarkMode as jest.Mock).mockImplementation(() => false);
(useEuiTheme as jest.Mock).mockReturnValue({
euiTheme: { themeName: 'borealis' },
colorMode: 'LIGHT',
});
const { result } = renderHook(() => useThemes());
expect(result.current.baseTheme).toBe(LEGACY_LIGHT_THEME);
expect(result.current.baseTheme).toBe(LIGHT_THEME);
});
it('should return dark baseTheme when isDarkMode true', () => {
(useDarkMode as jest.Mock).mockImplementation(() => true);
(useEuiTheme as jest.Mock).mockReturnValue({
euiTheme: { themeName: 'borealis' },
colorMode: 'DARK',
});
const { result } = renderHook(() => useThemes());
expect(result.current.baseTheme).toBe(LEGACY_DARK_THEME);
expect(result.current.baseTheme).toBe(DARK_THEME);
});
});
});

View file

@ -17,12 +17,12 @@ import type {
BarSeriesStyle,
Theme,
} from '@elastic/charts';
import { LEGACY_DARK_THEME, LEGACY_LIGHT_THEME, Position } from '@elastic/charts';
import { Position } from '@elastic/charts';
import { EuiFlexGroup } from '@elastic/eui';
import React from 'react';
import styled from '@emotion/styled';
import { useDarkMode } from '../../lib/kibana';
import { useElasticChartsTheme } from '@kbn/charts-theme';
export const defaultChartHeight = '100%';
export const defaultChartWidth = '100%';
@ -112,9 +112,7 @@ const theme: PartialTheme = {
},
};
export const useThemes = (): { baseTheme: Theme; theme: PartialTheme } => {
const isDarkMode = useDarkMode();
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
const baseTheme = isDarkMode ? LEGACY_DARK_THEME : LEGACY_LIGHT_THEME;
const baseTheme = useElasticChartsTheme();
return {
baseTheme,
theme,

View file

@ -6,15 +6,8 @@
*/
import React, { VFC } from 'react';
import {
Axis,
BarSeries,
Chart,
Position,
ScaleType,
Settings,
LEGACY_LIGHT_THEME,
} from '@elastic/charts';
import { Axis, BarSeries, Chart, Position, ScaleType, Settings } from '@elastic/charts';
import { useElasticChartsTheme } from '@kbn/charts-theme';
import { EuiComboBoxOptionOption, EuiThemeProvider } from '@elastic/eui';
import { TimeRangeBounds } from '@kbn/data-plugin/common';
import { i18n } from '@kbn/i18n';
@ -55,12 +48,12 @@ export const IndicatorsBarChart: VFC<IndicatorsBarChartProps> = ({
field,
height = DEFAULT_CHART_HEIGHT,
}) => {
const chartBaseTheme = useElasticChartsTheme();
return (
<EuiThemeProvider>
<Chart size={{ width: DEFAULT_CHART_WIDTH, height }}>
<Settings
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={chartBaseTheme}
showLegend
legendPosition={Position.Right}
legendSize={DEFAULT_LEGEND_SIZE}

View file

@ -34,7 +34,8 @@
"@kbn/securitysolution-io-ts-list-types",
"@kbn/core-ui-settings-browser",
"@kbn/search-types",
"@kbn/response-ops-alerts-fields-browser"
"@kbn/response-ops-alerts-fields-browser",
"@kbn/charts-theme"
],
"exclude": ["target/**/*"]
}