diff --git a/src/constants.ts b/src/constants.ts index 2a1832bc47..729d6e2bef 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -60,11 +60,10 @@ export const ALERT_INFO_BORDER = "#98DBE2"; export const ALERT_INFO_TEXT_COLOR = "#09414A"; export const BADGE_SELECTED_COLOR = "#E6F2F3"; -export const DEFAULT_CHART_PADDING = 20; -export const DEFAULT_CHART_FONT_SIZE = 22; - -export const SCORECARD_GAUGE_CHART_PADDING = 10; -export const SCORECARD_GAUGE_CHART_FONT_SIZE = 14; +export const CHART_PADDING = 20; +export const CHART_PADDING_BOTTOM = 10; +export const CHART_PADDING_TOP = 15; +export const CHART_TITLE_FONT_SIZE = 16; // Color picker defaults as upper case HEX to match `toHex`helper export const COLOR_PICKER_DEFAULTS: Color[] = [ diff --git a/src/helpers/figures/charts/bar_chart.ts b/src/helpers/figures/charts/bar_chart.ts index 930582a624..f5abcbe96e 100644 --- a/src/helpers/figures/charts/bar_chart.ts +++ b/src/helpers/figures/charts/bar_chart.ts @@ -45,10 +45,10 @@ import { CHART_COMMON_OPTIONS, truncateLabel } from "./chart_ui_common"; import { getBarChartData, getBarChartDatasets, - getBarChartLayout, getBarChartLegend, getBarChartScales, getBarChartTooltip, + getChartLayout, getChartShowValues, getChartTitle, } from "./runtime"; @@ -234,7 +234,7 @@ export function createBarChartRuntime(chart: BarChart, getters: Getters): BarCha options: { ...CHART_COMMON_OPTIONS, indexAxis: chart.horizontal ? "y" : "x", - layout: getBarChartLayout(definition), + layout: getChartLayout(definition), scales: getBarChartScales(definition, chartData), plugins: { title: getChartTitle(definition), diff --git a/src/helpers/figures/charts/chart_common.ts b/src/helpers/figures/charts/chart_common.ts index 5d978601c4..604f6e1000 100644 --- a/src/helpers/figures/charts/chart_common.ts +++ b/src/helpers/figures/charts/chart_common.ts @@ -332,6 +332,13 @@ export function chartFontColor(backgroundColor: Color | undefined): Color { return relativeLuminance(backgroundColor) < 0.3 ? "#FFFFFF" : "#000000"; } +export function chartMutedFontColor(backgroundColor: Color | undefined): Color { + if (!backgroundColor) { + return "#666666"; + } + return relativeLuminance(backgroundColor) < 0.3 ? "#C8C8C8" : "#666666"; +} + export function checkDataset(definition: ChartWithDataSetDefinition): CommandResult { if (definition.dataSets) { const invalidRanges = diff --git a/src/helpers/figures/charts/combo_chart.ts b/src/helpers/figures/charts/combo_chart.ts index b6fdf4454e..2bedd46c41 100644 --- a/src/helpers/figures/charts/combo_chart.ts +++ b/src/helpers/figures/charts/combo_chart.ts @@ -47,9 +47,9 @@ import { import { CHART_COMMON_OPTIONS, truncateLabel } from "./chart_ui_common"; import { getBarChartData, - getBarChartLayout, getBarChartScales, getBarChartTooltip, + getChartLayout, getChartShowValues, getChartTitle, getComboChartDatasets, @@ -236,7 +236,7 @@ export function createComboChartRuntime(chart: ComboChart, getters: Getters): Co }, options: { ...CHART_COMMON_OPTIONS, - layout: getBarChartLayout(definition), + layout: getChartLayout(definition), scales: getBarChartScales(definition, chartData), plugins: { title: getChartTitle(definition), diff --git a/src/helpers/figures/charts/gauge_chart_rendering.ts b/src/helpers/figures/charts/gauge_chart_rendering.ts index e96ae1d94e..0adbbd1e16 100644 --- a/src/helpers/figures/charts/gauge_chart_rendering.ts +++ b/src/helpers/figures/charts/gauge_chart_rendering.ts @@ -1,11 +1,11 @@ import { + CHART_PADDING, + CHART_PADDING_TOP, + CHART_TITLE_FONT_SIZE, DEFAULT_FONT, - SCORECARD_GAUGE_CHART_FONT_SIZE, - SCORECARD_GAUGE_CHART_PADDING, } from "../../../constants"; import { Color, PixelPosition, Rect } from "../../../types"; import { GaugeChartRuntime } from "../../../types/chart"; -import { relativeLuminance } from "../../color"; import { clip } from "../../misc"; import { computeTextDimension, @@ -13,6 +13,7 @@ import { getDefaultContextFont, getFontSizeMatchingWidth, } from "../../text_helper"; +import { chartMutedFontColor } from "./chart_common"; export const GAUGE_PADDING_SIDE = 30; export const GAUGE_PADDING_TOP = 10; @@ -21,15 +22,9 @@ export const GAUGE_LABELS_FONT_SIZE = 12; export const GAUGE_DEFAULT_VALUE_FONT_SIZE = 80; const GAUGE_BACKGROUND_COLOR = "#F3F2F1"; -export const GAUGE_TEXT_COLOR = "#666666"; -export const GAUGE_TEXT_COLOR_HIGH_CONTRAST = "#C8C8C8"; -const GAUGE_INFLECTION_MARKER_COLOR = "#666666aa"; const GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN = 6; export const GAUGE_TITLE_SECTION_HEIGHT = 25; -export const GAUGE_TITLE_FONT_SIZE = SCORECARD_GAUGE_CHART_FONT_SIZE; -export const GAUGE_TITLE_PADDING_LEFT = SCORECARD_GAUGE_CHART_PADDING; -export const GAUGE_TITLE_PADDING_TOP = SCORECARD_GAUGE_CHART_PADDING; interface RenderingParams { width: number; @@ -144,7 +139,7 @@ function drawInflectionValues(ctx: CanvasRenderingContext2D, config: RenderingPa ctx.rotate(Math.PI / 2 - inflectionValue.rotation); ctx.lineWidth = 2; - ctx.strokeStyle = GAUGE_INFLECTION_MARKER_COLOR; + ctx.strokeStyle = chartMutedFontColor(config.backgroundColor) + "aa"; ctx.beginPath(); ctx.moveTo(0, -(height - config.gauge.arcWidth)); ctx.lineTo(0, -height - 3); @@ -217,7 +212,7 @@ export function getGaugeRenderingConfig( y: gaugeRect.y + gaugeRect.height + GAUGE_LABELS_FONT_SIZE, }; - const textColor = getContrastedTextColor(runtime.background); + const textColor = chartMutedFontColor(runtime.background); const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx); @@ -228,20 +223,20 @@ export function getGaugeRenderingConfig( ({ width: titleWidth, height: titleHeight } = computeTextDimension( ctx, runtime.title.text, - { ...runtime.title, fontSize: GAUGE_TITLE_FONT_SIZE }, + { ...runtime.title, fontSize: CHART_TITLE_FONT_SIZE }, "px" )); } switch (runtime.title.align) { case "right": - x = boundingRect.width - titleWidth - GAUGE_TITLE_PADDING_LEFT; + x = boundingRect.width - titleWidth - CHART_PADDING; break; case "center": x = (boundingRect.width - titleWidth) / 2; break; case "left": default: - x = GAUGE_TITLE_PADDING_LEFT; + x = CHART_PADDING; break; } @@ -250,10 +245,10 @@ export function getGaugeRenderingConfig( height: boundingRect.height, title: { label: runtime.title.text ?? "", - fontSize: GAUGE_TITLE_FONT_SIZE, + fontSize: CHART_TITLE_FONT_SIZE, textPosition: { x, - y: GAUGE_TITLE_PADDING_TOP + titleHeight / 2, + y: CHART_PADDING_TOP + titleHeight / 2, }, color: runtime.title.color ?? textColor, bold: runtime.title.bold, @@ -384,12 +379,6 @@ function getGaugeColor(runtime: GaugeChartRuntime): Color { return runtime.colors.at(-1)!; } -function getContrastedTextColor(backgroundColor: Color) { - return relativeLuminance(backgroundColor) > 0.3 - ? GAUGE_TEXT_COLOR - : GAUGE_TEXT_COLOR_HIGH_CONTRAST; -} - function getSegmentsOfRectangle(rectangle: UnalignedRectangle): Segment[] { return [ { start: rectangle.topLeft, end: rectangle.topRight }, diff --git a/src/helpers/figures/charts/line_chart.ts b/src/helpers/figures/charts/line_chart.ts index 4dadd0ae87..037e711941 100644 --- a/src/helpers/figures/charts/line_chart.ts +++ b/src/helpers/figures/charts/line_chart.ts @@ -44,11 +44,11 @@ import { } from "./chart_common"; import { CHART_COMMON_OPTIONS, truncateLabel } from "./chart_ui_common"; import { + getChartLayout, getChartShowValues, getChartTitle, getLineChartData, getLineChartDatasets, - getLineChartLayout, getLineChartLegend, getLineChartScales, getLineChartTooltip, @@ -244,7 +244,7 @@ export function createLineChartRuntime(chart: LineChart, getters: Getters): Char }, options: { ...CHART_COMMON_OPTIONS, - layout: getLineChartLayout(definition), + layout: getChartLayout(definition), scales: getLineChartScales(definition, chartData), plugins: { title: getChartTitle(definition), diff --git a/src/helpers/figures/charts/pie_chart.ts b/src/helpers/figures/charts/pie_chart.ts index 842ed55ab3..0894754ae3 100644 --- a/src/helpers/figures/charts/pie_chart.ts +++ b/src/helpers/figures/charts/pie_chart.ts @@ -39,11 +39,11 @@ import { } from "./chart_common"; import { CHART_COMMON_OPTIONS, truncateLabel } from "./chart_ui_common"; import { + getChartLayout, getChartShowValues, getChartTitle, getPieChartData, getPieChartDatasets, - getPieChartLayout, getPieChartLegend, getPieChartTooltip, } from "./runtime"; @@ -207,7 +207,7 @@ export function createPieChartRuntime(chart: PieChart, getters: Getters): PieCha }, options: { ...CHART_COMMON_OPTIONS, - layout: getPieChartLayout(definition), + layout: getChartLayout(definition), plugins: { title: getChartTitle(definition), legend: getPieChartLegend(definition, chartData), diff --git a/src/helpers/figures/charts/pyramid_chart.ts b/src/helpers/figures/charts/pyramid_chart.ts index f18b8904ec..4b6f00a59f 100644 --- a/src/helpers/figures/charts/pyramid_chart.ts +++ b/src/helpers/figures/charts/pyramid_chart.ts @@ -36,8 +36,8 @@ import { import { CHART_COMMON_OPTIONS, truncateLabel } from "./chart_ui_common"; import { getBarChartDatasets, - getBarChartLayout, getBarChartLegend, + getChartLayout, getChartShowValues, getChartTitle, getPyramidChartData, @@ -210,7 +210,7 @@ export function createPyramidChartRuntime( options: { ...CHART_COMMON_OPTIONS, indexAxis: "y", - layout: getBarChartLayout(definition), + layout: getChartLayout(definition), scales: getPyramidChartScales(definition, chartData), plugins: { title: getChartTitle(definition), diff --git a/src/helpers/figures/charts/radar_chart.ts b/src/helpers/figures/charts/radar_chart.ts index 1c48281786..632d805c57 100644 --- a/src/helpers/figures/charts/radar_chart.ts +++ b/src/helpers/figures/charts/radar_chart.ts @@ -41,7 +41,7 @@ import { } from "./chart_common"; import { CHART_COMMON_OPTIONS, truncateLabel } from "./chart_ui_common"; import { - getBarChartLayout, + getChartLayout, getChartShowValues, getChartTitle, getRadarChartData, @@ -228,7 +228,7 @@ export function createRadarChartRuntime(chart: RadarChart, getters: Getters): Ra }, options: { ...CHART_COMMON_OPTIONS, - layout: getBarChartLayout(definition), + layout: getChartLayout(definition), scales: getRadarChartScales(definition, chartData), plugins: { title: getChartTitle(definition), diff --git a/src/helpers/figures/charts/runtime/chartjs_layout.ts b/src/helpers/figures/charts/runtime/chartjs_layout.ts index 2b5f3cc42b..91d821e2b2 100644 --- a/src/helpers/figures/charts/runtime/chartjs_layout.ts +++ b/src/helpers/figures/charts/runtime/chartjs_layout.ts @@ -1,80 +1,18 @@ import { ChartOptions } from "chart.js"; -import { DEFAULT_CHART_PADDING } from "../../../../constants"; -import { - BarChartDefinition, - ChartWithDataSetDefinition, - GenericDefinition, - LineChartDefinition, - PieChartDefinition, - WaterfallChartDefinition, -} from "../../../../types/chart"; +import { CHART_PADDING, CHART_PADDING_BOTTOM, CHART_PADDING_TOP } from "../../../../constants"; +import { ChartWithDataSetDefinition, GenericDefinition } from "../../../../types/chart"; type ChartLayout = ChartOptions["layout"]; -export function getCommonChartLayout( +export function getChartLayout( definition: GenericDefinition ): ChartLayout { - // TODO FIXME: this is unused ATM. All the charts should probably use this instead oh whatever padding they are using now - // also look into how DEFAULT_CHART_PADDING is used in scorecards, it look strange return { padding: { - left: DEFAULT_CHART_PADDING, - right: DEFAULT_CHART_PADDING, - top: definition.title?.text ? DEFAULT_CHART_PADDING / 2 : DEFAULT_CHART_PADDING + 5, - bottom: DEFAULT_CHART_PADDING, + left: CHART_PADDING, + right: CHART_PADDING, + top: CHART_PADDING_TOP, + bottom: CHART_PADDING_BOTTOM, }, }; } - -export function getBarChartLayout(definition: GenericDefinition): ChartLayout { - return { - padding: computeChartPadding({ - displayTitle: !!definition.title?.text, - displayLegend: definition.legendPosition === "top", - }), - }; -} - -export function getLineChartLayout( - definition: GenericDefinition -): ChartLayout { - return { - padding: computeChartPadding({ - displayTitle: !!definition.title?.text, - displayLegend: definition.legendPosition === "top", - }), - }; -} - -export function getPieChartLayout(definition: PieChartDefinition): ChartLayout { - return { - padding: { left: 20, right: 20, top: definition.title ? 10 : 25, bottom: 10 }, - }; -} - -export function getWaterfallChartLayout(definition: WaterfallChartDefinition): ChartLayout { - return { - padding: { left: 20, right: 20, top: definition.title ? 10 : 25, bottom: 10 }, - }; -} - -function computeChartPadding({ - displayTitle, - displayLegend, -}: { - displayTitle: boolean; - displayLegend: boolean; -}): { - top: number; - bottom: number; - left: number; - right: number; -} { - let top = 25; - if (displayTitle) { - top = 0; - } else if (displayLegend) { - top = 10; - } - return { left: 20, right: 20, top, bottom: 10 }; -} diff --git a/src/helpers/figures/charts/runtime/chartjs_title.ts b/src/helpers/figures/charts/runtime/chartjs_title.ts index 6a6662b666..90b71d70a3 100644 --- a/src/helpers/figures/charts/runtime/chartjs_title.ts +++ b/src/helpers/figures/charts/runtime/chartjs_title.ts @@ -1,15 +1,15 @@ import { TitleOptions } from "chart.js"; import { _DeepPartialObject } from "chart.js/dist/types/utils"; -import { DEFAULT_CHART_FONT_SIZE } from "../../../../constants"; +import { CHART_PADDING, CHART_TITLE_FONT_SIZE } from "../../../../constants"; import { _t } from "../../../../translation"; import { ChartWithDataSetDefinition } from "../../../../types/chart"; -import { chartFontColor } from "../chart_common"; +import { chartMutedFontColor } from "../chart_common"; export function getChartTitle( definition: ChartWithDataSetDefinition ): _DeepPartialObject { const chartTitle = definition.title; - const fontColor = chartFontColor(definition.background); + const fontColor = chartMutedFontColor(definition.background); return { display: !!chartTitle.text, text: _t(chartTitle.text!), @@ -17,9 +17,14 @@ export function getChartTitle( align: chartTitle.align === "center" ? "center" : chartTitle.align === "right" ? "end" : "start", font: { - size: DEFAULT_CHART_FONT_SIZE, + size: CHART_TITLE_FONT_SIZE, weight: chartTitle.bold ? "bold" : "normal", style: chartTitle.italic ? "italic" : "normal", }, + padding: { + // Disable title top/left/right padding to use the chart padding instead. + // The legend already has a top padding, so bottom padding is useless for the title there. + bottom: definition.legendPosition === "top" ? 0 : CHART_PADDING, + }, }; } diff --git a/src/helpers/figures/charts/scatter_chart.ts b/src/helpers/figures/charts/scatter_chart.ts index b362192e13..a4e7607687 100644 --- a/src/helpers/figures/charts/scatter_chart.ts +++ b/src/helpers/figures/charts/scatter_chart.ts @@ -42,10 +42,10 @@ import { } from "./chart_common"; import { CHART_COMMON_OPTIONS, truncateLabel } from "./chart_ui_common"; import { + getChartLayout, getChartShowValues, getChartTitle, getLineChartData, - getLineChartLayout, getLineChartTooltip, getScatterChartDatasets, getScatterChartLegend, @@ -237,7 +237,7 @@ export function createScatterChartRuntime( }, options: { ...CHART_COMMON_OPTIONS, - layout: getLineChartLayout(definition), + layout: getChartLayout(definition), scales: getScatterChartScales(definition, chartData), plugins: { title: getChartTitle(definition), diff --git a/src/helpers/figures/charts/scorecard_chart.ts b/src/helpers/figures/charts/scorecard_chart.ts index a8e8473223..483543fe9f 100644 --- a/src/helpers/figures/charts/scorecard_chart.ts +++ b/src/helpers/figures/charts/scorecard_chart.ts @@ -1,6 +1,6 @@ import { transformZone } from "../../../collaborative/ot/ot_helpers"; import { - DEFAULT_CHART_PADDING, + CHART_PADDING, DEFAULT_SCORECARD_BASELINE_COLOR_DOWN, DEFAULT_SCORECARD_BASELINE_COLOR_UP, DEFAULT_SCORECARD_BASELINE_MODE, @@ -295,7 +295,7 @@ export class ScorecardChart extends AbstractChart { export function drawScoreChart(structure: ScorecardChartConfig, canvas: HTMLCanvasElement) { const ctx = canvas.getContext("2d")!; canvas.width = structure.canvas.width; - const availableWidth = canvas.width - DEFAULT_CHART_PADDING; + const availableWidth = canvas.width - CHART_PADDING * 2; canvas.height = structure.canvas.height; ctx.fillStyle = structure.canvas.backgroundColor; diff --git a/src/helpers/figures/charts/scorecard_chart_config_builder.ts b/src/helpers/figures/charts/scorecard_chart_config_builder.ts index 08a7901b61..47b7943e59 100644 --- a/src/helpers/figures/charts/scorecard_chart_config_builder.ts +++ b/src/helpers/figures/charts/scorecard_chart_config_builder.ts @@ -1,20 +1,15 @@ import { Color } from "chart.js"; -import { - DEFAULT_CHART_PADDING, - SCORECARD_GAUGE_CHART_FONT_SIZE, - SCORECARD_GAUGE_CHART_PADDING, -} from "../../../constants"; import { DOMDimension, Pixel, PixelPosition } from "../../../types"; import { BaselineArrowDirection, ScorecardChartRuntime } from "../../../types/chart"; -import { relativeLuminance } from "../../color"; import { getDefaultContextFont } from "../../text_helper"; +import { chartMutedFontColor } from "./chart_common"; /* Padding at the border of the chart */ -const CHART_PADDING = SCORECARD_GAUGE_CHART_PADDING; +const CHART_PADDING = 10; const BOTTOM_PADDING_RATIO = 0.05; /* Maximum font sizes of each element */ -const CHART_TITLE_FONT_SIZE = SCORECARD_GAUGE_CHART_FONT_SIZE; +const CHART_TITLE_FONT_SIZE = 14; const KEY_VALUE_FONT_SIZE = 32; const BASELINE_MAX_FONT_SIZE = 16; @@ -149,7 +144,7 @@ class ScorecardChartConfigBuilder { }, }; - const minimalBaselinePosition = baselineArrowSize + DEFAULT_CHART_PADDING; + const minimalBaselinePosition = baselineArrowSize + CHART_PADDING * 2; if (structure.baseline.position.x < minimalBaselinePosition) { structure.baseline.position.x = minimalBaselinePosition; } @@ -244,7 +239,7 @@ class ScorecardChartConfigBuilder { } private get secondaryFontColor() { - return relativeLuminance(this.backgroundColor) > 0.3 ? "#525252" : "#C8C8C8"; + return chartMutedFontColor(this.backgroundColor); } private getTextDimensions(text: string, font: string) { diff --git a/src/helpers/figures/charts/waterfall_chart.ts b/src/helpers/figures/charts/waterfall_chart.ts index 7fbf35dfa9..3110c6832e 100644 --- a/src/helpers/figures/charts/waterfall_chart.ts +++ b/src/helpers/figures/charts/waterfall_chart.ts @@ -38,9 +38,9 @@ import { import { CHART_COMMON_OPTIONS } from "./chart_ui_common"; import { getBarChartData, + getChartLayout, getChartShowValues, getChartTitle, - getWaterfallChartLayout, getWaterfallChartLegend, getWaterfallChartScales, getWaterfallChartTooltip, @@ -232,7 +232,7 @@ export function createWaterfallChartRuntime( }, options: { ...CHART_COMMON_OPTIONS, - layout: getWaterfallChartLayout(definition), + layout: getChartLayout(definition), scales: getWaterfallChartScales(definition, chartData), plugins: { title: getChartTitle(definition), diff --git a/src/xlsx/functions/charts.ts b/src/xlsx/functions/charts.ts index 537e679e5c..94828a2178 100644 --- a/src/xlsx/functions/charts.ts +++ b/src/xlsx/functions/charts.ts @@ -1,5 +1,6 @@ -import { DEFAULT_CHART_FONT_SIZE } from "../../constants"; +import { CHART_TITLE_FONT_SIZE } from "../../constants"; import { ColorGenerator, largeMax, range } from "../../helpers"; +import { chartMutedFontColor } from "../../helpers/figures/charts"; import { Color, ExcelWorkbookData, FigureData } from "../../types"; import { ExcelChartDataset, ExcelChartDefinition, TitleDesign } from "../../types/chart/chart"; import { XMLAttributes, XMLString, XlsxHexColor } from "../../types/xlsx"; @@ -56,12 +57,10 @@ export function createChart( // to manually position the chart in the figure container let title = escapeXml``; if (chart.data.title?.text) { - const color = chart.data.title.color - ? toXlsxHexColor(chart.data.title.color) - : chart.data.fontColor; + const titleColor = toXlsxHexColor(chartMutedFontColor(chart.data.backgroundColor)); title = escapeXml/*xml*/ ` - ${insertText(chart.data.title.text, color, DEFAULT_CHART_FONT_SIZE, chart.data.title)} + ${insertText(chart.data.title.text, titleColor, CHART_TITLE_FONT_SIZE, chart.data.title)} `; @@ -159,7 +158,7 @@ function lineAttributes(params: LineAttributes): XMLString { function insertText( text: string, fontColor: XlsxHexColor = "000000", - fontsize: number = DEFAULT_CHART_FONT_SIZE, + fontsize: number, style: { bold?: boolean; italic?: boolean } = {} ): XMLString { return escapeXml/*xml*/ ` diff --git a/tests/figures/chart/__snapshots__/chart_plugin.test.ts.snap b/tests/figures/chart/__snapshots__/chart_plugin.test.ts.snap index 33ecddfd79..3622d06987 100644 --- a/tests/figures/chart/__snapshots__/chart_plugin.test.ts.snap +++ b/tests/figures/chart/__snapshots__/chart_plugin.test.ts.snap @@ -51,7 +51,7 @@ exports[`Linear/Time charts font color is white with a dark background color 1`] "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -76,13 +76,16 @@ exports[`Linear/Time charts font color is white with a dark background color 1`] }, "title": { "align": "start", - "color": "#FFFFFF", + "color": "#C8C8C8", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -183,7 +186,7 @@ exports[`Linear/Time charts snapshot test of chartJS configuration for date char "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -208,13 +211,16 @@ exports[`Linear/Time charts snapshot test of chartJS configuration for date char }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -322,7 +328,7 @@ exports[`Linear/Time charts snapshot test of chartJS configuration for linear ch "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -347,13 +353,16 @@ exports[`Linear/Time charts snapshot test of chartJS configuration for linear ch }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -436,7 +445,7 @@ exports[`datasource tests create a chart with stacked bar 1`] = ` "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -461,13 +470,16 @@ exports[`datasource tests create a chart with stacked bar 1`] = ` }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -548,7 +560,7 @@ exports[`datasource tests create chart with a dataset of one cell (no title) 1`] "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -573,13 +585,16 @@ exports[`datasource tests create chart with a dataset of one cell (no title) 1`] }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -678,7 +693,7 @@ exports[`datasource tests create chart with column datasets 1`] = ` "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -703,13 +718,16 @@ exports[`datasource tests create chart with column datasets 1`] = ` }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -808,7 +826,7 @@ exports[`datasource tests create chart with column datasets with category title "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -833,13 +851,16 @@ exports[`datasource tests create chart with column datasets with category title }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -938,7 +959,7 @@ exports[`datasource tests create chart with column datasets without series title "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -963,13 +984,16 @@ exports[`datasource tests create chart with column datasets without series title }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -1039,7 +1063,7 @@ exports[`datasource tests create chart with only the dataset title (no data) 1`] "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -1064,13 +1088,16 @@ exports[`datasource tests create chart with only the dataset title (no data) 1`] }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -1169,7 +1196,7 @@ exports[`datasource tests create chart with rectangle dataset 1`] = ` "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -1194,13 +1221,16 @@ exports[`datasource tests create chart with rectangle dataset 1`] = ` }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -1299,7 +1329,7 @@ exports[`datasource tests create chart with row datasets 1`] = ` "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -1324,13 +1354,16 @@ exports[`datasource tests create chart with row datasets 1`] = ` }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -1429,7 +1462,7 @@ exports[`datasource tests create chart with row datasets with category title 1`] "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -1454,13 +1487,16 @@ exports[`datasource tests create chart with row datasets with category title 1`] }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { @@ -1559,7 +1595,7 @@ exports[`datasource tests create chart with row datasets without series title 1` "bottom": 10, "left": 20, "right": 20, - "top": 0, + "top": 15, }, }, "maintainAspectRatio": false, @@ -1584,13 +1620,16 @@ exports[`datasource tests create chart with row datasets without series title 1` }, "title": { "align": "start", - "color": "#000000", + "color": "#666666", "display": true, "font": { - "size": 22, + "size": 16, "style": "normal", "weight": "normal", }, + "padding": { + "bottom": 0, + }, "text": "test", }, "tooltip": { diff --git a/tests/figures/chart/chart_plugin.test.ts b/tests/figures/chart/chart_plugin.test.ts index da9c6601d1..102fd5b0eb 100644 --- a/tests/figures/chart/chart_plugin.test.ts +++ b/tests/figures/chart/chart_plugin.test.ts @@ -48,7 +48,13 @@ import { } from "../../test_helpers/helpers"; import { ChartTerms } from "../../../src/components/translations_terms"; -import { FIGURE_ID_SPLITTER, MAX_CHAR_LABEL } from "../../../src/constants"; +import { + CHART_PADDING, + CHART_PADDING_BOTTOM, + CHART_PADDING_TOP, + FIGURE_ID_SPLITTER, + MAX_CHAR_LABEL, +} from "../../../src/constants"; import { range, toZone, zoneToXc } from "../../../src/helpers"; import { BarChart } from "../../../src/helpers/figures/charts"; import { ChartPlugin } from "../../../src/plugins/core"; @@ -2037,8 +2043,6 @@ describe("Chart design configuration", () => { createChart( model, { - dataSets: [{ dataRange: "B1:B2" }], - labelRange: "A1:A2", type: chartType, legendPosition: "none", title: { text: "" }, @@ -2047,10 +2051,10 @@ describe("Chart design configuration", () => { ); const config = getChartConfiguration(model, "1"); expect(config.options.layout.padding).toEqual({ - top: 25, - bottom: 10, - left: 20, - right: 20, + top: CHART_PADDING_TOP, + bottom: CHART_PADDING_BOTTOM, + left: CHART_PADDING, + right: CHART_PADDING, }); } ); @@ -2073,8 +2077,6 @@ describe("Chart design configuration", () => { createChart( model, { - dataSets: [{ dataRange: "B1:B2" }], - labelRange: "A1:A2", type: chartType, legendPosition: "bottom", title: { text: "" }, @@ -2083,39 +2085,18 @@ describe("Chart design configuration", () => { ); let config = getChartConfiguration(model, "1"); expect(config.options.layout.padding).toEqual({ - top: 25, - bottom: 10, - left: 20, - right: 20, + top: CHART_PADDING_TOP, + bottom: CHART_PADDING_BOTTOM, + left: CHART_PADDING, + right: CHART_PADDING, + }); + expect(config.options.plugins.title.padding).toEqual({ + bottom: CHART_PADDING, }); updateChart(model, "1", { legendPosition: "top" }); config = getChartConfiguration(model, "1"); - expect(config.options.layout.padding.top).toEqual(10); - } - ); - - test.each(["line", "scatter", "combo", "bar"] as const)( - "%s chart with a title and a legend have the correct padding", - (chartType) => { - createChart( - model, - { - dataSets: [{ dataRange: "B1:B2" }], - labelRange: "A1:A2", - type: chartType, - legendPosition: "bottom", - title: { text: "test" }, - }, - "1" - ); - const config = getChartConfiguration(model, "1"); - expect(config.options.layout.padding).toEqual({ - top: 0, - bottom: 10, - left: 20, - right: 20, - }); + expect(config.options.plugins.title.padding).toEqual({ bottom: 0 }); } ); }); diff --git a/tests/figures/chart/gauge/gauge_rendering.test.ts b/tests/figures/chart/gauge/gauge_rendering.test.ts index f560fcb1e1..360d5cf03e 100644 --- a/tests/figures/chart/gauge/gauge_rendering.test.ts +++ b/tests/figures/chart/gauge/gauge_rendering.test.ts @@ -1,10 +1,8 @@ +import { CHART_PADDING, CHART_TITLE_FONT_SIZE } from "../../../../src/constants"; +import { chartMutedFontColor } from "../../../../src/helpers/figures/charts"; import { GAUGE_DEFAULT_VALUE_FONT_SIZE, GAUGE_LABELS_FONT_SIZE, - GAUGE_TEXT_COLOR, - GAUGE_TEXT_COLOR_HIGH_CONTRAST, - GAUGE_TITLE_FONT_SIZE, - GAUGE_TITLE_PADDING_LEFT, getGaugeRenderingConfig, } from "../../../../src/helpers/figures/charts/gauge_chart_rendering"; import { Rect } from "../../../../src/types"; @@ -57,12 +55,12 @@ describe("Gauge rendering config", () => { test("Chart title", () => { expect(getRenderingConfig(testRuntime).title).toEqual({ label: testRuntime.title.text, - fontSize: GAUGE_TITLE_FONT_SIZE, + fontSize: CHART_TITLE_FONT_SIZE, textPosition: { - x: GAUGE_TITLE_PADDING_LEFT, + x: CHART_PADDING, y: NaN, }, - color: GAUGE_TEXT_COLOR, + color: chartMutedFontColor(testRuntime.background), }); }); @@ -75,7 +73,7 @@ describe("Gauge rendering config", () => { y: config.gauge.rect.y + config.gauge.rect.height + GAUGE_LABELS_FONT_SIZE, // below the gauge }, fontSize: GAUGE_LABELS_FONT_SIZE, - color: GAUGE_TEXT_COLOR, + color: chartMutedFontColor(testRuntime.background), }); }); @@ -88,7 +86,7 @@ describe("Gauge rendering config", () => { y: config.gauge.rect.y + config.gauge.rect.height + GAUGE_LABELS_FONT_SIZE, // below the gauge }, fontSize: GAUGE_LABELS_FONT_SIZE, - color: GAUGE_TEXT_COLOR, + color: chartMutedFontColor(testRuntime.background), }); }); @@ -159,14 +157,14 @@ describe("Gauge rendering config", () => { rotation: Math.PI * (1 - 0.25), label: "25", fontSize: GAUGE_LABELS_FONT_SIZE, - color: GAUGE_TEXT_COLOR, + color: chartMutedFontColor(testRuntime.background), offset: 0, }, { rotation: Math.PI * (1 - 0.75), label: "75", fontSize: GAUGE_LABELS_FONT_SIZE, - color: GAUGE_TEXT_COLOR, + color: chartMutedFontColor(testRuntime.background), offset: 0, }, ]); @@ -195,7 +193,7 @@ describe("Gauge rendering config", () => { y: config.gauge.rect.y + config.gauge.rect.height - config.gauge.rect.height / 12, }, fontSize: GAUGE_DEFAULT_VALUE_FONT_SIZE, - color: GAUGE_TEXT_COLOR, + color: chartMutedFontColor(testRuntime.background), }); }); @@ -214,11 +212,11 @@ describe("Gauge rendering config", () => { test("Text colors are contrasted on dark backgrounds", () => { const config = getRenderingConfig({ ...testRuntime, background: "#000000" }); - expect(config.title.color).toEqual(GAUGE_TEXT_COLOR_HIGH_CONTRAST); - expect(config.minLabel.color).toEqual(GAUGE_TEXT_COLOR_HIGH_CONTRAST); - expect(config.maxLabel.color).toEqual(GAUGE_TEXT_COLOR_HIGH_CONTRAST); - expect(config.gaugeValue.color).toEqual(GAUGE_TEXT_COLOR_HIGH_CONTRAST); - expect(config.inflectionValues[0].color).toEqual(GAUGE_TEXT_COLOR_HIGH_CONTRAST); - expect(config.inflectionValues[1].color).toEqual(GAUGE_TEXT_COLOR_HIGH_CONTRAST); + expect(config.title.color).toEqual(chartMutedFontColor("#000000")); + expect(config.minLabel.color).toEqual(chartMutedFontColor("#000000")); + expect(config.maxLabel.color).toEqual(chartMutedFontColor("#000000")); + expect(config.gaugeValue.color).toEqual(chartMutedFontColor("#000000")); + expect(config.inflectionValues[0].color).toEqual(chartMutedFontColor("#000000")); + expect(config.inflectionValues[1].color).toEqual(chartMutedFontColor("#000000")); }); }); diff --git a/tests/figures/chart/scorecard/scorecard_chart_component.test.ts b/tests/figures/chart/scorecard/scorecard_chart_component.test.ts index 76db384986..5a6357977a 100644 --- a/tests/figures/chart/scorecard/scorecard_chart_component.test.ts +++ b/tests/figures/chart/scorecard/scorecard_chart_component.test.ts @@ -4,7 +4,7 @@ import { DEFAULT_SCORECARD_BASELINE_COLOR_UP, } from "../../../../src/constants"; import { getContextFontSize } from "../../../../src/helpers"; -import { drawScoreChart } from "../../../../src/helpers/figures/charts"; +import { chartMutedFontColor, drawScoreChart } from "../../../../src/helpers/figures/charts"; import { ScorecardChartConfig, formatBaselineDescr, @@ -28,6 +28,8 @@ let model: Model; let chartId: string; let sheetId: string; +const mutedFontColor = chartMutedFontColor("#fff"); + function updateScorecardChartSize(width: Pixel, height: Pixel) { model.dispatch("UPDATE_FIGURE", { sheetId, @@ -165,7 +167,7 @@ describe("Scorecard charts computation", () => { const chartDesign = getChartDesign(model, chartId, sheetId); expect(chartDesign.baseline?.text).toEqual("1"); - expect(chartDesign.baseline?.style.color).toBeSameColorAs("#525252"); + expect(chartDesign.baseline?.style.color).toBeSameColorAs(mutedFontColor); }); test("Baseline description and arrow with mode 'progress' are not displayed", () => { @@ -178,7 +180,7 @@ describe("Scorecard charts computation", () => { expect(chartDesign.baselineDescr).toBeUndefined(); expect(chartDesign.baselineArrow).toBeUndefined(); - expect(chartDesign.baseline?.style.color).toBeSameColorAs("#525252"); + expect(chartDesign.baseline?.style.color).toBeSameColorAs(mutedFontColor); expect(chartDesign.baseline?.text).toEqual("200.0%"); }); @@ -264,7 +266,7 @@ describe("Scorecard charts computation", () => { const chartDesign = getChartDesign(model, chartId, sheetId); expect(chartDesign.baselineArrow).toBeUndefined(); - expect(chartDesign.baseline?.style.color).toBeSameColorAs("#525252"); + expect(chartDesign.baseline?.style.color).toBeSameColorAs(mutedFontColor); expect(chartDesign.baseline?.text).toEqual("0"); }); @@ -507,7 +509,7 @@ describe("Scorecard charts rendering", () => { test("Baseline with mode 'text' is plainly displayed", () => { createScorecardChart(model, { keyValue: "A1", baseline: "B1", baselineMode: "text" }, chartId); renderScorecardChart(model, chartId, sheetId, canvas); - expect(scorecardChartStyle.baseline.color).toBeSameColorAs("#525252"); + expect(scorecardChartStyle.baseline.color).toBeSameColorAs(mutedFontColor); }); test("Key < baseline display in red with down arrow", () => { @@ -527,7 +529,7 @@ describe("Scorecard charts rendering", () => { test("Key = baseline display default font color with no arrow", () => { createScorecardChart(model, { keyValue: "A1", baseline: "B2" }, chartId); renderScorecardChart(model, chartId, sheetId, canvas); - expect(scorecardChartStyle.baseline.color).toBeSameColorAs("#525252"); + expect(scorecardChartStyle.baseline.color).toBeSameColorAs(mutedFontColor); }); test("Key value and baseline are displayed with the cell style", () => { diff --git a/tests/xlsx/__snapshots__/xlsx_export.test.ts.snap b/tests/xlsx/__snapshots__/xlsx_export.test.ts.snap index 0a6d1b23b0..6aded8dd3c 100644 --- a/tests/xlsx/__snapshots__/xlsx_export.test.ts.snap +++ b/tests/xlsx/__snapshots__/xlsx_export.test.ts.snap @@ -36,14 +36,14 @@ exports[`Test XLSX export Charts Chart legend is set to none position 1`] = ` - + - + test @@ -640,14 +640,14 @@ exports[`Test XLSX export Charts Export chart overflowing outside the sheet 1`] - + - + test @@ -1230,14 +1230,14 @@ exports[`Test XLSX export Charts chart dataset without title 1`] = ` - + - + test @@ -1821,14 +1821,14 @@ exports[`Test XLSX export Charts chart font color is white with a dark backgroun - + - + test @@ -2105,14 +2105,14 @@ exports[`Test XLSX export Charts chart font color is white with a dark backgroun - + - + test @@ -2314,14 +2314,14 @@ exports[`Test XLSX export Charts chart font color is white with a dark backgroun - + - + test @@ -2621,14 +2621,14 @@ exports[`Test XLSX export Charts chart font color is white with a dark backgroun - + - + test @@ -2708,14 +2708,14 @@ exports[`Test XLSX export Charts chart font color is white with a dark backgroun - + - + test @@ -3015,14 +3015,14 @@ exports[`Test XLSX export Charts chart font color is white with a dark backgroun - + - + test @@ -3925,14 +3925,14 @@ exports[`Test XLSX export Charts charts in different sheets 1`] = ` - + - + test @@ -4405,14 +4405,14 @@ exports[`Test XLSX export Charts charts in different sheets 1`] = ` - + - + test @@ -4948,14 +4948,14 @@ exports[`Test XLSX export Charts multiple charts in the same sheet 1`] = ` - + - + test @@ -5255,14 +5255,14 @@ exports[`Test XLSX export Charts multiple charts in the same sheet 1`] = ` - + - + test @@ -5907,14 +5907,14 @@ exports[`Test XLSX export Charts pie chart with only title dataset 1`] = ` - + - + test @@ -6205,14 +6205,14 @@ exports[`Test XLSX export Charts simple bar chart with customized axis 1`] = ` - + - + test @@ -6775,14 +6775,14 @@ exports[`Test XLSX export Charts simple bar chart with customized dataset 1`] = - + - + test @@ -7339,14 +7339,14 @@ exports[`Test XLSX export Charts simple bar chart with customized title 1`] = ` - + - + Coucou @@ -7905,14 +7905,14 @@ exports[`Test XLSX export Charts simple bar chart with dataset [ [Object] ] 1`] - + - + test @@ -8471,14 +8471,14 @@ exports[`Test XLSX export Charts simple bar chart with dataset [ [Object], [Obje - + - + test @@ -9075,14 +9075,14 @@ exports[`Test XLSX export Charts simple combo chart with customized axis 1`] = ` - + - + test @@ -9644,14 +9644,14 @@ exports[`Test XLSX export Charts simple combo chart with customized dataset 1`] - + - + test @@ -10207,14 +10207,14 @@ exports[`Test XLSX export Charts simple combo chart with customized title 1`] = - + - + Coucou @@ -10772,14 +10772,14 @@ exports[`Test XLSX export Charts simple combo chart with dataset [ [Object] ] 1` - + - + test @@ -11337,14 +11337,14 @@ exports[`Test XLSX export Charts simple combo chart with dataset [ [Object], [Ob - + - + test @@ -11961,14 +11961,14 @@ exports[`Test XLSX export Charts simple line chart with customized axis 1`] = ` - + - + test @@ -12541,14 +12541,14 @@ exports[`Test XLSX export Charts simple line chart with customized dataset 1`] = - + - + test @@ -13115,14 +13115,14 @@ exports[`Test XLSX export Charts simple line chart with customized title 1`] = ` - + - + Coucou @@ -13691,14 +13691,14 @@ exports[`Test XLSX export Charts simple line chart with dataset [ [Object] ] 1`] - + - + test @@ -14267,14 +14267,14 @@ exports[`Test XLSX export Charts simple line chart with dataset [ [Object], [Obj - + - + test @@ -14894,14 +14894,14 @@ exports[`Test XLSX export Charts simple pie chart with dataset [ [Object] ] 1`] - + - + test @@ -15375,14 +15375,14 @@ exports[`Test XLSX export Charts simple pie chart with dataset [ [Object], [Obje - + - + test @@ -15930,14 +15930,14 @@ exports[`Test XLSX export Charts simple radar chart with customized axis 1`] = ` - + - + test @@ -16505,14 +16505,14 @@ exports[`Test XLSX export Charts simple radar chart with customized dataset 1`] - + - + test @@ -17078,14 +17078,14 @@ exports[`Test XLSX export Charts simple radar chart with customized title 1`] = - + - + Coucou @@ -17653,14 +17653,14 @@ exports[`Test XLSX export Charts simple radar chart with dataset [ [Object] ] 1` - + - + test @@ -18228,14 +18228,14 @@ exports[`Test XLSX export Charts simple radar chart with dataset [ [Object], [Ob - + - + test @@ -18854,14 +18854,14 @@ exports[`Test XLSX export Charts simple scatter chart with customized axis 1`] = - + - + test @@ -19434,14 +19434,14 @@ exports[`Test XLSX export Charts simple scatter chart with customized dataset 1` - + - + test @@ -20008,14 +20008,14 @@ exports[`Test XLSX export Charts simple scatter chart with customized title 1`] - + - + Coucou @@ -20584,14 +20584,14 @@ exports[`Test XLSX export Charts simple scatter chart with dataset [ [Object] ] - + - + test @@ -21160,14 +21160,14 @@ exports[`Test XLSX export Charts simple scatter chart with dataset [ [Object], [ - + - + test @@ -21787,14 +21787,14 @@ exports[`Test XLSX export Charts stacked bar chart 1`] = ` - + - + test @@ -32998,14 +32998,14 @@ exports[`Test XLSX export multiple elements are exported in the correct order 1` - + - + test @@ -33510,14 +33510,14 @@ exports[`Test XLSX export references with headers should be converted to referen - + - + test @@ -33817,14 +33817,14 @@ exports[`Test XLSX export references with headers should be converted to referen - + - + test @@ -34101,14 +34101,14 @@ exports[`Test XLSX export references with headers should be converted to referen - + - + test @@ -35831,14 +35831,14 @@ exports[`Test XLSX export references with headers should be converted to referen - + - + test @@ -36138,14 +36138,14 @@ exports[`Test XLSX export references with headers should be converted to referen - + - + test