Răsfoiți Sursa

chart disappears on refresh (#1346)

* chart disappaers on refresh
resolves #1339
resolves #1064

* Fab's comments

---------

Co-authored-by: Fred Lefévère-Laoide <Fred.Lefevere-Laoide@Taipy.io>
Fred Lefévère-Laoide 11 luni în urmă
părinte
comite
cc5ec3aaee

+ 35 - 32
frontend/taipy-gui/package-lock.json

@@ -20,7 +20,7 @@
         "date-fns-tz": "^3.1.3",
         "lodash": "^4.17.21",
         "notistack": "^3.0.0",
-        "plotly.js": "^2.6.0",
+        "plotly.js": "^2.33.0",
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
         "react-error-boundary": "^4.0.3",
@@ -1854,13 +1854,13 @@
       }
     },
     "node_modules/@mui/x-date-pickers": {
-      "version": "7.5.1",
-      "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.5.1.tgz",
-      "integrity": "sha512-O3K2pewxk5u9mK8PG0+xgIOAn+GSBRWHtU0ZbzaqCjS8ZbxNT2OhkI0aXqp/W2ECVwxYaGjwtjl3ypQIdqRvjw==",
+      "version": "7.6.1",
+      "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.6.1.tgz",
+      "integrity": "sha512-erSq5cnOUyBgBmpHnMxIit5yhT3bl/lOaNZKpObvJtvEJetvNA9xWQ7dz/J/AufLzDuvThjusuRD0y+GmeXtiw==",
       "dependencies": {
-        "@babel/runtime": "^7.24.5",
+        "@babel/runtime": "^7.24.6",
         "@mui/base": "^5.0.0-beta.40",
-        "@mui/system": "^5.15.14",
+        "@mui/system": "^5.15.15",
         "@mui/utils": "^5.15.14",
         "@types/react-transition-group": "^4.4.10",
         "clsx": "^2.1.1",
@@ -1919,13 +1919,13 @@
       }
     },
     "node_modules/@mui/x-tree-view": {
-      "version": "7.5.1",
-      "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-7.5.1.tgz",
-      "integrity": "sha512-b4Lfclg1Lpa+kSs305snl/xFG5yOxq3/oVZEyPIseg8oOfl0r79UKqCIdO2iQqQydjUsUMbLtnR9TFypxlwCbQ==",
+      "version": "7.6.1",
+      "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-7.6.1.tgz",
+      "integrity": "sha512-FR8GUTMG0GgStHj+TDs2UzTln6SeWcGdVj62CAcQGVW61RpVRvPgBhYH3+g0SVtps6FYQxe/pvi83eLwMWW0Fw==",
       "dependencies": {
-        "@babel/runtime": "^7.24.5",
+        "@babel/runtime": "^7.24.6",
         "@mui/base": "^5.0.0-beta.40",
-        "@mui/system": "^5.15.14",
+        "@mui/system": "^5.15.15",
         "@mui/utils": "^5.15.14",
         "@types/react-transition-group": "^4.4.10",
         "clsx": "^2.1.1",
@@ -3500,16 +3500,19 @@
       }
     },
     "node_modules/array.prototype.tosorted": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz",
-      "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==",
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+      "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.5",
+        "call-bind": "^1.0.7",
         "define-properties": "^1.2.1",
-        "es-abstract": "^1.22.3",
-        "es-errors": "^1.1.0",
+        "es-abstract": "^1.23.3",
+        "es-errors": "^1.3.0",
         "es-shim-unscopables": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
       }
     },
     "node_modules/arraybuffer.prototype.slice": {
@@ -3909,9 +3912,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001625",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001625.tgz",
-      "integrity": "sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w==",
+      "version": "1.0.30001627",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001627.tgz",
+      "integrity": "sha512-4zgNiB8nTyV/tHhwZrFs88ryjls/lHiqFhrxCW4qSTeuRByBVnPYpDInchOIySWknznucaf31Z4KYqjfbrecVw==",
       "funding": [
         {
           "type": "opencollective",
@@ -4932,9 +4935,9 @@
       }
     },
     "node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "version": "4.3.5",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+      "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
       "dependencies": {
         "ms": "2.1.2"
       },
@@ -5310,9 +5313,9 @@
       "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.786",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.786.tgz",
-      "integrity": "sha512-i/A2UB0sxYViMN0M2zIotQFRIOt1jLuVXudACHBDiJ5gGuAUzf/crZxwlBTdA0O52Hy4CNtTzS7AKRAacs/08Q=="
+      "version": "1.4.788",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.788.tgz",
+      "integrity": "sha512-ubp5+Ev/VV8KuRoWnfP2QF2Bg+O2ZFdb49DiiNbz2VmgkIqrnyYaqIOqj8A6K/3p1xV0QcU5hBQ1+BmB6ot1OA=="
     },
     "node_modules/element-size": {
       "version": "1.1.1",
@@ -9272,9 +9275,9 @@
       }
     },
     "node_modules/lint-staged/node_modules/yaml": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz",
-      "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==",
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.3.tgz",
+      "integrity": "sha512-sntgmxj8o7DE7g/Qi60cqpLBA3HG3STcDA0kO+WfB05jEKhZMbY7umNm2rBpQvsmZ16/lPXCJGW2672dgOUkrg==",
       "dev": true,
       "bin": {
         "yaml": "bin.mjs"
@@ -13191,9 +13194,9 @@
       "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
     },
     "node_modules/type": {
-      "version": "2.7.2",
-      "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
-      "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
+      "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="
     },
     "node_modules/type-check": {
       "version": "0.4.0",

+ 1 - 1
frontend/taipy-gui/package.json

@@ -15,7 +15,7 @@
     "date-fns-tz": "^3.1.3",
     "lodash": "^4.17.21",
     "notistack": "^3.0.0",
-    "plotly.js": "^2.6.0",
+    "plotly.js": "^2.33.0",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "react-error-boundary": "^4.0.3",

+ 29 - 29
frontend/taipy-gui/src/components/Taipy/Chart.tsx

@@ -11,16 +11,7 @@
  * specific language governing permissions and limitations under the License.
  */
 
-import React, {
-    CSSProperties,
-    useCallback,
-    useEffect,
-    useMemo,
-    useRef,
-    useState,
-    lazy,
-    Suspense,
-} from "react";
+import React, { CSSProperties, useCallback, useEffect, useMemo, useRef, useState, lazy, Suspense } from "react";
 import {
     Config,
     Data,
@@ -214,7 +205,7 @@ const defaultConfig = {
     addIndex: [],
 } as ChartConfig;
 
-const emptyLayout = {} as Record<string, Record<string, unknown>>;
+const emptyLayout = {} as Partial<Layout>;
 const emptyData = {} as Record<string, TraceValueType>;
 
 const TaipyPlotlyButtons: ModeBarButtonAny[] = [
@@ -227,15 +218,20 @@ const TaipyPlotlyButtons: ModeBarButtonAny[] = [
             path: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z",
         },
         click: function (gd: HTMLElement, evt: Event) {
-            const title = gd.classList.toggle("full-screen") ? "Exit Full screen" : "Full screen";
-            (evt.currentTarget as HTMLElement).setAttribute("data-title", title);
-            const {height} = gd.dataset;
-            if (height) {
-                gd.attributeStyleMap.set("height", height);
-            } else {
-                gd.setAttribute("data-height", getComputedStyle(gd).height)
+            const div = gd.querySelector("div.svg-container") as HTMLDivElement;
+            if (!div) {
+                return;
+            }
+            const { height } = gd.dataset;
+            if (!height) {
+                gd.setAttribute("data-height", getComputedStyle(div).height);
+            }
+            const fs = gd.classList.toggle("full-screen");
+            (evt.currentTarget as HTMLElement).setAttribute("data-title", fs ? "Exit Full screen" : "Full screen");
+            if (height && !fs) {
+                div.attributeStyleMap.set("height", height);
             }
-            window.dispatchEvent(new Event('resize'));
+            window.dispatchEvent(new Event("resize"));
         },
     },
 ];
@@ -421,16 +417,20 @@ const Chart = (props: ChartProp) => {
                           getArrayValue(config.names, idx) ||
                           (config.columns[trace[1]] ? getColNameFromIndexed(config.columns[trace[1]].dfid) : undefined),
                   } as Record<string, unknown>;
-                  ret.marker = {...getArrayValue(config.markers, idx, ret.marker || {})};
-                  MARKER_TO_COL.forEach((prop) => {
-                      const val = (ret.marker as Record<string, unknown>)[prop];
-                      if (typeof val === "string") {
-                          const arr = getValueFromCol(datum, val as string);
-                          if (arr.length) {
-                              (ret.marker as Record<string, unknown>)[prop] = arr;
+                  ret.marker = { ...getArrayValue(config.markers, idx, ret.marker || {}) };
+                  if (Object.keys(ret.marker as object).length) {
+                      MARKER_TO_COL.forEach((prop) => {
+                          const val = (ret.marker as Record<string, unknown>)[prop];
+                          if (typeof val === "string") {
+                              const arr = getValueFromCol(datum, val as string);
+                              if (arr.length) {
+                                  (ret.marker as Record<string, unknown>)[prop] = arr;
+                              }
                           }
-                      }
-                  });
+                      });
+                  } else {
+                      delete ret.marker;
+                  }
                   const xs = getValue(datum, trace, 0) || [];
                   const ys = getValue(datum, trace, 1) || [];
                   const addIndex = getArrayValue(config.addIndex, idx, true) && !ys.length;
@@ -504,7 +504,7 @@ const Chart = (props: ChartProp) => {
             }
         }
         plconf.modeBarButtonsToAdd = TaipyPlotlyButtons;
-        plconf.responsive = true;
+        // plconf.responsive = true; // this is the source of the on/off height ...
         plconf.autosizable = true;
         if (!active) {
             plconf.staticPlot = true;

+ 2 - 2
taipy/gui/gui.py

@@ -962,8 +962,8 @@ class Gui:
                                 # remove file_path after it is merged
                                 part_file_path.unlink()
                     except EnvironmentError as ee:  # pragma: no cover
-                        _warn("Cannot group file after chunk upload", ee)
-                        return
+                        _warn(f"Cannot group file after chunk upload for {file.filename}", ee)
+                        return (f"Cannot group file after chunk upload for {file.filename}", 500)
                 # notify the file is uploaded
                 newvalue = str(file_path)
                 if multiple: