-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Task Description This task aims to add the new Radar chart type. Related Task(s) closes #5095 Task: 3633666 Signed-off-by: Lucas Lefèvre (lul) <[email protected]>
- Loading branch information
Showing
36 changed files
with
6,820 additions
and
1,968 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
src/components/side_panel/chart/building_blocks/series_design/series_design_editor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { Component, useState } from "@odoo/owl"; | ||
import { getColorsPalette, getNthColor, toHex } from "../../../../../helpers"; | ||
import { | ||
ChartWithDataSetDefinition, | ||
DispatchResult, | ||
SpreadsheetChildEnv, | ||
UID, | ||
} from "../../../../../types"; | ||
import { SidePanelCollapsible } from "../../../components/collapsible/side_panel_collapsible"; | ||
import { RoundColorPicker } from "../../../components/round_color_picker/round_color_picker"; | ||
import { Section } from "../../../components/section/section"; | ||
|
||
interface Props { | ||
figureId: UID; | ||
definition: ChartWithDataSetDefinition; | ||
canUpdateChart: ( | ||
figureID: UID, | ||
definition: Partial<ChartWithDataSetDefinition> | ||
) => DispatchResult; | ||
updateChart: (figureId: UID, definition: Partial<ChartWithDataSetDefinition>) => DispatchResult; | ||
} | ||
|
||
export class SeriesDesignEditor extends Component<Props, SpreadsheetChildEnv> { | ||
static template = "o-spreadsheet-SeriesDesignEditor"; | ||
static components = { | ||
SidePanelCollapsible, | ||
Section, | ||
RoundColorPicker, | ||
}; | ||
static props = { | ||
figureId: String, | ||
definition: Object, | ||
updateChart: Function, | ||
canUpdateChart: Function, | ||
slots: { type: Object, optional: true }, | ||
}; | ||
|
||
protected state = useState({ index: 0 }); | ||
|
||
getDataSeries() { | ||
const runtime = this.env.model.getters.getChartRuntime(this.props.figureId); | ||
if (!runtime || !("chartJsConfig" in runtime)) { | ||
return []; | ||
} | ||
return runtime.chartJsConfig.data.datasets.map((d) => d.label); | ||
} | ||
|
||
updateSerieEditor(ev) { | ||
this.state.index = ev.target.selectedIndex; | ||
} | ||
|
||
updateDataSeriesColor(color: string) { | ||
const dataSets = this.props.definition.dataSets; | ||
if (!dataSets?.[this.state.index]) return; | ||
dataSets[this.state.index] = { | ||
...dataSets[this.state.index], | ||
backgroundColor: color, | ||
}; | ||
this.props.updateChart(this.props.figureId, { dataSets }); | ||
} | ||
|
||
getDataSerieColor() { | ||
const dataSets = this.props.definition.dataSets; | ||
if (!dataSets?.[this.state.index]) return ""; | ||
const color = dataSets[this.state.index].backgroundColor; | ||
return color | ||
? toHex(color) | ||
: getNthColor(this.state.index, getColorsPalette(this.props.definition.dataSets.length)); | ||
} | ||
|
||
updateDataSeriesLabel(ev) { | ||
const label = ev.target.value; | ||
const dataSets = this.props.definition.dataSets; | ||
if (!dataSets?.[this.state.index]) return; | ||
dataSets[this.state.index] = { | ||
...dataSets[this.state.index], | ||
label, | ||
}; | ||
this.props.updateChart(this.props.figureId, { dataSets }); | ||
} | ||
|
||
getDataSerieLabel() { | ||
const dataSets = this.props.definition.dataSets; | ||
return dataSets[this.state.index]?.label || this.getDataSeries()[this.state.index]; | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
src/components/side_panel/chart/building_blocks/series_design/series_design_editor.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<templates> | ||
<t t-name="o-spreadsheet-SeriesDesignEditor"> | ||
<SidePanelCollapsible collapsedAtInit="true" title.translate="Data Series"> | ||
<t t-set-slot="content"> | ||
<Section class="'pt-0 pb-0'"> | ||
<select | ||
class="o-input data-series-selector" | ||
t-model="state.label" | ||
t-on-change="(ev) => this.updateSerieEditor(ev)"> | ||
<t t-foreach="getDataSeries()" t-as="serie" t-key="serie_index"> | ||
<option | ||
t-att-value="serie" | ||
t-att-selected="state.index === serie_index" | ||
t-esc="serie" | ||
/> | ||
</t> | ||
</select> | ||
<Section class="'px-0'"> | ||
<div class="d-flex align-items-center"> | ||
<span class="o-section-title mb-0 pe-2">Series color</span> | ||
<RoundColorPicker | ||
currentColor="getDataSerieColor()" | ||
onColorPicked.bind="updateDataSeriesColor" | ||
/> | ||
</div> | ||
</Section> | ||
<Section class="'pt-0 px-0'" title.translate="Series name"> | ||
<input | ||
class="o-input o-serie-label-editor" | ||
type="text" | ||
t-att-value="getDataSerieLabel()" | ||
t-on-change="(ev) => this.updateDataSeriesLabel(ev)" | ||
/> | ||
</Section> | ||
</Section> | ||
<t t-slot="data-series-extension" index="state.index"/> | ||
</t> | ||
</SidePanelCollapsible> | ||
</t> | ||
</templates> |
165 changes: 165 additions & 0 deletions
165
...mponents/side_panel/chart/building_blocks/series_design/series_with_axis_design_editor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
import { Component } from "@odoo/owl"; | ||
import { getColorsPalette, getNthColor, setColorAlpha, toHex } from "../../../../../helpers"; | ||
import { CHART_AXIS_CHOICES } from "../../../../../helpers/figures/charts"; | ||
import { | ||
ChartWithDataSetDefinition, | ||
Color, | ||
DispatchResult, | ||
SpreadsheetChildEnv, | ||
TrendConfiguration, | ||
UID, | ||
} from "../../../../../types"; | ||
import { Checkbox } from "../../../components/checkbox/checkbox"; | ||
import { RadioSelection } from "../../../components/radio_selection/radio_selection"; | ||
import { RoundColorPicker } from "../../../components/round_color_picker/round_color_picker"; | ||
import { Section } from "../../../components/section/section"; | ||
import { SeriesDesignEditor } from "./series_design_editor"; | ||
|
||
interface Props { | ||
figureId: UID; | ||
definition: ChartWithDataSetDefinition; | ||
canUpdateChart: ( | ||
figureID: UID, | ||
definition: Partial<ChartWithDataSetDefinition> | ||
) => DispatchResult; | ||
updateChart: (figureId: UID, definition: Partial<ChartWithDataSetDefinition>) => DispatchResult; | ||
} | ||
|
||
export class SeriesWithAxisDesignEditor extends Component<Props, SpreadsheetChildEnv> { | ||
static template = "o-spreadsheet-SeriesWithAxisDesignEditor"; | ||
static components = { | ||
SeriesDesignEditor, | ||
Checkbox, | ||
RadioSelection, | ||
Section, | ||
RoundColorPicker, | ||
}; | ||
static props = { | ||
figureId: String, | ||
definition: Object, | ||
canUpdateChart: Function, | ||
updateChart: Function, | ||
slots: { type: Object, optional: true }, | ||
}; | ||
|
||
axisChoices = CHART_AXIS_CHOICES; | ||
|
||
updateDataSeriesAxis(index: number, axis: "left" | "right") { | ||
const dataSets = [...this.props.definition.dataSets]; | ||
if (!dataSets?.[index]) { | ||
return; | ||
} | ||
dataSets[index] = { | ||
...dataSets[index], | ||
yAxisId: axis === "left" ? "y" : "y1", | ||
}; | ||
this.props.updateChart(this.props.figureId, { dataSets }); | ||
} | ||
|
||
getDataSerieAxis(index: number) { | ||
const dataSets = this.props.definition.dataSets; | ||
if (!dataSets?.[index]) { | ||
return "left"; | ||
} | ||
return dataSets[index].yAxisId === "y1" ? "right" : "left"; | ||
} | ||
|
||
get canHaveTwoVerticalAxis() { | ||
return !("horizontal" in this.props.definition && this.props.definition.horizontal); | ||
} | ||
|
||
toggleDataTrend(index: number, display: boolean) { | ||
const dataSets = [...this.props.definition.dataSets]; | ||
if (!dataSets?.[index]) { | ||
return; | ||
} | ||
dataSets[index] = { | ||
...dataSets[index], | ||
trend: { | ||
type: "polynomial", | ||
order: 1, | ||
...dataSets[index].trend, | ||
display, | ||
}, | ||
}; | ||
this.props.updateChart(this.props.figureId, { dataSets }); | ||
} | ||
|
||
getTrendLineConfiguration(index: number) { | ||
const dataSets = this.props.definition.dataSets; | ||
return dataSets?.[index]?.trend; | ||
} | ||
|
||
getTrendType(config: TrendConfiguration) { | ||
if (!config) { | ||
return ""; | ||
} | ||
return config.type === "polynomial" && config.order === 1 ? "linear" : config.type; | ||
} | ||
|
||
onChangeTrendType(index, ev: InputEvent) { | ||
const type = (ev.target as HTMLInputElement).value; | ||
let config: TrendConfiguration; | ||
switch (type) { | ||
case "linear": | ||
case "polynomial": | ||
config = { | ||
type: "polynomial", | ||
order: type === "linear" ? 1 : 2, | ||
}; | ||
break; | ||
case "exponential": | ||
case "logarithmic": | ||
config = { type }; | ||
break; | ||
default: | ||
return; | ||
} | ||
this.updateTrendLineValue(index, config); | ||
} | ||
|
||
onChangePolynomialDegree(index: number, ev: InputEvent) { | ||
const element = ev.target as HTMLInputElement; | ||
const order = parseInt(element.value || "1"); | ||
if (order < 2) { | ||
element.value = `${this.getTrendLineConfiguration(index)?.order ?? 2}`; | ||
return; | ||
} | ||
this.updateTrendLineValue(index, { order }); | ||
} | ||
|
||
getDataSerieColor(index: number) { | ||
const dataSets = this.props.definition.dataSets; | ||
if (!dataSets?.[index]) return ""; | ||
const color = dataSets[index].backgroundColor; | ||
return color | ||
? toHex(color) | ||
: getNthColor(index, getColorsPalette(this.props.definition.dataSets.length)); | ||
} | ||
|
||
getTrendLineColor(index: number) { | ||
return ( | ||
this.getTrendLineConfiguration(index)?.color ?? | ||
setColorAlpha(this.getDataSerieColor(index), 0.5) | ||
); | ||
} | ||
|
||
updateTrendLineColor(index: number, color: Color) { | ||
this.updateTrendLineValue(index, { color }); | ||
} | ||
|
||
updateTrendLineValue(index: number, config: any) { | ||
const dataSets = [...this.props.definition.dataSets]; | ||
if (!dataSets?.[index]) { | ||
return; | ||
} | ||
dataSets[index] = { | ||
...dataSets[index], | ||
trend: { | ||
...dataSets[index].trend, | ||
...config, | ||
}, | ||
}; | ||
this.props.updateChart(this.props.figureId, { dataSets }); | ||
} | ||
} |
Oops, something went wrong.