diff --git a/DataPlotly/core/plot_factory.py b/DataPlotly/core/plot_factory.py
index ace3be58..781487c7 100644
--- a/DataPlotly/core/plot_factory.py
+++ b/DataPlotly/core/plot_factory.py
@@ -722,7 +722,7 @@ def build_html(self, config) -> str:
match = re.search(r'Plotly.newPlot\(\s*[\'"](.+?)[\'"]', raw_plot)
substr = match.group(1)
raw_plot = raw_plot.replace('ReplaceTheDiv', substr)
- return raw_plot
+ return raw_plot, fig
def build_figure(self) -> str:
"""
@@ -753,9 +753,11 @@ def build_figure(self) -> str:
'modeBarButtonsToRemove': ['toImage', 'sendDataToCloud', 'editInChartStudio']
}
+ raw_plot, fig = self.build_html(config)
+
with open(self.plot_path, "w", encoding="utf8") as f:
- f.write(self.build_html(config))
- return self.plot_path
+ f.write(raw_plot)
+ return self.plot_path, fig
def build_figures(self, plot_type, ptrace, config=None) -> str:
"""
@@ -819,7 +821,7 @@ def build_figures(self, plot_type, ptrace, config=None) -> str:
with open(self.plot_path, "w", encoding="utf8") as f:
f.write(self.raw_plot)
- return self.plot_path
+ return self.plot_path, figures
def build_sub_plots(self, grid, row, column, ptrace): # pylint:disable=too-many-arguments
"""
@@ -877,7 +879,7 @@ def build_sub_plots(self, grid, row, column, ptrace): # pylint:disable=too-many
with open(self.plot_path, "w", encoding="utf8") as f:
f.write(self.raw_plot)
- return self.plot_path
+ return self.plot_path, fig
def build_plot_dict(self) -> dict:
"""
diff --git a/DataPlotly/data_plotly.py b/DataPlotly/data_plotly.py
index 08f45f60..58f7de2b 100644
--- a/DataPlotly/data_plotly.py
+++ b/DataPlotly/data_plotly.py
@@ -270,6 +270,9 @@ def unload(self):
# unregister the function
QgsExpression.unregisterFunction('get_symbol_colors')
+ # TODO QGIS 4
+ # QgsGui.layoutItemGuiRegistry().removeLayoutItemGuiMetadata(self.plot_item_gui_metadata)
+
# disconnect signals for easy dev when using plugin reloader
QgsProject.instance().cleared.disconnect(self.dock_manager.removeDocks)
QgsProject.instance().readProject.disconnect(
diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py
index 174d6b40..07aa7925 100644
--- a/DataPlotly/gui/plot_settings_widget.py
+++ b/DataPlotly/gui/plot_settings_widget.py
@@ -208,12 +208,14 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b
self.z_combo.fieldChanged.connect(self.setLegend)
self.draw_btn.clicked.connect(self.create_plot)
- self.update_btn.clicked.connect(self.UpdatePlot)
+ self.update_btn.clicked.connect(self.updatePlot)
self.clear_btn.clicked.connect(self.clearPlotView)
self.save_plot_btn.clicked.connect(self.save_plot_as_image)
self.save_plot_html_btn.clicked.connect(self.save_plot_as_html)
+ self.save_plot_json_btn.clicked.connect(self.save_plot_as_json)
self.save_plot_btn.setIcon(GuiUtils.get_icon('save_as_image.svg'))
self.save_plot_html_btn.setIcon(GuiUtils.get_icon('save_as_html.svg'))
+ self.save_plot_json_btn.setIcon(GuiUtils.get_icon('save_as_json.svg'))
# initialize the empty dictionary of plots
self.plot_factories = {}
@@ -1496,7 +1498,7 @@ def refresh_plot(self, factory):
"""
Refreshes the plot built by the specified factory
"""
- self.plot_path = factory.build_figure()
+ self.plot_path, _ = factory.build_figure()
self.refreshPlotView()
def create_plot(self):
@@ -1519,7 +1521,7 @@ def create_plot(self):
# plot single plot, check the object dictionary length
if len(self.plot_factories) <= 1 or self.ptype == 'radar':
- self.plot_path = plot_factory.build_figure()
+ self.plot_path, self.fig = plot_factory.build_figure()
# to plot many plots in the same figure
else:
@@ -1527,7 +1529,7 @@ def create_plot(self):
pl = []
for _, v in self.plot_factories.items():
pl.append(v.trace[0])
- self.plot_path = plot_factory.build_figures(self.ptype, pl)
+ self.plot_path, self.fig = plot_factory.build_figures(self.ptype, pl)
# choice to draw subplots instead depending on the combobox
elif self.subcombo.currentData() == 'subplots':
@@ -1541,13 +1543,13 @@ def create_plot(self):
# plot in single row and many columns
if self.radio_rows.isChecked():
- self.plot_path = plot_factory.build_sub_plots(
+ self.plot_path, self.fig = plot_factory.build_sub_plots(
'row', 1, gr, pl)
# plot in single column and many rows
elif self.radio_columns.isChecked():
- self.plot_path = plot_factory.build_sub_plots(
+ self.plot_path, self.fig = plot_factory.build_sub_plots(
'col', gr, 1, pl)
except: # pylint: disable=bare-except # noqa: F401
if self.message_bar:
@@ -1559,7 +1561,7 @@ def create_plot(self):
# connect to a simple function that reloads the view
self.refreshPlotView()
- def UpdatePlot(self):
+ def updatePlot(self):
"""
updates only the LAST plot created
get the key of the last plot created and delete it from the plot container
@@ -1642,7 +1644,7 @@ def save_plot_as_html(self):
"""
plot_file, _ = QFileDialog.getSaveFileName(
- self, self.tr("Save Plot"), "", "*.html")
+ self, self.tr("Save Plot as HTML"), "", "*.html")
if not plot_file:
return
@@ -1657,6 +1659,29 @@ def save_plot_as_html(self):
plot_file).toString(),
QDir.toNativeSeparators(plot_file)))
+ def save_plot_as_json(self):
+ """
+ Saves the plot as a local json file. The whole plot canvas is saves,
+ even if there are stacked plots or different subplots
+ """
+
+ plot_file, _ = QFileDialog.getSaveFileName(
+ self, self.tr("Save Plot as JSON"), "", "*.json")
+ if not plot_file:
+ return
+
+ plot_file = QgsFileUtils.ensureFileNameHasExtension(plot_file, [
+ 'json'])
+
+ self.fig.write_json(plot_file, validate=True, pretty=True)
+
+ if self.message_bar:
+ self.message_bar.pushSuccess(self.tr('DataPlotly'),
+ self.tr('Saved plot to {}').format(
+ QUrl.fromLocalFile(
+ plot_file).toString(),
+ QDir.toNativeSeparators(plot_file)))
+
def showPlotFromDic(self, plot_input_dic):
"""
Allows to call the plugin from the python console
@@ -1720,7 +1745,7 @@ def showPlotFromDic(self, plot_input_dic):
# create Plot instance
factory = PlotFactory(settings)
- standalone_plot_path = factory.build_figure()
+ standalone_plot_path, _ = factory.build_figure()
standalone_plot_url = QUrl.fromLocalFile(standalone_plot_path)
self.plot_view.load(standalone_plot_url)
diff --git a/DataPlotly/icons/save_as_json.svg b/DataPlotly/icons/save_as_json.svg
new file mode 100644
index 00000000..dc29eb67
--- /dev/null
+++ b/DataPlotly/icons/save_as_json.svg
@@ -0,0 +1,73 @@
+
+
diff --git a/DataPlotly/layouts/plot_layout_item.py b/DataPlotly/layouts/plot_layout_item.py
index 24922f47..024c4514 100644
--- a/DataPlotly/layouts/plot_layout_item.py
+++ b/DataPlotly/layouts/plot_layout_item.py
@@ -180,7 +180,8 @@ def create_plot(self):
if len(self.plot_settings) == 1:
plot_factory = PlotFactory(self.plot_settings[0], self, polygon_filter=polygon_filter)
self.plot_settings[0].properties['visible_features_only'] = visible_features_only
- return plot_factory.build_html(config)
+ raw_plot, _ = plot_factory.build_html(config)
+ return raw_plot
# to plot many plots in the same figure
elif len(self.plot_settings) > 1:
@@ -194,7 +195,7 @@ def create_plot(self):
factory = PlotFactory(plot_setting, self, polygon_filter=polygon_filter)
pl.append(factory.trace[0])
- plot_path = plot_factory.build_figures(self.plot_settings[0].plot_type, pl, config=config)
+ plot_path, _ = plot_factory.build_figures(self.plot_settings[0].plot_type, pl, config=config)
with open(plot_path) as myfile:
return myfile.read()
diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui
index d320d1ed..c8f26fc6 100644
--- a/DataPlotly/ui/dataplotly_dockwidget_base.ui
+++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui
@@ -320,9 +320,9 @@ QListWidget::item::selected {
0
- -537
- 673
- 1252
+ 0
+ 666
+ 1666
@@ -1012,8 +1012,8 @@ QListWidget::item::selected {
0
0
- 406
- 803
+ 477
+ 1043
@@ -1504,7 +1504,24 @@ QListWidget::item::selected {
-
-
-
+
-
+
+
+
+
+
+
+ -
+
+
+ Export as html
+
+
+
+
+
+
+ -
@@ -1514,20 +1531,7 @@ QListWidget::item::selected {
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
+
-
Export as image
@@ -1546,22 +1550,18 @@ QListWidget::item::selected {
- -
-
-
- Export as html
-
-
-
+
-
+
+
+ Qt::Horizontal
-
-
- -
-
-
-
+
+
+ 40
+ 20
+
-
+
-
@@ -1573,6 +1573,16 @@ QListWidget::item::selected {
+ -
+
+
+ Export as json
+
+
+
+
+
+