fields
forms
Gauge
Odoo 19 fields — Gauge (views)
Live preview
Interactive
Source excerpt
web/static/src/views/fields/gauge/gauge_field.js
import { _t } from "@web/core/l10n/translation";
import { loadBundle } from "@web/core/assets";
import { registry } from "@web/core/registry";
import { formatFloat } from "@web/views/fields/formatters";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
import { Component, onWillStart, useEffect, useRef } from "@odoo/owl";
export class GaugeField extends Component {
static template = "web.GaugeField";
static props = {
...standardFieldProps,
maxValueField: { type: String, optional: true },
maxValue: { type: Number, optional: true },
title: { type: String, optional: true },
};
static defaultProps = {
maxValue: 100,
};
setup() {
this.chart = null;
this.canvasRef = useRef("canvas");
onWillStart(async () => await loadBundle("web.chartjs_lib"));
useEffect(() => {
this.renderChart();
return () => {
if (this.chart) {
this.chart.destroy();
}
};
});
}
get title() {
return this.props.title || this.props.record.fields[this.props.name].string || "";
}
get formattedValue() {
return formatFloat(this.props.record.data[this.props.name], {
humanReadable: true,
decimals: 1,
});
}
renderChart() {
const gaugeValue = this.props.record.data[this.props.name];
let maxValue = this.props.maxValueField ? this.props.record.data[this.props.maxValueField] : this.props.maxValue;
maxValue = Math.max(gaugeValue, maxValue);
let maxLabel = maxValue;
if (gaugeValue === 0 && maxValue === 0) {
maxValue = 1;
maxLabel = 0;
}
const config = {
type: "doughnut",
data: {
datasets: [
{
data: [gaugeValue, maxValue - gaugeValue],
backgroundColor: ["#1f77b4", "#dddddd"],
label: this.title,
},
],
},
options: {
circumference: 180,
rotation: 270,
responsive: true,
maintainAspectRatio: false,
cutout: "70%",
layout: {
padding: 5,
},
plugins: {
title: {
display: true,
text: this.title,
padding: 4,
},
tooltip: {
displayColors: false,
callbacks: {
label: function (tooltipItem) {
if (tooltipItem.dataIndex === 0) {
return _t("Value: %(value)s", { value: gaugeValue });
}
return _t("Max: %(max)s", { max: maxLabel });
},
},
},
},
aspectRatio: 2,
},
};
this.chart = new Chart(this.canvasRef.el, config);
}
}
export const gaugeField = {
component: GaugeField,
supportedOptions: [
{
label: _t("Title"),
name: "title",
type: "string",
},
{
label: _t("Max value field"),
name: "max_value_field",
type: "field",
availableTypes: ["integer", "float"],
},
{
label: _t("Max value"),
name: "max_value",
type: "string",
},
Registry / API
- Registry name
gauge- Category
fields- Module
web- Slug
gauge- Nav group
forms