diff --git a/package-lock.json b/package-lock.json
index 932c438..3317a45 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,16 +1,17 @@
{
"name": "sqliteviz",
- "version": "0.15.3",
+ "version": "0.16.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "sqliteviz",
- "version": "0.15.3",
+ "version": "0.16.0",
"license": "Apache-2.0",
"dependencies": {
"codemirror": "^5.57.0",
"core-js": "^3.6.5",
+ "dataurl-to-blob": "^0.0.1",
"html2canvas": "^1.1.4",
"jquery": "^3.6.0",
"nanoid": "^3.1.12",
@@ -5077,6 +5078,18 @@
"node": ">=6"
}
},
+ "node_modules/cli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
+ "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+ "dependencies": {
+ "exit": "0.1.2",
+ "glob": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=0.2.5"
+ }
+ },
"node_modules/cli-cursor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
@@ -6746,6 +6759,14 @@
"node": ">=0.10"
}
},
+ "node_modules/dataurl-to-blob": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/dataurl-to-blob/-/dataurl-to-blob-0.0.1.tgz",
+ "integrity": "sha1-B75KpV2G1MtWIk5Y4xgR9diFxMs=",
+ "dependencies": {
+ "jshint": "^2.9.2"
+ }
+ },
"node_modules/date-format": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz",
@@ -6755,6 +6776,11 @@
"node": ">=4.0"
}
},
+ "node_modules/date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
+ },
"node_modules/dateformat": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
@@ -7333,7 +7359,6 @@
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
- "dev": true,
"dependencies": {
"domelementtype": "^2.0.1",
"entities": "^2.0.0"
@@ -7342,8 +7367,7 @@
"node_modules/dom-serializer/node_modules/domelementtype": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
- "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
- "dev": true
+ "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
},
"node_modules/domain-browser": {
"version": "1.2.0",
@@ -7358,8 +7382,7 @@
"node_modules/domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
- "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
- "dev": true
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
},
"node_modules/domhandler": {
"version": "2.4.2",
@@ -7780,8 +7803,7 @@
"node_modules/entities": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
- "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
- "dev": true
+ "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ=="
},
"node_modules/errno": {
"version": "0.1.7",
@@ -8723,6 +8745,14 @@
"node": ">=6"
}
},
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/expand-braces": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
@@ -12823,6 +12853,87 @@
"node": ">=4"
}
},
+ "node_modules/jshint": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.1.tgz",
+ "integrity": "sha512-vymzfR3OysF5P774x6zYv0bD4EpH6NWRxpq54wO9mA9RuY49yb1teKSICkLx2Ryx+mfzlVVNNbTBtsRtg78t7g==",
+ "dependencies": {
+ "cli": "~1.0.0",
+ "console-browserify": "1.1.x",
+ "exit": "0.1.x",
+ "htmlparser2": "3.8.x",
+ "lodash": "~4.17.21",
+ "minimatch": "~3.0.2",
+ "shelljs": "0.3.x",
+ "strip-json-comments": "1.0.x"
+ },
+ "bin": {
+ "jshint": "bin/jshint"
+ }
+ },
+ "node_modules/jshint/node_modules/console-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "dependencies": {
+ "date-now": "^0.1.4"
+ }
+ },
+ "node_modules/jshint/node_modules/domhandler": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+ "dependencies": {
+ "domelementtype": "1"
+ }
+ },
+ "node_modules/jshint/node_modules/domutils": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+ "dependencies": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "node_modules/jshint/node_modules/entities": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY="
+ },
+ "node_modules/jshint/node_modules/htmlparser2": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+ "dependencies": {
+ "domelementtype": "1",
+ "domhandler": "2.3",
+ "domutils": "1.5",
+ "entities": "1.0",
+ "readable-stream": "1.1"
+ }
+ },
+ "node_modules/jshint/node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "node_modules/jshint/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/jshint/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ },
"node_modules/json-loader": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
@@ -18831,6 +18942,17 @@
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
"dev": true
},
+ "node_modules/shelljs": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+ "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
+ "bin": {
+ "shjs": "bin/shjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/sigmund": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
@@ -19856,6 +19978,17 @@
"node": ">=4"
}
},
+ "node_modules/strip-json-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+ "bin": {
+ "strip-json-comments": "cli.js"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/strongly-connected-components": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/strongly-connected-components/-/strongly-connected-components-1.0.1.tgz",
@@ -27691,6 +27824,15 @@
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
"dev": true
},
+ "cli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
+ "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+ "requires": {
+ "exit": "0.1.2",
+ "glob": "^7.1.1"
+ }
+ },
"cli-cursor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
@@ -29141,12 +29283,25 @@
"assert-plus": "^1.0.0"
}
},
+ "dataurl-to-blob": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/dataurl-to-blob/-/dataurl-to-blob-0.0.1.tgz",
+ "integrity": "sha1-B75KpV2G1MtWIk5Y4xgR9diFxMs=",
+ "requires": {
+ "jshint": "^2.9.2"
+ }
+ },
"date-format": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz",
"integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=",
"dev": true
},
+ "date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
+ },
"dateformat": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
@@ -29627,7 +29782,6 @@
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
- "dev": true,
"requires": {
"domelementtype": "^2.0.1",
"entities": "^2.0.0"
@@ -29636,8 +29790,7 @@
"domelementtype": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
- "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
- "dev": true
+ "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
}
}
},
@@ -29650,8 +29803,7 @@
"domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
- "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
- "dev": true
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
},
"domhandler": {
"version": "2.4.2",
@@ -30046,8 +30198,7 @@
"entities": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
- "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
- "dev": true
+ "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ=="
},
"errno": {
"version": "0.1.7",
@@ -30833,6 +30984,11 @@
"strip-eof": "^1.0.0"
}
},
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw="
+ },
"expand-braces": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
@@ -34363,6 +34519,86 @@
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
},
+ "jshint": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.1.tgz",
+ "integrity": "sha512-vymzfR3OysF5P774x6zYv0bD4EpH6NWRxpq54wO9mA9RuY49yb1teKSICkLx2Ryx+mfzlVVNNbTBtsRtg78t7g==",
+ "requires": {
+ "cli": "~1.0.0",
+ "console-browserify": "1.1.x",
+ "exit": "0.1.x",
+ "htmlparser2": "3.8.x",
+ "lodash": "~4.17.21",
+ "minimatch": "~3.0.2",
+ "shelljs": "0.3.x",
+ "strip-json-comments": "1.0.x"
+ },
+ "dependencies": {
+ "console-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "requires": {
+ "date-now": "^0.1.4"
+ }
+ },
+ "domhandler": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "entities": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY="
+ },
+ "htmlparser2": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+ "requires": {
+ "domelementtype": "1",
+ "domhandler": "2.3",
+ "domutils": "1.5",
+ "entities": "1.0",
+ "readable-stream": "1.1"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ }
+ }
+ },
"json-loader": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
@@ -39562,6 +39798,11 @@
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
"dev": true
},
+ "shelljs": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+ "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E="
+ },
"sigmund": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
@@ -40488,6 +40729,11 @@
"integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
"dev": true
},
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E="
+ },
"strongly-connected-components": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/strongly-connected-components/-/strongly-connected-components-1.0.1.tgz",
diff --git a/package.json b/package.json
index 2bfb29e..ed72f1c 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"dependencies": {
"codemirror": "^5.57.0",
"core-js": "^3.6.5",
+ "dataurl-to-blob": "^0.0.1",
"html2canvas": "^1.1.4",
"jquery": "^3.6.0",
"nanoid": "^3.1.12",
diff --git a/src/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper.js b/src/lib/chartHelper.js
similarity index 69%
rename from src/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper.js
rename to src/lib/chartHelper.js
index 1a19f94..8558ef6 100644
--- a/src/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper.js
+++ b/src/lib/chartHelper.js
@@ -1,4 +1,5 @@
import dereference from 'react-chart-editor/lib/lib/dereference'
+import plotly from 'plotly.js'
export function getOptionsFromDataSources (dataSources) {
if (!dataSources) {
@@ -23,7 +24,17 @@ export function getOptionsForSave (state, dataSources) {
return stateCopy
}
+export async function getImageDataUrl (element, type) {
+ const chartElement = element.querySelector('.js-plotly-plot')
+ return await plotly.toImage(chartElement, {
+ format: type,
+ width: null,
+ height: null
+ })
+}
+
export default {
getOptionsFromDataSources,
- getOptionsForSave
+ getOptionsForSave,
+ getImageDataUrl
}
diff --git a/src/lib/utils/clipboardIo.js b/src/lib/utils/clipboardIo.js
index 4557b6b..e9cbd5c 100644
--- a/src/lib/utils/clipboardIo.js
+++ b/src/lib/utils/clipboardIo.js
@@ -1,8 +1,30 @@
import Lib from 'plotly.js/src/lib'
+import dataUrlToBlob from 'dataurl-to-blob'
+
+async function _copyBlob(blob) {
+ await navigator.clipboard.write([
+ new ClipboardItem({
+ [blob.type]: blob
+ })
+ ])
+}
export default {
async copyCsv (str) {
await navigator.clipboard.writeText(str)
Lib.notifier('CSV copied to clipboard successfully', 'long')
+ },
+
+ async copyCanvas (canvas, type) {
+ canvas.toBlob(async (blob) => {
+ await _copyBlob(blob)
+ Lib.notifier('Image copied to clipboard successfully', 'long')
+ }, 'image/png', 1)
+ },
+
+ async copyFromDataUrl (url) {
+ const blob = dataUrlToBlob(url)
+ await _copyBlob(blob)
+ Lib.notifier('Image copied to clipboard successfully', 'long')
}
}
diff --git a/src/views/Main/Workspace/Tabs/Tab/DataView/Chart/index.vue b/src/views/Main/Workspace/Tabs/Tab/DataView/Chart/index.vue
index fafc830..1dc8a81 100644
--- a/src/views/Main/Workspace/Tabs/Tab/DataView/Chart/index.vue
+++ b/src/views/Main/Workspace/Tabs/Tab/DataView/Chart/index.vue
@@ -28,9 +28,10 @@ import plotly from 'plotly.js'
import 'react-chart-editor/lib/react-chart-editor.min.css'
import PlotlyEditor from 'react-chart-editor'
-import chartHelper from './chartHelper'
+import chartHelper from '@/lib/chartHelper'
import dereference from 'react-chart-editor/lib/lib/dereference'
import fIo from '@/lib/utils/fileIo'
+import cIo from '@/lib/utils/clipboardIo'
export default {
name: 'Chart',
@@ -89,10 +90,13 @@ export default {
return chartHelper.getOptionsForSave(this.state, this.dataSources)
},
async saveAsPng () {
- const chartElement = this.$refs.plotlyEditor.$el.querySelector('.js-plotly-plot')
- const url = await plotly.toImage(chartElement, { format: 'png', width: null, height: null })
+ const url = await chartHelper.getImageDataUrl(this.$refs.plotlyEditor.$el, 'png')
this.$emit('loadingImageCompleted')
fIo.downloadFromUrl(url, 'chart')
+ },
+ async copyPngToClipboard () {
+ const url = await chartHelper.getImageDataUrl(this.$refs.plotlyEditor.$el, 'png')
+ cIo.copyFromDataUrl(url)
}
}
}
diff --git a/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi/index.vue b/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi/index.vue
index 98b6fd2..023fcce 100644
--- a/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi/index.vue
+++ b/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi/index.vue
@@ -139,7 +139,7 @@
import $ from 'jquery'
import Multiselect from 'vue-multiselect'
import PivotSortBtn from './PivotSortBtn'
-import { renderers, aggregators, zeroValAggregators, twoValAggregators } from './pivotHelper'
+import { renderers, aggregators, zeroValAggregators, twoValAggregators } from '../pivotHelper'
import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart'
import Vue from 'vue'
const ChartClass = Vue.extend(Chart)
diff --git a/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/index.vue b/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/index.vue
index 3e7e58c..2f5c9d6 100644
--- a/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/index.vue
+++ b/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/index.vue
@@ -14,14 +14,15 @@
diff --git a/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi/pivotHelper.js b/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper.js
similarity index 91%
rename from src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi/pivotHelper.js
rename to src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper.js
index d20d8f9..9cd00eb 100644
--- a/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi/pivotHelper.js
+++ b/src/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper.js
@@ -2,6 +2,7 @@ import $ from 'jquery'
import 'pivottable'
import 'pivottable/dist/export_renderers.js'
import 'pivottable/dist/plotly_renderers.js'
+import html2canvas from 'html2canvas'
export const zeroValAggregators = [
'Count',
@@ -75,3 +76,8 @@ export const aggregators = Object.keys($.pivotUtilities.aggregators).map(key =>
fun: $.pivotUtilities.aggregators[key]
}
})
+
+export async function getPivotCanvas (pivotOutput) {
+ const tableElement = pivotOutput.querySelector('.pvtTable')
+ return await html2canvas(tableElement)
+}
diff --git a/src/views/Main/Workspace/Tabs/Tab/DataView/index.vue b/src/views/Main/Workspace/Tabs/Tab/DataView/index.vue
index 652a6df..06e0f10 100644
--- a/src/views/Main/Workspace/Tabs/Tab/DataView/index.vue
+++ b/src/views/Main/Workspace/Tabs/Tab/DataView/index.vue
@@ -40,6 +40,14 @@
>
+
+
+
+
@@ -52,6 +60,7 @@ import IconButton from '@/components/IconButton'
import ChartIcon from '@/components/svg/chart'
import PivotIcon from '@/components/svg/pivot'
import PngIcon from '@/components/svg/png'
+import ClipboardIcon from '@/components/svg/clipboard'
export default {
name: 'DataView',
@@ -63,7 +72,8 @@ export default {
IconButton,
ChartIcon,
PivotIcon,
- PngIcon
+ PngIcon,
+ ClipboardIcon
},
data () {
return {
@@ -95,6 +105,9 @@ export default {
},
getOptionsForSave () {
return this.$refs.viewComponent.getOptionsForSave()
+ },
+ copyToClipboard () {
+ this.$refs.viewComponent.copyPngToClipboard()
}
}
}
diff --git a/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/Chart.spec.js b/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/Chart.spec.js
index f28aec5..44de677 100644
--- a/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/Chart.spec.js
+++ b/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/Chart.spec.js
@@ -2,7 +2,7 @@ import { expect } from 'chai'
import sinon from 'sinon'
import { mount, shallowMount } from '@vue/test-utils'
import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart'
-import chartHelper from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper'
+import chartHelper from '@/lib/chartHelper'
import * as dereference from 'react-chart-editor/lib/lib/dereference'
describe('Chart.vue', () => {
diff --git a/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/Pivot/PivotUi/pivotHelper.spec.js b/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/Pivot/PivotUi/pivotHelper.spec.js
index 581668e..c352f92 100644
--- a/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/Pivot/PivotUi/pivotHelper.spec.js
+++ b/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/Pivot/PivotUi/pivotHelper.spec.js
@@ -1,5 +1,5 @@
import { expect } from 'chai'
-import { _getDataSources } from '@/views/Main/Workspace/Tabs/Tab/DataView/Pivot/PivotUi/pivotHelper'
+import { _getDataSources } from '@/views/Main/Workspace/Tabs/Tab/DataView/Pivot/pivotHelper'
describe('pivotHelper.js', () => {
it('_getDataSources returns data sources', () => {
diff --git a/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper.spec.js b/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper.spec.js
index b35550c..79c6176 100644
--- a/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper.spec.js
+++ b/tests/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper.spec.js
@@ -1,6 +1,6 @@
import { expect } from 'chai'
import sinon from 'sinon'
-import * as chartHelper from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart/chartHelper'
+import * as chartHelper from '@/lib/chartHelper'
import * as dereference from 'react-chart-editor/lib/lib/dereference'
describe('chartHelper.js', () => {