1+ import { _t } from "@odoo/o-spreadsheet-engine" ;
12import { CHART_AXIS_TITLE_FONT_SIZE } from "@odoo/o-spreadsheet-engine/constants" ;
3+ import { LineChartRuntime } from "@odoo/o-spreadsheet-engine/types/chart" ;
24import { SpreadsheetChildEnv } from "@odoo/o-spreadsheet-engine/types/spreadsheet_env" ;
35import { Component , useState } from "@odoo/owl" ;
46import { deepCopy } from "../../../../../helpers" ;
5- import { ChartWithAxisDefinition , DispatchResult , TitleDesign , UID } from "../../../../../types" ;
7+ import { getDefinedAxis } from "../../../../../helpers/figures/charts" ;
8+ import {
9+ AxisDesign ,
10+ AxisScaleType ,
11+ ChartWithAxisDefinition ,
12+ DispatchResult ,
13+ TitleDesign ,
14+ UID ,
15+ } from "../../../../../types" ;
616import { BadgeSelection } from "../../../components/badge_selection/badge_selection" ;
17+ import { Checkbox } from "../../../components/checkbox/checkbox" ;
718import { Section } from "../../../components/section/section" ;
819import { ChartTitle } from "../chart_title/chart_title" ;
920
@@ -21,7 +32,7 @@ interface Props {
2132
2233export class AxisDesignEditor extends Component < Props , SpreadsheetChildEnv > {
2334 static template = "o-spreadsheet-AxisDesignEditor" ;
24- static components = { Section, ChartTitle, BadgeSelection } ;
35+ static components = { Section, ChartTitle, BadgeSelection, Checkbox } ;
2536 static props = { chartId : String , definition : Object , updateChart : Function , axesList : Array } ;
2637
2738 state = useState ( { currentAxis : "x" } ) ;
@@ -42,7 +53,7 @@ export class AxisDesignEditor extends Component<Props, SpreadsheetChildEnv> {
4253
4354 getAxisTitle ( ) {
4455 const axesDesign = this . props . definition . axesDesign ?? { } ;
45- return axesDesign [ this . state . currentAxis ] ?. title . text || "" ;
56+ return axesDesign [ this . state . currentAxis ] ?. title ? .text || "" ;
4657 }
4758
4859 updateAxisTitle ( text : string ) {
@@ -65,4 +76,141 @@ export class AxisDesignEditor extends Component<Props, SpreadsheetChildEnv> {
6576 } ;
6677 this . props . updateChart ( this . props . chartId , { axesDesign } ) ;
6778 }
79+
80+ get axisMin ( ) : number | undefined {
81+ return this . currentAxisDesign ?. min ;
82+ }
83+
84+ get axisMax ( ) : number | undefined {
85+ return this . currentAxisDesign ?. max ;
86+ }
87+
88+ get axisScaleType ( ) : AxisScaleType {
89+ return this . currentAxisDesign ?. scaleType ?? "linear" ;
90+ }
91+
92+ get isMajorGridEnabled ( ) : boolean {
93+ const designValue = this . currentAxisDesign ?. grid ?. major ;
94+ if ( designValue !== undefined ) {
95+ return designValue ;
96+ }
97+ return this . getDefaultMajorGridValue ( this . state . currentAxis ) ;
98+ }
99+
100+ get isMinorGridEnabled ( ) : boolean {
101+ return ! ! this . currentAxisDesign ?. grid ?. minor ;
102+ }
103+
104+ get majorGridLabel ( ) {
105+ return this . state . currentAxis === "x"
106+ ? _t ( "Vertical major gridlines" )
107+ : _t ( "Horizontal major gridlines" ) ;
108+ }
109+
110+ get minorGridLabel ( ) {
111+ return this . state . currentAxis === "x"
112+ ? _t ( "Vertical minor gridlines" )
113+ : _t ( "Horizontal minor gridlines" ) ;
114+ }
115+
116+ updateAxisMin ( ev : InputEvent ) {
117+ const value = ( ev . target as HTMLInputElement ) . value . trim ( ) ;
118+ const parsed = value === "" ? undefined : Number ( value ) ;
119+ if ( parsed === undefined || ! isNaN ( parsed ) ) {
120+ const axesDesign = deepCopy ( this . props . definition . axesDesign ) ?? { } ;
121+ axesDesign [ this . state . currentAxis ] = {
122+ ...axesDesign [ this . state . currentAxis ] ,
123+ min : parsed ,
124+ } ;
125+ this . props . updateChart ( this . props . chartId , { axesDesign } ) ;
126+ }
127+ }
128+
129+ updateAxisMax ( ev : InputEvent ) {
130+ const value = ( ev . target as HTMLInputElement ) . value . trim ( ) ;
131+ const parsed = value === "" ? undefined : Number ( value ) ;
132+ if ( parsed === undefined || ! isNaN ( parsed ) ) {
133+ const axesDesign = deepCopy ( this . props . definition . axesDesign ) ?? { } ;
134+ axesDesign [ this . state . currentAxis ] = {
135+ ...axesDesign [ this . state . currentAxis ] ,
136+ max : parsed ,
137+ } ;
138+ this . props . updateChart ( this . props . chartId , { axesDesign } ) ;
139+ }
140+ }
141+
142+ updateAxisScaleType ( ev : InputEvent ) {
143+ const type = ( ev . target as HTMLSelectElement ) . value as AxisScaleType ;
144+ const axesDesign = deepCopy ( this . props . definition . axesDesign ) ?? { } ;
145+ axesDesign [ this . state . currentAxis ] = {
146+ ...axesDesign [ this . state . currentAxis ] ,
147+ scaleType : type === "linear" ? undefined : type ,
148+ } ;
149+ this . props . updateChart ( this . props . chartId , { axesDesign } ) ;
150+ }
151+
152+ toggleMajorGrid ( major : boolean ) {
153+ const axesDesign = deepCopy ( this . props . definition . axesDesign ) ?? { } ;
154+ axesDesign [ this . state . currentAxis ] = {
155+ ...axesDesign [ this . state . currentAxis ] ,
156+ grid : {
157+ ...axesDesign [ this . state . currentAxis ] ?. grid ,
158+ major,
159+ } ,
160+ } ;
161+ this . props . updateChart ( this . props . chartId , { axesDesign } ) ;
162+ }
163+
164+ toggleMinorGrid ( minor : boolean ) {
165+ const axesDesign = deepCopy ( this . props . definition . axesDesign ) ?? { } ;
166+ axesDesign [ this . state . currentAxis ] = {
167+ ...axesDesign [ this . state . currentAxis ] ,
168+ grid : {
169+ ...axesDesign [ this . state . currentAxis ] ?. grid ,
170+ minor,
171+ } ,
172+ } ;
173+ this . props . updateChart ( this . props . chartId , { axesDesign } ) ;
174+ }
175+
176+ private get currentAxisDesign ( ) : AxisDesign | undefined {
177+ return this . props . definition . axesDesign ?. [ this . state . currentAxis ] ;
178+ }
179+
180+ private getDefaultMajorGridValue ( axisId : string ) : boolean {
181+ const { useLeftAxis, useRightAxis } = getDefinedAxis ( this . props . definition ) ;
182+ if ( axisId === "x" ) {
183+ if ( "horizontal" in this . props . definition && this . props . definition . horizontal ) {
184+ return true ;
185+ }
186+ if ( this . props . definition . type === "scatter" ) {
187+ return true ;
188+ }
189+ } else if ( axisId === "y" ) {
190+ return true ;
191+ } else if ( axisId === "y1" ) {
192+ return ! useLeftAxis && useRightAxis ;
193+ }
194+ return false ;
195+ }
196+
197+ get isCategoricalAxis ( ) : boolean {
198+ if ( this . state . currentAxis !== "x" ) {
199+ return false ;
200+ }
201+ const runtime = this . env . model . getters . getChartRuntime ( this . props . chartId ) as LineChartRuntime ;
202+ const axisType = runtime ?. chartJsConfig . options ?. scales ?. x ?. type ;
203+ return axisType === undefined || axisType === "time" ;
204+ }
205+
206+ get canChangeMinorGridVisibility ( ) : boolean {
207+ if ( this . state . currentAxis !== "x" ) {
208+ return true ;
209+ }
210+ if ( this . isCategoricalAxis ) {
211+ return false ;
212+ }
213+ const type = this . props . definition . type ;
214+ return type === "line" || type === "scatter" ;
215+ }
68216}
0 commit comments