Skip to content

Commit e6ad813

Browse files
committed
[IMP] chart: add animation to calendar chart
Add a color fade-in animation to calendar chart when it is created or updated. closes #7211 Task: 5123652 Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
1 parent 30800f6 commit e6ad813

File tree

6 files changed

+68
-10
lines changed

6 files changed

+68
-10
lines changed

src/components/figures/chart/chartJs/chartjs.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Store, useStore } from "../../../../store_engine";
77
import { UID } from "../../../../types";
88
import { chartJsExtensionRegistry, registerChartJSExtensions } from "./chart_js_extension";
99
import { ChartAnimationStore } from "./chartjs_animation_store";
10+
import { getCalendarChartController } from "./chartjs_calendar_chart";
1011
import { chartColorScalePlugin } from "./chartjs_colorscale_plugin";
1112
import {
1213
funnelTooltipPositioner,
@@ -57,6 +58,10 @@ chartJsExtensionRegistry.add("chartColorScalePlugin", {
5758
register: (Chart) => Chart.register(chartColorScalePlugin),
5859
unregister: (Chart) => Chart.unregister(chartColorScalePlugin),
5960
});
61+
chartJsExtensionRegistry.add("calendarController", {
62+
register: (Chart) => Chart.register(getCalendarChartController()),
63+
unregister: (Chart) => Chart.unregister(getCalendarChartController()),
64+
});
6065

6166
export class ChartJsComponent extends Component<Props, SpreadsheetChildEnv> {
6267
static template = "o-spreadsheet-ChartJsComponent";
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {
2+
BarController,
3+
BarControllerChartOptions,
4+
BarControllerDatasetOptions,
5+
CartesianParsedData,
6+
CartesianScaleTypeRegistry,
7+
Chart,
8+
ChartComponent,
9+
} from "chart.js";
10+
11+
export function getCalendarChartController(): ChartComponent & {
12+
prototype: BarController;
13+
new (chart: Chart, datasetIndex: number): BarController;
14+
} {
15+
return class CalendarChartController extends window.Chart.BarController {
16+
static id = "calendar";
17+
static defaults = {
18+
...window.Chart?.BarController.defaults,
19+
dataElementType: "bar",
20+
animations: {
21+
numbers: { type: "number", properties: [] }, // Disable number animations (width, height, ...)
22+
},
23+
};
24+
25+
updateElements(rects, start, count, mode) {
26+
super.updateElements(rects, start, count, mode);
27+
28+
// Remove the element background at the start of an animation
29+
const chartBackground = (this.chart.config as any).options?.chartBackground;
30+
const backgroundColor = chartBackground || "#ffffff";
31+
for (let i = start; i < start + count; i++) {
32+
if (mode === "reset") {
33+
this.updateElement(rects[i], i, { options: { backgroundColor } }, mode);
34+
}
35+
}
36+
}
37+
};
38+
}
39+
40+
declare module "chart.js" {
41+
interface ChartTypeRegistry {
42+
calendar: {
43+
chartOptions: BarControllerChartOptions & { chartBackground: string };
44+
datasetOptions: BarControllerDatasetOptions & { values: number[] };
45+
defaultDataPoint: number | null;
46+
metaExtensions: {};
47+
parsedDataType: CartesianParsedData;
48+
scales: keyof CartesianScaleTypeRegistry;
49+
};
50+
}
51+
}

src/helpers/figures/charts/calendar_chart.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { CHART_COMMON_OPTIONS } from "@odoo/o-spreadsheet-engine/helpers/figures
1414
import { createValidRange } from "@odoo/o-spreadsheet-engine/helpers/range";
1515
import {
1616
BarChartDefinition,
17-
BarChartRuntime,
1817
ChartCreationContext,
1918
CustomizedDataSet,
2019
ExcelChartDefinition,
@@ -24,6 +23,7 @@ import {
2423
CALENDAR_CHART_GRANULARITIES,
2524
CalendarChartDefinition,
2625
CalendarChartGranularity,
26+
CalendarChartRuntime,
2727
} from "@odoo/o-spreadsheet-engine/types/chart/calendar_chart";
2828
import type { ChartConfiguration } from "chart.js";
2929
import {
@@ -217,13 +217,13 @@ export class CalendarChart extends AbstractChart {
217217
export function createCalendarChartRuntime(
218218
chart: CalendarChart,
219219
getters: Getters
220-
): BarChartRuntime {
220+
): CalendarChartRuntime {
221221
const definition = chart.getDefinition();
222222
const chartData = getCalendarChartData(definition, chart.dataSets, chart.labelRange, getters);
223223
const { labels, datasets } = getCalendarChartDatasetAndLabels(definition, chartData);
224224

225-
const config: ChartConfiguration<"bar"> = {
226-
type: "bar",
225+
const config: ChartConfiguration<"calendar"> = {
226+
type: "calendar",
227227
data: {
228228
labels,
229229
datasets,
@@ -240,6 +240,7 @@ export function createCalendarChartRuntime(
240240
chartShowValuesPlugin: getCalendarChartShowValues(definition, chartData),
241241
chartColorScalePlugin: getCalendarColorScale(definition, chartData),
242242
},
243+
chartBackground: definition.background || BACKGROUND_CHART_COLOR,
243244
},
244245
};
245246

src/helpers/figures/charts/runtime/chartjs_dataset.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export function getCalendarChartDatasetAndLabels(
111111
definition: CalendarChartDefinition,
112112
args: ChartRuntimeGenerationArgs
113113
): {
114-
datasets: (ChartDataset<"bar"> & { values: number[] })[];
114+
datasets: ChartDataset<"calendar">[];
115115
labels: string[];
116116
} {
117117
const { labels, dataSetsValues } = args;
@@ -129,7 +129,7 @@ export function getCalendarChartDatasetAndLabels(
129129
maxValue
130130
);
131131

132-
const dataSets: (ChartDataset<"bar"> & { values: number[] })[] = [];
132+
const dataSets: ChartDataset<"calendar">[] = [];
133133
for (const dataSetValues of dataSetsValues) {
134134
dataSets.push({
135135
label: dataSetValues.label,

src/helpers/figures/charts/runtime/chartjs_scales.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export function getBarChartScales(
9494
export function getCalendarChartScales(
9595
definition: GenericDefinition<BarChartDefinition>,
9696
datasets: ChartDataset[]
97-
): DeepPartial<ScaleChartOptions<"line" | "bar">["scales"]> {
97+
): DeepPartial<ScaleChartOptions<"calendar">["scales"]> {
9898
const yLabels = datasets.map((dataset) => dataset.label || "");
9999
const fontColor = chartFontColor(definition.background);
100100
return {

tests/figures/chart/charts_component.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,7 +2454,7 @@ test("ChartJS charts extensions are loaded when mounting a spreadsheet, are only
24542454
const spyUnregister = jest.spyOn(window.Chart, "unregister");
24552455
createChart(model, { type: "bar" }, chartId);
24562456
await mountSpreadsheet();
2457-
expect(spyRegister).toHaveBeenCalledTimes(8);
2457+
expect(spyRegister).toHaveBeenCalledTimes(9);
24582458
expect(window.Chart.registry.plugins["items"].map((i) => i.id)).toMatchObject([
24592459
"chartShowValuesPlugin",
24602460
"waterfallLinesPlugin",
@@ -2463,16 +2463,17 @@ test("ChartJS charts extensions are loaded when mounting a spreadsheet, are only
24632463
"sunburstLabelsPlugin",
24642464
"sunburstHoverPlugin",
24652465
"chartColorScalePlugin",
2466+
"calendar", // Calendar controller
24662467
"zoomWindowPlugin",
24672468
]);
24682469

24692470
createChart(model, { type: "line" }, "chart2");
24702471
await nextTick();
2471-
expect(spyRegister).toHaveBeenCalledTimes(8);
2472+
expect(spyRegister).toHaveBeenCalledTimes(9);
24722473

24732474
app.destroy();
24742475
await nextTick();
2475-
expect(spyUnregister).toHaveBeenCalledTimes(8);
2476+
expect(spyUnregister).toHaveBeenCalledTimes(9);
24762477
expect(window.Chart.registry.plugins["items"]).toEqual([]);
24772478
});
24782479

0 commit comments

Comments
 (0)