From 85fda6b557600520c2723461d57e02fe361c4192 Mon Sep 17 00:00:00 2001 From: BernatPForgeFlow Date: Wed, 12 Jul 2023 12:17:30 +0200 Subject: [PATCH] [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.com --- web_widget_bokeh_chart/README.rst | 44 +++++++++- web_widget_bokeh_chart/__manifest__.py | 1 + web_widget_bokeh_chart/readme/ROADMAP.rst | 1 + web_widget_bokeh_chart/readme/USAGE.rst | 37 +++++++++ .../static/description/index.html | 81 +++++++++++++++---- .../src/js/web_widget_bokeh_chart.esm.js | 24 ++++-- .../src/js/web_widget_bokeh_json_chart.esm.js | 40 +++++++++ .../static/src/xml/bokeh.xml | 10 ++- 8 files changed, 213 insertions(+), 25 deletions(-) create mode 100644 web_widget_bokeh_chart/readme/ROADMAP.rst create mode 100644 web_widget_bokeh_chart/static/src/js/web_widget_bokeh_json_chart.esm.js diff --git a/web_widget_bokeh_chart/README.rst b/web_widget_bokeh_chart/README.rst index 62bf1e87e..d3ef203db 100644 --- a/web_widget_bokeh_chart/README.rst +++ b/web_widget_bokeh_chart/README.rst @@ -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: + +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:: + +
+
+ + +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:: + +
+ Production/Stable License: LGPL-3 OCA/web Translate me on Weblate Try me on Runboat

This module add the possibility to insert Bokeh charts into Odoo standard views.

@@ -384,13 +384,18 @@ plots, dashboards, and data applications.

  • Installation
  • -
  • Usage
  • -
  • Bug Tracker
  • -
  • Credits @@ -405,6 +410,8 @@ pip3 install bokeh==3.1.1

    Usage

    To insert a Bokeh chart in a view proceed as follows:

    +
    +

    Using a Char field

    1. Declare a text computed field like this:

      @@ -444,8 +451,54 @@ bokeh chart:

    +
    +

    Using a Json field

    +
      +
    1. Declare a json computed field like this:

      +
      +bokeh_chart = fields.Json(
      +    string='Bokeh Chart',
      +    compute='_compute_bokeh_chart',
      +)
      +
      +
    2. +
    3. At the top of the module add the following imports:

      +
      +from bokeh.plotting import figure
      +from bokeh.embed import components
      +
      +
    4. +
    5. 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}
      +
      +
    6. +
    7. In the view, add something like this wherever you want to display your +bokeh chart:

      +
      +<div>
      +    <field name="bokeh_chart" widget="bokeh_chart_json
      +
      +
    8. +
    +
    +
    +
    +

    Known issues / Roadmap

    +
      +
    1. On 17, we could remove the char field and only use the Json Field
    2. +
    +
    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. 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

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • ForgeFlow
    • Creu Blanca
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    • This module uses the library Bokeh which is under the open-source BSD 3-clause “New” or “Revised” License. @@ -483,7 +536,7 @@ Copyright (c) 2012, Anaconda, Inc.
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association

    OCA, or the Odoo Community Association, is a nonprofit organization whose diff --git a/web_widget_bokeh_chart/static/src/js/web_widget_bokeh_chart.esm.js b/web_widget_bokeh_chart/static/src/js/web_widget_bokeh_chart.esm.js index 362a77d66..cd972c2dd 100644 --- a/web_widget_bokeh_chart/static/src/js/web_widget_bokeh_chart.esm.js +++ b/web_widget_bokeh_chart/static/src/js/web_widget_bokeh_chart.esm.js @@ -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; diff --git a/web_widget_bokeh_chart/static/src/js/web_widget_bokeh_json_chart.esm.js b/web_widget_bokeh_chart/static/src/js/web_widget_bokeh_json_chart.esm.js new file mode 100644 index 000000000..04f4605b2 --- /dev/null +++ b/web_widget_bokeh_chart/static/src/js/web_widget_bokeh_json_chart.esm.js @@ -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); diff --git a/web_widget_bokeh_chart/static/src/xml/bokeh.xml b/web_widget_bokeh_chart/static/src/xml/bokeh.xml index fbe607509..1b4bfcb9a 100644 --- a/web_widget_bokeh_chart/static/src/xml/bokeh.xml +++ b/web_widget_bokeh_chart/static/src/xml/bokeh.xml @@ -1,7 +1,9 @@ - - -