I'm trying to make a custom graph widget that creates a bar chart from a JSON.
model file:
class CrmLead(models.Model):
_inherit = 'crm.lead'
graph_json = fields.Text(compute='_compute_raw_duration')
def _compute_raw_duration(self):
Stage = self.env['crm.stage'].search([]) # get all stages
for record in self:
# Get the original duration tracking (e.g., {"15": 71, "19": 85406})
duration_dict = record.duration_tracking or {}
# Initialize with all stage names and 0 durations
mapped_duration = {stage.name: 0 for stage in Stage}
# Add actual durations for stages that exist
for stage_id_str, duration in duration_dict.items():
try:
stage_id = int(stage_id_str)
stage = Stage.filtered(lambda s: s.id == stage_id)
if stage:
mapped_duration[stage.name] = duration
else:
mapped_duration[f"Unknown Stage ({stage_id})"] = duration
except ValueError:
mapped_duration[f"Invalid Stage ID ({stage_id_str})"] = duration
# Store the result
record.graph_json = json.dumps(mapped_duration)
custom_crm/static/src/xml/graph_widget_template.xml
<?xml version="1.0" encoding="utf-8"?>
<templates xml:space="preserve">
<t t-name="custom_crm.GraphWidget">
<canvas t-ref="canvas" width="400" height="200"></canvas>
</t>
</templates>
custom_crm/static/src/js/graph_widget.js
/** @odoo-module **/
import { Component, useRef } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { loadJS } from "@web/core/assets";
console.log("✅ graph_widget.js JS loaded")
class GraphWidget extends Component {
setup() {
this.canvasRef = useRef("canvas");
console.log("setup done")
}
async willStart() {
await loadJS("/web/static/lib/Chart/Chart.js");
console.log("✅ Chart.js loaded successfully");
}
mounted() {
console.log("✅ GraphWidget mounted");
const jsonString = this.props.record.data.graph_json || '{}';
console.log("Raw JSON:", jsonString);
const data = JSON.parse(jsonString);
const labels = Object.keys(data);
const values = Object.values(data);
//const ctx = this.refs.canvas.getContext('2d');
const ctx = this.canvasRef.el.getContext('2d');
if (!ctx) {
console.warn("Canvas not found");
return;
}
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Stage Time (s)',
data: values,
backgroundColor: 'rgba(54, 162, 235, 0.6)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: { beginAtZero: true }
}
}
});
}
static template = "custom_crm.GraphWidget";
}
registry.category("fields").add("json_graph", {
component: GraphWidget,
supportedTypes: ["Text"],
});
- The canvas is present in the view, but there is no graph.
- The console has the following messages only:
✅ graph_widget.js JS loaded
setup done