mirror of https://github.com/OCA/web.git
[FIX] web_widget_bokeh_chart: Make bokeh charts work when inputs change
Co-authored-by: Enric Tobella enric.tobella@dixmit.com Co-authored-by: David Jimenez david.jimenez@forgeflow.compull/2562/head
parent
d371109c24
commit
85fda6b557
|
@ -7,7 +7,7 @@ Web Widget Bokeh Chart
|
|||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:0a02d8d60cad93e68d1d480d70db7de03cc3d2a249d032714232c8eeea16dc0a
|
||||
!! source digest: sha256:e10fc7f154772b092b0f09326d3c1b8dcec1fbe1c90ada30e47dd0a23d8866f8
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
|
||||
|
@ -62,6 +62,9 @@ Usage
|
|||
|
||||
To insert a Bokeh chart in a view proceed as follows:
|
||||
|
||||
Using a Char field
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#. Declare a text computed field like this::
|
||||
|
||||
bokeh_chart = fields.Text(
|
||||
|
@ -94,6 +97,45 @@ To insert a Bokeh chart in a view proceed as follows:
|
|||
<field name="bokeh_chart" widget="bokeh_chart" nolabel="1"/>
|
||||
</div>
|
||||
|
||||
|
||||
Using a Json field
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#. Declare a json computed field like this::
|
||||
|
||||
bokeh_chart = fields.Json(
|
||||
string='Bokeh Chart',
|
||||
compute='_compute_bokeh_chart',
|
||||
)
|
||||
|
||||
#. At the top of the module add the following imports::
|
||||
|
||||
from bokeh.plotting import figure
|
||||
from bokeh.embed import components
|
||||
|
||||
#. In its computed method do::
|
||||
|
||||
def _compute_bokeh_chart(self):
|
||||
for rec in self:
|
||||
# Design your bokeh figure:
|
||||
p = figure()
|
||||
line = p.line([0, 2], [1, 8], line_width=5)
|
||||
# (...)
|
||||
# fill the record field with both markup and the script of a chart.
|
||||
script, div = components(p, wrap_script=False)
|
||||
rec.bokeh_chart = {"div": div, "script": script}
|
||||
|
||||
#. In the view, add something like this wherever you want to display your
|
||||
bokeh chart::
|
||||
|
||||
<div>
|
||||
<field name="bokeh_chart" widget="bokeh_chart_json
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
#. On 17, we could remove the char field and only use the Json Field
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"assets": {
|
||||
"web.assets_backend": [
|
||||
"web_widget_bokeh_chart/static/src/js/web_widget_bokeh_chart.esm.js",
|
||||
"web_widget_bokeh_chart/static/src/js/web_widget_bokeh_json_chart.esm.js",
|
||||
"web_widget_bokeh_chart/static/src/xml/bokeh.xml",
|
||||
],
|
||||
},
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#. On 17, we could remove the char field and only use the Json Field
|
|
@ -1,5 +1,8 @@
|
|||
To insert a Bokeh chart in a view proceed as follows:
|
||||
|
||||
Using a Char field
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#. Declare a text computed field like this::
|
||||
|
||||
bokeh_chart = fields.Text(
|
||||
|
@ -31,3 +34,37 @@ To insert a Bokeh chart in a view proceed as follows:
|
|||
<div>
|
||||
<field name="bokeh_chart" widget="bokeh_chart" nolabel="1"/>
|
||||
</div>
|
||||
|
||||
|
||||
Using a Json field
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#. Declare a json computed field like this::
|
||||
|
||||
bokeh_chart = fields.Json(
|
||||
string='Bokeh Chart',
|
||||
compute='_compute_bokeh_chart',
|
||||
)
|
||||
|
||||
#. At the top of the module add the following imports::
|
||||
|
||||
from bokeh.plotting import figure
|
||||
from bokeh.embed import components
|
||||
|
||||
#. In its computed method do::
|
||||
|
||||
def _compute_bokeh_chart(self):
|
||||
for rec in self:
|
||||
# Design your bokeh figure:
|
||||
p = figure()
|
||||
line = p.line([0, 2], [1, 8], line_width=5)
|
||||
# (...)
|
||||
# fill the record field with both markup and the script of a chart.
|
||||
script, div = components(p, wrap_script=False)
|
||||
rec.bokeh_chart = {"div": div, "script": script}
|
||||
|
||||
#. In the view, add something like this wherever you want to display your
|
||||
bokeh chart::
|
||||
|
||||
<div>
|
||||
<field name="bokeh_chart" widget="bokeh_chart_json
|
||||
|
|
|
@ -367,7 +367,7 @@ ul.auto-toc {
|
|||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:0a02d8d60cad93e68d1d480d70db7de03cc3d2a249d032714232c8eeea16dc0a
|
||||
!! source digest: sha256:e10fc7f154772b092b0f09326d3c1b8dcec1fbe1c90ada30e47dd0a23d8866f8
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/web/tree/16.0/web_widget_bokeh_chart"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/web-16-0/web-16-0-web_widget_bokeh_chart"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
||||
<p>This module add the possibility to insert Bokeh charts into Odoo standard views.</p>
|
||||
|
@ -384,13 +384,18 @@ plots, dashboards, and data applications.</p>
|
|||
<div class="contents local topic" id="contents">
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#installation" id="toc-entry-1">Installation</a></li>
|
||||
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#other-credits" id="toc-entry-7">Other credits</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="toc-entry-8">Maintainers</a></li>
|
||||
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a><ul>
|
||||
<li><a class="reference internal" href="#using-a-char-field" id="toc-entry-3">Using a Char field</a></li>
|
||||
<li><a class="reference internal" href="#using-a-json-field" id="toc-entry-4">Using a Json field</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-5">Known issues / Roadmap</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-6">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="toc-entry-7">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="toc-entry-8">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="toc-entry-9">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#other-credits" id="toc-entry-10">Other credits</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="toc-entry-11">Maintainers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -405,6 +410,8 @@ pip3 install bokeh==3.1.1
|
|||
<div class="section" id="usage">
|
||||
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
|
||||
<p>To insert a Bokeh chart in a view proceed as follows:</p>
|
||||
<div class="section" id="using-a-char-field">
|
||||
<h2><a class="toc-backref" href="#toc-entry-3">Using a Char field</a></h2>
|
||||
<ol class="arabic">
|
||||
<li><p class="first">Declare a text computed field like this:</p>
|
||||
<pre class="literal-block">
|
||||
|
@ -444,8 +451,54 @@ bokeh chart:</p>
|
|||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="section" id="using-a-json-field">
|
||||
<h2><a class="toc-backref" href="#toc-entry-4">Using a Json field</a></h2>
|
||||
<ol class="arabic">
|
||||
<li><p class="first">Declare a json computed field like this:</p>
|
||||
<pre class="literal-block">
|
||||
bokeh_chart = fields.Json(
|
||||
string='Bokeh Chart',
|
||||
compute='_compute_bokeh_chart',
|
||||
)
|
||||
</pre>
|
||||
</li>
|
||||
<li><p class="first">At the top of the module add the following imports:</p>
|
||||
<pre class="literal-block">
|
||||
from bokeh.plotting import figure
|
||||
from bokeh.embed import components
|
||||
</pre>
|
||||
</li>
|
||||
<li><p class="first">In its computed method do:</p>
|
||||
<pre class="literal-block">
|
||||
def _compute_bokeh_chart(self):
|
||||
for rec in self:
|
||||
# Design your bokeh figure:
|
||||
p = figure()
|
||||
line = p.line([0, 2], [1, 8], line_width=5)
|
||||
# (...)
|
||||
# fill the record field with both markup and the script of a chart.
|
||||
script, div = components(p, wrap_script=False)
|
||||
rec.bokeh_chart = {"div": div, "script": script}
|
||||
</pre>
|
||||
</li>
|
||||
<li><p class="first">In the view, add something like this wherever you want to display your
|
||||
bokeh chart:</p>
|
||||
<pre class="literal-block">
|
||||
<div>
|
||||
<field name="bokeh_chart" widget="bokeh_chart_json
|
||||
</pre>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="known-issues-roadmap">
|
||||
<h1><a class="toc-backref" href="#toc-entry-5">Known issues / Roadmap</a></h1>
|
||||
<ol class="arabic simple">
|
||||
<li>On 17, we could remove the char field and only use the Json Field</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="section" id="bug-tracker">
|
||||
<h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1>
|
||||
<h1><a class="toc-backref" href="#toc-entry-6">Bug Tracker</a></h1>
|
||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||
|
@ -453,16 +506,16 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
<h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1>
|
||||
<h1><a class="toc-backref" href="#toc-entry-7">Credits</a></h1>
|
||||
<div class="section" id="authors">
|
||||
<h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2>
|
||||
<h2><a class="toc-backref" href="#toc-entry-8">Authors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>ForgeFlow</li>
|
||||
<li>Creu Blanca</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contributors">
|
||||
<h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
|
||||
<h2><a class="toc-backref" href="#toc-entry-9">Contributors</a></h2>
|
||||
<ul class="simple">
|
||||
<li>Jordi Ballester Alomar <<a class="reference external" href="mailto:jordi.ballester@forgeflow.com">jordi.ballester@forgeflow.com</a>></li>
|
||||
<li>Lois Rilo Antelo <<a class="reference external" href="mailto:lois.rilo@forgeflow.com">lois.rilo@forgeflow.com</a>></li>
|
||||
|
@ -474,7 +527,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|||
</ul>
|
||||
</div>
|
||||
<div class="section" id="other-credits">
|
||||
<h2><a class="toc-backref" href="#toc-entry-7">Other credits</a></h2>
|
||||
<h2><a class="toc-backref" href="#toc-entry-10">Other credits</a></h2>
|
||||
<ul class="simple">
|
||||
<li>This module uses the library <a class="reference external" href="https://github.com/bokeh/bokeh">Bokeh</a>
|
||||
which is under the open-source BSD 3-clause “New” or “Revised” License.
|
||||
|
@ -483,7 +536,7 @@ Copyright (c) 2012, Anaconda, Inc.</li>
|
|||
</ul>
|
||||
</div>
|
||||
<div class="section" id="maintainers">
|
||||
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
|
||||
<h2><a class="toc-backref" href="#toc-entry-11">Maintainers</a></h2>
|
||||
<p>This module is maintained by the OCA.</p>
|
||||
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
|
||||
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {CharField} from "@web/views/fields/char/char_field";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {loadBundle} from "@web/core/assets";
|
||||
const {onWillStart, markup} = owl;
|
||||
class BokehChartWidget extends CharField {
|
||||
import {registry} from "@web/core/registry";
|
||||
const {onWillStart, markup, onMounted, onPatched, useRef} = owl;
|
||||
|
||||
export default class BokehChartWidget extends CharField {
|
||||
setup() {
|
||||
this.widget = useRef("widget");
|
||||
onPatched(() => {
|
||||
var script = document.createElement("script");
|
||||
script.text = this.json_value.script;
|
||||
this.widget.el.append(script);
|
||||
});
|
||||
onMounted(() => {
|
||||
var script = document.createElement("script");
|
||||
script.text = this.json_value.script;
|
||||
this.widget.el.append(script);
|
||||
});
|
||||
super.setup();
|
||||
onWillStart(() =>
|
||||
loadBundle({
|
||||
|
@ -22,11 +34,11 @@ class BokehChartWidget extends CharField {
|
|||
}
|
||||
get json_value() {
|
||||
var value = JSON.parse(this.props.value);
|
||||
value.div = markup(value.div.trim());
|
||||
if (value) {
|
||||
value.div = markup(value.div.trim());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
BokehChartWidget.template = "web_widget_bokeh_chart.BokehChartField";
|
||||
registry.category("fields").add("bokeh_chart", BokehChartWidget);
|
||||
|
||||
export default BokehChartWidget;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {loadBundle} from "@web/core/assets";
|
||||
import {registry} from "@web/core/registry";
|
||||
const {onWillStart, markup, Component, onMounted, onPatched, useRef} = owl;
|
||||
|
||||
export default class BokehChartJsonWidget extends Component {
|
||||
setup() {
|
||||
this.widget = useRef("widget");
|
||||
onPatched(() => {
|
||||
var script = document.createElement("script");
|
||||
script.text = this.props.value.script;
|
||||
this.widget.el.append(script);
|
||||
});
|
||||
onMounted(() => {
|
||||
var script = document.createElement("script");
|
||||
script.text = this.props.value.script;
|
||||
this.widget.el.append(script);
|
||||
});
|
||||
onWillStart(() =>
|
||||
loadBundle({
|
||||
jsLibs: [
|
||||
"/web_widget_bokeh_chart/static/src/lib/bokeh/bokeh-3.1.1.min.js",
|
||||
"/web_widget_bokeh_chart/static/src/lib/bokeh/bokeh-api-3.1.1.min.js",
|
||||
"/web_widget_bokeh_chart/static/src/lib/bokeh/bokeh-widgets-3.1.1.min.js",
|
||||
"/web_widget_bokeh_chart/static/src/lib/bokeh/bokeh-tables-3.1.1.min.js",
|
||||
"/web_widget_bokeh_chart/static/src/lib/bokeh/bokeh-mathjax-3.1.1.min.js",
|
||||
"/web_widget_bokeh_chart/static/src/lib/bokeh/bokeh-gl-3.1.1.min.js",
|
||||
],
|
||||
})
|
||||
);
|
||||
}
|
||||
markup(value) {
|
||||
console.log("Marking up...");
|
||||
return markup(value);
|
||||
}
|
||||
}
|
||||
|
||||
BokehChartJsonWidget.template = "web_widget_bokeh_chart.BokehChartlJsonField";
|
||||
registry.category("fields").add("bokeh_chart_json", BokehChartJsonWidget);
|
|
@ -1,7 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="web_widget_bokeh_chart.BokehChartField" owl="1">
|
||||
<t t-out="json_value.div" />
|
||||
<script type="text/javascript" t-out="json_value.script" />
|
||||
</t>
|
||||
<div t-ref="widget" t-name="web_widget_bokeh_chart.BokehChartField" owl="1">
|
||||
<t t-out="json_value.div" />
|
||||
</div>
|
||||
<div t-ref="widget" t-name="web_widget_bokeh_chart.BokehChartlJsonField" owl="1">
|
||||
<t t-out="markup(props.value.div)" />
|
||||
</div>
|
||||
</templates>
|
||||
|
|
Loading…
Reference in New Issue