Browse Source

Try to fix Plotly layout issues (#2957)

* try to fix Plotly layout issues

* avoid re-rendering when replacing undefined attributes

* reorder attributes to clean up the diff
Falko Schindler 1 năm trước cách đây
mục cha
commit
44e4e2a5bb
2 tập tin đã thay đổi với 36 bổ sung13 xóa
  1. 15 4
      nicegui/elements/plotly.vue
  2. 21 9
      nicegui/static/nicegui.js

+ 15 - 4
nicegui/elements/plotly.vue

@@ -7,7 +7,6 @@ export default {
   async mounted() {
     await this.$nextTick();
     this.update();
-    this.set_handlers();
   },
   updated() {
     this.update();
@@ -19,9 +18,16 @@ export default {
       if (options.config === undefined) options.config = { responsive: true };
       if (options.config.responsive === undefined) options.config.responsive = true;
 
-      // Plotly.react can be used to create a new plot and to update it efficiently
-      // https://plotly.com/javascript/plotlyjs-function-reference/#plotlyreact
-      Plotly.react(this.$el.id, this.options.data, this.options.layout, options.config);
+      // re-use plotly instance if config is the same
+      if (JSON.stringify(options.config) == JSON.stringify(this.last_options.config)) {
+        Plotly.react(this.$el.id, this.options.data, this.options.layout);
+      } else {
+        Plotly.newPlot(this.$el.id, this.options.data, this.options.layout, options.config);
+        this.set_handlers();
+      }
+
+      // store last options
+      this.last_options = options;
     },
     set_handlers() {
       // forward events
@@ -61,6 +67,11 @@ export default {
       }
     },
   },
+  data() {
+    return {
+      last_options: {},
+    };
+  },
   props: {
     options: Object,
   },

+ 21 - 9
nicegui/static/nicegui.js

@@ -19,6 +19,25 @@ function parseElements(raw_elements) {
   );
 }
 
+function replaceUndefinedAttributes(elements, id) {
+  const element = elements[id];
+  if (element === undefined) {
+    return;
+  }
+  element.class ??= [];
+  element.style ??= {};
+  element.props ??= {};
+  element.text ??= null;
+  element.events ??= [];
+  element.component ??= null;
+  element.libraries ??= [];
+  element.slots = {
+    default: { ids: element.children || [] },
+    ...(element.slots ?? {}),
+  };
+  Object.values(element.slots).forEach((slot) => slot.ids.forEach((id) => replaceUndefinedAttributes(elements, id)));
+}
+
 function getElement(id) {
   const _id = id instanceof HTMLElement ? id.id : id;
   return mounted_app.$refs["r" + _id];
@@ -111,15 +130,6 @@ function renderRecursively(elements, id) {
     return;
   }
 
-  element.class ??= [];
-  element.style ??= {};
-  element.props ??= {};
-  element.text ??= null;
-  element.slots ??= {};
-  element.events ??= [];
-  element.component ??= null;
-  element.libraries ??= [];
-
   // @todo: Try avoid this with better handling of initial page load.
   if (element.component) loaded_components.add(element.component.name);
   element.libraries.forEach((library) => loaded_libraries.add(library.name));
@@ -264,6 +274,7 @@ function createRandomUUID() {
 }
 
 function createApp(elements, options) {
+  replaceUndefinedAttributes(elements, 0);
   return (app = Vue.createApp({
     data() {
       return {
@@ -324,6 +335,7 @@ function createApp(elements, options) {
               await loadDependencies(element, options.prefix, options.version);
             }
             this.elements[id] = element;
+            replaceUndefinedAttributes(this.elements, id);
           }
         },
         run_javascript: (msg) => runJavascript(msg["code"], msg["request_id"]),