def test_set_default_settings(self): """ Test setting dialog to a newly constructed settings object """ settings = PlotSettings() dialog = DataPlotlyPanelWidget(None, override_iface=IFACE) dialog.set_settings(settings) self.assertEqual(dialog.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): if k in ['x', 'y', 'z', 'additional_hover_text', 'featureIds', 'featureBox', 'custom', 'marker_size', 'hover_text', 'hover_label_text']: continue self.assertEqual(dialog.get_settings().properties[k], settings.properties[k]) for k in settings.layout.keys(): self.assertEqual(dialog.get_settings().layout[k], settings.layout[k])
class PlotLayoutItemWidget(QgsLayoutItemBaseWidget): """ Configuration widget for layout plot items """ def __init__(self, parent, layout_object): super().__init__(parent, layout_object) self.plot_item = layout_object vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) self.plot_properties_button = QPushButton(self.tr('Setup Plot')) vl.addWidget(self.plot_properties_button) self.plot_properties_button.clicked.connect(self.show_properties) self.panel = None self.setPanelTitle(self.tr('Plot Properties')) self.item_properties_widget = QgsLayoutItemPropertiesWidget( self, layout_object) vl.addWidget(self.item_properties_widget) self.setLayout(vl) def show_properties(self): """ Shows the plot properties panel """ self.panel = DataPlotlyPanelWidget( mode=DataPlotlyPanelWidget.MODE_LAYOUT) self.panel.set_settings(self.plot_item.plot_settings) # self.panel.set_settings(self.layoutItem().plot_settings) self.openPanel(self.panel) self.panel.widgetChanged.connect(self.update_item_settings) self.panel.panelAccepted.connect(self.set_item_settings) def update_item_settings(self): """ Updates the plot item without dismissing the properties panel """ if not self.panel: return self.plot_item.set_plot_settings(self.panel.get_settings()) self.plot_item.update() def set_item_settings(self): """ Updates the plot item based on the settings from the properties panel """ if not self.panel: return self.plot_item.set_plot_settings(self.panel.get_settings()) self.panel = None self.plot_item.update() def setNewItem(self, item): # pylint: disable=missing-docstring if item.type() != ITEM_TYPE: return False self.plot_item = item self.item_properties_widget.setItem(item) if self.panel is not None: self.panel.set_settings(self.plot_item.plot_settings) return True
class PlotLayoutItemWidget(QgsLayoutItemBaseWidget): """ Configuration widget for layout plot items """ def __init__(self, parent, layout_object): super().__init__(parent, layout_object) self.plot_item = layout_object self.message_bar = None vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) self.plot_properties_button = QPushButton(self.tr('Setup Plot')) vl.addWidget(self.plot_properties_button) self.plot_properties_button.clicked.connect(self.show_properties) self.panel = None self.setPanelTitle(self.tr('Plot Properties')) self.item_properties_widget = QgsLayoutItemPropertiesWidget( self, layout_object) vl.addWidget(self.item_properties_widget) self.setLayout(vl) def show_properties(self): """ Shows the plot properties panel """ self.panel = DataPlotlyPanelWidget( mode=DataPlotlyPanelWidget.MODE_LAYOUT, message_bar=self.message_bar) self.panel.registerExpressionContextGenerator(self.plot_item) self.panel.set_print_layout(self.plot_item.layout()) self.panel.linked_map_combo.blockSignals(True) self.panel.linked_map_combo.setItem(self.plot_item.linked_map) self.panel.linked_map_combo.blockSignals(False) self.panel.filter_by_map_check.toggled.connect( self.filter_by_map_toggled) self.panel.filter_by_atlas_check.toggled.connect( self.filter_by_atlas_toggled) self.panel.linked_map_combo.itemChanged.connect( self.linked_map_changed) self.panel.filter_by_map_check.blockSignals(True) self.panel.filter_by_map_check.setChecked(self.plot_item.filter_by_map) self.panel.filter_by_map_check.blockSignals(False) self.panel.filter_by_atlas_check.blockSignals(True) self.panel.filter_by_atlas_check.setChecked( self.plot_item.filter_by_atlas) self.panel.filter_by_atlas_check.blockSignals(False) self.panel.set_settings(self.plot_item.plot_settings) # self.panel.set_settings(self.layoutItem().plot_settings) self.openPanel(self.panel) self.panel.widgetChanged.connect(self.update_item_settings) self.panel.panelAccepted.connect(self.set_item_settings) def update_item_settings(self): """ Updates the plot item without dismissing the properties panel """ if not self.panel: return self.plot_item.set_plot_settings(self.panel.get_settings()) self.plot_item.update() def set_item_settings(self): """ Updates the plot item based on the settings from the properties panel """ if not self.panel: return self.plot_item.set_plot_settings(self.panel.get_settings()) self.panel = None self.plot_item.update() def filter_by_map_toggled(self, value): """ Triggered when the filter by map option is toggled """ self.plot_item.filter_by_map = bool(value) self.plot_item.update() def filter_by_atlas_toggled(self, value): """ Triggered when the filter by atlas option is toggled """ self.plot_item.filter_by_atlas = bool(value) self.plot_item.update() def linked_map_changed(self, linked_map): """ Triggered when the linked map is changed """ self.plot_item.set_linked_map(linked_map) self.plot_item.update() def setNewItem(self, item): # pylint: disable=missing-docstring if item.type() != ITEM_TYPE: return False self.plot_item = item self.item_properties_widget.setItem(item) if self.panel is not None: self.panel.set_settings(self.plot_item.plot_settings) self.panel.filter_by_map_check.blockSignals(True) self.panel.filter_by_map_check.setChecked(item.filter_by_map) self.panel.filter_by_map_check.blockSignals(False) self.panel.filter_by_atlas_check.blockSignals(True) self.panel.filter_by_atlas_check.setChecked(item.filter_by_atlas) self.panel.filter_by_atlas_check.blockSignals(False) self.panel.linked_map_combo.blockSignals(True) self.panel.linked_map_combo.setItem(self.plot_item.linked_map) self.panel.linked_map_combo.blockSignals(False) return True def setDesignerInterface(self, iface): # pylint: disable=missing-docstring super().setDesignerInterface(iface) self.message_bar = iface.messageBar() if self.panel: self.panel.message_bar = self.message_bar
def test_settings_round_trip(self): # pylint: disable=too-many-statements """ Test setting and retrieving settings results in identical results """ layer_path = os.path.join(os.path.dirname(__file__), 'test_layer.geojson') vl1 = QgsVectorLayer(layer_path, 'test_layer', 'ogr') vl2 = QgsVectorLayer(layer_path, 'test_layer1', 'ogr') vl3 = QgsVectorLayer(layer_path, 'test_layer2', 'ogr') QgsProject.instance().addMapLayers([vl1, vl2, vl3]) dialog = DataPlotlyPanelWidget(None, override_iface=IFACE) settings = dialog.get_settings() # default should be scatter plot self.assertEqual(settings.plot_type, 'scatter') # print('dialog loaded') # customise settings settings.plot_type = 'bar' settings.properties['name'] = 'my legend title' settings.properties['hover_text'] = 'y' settings.properties['box_orientation'] = 'h' settings.properties['normalization'] = 'probability' settings.properties['box_stat'] = 'sd' settings.properties['box_outliers'] = 'suspectedoutliers' settings.properties['violin_side'] = 'negative' settings.properties['show_mean_line'] = True settings.properties['cumulative'] = True settings.properties['invert_hist'] = 'decreasing' settings.source_layer_id = vl3.id() settings.properties['x_name'] = 'so4' settings.properties['y_name'] = 'ca' settings.properties['z_name'] = 'mg' settings.properties['color_scale'] = 'Earth' settings.properties['violin_box'] = True settings.properties['layout_filter_by_map'] = True settings.properties['layout_filter_by_atlas'] = True # TODO: likely need to test other settings.properties values here! settings.layout['legend'] = False settings.layout['legend_orientation'] = 'h' settings.layout['title'] = 'my title' settings.layout['x_title'] = 'my x title' settings.layout['y_title'] = 'my y title' settings.layout['z_title'] = 'my z title' settings.layout['font_title_size'] = 10 settings.layout['font_title_family'] = "Arial" settings.layout['font_title_color'] = "#000000" settings.layout['font_xlabel_size'] = 10 settings.layout['font_xlabel_family'] = "Arial" settings.layout['font_xlabel_color'] = "#000000" settings.layout['font_xticks_size'] = 10 settings.layout['font_xticks_family'] = "Arial" settings.layout['font_xticks_color'] = "#000000" settings.layout['font_ylabel_size'] = 10 settings.layout['font_ylabel_family'] = "Arial" settings.layout['font_ylabel_color'] = "#000000" settings.layout['font_yticks_size'] = 10 settings.layout['font_yticks_family'] = "Arial" settings.layout['font_yticks_color'] = "#000000" settings.layout['range_slider']['visible'] = True settings.layout['bar_mode'] = 'overlay' settings.layout['x_type'] = 'log' settings.layout['y_type'] = 'category' settings.layout['x_inv'] = 'reversed' settings.layout['y_inv'] = 'reversed' settings.layout['bargaps'] = 0.8 settings.layout['additional_info_expression'] = '1+2' settings.layout['bins_check'] = True settings.layout['gridcolor'] = '#bdbfc0' settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_FILTER, QgsProperty.fromExpression('"ap">50')) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_MARKER_SIZE, QgsProperty.fromExpression('5+64')) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_COLOR, QgsProperty.fromExpression("'red'")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_STROKE_WIDTH, QgsProperty.fromExpression("12/2")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_TITLE, QgsProperty.fromExpression("concat('my', '_title_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_LEGEND_TITLE, QgsProperty.fromExpression("concat('my', '_legend_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_TITLE, QgsProperty.fromExpression("concat('my', '_x_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_TITLE, QgsProperty.fromExpression("concat('my', '_y_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Z_TITLE, QgsProperty.fromExpression("concat('my', '_z_axis_', @some_var)")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_MIN, QgsProperty.fromExpression("-1*10")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_X_MAX, QgsProperty.fromExpression("+1*10")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_MIN, QgsProperty.fromExpression("-1*10")) settings.data_defined_properties.setProperty( PlotSettings.PROPERTY_Y_MAX, QgsProperty.fromExpression("+1*10")) dialog2 = DataPlotlyPanelWidget(None, override_iface=IFACE) dialog2.set_settings(settings) # print('set settings') self.assertEqual(dialog2.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): # print(k) if k in [ 'x', 'y', 'z', 'additional_hover_text', 'featureIds', 'featureBox', 'custom' ]: continue self.assertEqual(dialog2.get_settings().properties[k], settings.properties[k]) for k in settings.layout.keys(): self.assertEqual(dialog2.get_settings().layout[k], settings.layout[k]) self.assertEqual(dialog2.get_settings().source_layer_id, vl3.id()) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_FILTER), settings.data_defined_properties.property( PlotSettings.PROPERTY_FILTER)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_MARKER_SIZE), settings.data_defined_properties.property( PlotSettings.PROPERTY_MARKER_SIZE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_COLOR), settings.data_defined_properties.property( PlotSettings.PROPERTY_COLOR)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_STROKE_WIDTH), settings.data_defined_properties.property( PlotSettings.PROPERTY_STROKE_WIDTH)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_X_MIN), settings.data_defined_properties.property( PlotSettings.PROPERTY_X_MIN)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_X_MAX), settings.data_defined_properties.property( PlotSettings.PROPERTY_X_MAX)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_Y_MIN), settings.data_defined_properties.property( PlotSettings.PROPERTY_Y_MIN)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_Y_MAX), settings.data_defined_properties.property( PlotSettings.PROPERTY_Y_MAX)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_TITLE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_LEGEND_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_LEGEND_TITLE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_X_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_X_TITLE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_Y_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_Y_TITLE)) self.assertEqual( dialog2.get_settings().data_defined_properties.property( PlotSettings.PROPERTY_Z_TITLE), settings.data_defined_properties.property( PlotSettings.PROPERTY_Z_TITLE)) dialog2.deleteLater() del dialog2 settings = dialog.get_settings() dialog.deleteLater() del dialog dialog3 = DataPlotlyPanelWidget(None, override_iface=IFACE) # print('dialog 2') dialog3.set_settings(settings) # print('set settings') self.assertEqual(dialog3.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): # print(k) self.assertEqual(dialog3.get_settings().properties[k], settings.properties[k]) self.assertEqual(dialog3.get_settings().properties, settings.properties) for k in settings.layout.keys(): # print(k) self.assertEqual(dialog3.get_settings().layout[k], settings.layout[k]) dialog3.deleteLater() del dialog3 # print('done') QgsProject.instance().clear()
def test_settings_round_trip_secondary(self): # pylint: disable=too-many-statements """ Test setting and retrieving settings results in identical results -- this secondary test allows for different values to be checked (e.g. True if the first test checks for False) """ layer_path = os.path.join(os.path.dirname(__file__), 'test_layer.geojson') vl1 = QgsVectorLayer(layer_path, 'test_layer', 'ogr') vl2 = QgsVectorLayer(layer_path, 'test_layer1', 'ogr') vl3 = QgsVectorLayer(layer_path, 'test_layer2', 'ogr') QgsProject.instance().addMapLayers([vl1, vl2, vl3]) dialog = DataPlotlyPanelWidget(None, override_iface=IFACE) settings = dialog.get_settings() # default should be scatter plot self.assertEqual(settings.plot_type, 'scatter') # print('dialog loaded') # customise settings settings.plot_type = 'bar' settings.properties['violin_box'] = False dialog2 = DataPlotlyPanelWidget(None, override_iface=IFACE) dialog2.set_settings(settings) # print('set settings') self.assertEqual(dialog2.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): # print(k) if k in [ 'x', 'y', 'z', 'additional_hover_text', 'featureIds', 'featureBox', 'custom' ]: continue self.assertEqual(dialog2.get_settings().properties[k], settings.properties[k]) for k in settings.layout.keys(): self.assertEqual(dialog2.get_settings().layout[k], settings.layout[k]) dialog2.deleteLater() del dialog2 settings = dialog.get_settings() dialog.deleteLater() del dialog dialog3 = DataPlotlyPanelWidget(None, override_iface=IFACE) # print('dialog 2') dialog3.set_settings(settings) # print('set settings') self.assertEqual(dialog3.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): # print(k) self.assertEqual(dialog3.get_settings().properties[k], settings.properties[k]) self.assertEqual(dialog3.get_settings().properties, settings.properties) for k in settings.layout.keys(): # print(k) self.assertEqual(dialog3.get_settings().layout[k], settings.layout[k]) dialog3.deleteLater() del dialog3 # print('done') QgsProject.instance().clear()
class PlotLayoutItemWidget(QgsLayoutItemBaseWidget): """ Configuration widget for layout plot items """ def __init__(self, parent, layout_object): super().__init__(parent, layout_object) self.plot_item = layout_object self.message_bar = None vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) plot_tools_layout = QHBoxLayout() plot_add_button = QPushButton() plot_add_button.setIcon(GuiUtils.get_icon('symbologyAdd.svg')) plot_add_button.setToolTip('Add a new plot') plot_tools_layout.addWidget(plot_add_button) plot_add_button.clicked.connect(self.add_plot) plot_remove_button = QPushButton() plot_remove_button.setIcon(GuiUtils.get_icon('symbologyRemove.svg')) plot_remove_button.setToolTip('Remove selected plot') plot_tools_layout.addWidget(plot_remove_button) plot_remove_button.clicked.connect(self.remove_plot) plot_duplicate_button = QPushButton() plot_duplicate_button.setIcon( GuiUtils.get_icon('mActionDuplicateLayer.svg')) plot_duplicate_button.setToolTip('Duplicates the selected plot') plot_tools_layout.addWidget(plot_duplicate_button) plot_duplicate_button.clicked.connect(self.duplicate_plot) plot_move_up_button = QPushButton() plot_move_up_button.setIcon(GuiUtils.get_icon('mActionArrowUp.svg')) plot_move_up_button.setToolTip('Move selected plot up') plot_tools_layout.addWidget(plot_move_up_button) plot_move_up_button.clicked.connect(self.move_up_plot) plot_move_down_button = QPushButton() plot_move_down_button.setIcon( GuiUtils.get_icon('mActionArrowDown.svg')) plot_move_down_button.setToolTip('Move selected plot down') plot_tools_layout.addWidget(plot_move_down_button) plot_move_down_button.clicked.connect(self.move_down_plot) vl.addLayout(plot_tools_layout) self.plot_list = QListWidget() self.plot_list.setSelectionMode(QListWidget.SingleSelection) self.plot_list.doubleClicked.connect(self.show_properties) vl.addWidget(self.plot_list) self.populate_plot_list() plot_properties_button = QPushButton(self.tr('Setup Selected Plot')) vl.addWidget(plot_properties_button) plot_properties_button.clicked.connect(self.show_properties) self.panel = None self.setPanelTitle(self.tr('Plot Properties')) self.item_properties_widget = QgsLayoutItemPropertiesWidget( self, layout_object) vl.addWidget(self.item_properties_widget) self.setLayout(vl) def populate_plot_list(self): """ Clears and re-populates the plot list widget. The currently selection is retained """ selected_index = self.plot_list.currentRow() self.plot_list.clear() for setting in self.plot_item.plot_settings: plot_type = setting.plot_type if setting.plot_type is not None else '(not set)' legend_title = ('[' + setting.properties.get('name') + ']') \ if setting.properties.get('name', '') != '' else '' self.plot_list.addItem(plot_type + ' ' + legend_title) # select index within range [0, len(plot_settings)-1] selected_index = max( 0, min(len(self.plot_item.plot_settings) - 1, selected_index)) self.plot_list.setCurrentRow(selected_index, QItemSelectionModel.SelectCurrent) def add_plot(self): """ Adds a new plot and updates the plot list and the plot item """ self.plot_item.add_plot() self.populate_plot_list() self.plot_item.refresh() def duplicate_plot(self): """ Duplicates an existing plot and updates the plot list and the plot item """ selected_plot_index = self.plot_list.currentRow() if selected_plot_index < 0: return self.plot_item.duplicate_plot(selected_plot_index) self.populate_plot_list() self.plot_item.refresh() def remove_plot(self): """ Removes the selected plot and updates the plot list and the plot item """ selected_index = self.plot_list.currentRow() if selected_index < 0: return self.plot_item.remove_plot(selected_index) self.populate_plot_list() self.plot_item.refresh() def move_up_plot(self): """ Moves the selected plot up and updates the plot list and the plot item """ selected_index = self.plot_list.currentRow() if selected_index <= 0: return item = self.plot_item.plot_settings.pop(selected_index) self.plot_item.plot_settings.insert(selected_index - 1, item) self.plot_list.setCurrentRow(selected_index - 1, QItemSelectionModel.SelectCurrent) self.populate_plot_list() self.plot_item.refresh() def move_down_plot(self): """ Moves the selected plot down and updates the plot list and the plot item """ selected_index = self.plot_list.currentRow() if selected_index >= len(self.plot_item.plot_settings) - 1: return item = self.plot_item.plot_settings.pop(selected_index) self.plot_item.plot_settings.insert(selected_index + 1, item) self.plot_list.setCurrentRow(selected_index + 1, QItemSelectionModel.SelectCurrent) self.populate_plot_list() self.plot_item.refresh() def show_properties(self): """ Shows the plot properties panel """ selected_plot_index = self.plot_list.currentRow() if selected_plot_index < 0: return self.panel = DataPlotlyPanelWidget( mode=DataPlotlyPanelWidget.MODE_LAYOUT, message_bar=self.message_bar) # not quite right -- we ideally want to also add the source layer scope into the context given by plot item, # but that causes a hard lock in the Python GIL (because PyQt doesn't release the GIL when creating the menu # for the property override buttons). Nothing much we can do about that here (or in QGIS, # it's a Python/PyQt limitation) self.panel.registerExpressionContextGenerator(self.plot_item) self.panel.set_print_layout(self.plot_item.layout()) self.panel.linked_map_combo.blockSignals(True) self.panel.linked_map_combo.setItem(self.plot_item.linked_map) self.panel.linked_map_combo.blockSignals(False) self.panel.linked_map_combo.itemChanged.connect( self.linked_map_changed) self.panel.set_settings( self.plot_item.plot_settings[selected_plot_index]) # self.panel.set_settings(self.layoutItem().plot_settings) self.openPanel(self.panel) self.panel.widgetChanged.connect(self.update_item_settings) self.panel.panelAccepted.connect(self.set_item_settings) def update_item_settings(self): """ Updates the plot item without dismissing the properties panel """ if not self.panel: return self.plot_item.set_plot_settings(self.plot_list.currentRow(), self.panel.get_settings()) self.populate_plot_list() self.plot_item.update() def set_item_settings(self): """ Updates the plot item based on the settings from the properties panel """ if not self.panel: return self.plot_item.set_plot_settings(self.plot_list.currentRow(), self.panel.get_settings()) self.populate_plot_list() self.panel = None self.plot_item.update() def linked_map_changed(self, linked_map): """ Triggered when the linked map is changed """ self.plot_item.set_linked_map(linked_map) self.plot_item.update() def setNewItem(self, item): # pylint: disable=missing-docstring if item.type() != ITEM_TYPE: return False self.plot_item = item self.item_properties_widget.setItem(item) self.populate_plot_list() if self.panel is not None: self.panel.set_settings(self.plot_item.plot_settings[0]) self.panel.linked_map_combo.blockSignals(True) self.panel.linked_map_combo.setItem(self.plot_item.linked_map) self.panel.linked_map_combo.blockSignals(False) return True def setDesignerInterface(self, iface): # pylint: disable=missing-docstring super().setDesignerInterface(iface) self.message_bar = iface.messageBar() if self.panel: self.panel.message_bar = self.message_bar
def test_settings_round_trip(self): # pylint: disable=too-many-statements """ Test setting and retrieving settings results in identical results """ layer_path = os.path.join( os.path.dirname(__file__), 'test_layer.geojson') vl1 = QgsVectorLayer(layer_path, 'test_layer', 'ogr') vl2 = QgsVectorLayer(layer_path, 'test_layer1', 'ogr') vl3 = QgsVectorLayer(layer_path, 'test_layer2', 'ogr') QgsProject.instance().addMapLayers([vl1, vl2, vl3]) dialog = DataPlotlyPanelWidget(None, iface=IFACE) settings = dialog.get_settings() # default should be scatter plot self.assertEqual(settings.plot_type, 'scatter') # customise settings settings.plot_type = 'violin' settings.properties['name'] = 'my legend title' settings.properties['hover_text'] = 'y' settings.properties['box_orientation'] = 'h' settings.properties['normalization'] = 'probability' settings.properties['box_stat'] = 'sd' settings.properties['box_outliers'] = 'suspectedoutliers' settings.properties['violin_side'] = 'negative' settings.properties['show_mean_line'] = True settings.properties['cumulative'] = True settings.properties['invert_hist'] = 'decreasing' settings.source_layer_id = vl3.id() settings.properties['x_name'] = 'so4' settings.properties['y_name'] = 'ca' settings.properties['z_name'] = 'mg' settings.properties['in_color_value'] = '100,150,180,50' settings.properties['in_color_property'] = QgsProperty.fromExpression('5+6').toVariant() settings.properties['size_property'] = QgsProperty.fromExpression('5+64').toVariant() settings.properties['color_scale'] = 'Earth' settings.properties['colorscale_in'] = 'Earth' # TODO: likely need to test other settings.properties values here! settings.layout['legend'] = False settings.layout['legend_orientation'] = 'h' settings.layout['title'] = 'my title' settings.layout['x_title'] = 'my x title' settings.layout['y_title'] = 'my y title' settings.layout['z_title'] = 'my z title' settings.layout['range_slider']['visible'] = True settings.layout['bar_mode'] = 'overlay' settings.layout['x_type'] = 'log' settings.layout['y_type'] = 'category' settings.layout['x_inv'] = 'reversed' settings.layout['y_inv'] = 'reversed' settings.layout['bargaps'] = 0.8 settings.layout['additional_info_expression'] = '1+2' settings.layout['bins_check'] = True dialog2 = DataPlotlyPanelWidget(None, iface=IFACE) dialog2.set_settings(settings) self.assertEqual(dialog2.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): if k in ['x', 'y', 'z', 'additional_hover_text', 'featureIds', 'featureBox', 'custom', 'in_color', 'marker_size']: continue print(k) self.assertEqual(dialog2.get_settings().properties[k], settings.properties[k]) for k in settings.layout.keys(): print(k) self.assertEqual(dialog2.get_settings().layout[k], settings.layout[k]) self.assertEqual(dialog2.get_settings().source_layer_id, vl3.id()) settings = dialog.get_settings() dialog3 = DataPlotlyPanelWidget(None, iface=IFACE) dialog3.set_settings(settings) self.assertEqual(dialog3.get_settings().plot_type, settings.plot_type) for k in settings.properties.keys(): print(k) self.assertEqual(dialog3.get_settings().properties[k], settings.properties[k]) self.assertEqual(dialog3.get_settings().properties, settings.properties) for k in settings.layout.keys(): print(k) self.assertEqual(dialog3.get_settings().layout[k], settings.layout[k]) QgsProject.instance().clear()