From 2ba25ed66f198eb57b3eee49506ab3ed53fbc8c7 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Fri, 19 Mar 2021 11:38:19 +0100 Subject: [PATCH 01/57] Allow to choose the gridaxis color of the plot (#259) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * allow to choose the gridaxis color of the plot * fix test? * Update DataPlotly/core/plot_types/plot_type.py Co-authored-by: Simon Gröchenig <simon.groechenig@salzburgresearch.at> * Apply suggestions from code review Co-authored-by: Simon Gröchenig <simon.groechenig@salzburgresearch.at> Co-authored-by: Nyall Dawson <nyall.dawson@gmail.com> * use hex color strings and lowerize all of them. fix tests? Co-authored-by: Simon Gröchenig <simon.groechenig@salzburgresearch.at> Co-authored-by: Nyall Dawson <nyall.dawson@gmail.com> --- DataPlotly/core/plot_settings.py | 3 +- DataPlotly/core/plot_types/plot_type.py | 6 +- DataPlotly/gui/plot_settings_widget.py | 8 +- DataPlotly/test/test_data_plotly_dialog.py | 1 + DataPlotly/ui/dataplotly_dockwidget_base.ui | 865 ++++++++++---------- 5 files changed, 464 insertions(+), 419 deletions(-) diff --git a/DataPlotly/core/plot_settings.py b/DataPlotly/core/plot_settings.py index 4d7d8a0b..aa2ac6b6 100644 --- a/DataPlotly/core/plot_settings.py +++ b/DataPlotly/core/plot_settings.py @@ -132,7 +132,8 @@ def __init__(self, plot_type: str = 'scatter', properties: dict = None, layout: 'bargaps': 0, 'polar': {'angularaxis': {'direction': 'clockwise'}}, 'additional_info_expression': '', - 'bins_check': False + 'bins_check': False, + 'gridcolor': '#bdbfc0' } self.plot_base_dic = { diff --git a/DataPlotly/core/plot_types/plot_type.py b/DataPlotly/core/plot_types/plot_type.py index c7ef5835..2e9ff249 100644 --- a/DataPlotly/core/plot_types/plot_type.py +++ b/DataPlotly/core/plot_types/plot_type.py @@ -85,12 +85,14 @@ def create_layout(settings): xaxis={ 'title': x_title, 'autorange': settings.layout['x_inv'], - 'range': range_x + 'range': range_x, + 'gridcolor': settings.layout.get('gridcolor', '#bdbfc0') }, yaxis={ 'title': y_title, 'autorange': settings.layout['y_inv'], - 'range': range_y + 'range': range_y, + 'gridcolor': settings.layout.get('gridcolor', '#bdbfc0') }, paper_bgcolor=bg_color, plot_bgcolor=bg_color diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index e1e12b38..cc7e674b 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -282,6 +282,9 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b self.y_axis_min.setRange(sys.float_info.max * -1, sys.float_info.max) self.y_axis_max.setRange(sys.float_info.max * -1, sys.float_info.max) + # default gridaxis color + self.layout_grid_axis_color.setColor(QColor('#bdbfc0')) + self.pid = None self.plot_path = None self.plot_url = None @@ -1035,7 +1038,8 @@ def get_settings(self) -> PlotSettings: # pylint: disable=R0915 'y_max': self.y_axis_max.value() if self.y_axis_bounds_check.isChecked() else None, 'bargaps': self.bar_gap.value(), 'additional_info_expression': self.additional_info_combo.expression(), - 'bins_check': self.bins_check.isChecked()} + 'bins_check': self.bins_check.isChecked(), + 'gridcolor': self.layout_grid_axis_color.color().name()} settings = PlotSettings(plot_type=self.ptype, properties=plot_properties, layout=layout_properties, source_layer_id=self.layer_combo.currentLayer().id() if self.layer_combo.currentLayer() else None) @@ -1138,6 +1142,8 @@ def set_settings(self, settings: PlotSettings): # pylint: disable=too-many-stat self.bins_value.setValue(settings.properties.get('bins', 0)) self.bar_gap.setValue(settings.layout.get('bargaps', 0)) self.show_legend_check.setChecked(settings.layout.get('legend', True)) + self.layout_grid_axis_color.setColor( + QColor(settings.layout.get('gridcolor') or '#bdbfc0')) def create_plot_factory(self) -> PlotFactory: """ diff --git a/DataPlotly/test/test_data_plotly_dialog.py b/DataPlotly/test/test_data_plotly_dialog.py index 722145dd..cbe14a1d 100644 --- a/DataPlotly/test/test_data_plotly_dialog.py +++ b/DataPlotly/test/test_data_plotly_dialog.py @@ -136,6 +136,7 @@ def test_settings_round_trip(self): # pylint: disable=too-many-statements 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')) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index 38d6a16a..94c06439 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>593</width> - <height>624</height> + <width>1072</width> + <height>845</height> </rect> </property> <property name="windowTitle"> @@ -138,6 +138,123 @@ QListWidget::item::selected { <property name="bottomMargin"> <number>0</number> </property> + <item row="2" column="0"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="1" colspan="3"> + <widget class="QComboBox" name="subcombo"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="subcombo_label"> + <property name="text"> + <string>Type of plot</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="4"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <widget class="QRadioButton" name="radio_columns"> + <property name="text"> + <string>Plot in columns</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radio_rows"> + <property name="text"> + <string>Plot in rows</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="2" column="0" colspan="4"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="clear_btn"> + <property name="text"> + <string>Clean Plot Canvas</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="update_btn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Update Plot</string> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="draw_btn"> + <property name="text"> + <string>Create Plot</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="configuration_btn"> + <property name="text"> + <string>Configuration</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> <item row="0" column="0"> <widget class="QStackedWidget" name="stackedNestedPlotWidget"> <property name="currentIndex"> @@ -204,8 +321,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>531</width> - <height>653</height> + <width>804</width> + <height>719</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_9"> @@ -418,7 +535,7 @@ QListWidget::item::selected { </widget> </item> <item row="10" column="1" colspan="5"> - <widget class="QgsOpacityWidget" name="opacity_widget" native="true"> + <widget class="QgsOpacityWidget" name="opacity_widget"> <property name="focusPolicy"> <enum>Qt::StrongFocus</enum> </property> @@ -492,7 +609,7 @@ QListWidget::item::selected { <widget class="QgsLayoutItemComboBox" name="linked_map_combo"/> </item> <item row="8" column="1" colspan="2"> - <widget class="QgsFieldExpressionWidget" name="y_combo" native="true"/> + <widget class="QgsFieldExpressionWidget" name="y_combo"/> </item> <item row="9" column="0"> <widget class="QLabel" name="z_label"> @@ -502,7 +619,7 @@ QListWidget::item::selected { </widget> </item> <item row="7" column="1" colspan="2"> - <widget class="QgsFieldExpressionWidget" name="x_combo" native="true"/> + <widget class="QgsFieldExpressionWidget" name="x_combo"/> </item> <item row="8" column="0"> <widget class="QLabel" name="y_label"> @@ -537,7 +654,7 @@ QListWidget::item::selected { </widget> </item> <item row="9" column="1" colspan="2"> - <widget class="QgsFieldExpressionWidget" name="z_combo" native="true"/> + <widget class="QgsFieldExpressionWidget" name="z_combo"/> </item> <item row="0" column="1" colspan="2"> <widget class="QgsMapLayerComboBox" name="layer_combo"> @@ -588,6 +705,12 @@ QListWidget::item::selected { </property> <item row="0" column="0"> <widget class="QScrollArea" name="scrollArea_6"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="frameShape"> <enum>QFrame::NoFrame</enum> </property> @@ -598,9 +721,9 @@ QListWidget::item::selected { <property name="geometry"> <rect> <x>0</x> - <y>0</y> - <width>424</width> - <height>979</height> + <y>-210</y> + <width>790</width> + <height>958</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,1,0"> @@ -616,58 +739,126 @@ QListWidget::item::selected { <property name="bottomMargin"> <number>0</number> </property> - <item row="3" column="1" colspan="2"> - <widget class="QLineEdit" name="plot_title_line"/> + <item row="6" column="3"> + <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> </item> - <item row="28" column="1" colspan="3"> - <layout class="QHBoxLayout" name="horizontalLayout_8" stretch="1,1"> + <item row="16" column="0" colspan="4"> + <widget class="QgsCollapsibleGroupBox" name="y_axis_bounds_check"> + <property name="title"> + <string>Set Y Axis Bounds</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridYAxisBounds"> + <item row="0" column="0"> + <widget class="QLabel" name="y_axis_min_label"> + <property name="text"> + <string>Minimum</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QgsDoubleSpinBox" name="y_axis_min"/> + </item> + <item row="0" column="2"> + <widget class="QgsPropertyOverrideButton" name="y_axis_min_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="y_axis_max_label"> + <property name="text"> + <string>Maximum</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QgsDoubleSpinBox" name="y_axis_max"/> + </item> + <item row="1" column="2"> + <widget class="QgsPropertyOverrideButton" name="y_axis_max_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="28" column="0"> + <widget class="QCheckBox" name="bins_check"> + <property name="text"> + <string>Manual bin size</string> + </property> + </widget> + </item> + <item row="23" column="0"> + <widget class="QLabel" name="violinSideLabel"> + <property name="text"> + <string>Violin side</string> + </property> + </widget> + </item> + <item row="26" column="0" colspan="4"> + <layout class="QHBoxLayout" name="horizontalLayout_7"> <item> - <widget class="QgsSpinBox" name="bins_value"> + <widget class="QCheckBox" name="invert_hist_check"> <property name="enabled"> - <bool>false</bool> - </property> - <property name="maximum"> - <number>1000</number> + <bool>true</bool> </property> - <property name="value"> - <number>10</number> + <property name="text"> + <string>Invert histogram direction</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> + <widget class="QCheckBox" name="cumulative_hist_check"> + <property name="enabled"> + <bool>true</bool> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> + <property name="text"> + <string>Cumulative histogram</string> </property> - </spacer> + </widget> </item> </layout> </item> - <item row="21" column="1" colspan="3"> - <widget class="QComboBox" name="box_statistic_combo"/> + <item row="11" column="0"> + <widget class="QCheckBox" name="hover_as_text_check"> + <property name="text"> + <string>Hover label as text</string> + </property> + </widget> </item> - <item row="6" column="3"> - <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> + <item row="20" column="1" colspan="3"> + <widget class="QComboBox" name="hist_norm_combo"/> + </item> + <item row="21" column="0"> + <widget class="QLabel" name="box_statistic_label"> <property name="text"> - <string>...</string> + <string>Show statistics</string> </property> </widget> </item> - <item row="10" column="0"> - <widget class="QLabel" name="additional_info_label"> + <item row="18" column="0"> + <widget class="QLabel" name="orientation_label"> <property name="text"> - <string>Additional hover label</string> + <string>Bar orientation</string> </property> </widget> </item> - <item row="6" column="1" rowspan="2" colspan="2"> - <widget class="QLineEdit" name="y_axis_title"/> + <item row="8" column="1" colspan="2"> + <widget class="QLineEdit" name="z_axis_title"/> </item> <item row="2" column="0" colspan="4"> <layout class="QHBoxLayout" name="horizontalLayout_6"> @@ -697,54 +888,95 @@ QListWidget::item::selected { </item> </layout> </item> - <item row="3" column="0"> - <widget class="QLabel" name="plot_title_lab"> + <item row="12" column="1" colspan="3"> + <widget class="QComboBox" name="combo_text_position"/> + </item> + <item row="30" column="0"> + <widget class="QLabel" name="bar_gap_label"> <property name="text"> - <string>Plot title</string> + <string>Bar gap</string> </property> </widget> </item> - <item row="22" column="0"> - <widget class="QLabel" name="outliers_label"> + <item row="12" column="0"> + <widget class="QLabel" name="label_text_position"> <property name="text"> - <string>Outliers</string> + <string>Label text position</string> </property> </widget> </item> - <item row="22" column="1" colspan="3"> - <widget class="QComboBox" name="outliers_combo"/> + <item row="19" column="1" colspan="3"> + <widget class="QComboBox" name="bar_mode_combo"/> </item> - <item row="30" column="0" colspan="3"> - <spacer name="verticalSpacer_6"> - <property name="orientation"> - <enum>Qt::Vertical</enum> + <item row="24" column="0" colspan="4"> + <widget class="QCheckBox" name="violinBox"> + <property name="toolTip"> + <string>If checked, box plots will be overlaid on top of violin plots</string> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>255</width> - <height>222</height> - </size> + <property name="text"> + <string>Include box plots</string> </property> - </spacer> - </item> - <item row="5" column="1" colspan="2"> - <widget class="QLineEdit" name="x_axis_title"/> - </item> - <item row="4" column="1" colspan="2"> - <widget class="QLineEdit" name="legend_title"/> + <property name="checked"> + <bool>true</bool> + </property> + </widget> </item> <item row="23" column="1" colspan="3"> <widget class="QComboBox" name="violinSideCombo"/> </item> - <item row="18" column="0"> - <widget class="QLabel" name="orientation_label"> + <item row="13" column="0"> + <widget class="QCheckBox" name="invert_x_check"> <property name="text"> - <string>Bar orientation</string> + <string>Invert X axis</string> </property> </widget> </item> - <item row="10" column="1" colspan="3"> - <widget class="QgsFieldExpressionWidget" name="additional_info_combo" native="true"/> + <item row="28" column="1" colspan="3"> + <layout class="QHBoxLayout" name="horizontalLayout_8" stretch="1,1"> + <item> + <widget class="QgsSpinBox" name="bins_value"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximum"> + <number>1000</number> + </property> + <property name="value"> + <number>10</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="x_axis_label"> + <property name="text"> + <string>X label</string> + </property> + </widget> + </item> + <item row="18" column="1" colspan="3"> + <widget class="QComboBox" name="orientation_combo"/> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="legend_label"> + <property name="text"> + <string>Legend title</string> + </property> + </widget> </item> <item row="15" column="0" colspan="4"> <widget class="QgsCollapsibleGroupBox" name="x_axis_bounds_check"> @@ -795,51 +1027,30 @@ QListWidget::item::selected { </layout> </widget> </item> - <item row="3" column="3"> - <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> + <item row="14" column="1"> + <widget class="QLabel" name="y_axis_mode_label"> <property name="text"> - <string>...</string> + <string>Y axis mode</string> </property> </widget> </item> - <item row="26" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <item> - <widget class="QCheckBox" name="invert_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Invert histogram direction</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cumulative_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Cumulative histogram</string> - </property> - </widget> - </item> - </layout> + <item row="3" column="1" colspan="2"> + <widget class="QLineEdit" name="plot_title_line"/> </item> - <item row="5" column="3"> - <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> + <item row="22" column="0"> + <widget class="QLabel" name="outliers_label"> <property name="text"> - <string>...</string> + <string>Outliers</string> </property> </widget> </item> - <item row="19" column="1" colspan="3"> - <widget class="QComboBox" name="bar_mode_combo"/> + <item row="4" column="1" colspan="2"> + <widget class="QLineEdit" name="legend_title"/> </item> - <item row="13" column="0"> - <widget class="QCheckBox" name="invert_x_check"> + <item row="14" column="0"> + <widget class="QCheckBox" name="invert_y_check"> <property name="text"> - <string>Invert X axis</string> + <string>Invert Y axis</string> </property> </widget> </item> @@ -850,46 +1061,8 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="9" column="0"> - <widget class="QLabel" name="info_label"> - <property name="text"> - <string>Hover tooltip</string> - </property> - </widget> - </item> - <item row="11" column="0"> - <widget class="QCheckBox" name="hover_as_text_check"> - <property name="text"> - <string>Hover label as text</string> - </property> - </widget> - </item> - <item row="13" column="1"> - <widget class="QLabel" name="x_axis_mode_label"> - <property name="text"> - <string>X axis mode</string> - </property> - </widget> - </item> - <item row="21" column="0"> - <widget class="QLabel" name="box_statistic_label"> - <property name="text"> - <string>Show statistics</string> - </property> - </widget> - </item> - <item row="9" column="1" colspan="3"> - <widget class="QComboBox" name="info_combo"/> - </item> - <item row="14" column="2" colspan="2"> - <widget class="QComboBox" name="y_axis_mode_combo"/> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="legend_label"> - <property name="text"> - <string>Legend title</string> - </property> - </widget> + <item row="13" column="2" colspan="2"> + <widget class="QComboBox" name="x_axis_mode_combo"/> </item> <item row="25" column="0" colspan="4"> <widget class="QCheckBox" name="showMeanCheck"> @@ -901,27 +1074,63 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="5" column="0"> - <widget class="QLabel" name="x_axis_label"> + <item row="30" column="1" colspan="3"> + <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,1"> + <item> + <widget class="QgsDoubleSpinBox" name="bar_gap"> + <property name="maximum"> + <double>1.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.100000000000000</double> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="21" column="1" colspan="3"> + <widget class="QComboBox" name="box_statistic_combo"/> + </item> + <item row="5" column="1" colspan="2"> + <widget class="QLineEdit" name="x_axis_title"/> + </item> + <item row="8" column="3"> + <widget class="QgsPropertyOverrideButton" name="z_axis_title_defined_button"> <property name="text"> - <string>X label</string> + <string>...</string> </property> </widget> </item> - <item row="29" column="0"> - <widget class="QLabel" name="bar_gap_label"> + <item row="13" column="1"> + <widget class="QLabel" name="x_axis_mode_label"> <property name="text"> - <string>Bar gap</string> + <string>X axis mode</string> </property> </widget> </item> - <item row="14" column="0"> - <widget class="QCheckBox" name="invert_y_check"> + <item row="10" column="0"> + <widget class="QLabel" name="additional_info_label"> <property name="text"> - <string>Invert Y axis</string> + <string>Additional hover label</string> </property> </widget> </item> + <item row="14" column="2" colspan="2"> + <widget class="QComboBox" name="y_axis_mode_combo"/> + </item> <item row="4" column="3"> <widget class="QgsPropertyOverrideButton" name="legend_title_defined_button"> <property name="text"> @@ -929,165 +1138,108 @@ QListWidget::item::selected { </property> </widget> </item> + <item row="6" column="1" rowspan="2" colspan="2"> + <widget class="QLineEdit" name="y_axis_title"/> + </item> <item row="6" column="0" rowspan="2"> <widget class="QLabel" name="y_axis_label"> <property name="text"> - <string>Y label</string> - </property> - </widget> - </item> - <item row="16" column="0" colspan="4"> - <widget class="QgsCollapsibleGroupBox" name="y_axis_bounds_check"> - <property name="title"> - <string>Set Y Axis Bounds</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <layout class="QGridLayout" name="gridYAxisBounds"> - <item row="0" column="0"> - <widget class="QLabel" name="y_axis_min_label"> - <property name="text"> - <string>Minimum</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QgsDoubleSpinBox" name="y_axis_min"/> - </item> - <item row="0" column="2"> - <widget class="QgsPropertyOverrideButton" name="y_axis_min_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="y_axis_max_label"> - <property name="text"> - <string>Maximum</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QgsDoubleSpinBox" name="y_axis_max"/> - </item> - <item row="1" column="2"> - <widget class="QgsPropertyOverrideButton" name="y_axis_max_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="14" column="1"> - <widget class="QLabel" name="y_axis_mode_label"> - <property name="text"> - <string>Y axis mode</string> - </property> - </widget> - </item> - <item row="8" column="1" colspan="2"> - <widget class="QLineEdit" name="z_axis_title"/> - </item> - <item row="28" column="0"> - <widget class="QCheckBox" name="bins_check"> - <property name="text"> - <string>Manual bin size</string> + <string>Y label</string> </property> </widget> </item> - <item row="8" column="0"> - <widget class="QLabel" name="z_axis_label"> + <item row="9" column="1" colspan="3"> + <widget class="QComboBox" name="info_combo"/> + </item> + <item row="32" column="0" colspan="3"> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>255</width> + <height>222</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="3"> + <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> <property name="text"> - <string>Z label</string> + <string>...</string> </property> </widget> </item> - <item row="23" column="0"> - <widget class="QLabel" name="violinSideLabel"> + <item row="10" column="1" colspan="3"> + <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> + </item> + <item row="20" column="0"> + <widget class="QLabel" name="hist_norm_label"> <property name="text"> - <string>Violin side</string> + <string>Normalization</string> </property> </widget> </item> - <item row="8" column="3"> - <widget class="QgsPropertyOverrideButton" name="z_axis_title_defined_button"> + <item row="5" column="3"> + <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> <property name="text"> <string>...</string> </property> </widget> </item> - <item row="18" column="1" colspan="3"> - <widget class="QComboBox" name="orientation_combo"/> - </item> - <item row="20" column="1" colspan="3"> - <widget class="QComboBox" name="hist_norm_combo"/> - </item> - <item row="13" column="2" colspan="2"> - <widget class="QComboBox" name="x_axis_mode_combo"/> - </item> - <item row="29" column="1" colspan="3"> - <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,1"> - <item> - <widget class="QgsDoubleSpinBox" name="bar_gap"> - <property name="maximum"> - <double>1.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_5"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="24" column="0" colspan="4"> - <widget class="QCheckBox" name="violinBox"> - <property name="toolTip"> - <string>If checked, box plots will be overlaid on top of violin plots</string> - </property> + <item row="8" column="0"> + <widget class="QLabel" name="z_axis_label"> <property name="text"> - <string>Include box plots</string> - </property> - <property name="checked"> - <bool>true</bool> + <string>Z label</string> </property> </widget> </item> - <item row="20" column="0"> - <widget class="QLabel" name="hist_norm_label"> + <item row="22" column="1" colspan="3"> + <widget class="QComboBox" name="outliers_combo"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="plot_title_lab"> <property name="text"> - <string>Normalization</string> + <string>Plot title</string> </property> </widget> </item> - <item row="12" column="0"> - <widget class="QLabel" name="label_text_position"> + <item row="9" column="0"> + <widget class="QLabel" name="info_label"> <property name="text"> - <string>Label text position</string> + <string>Hover tooltip</string> </property> </widget> </item> - <item row="12" column="1" colspan="3"> - <widget class="QComboBox" name="combo_text_position"/> + <item row="31" column="0" colspan="4"> + <widget class="QgsCollapsibleGroupBox" name="layout_configuration_box"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Layout Options</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="grid_color_label"> + <property name="text"> + <string>Grid color</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QgsColorButton" name="layout_grid_axis_color"> + <property name="allowOpacity"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> </item> </layout> </widget> @@ -1097,123 +1249,6 @@ QListWidget::item::selected { </widget> </widget> </item> - <item row="1" column="0"> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="1" colspan="3"> - <widget class="QComboBox" name="subcombo"/> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="subcombo_label"> - <property name="text"> - <string>Type of plot</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="topMargin"> - <number>0</number> - </property> - <item> - <widget class="QRadioButton" name="radio_columns"> - <property name="text"> - <string>Plot in columns</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radio_rows"> - <property name="text"> - <string>Plot in rows</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="2" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <property name="topMargin"> - <number>0</number> - </property> - <item> - <widget class="QPushButton" name="clear_btn"> - <property name="text"> - <string>Clean Plot Canvas</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="update_btn"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Update Plot</string> - </property> - <property name="checkable"> - <bool>false</bool> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <property name="autoDefault"> - <bool>true</bool> - </property> - <property name="default"> - <bool>false</bool> - </property> - <property name="flat"> - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="draw_btn"> - <property name="text"> - <string>Create Plot</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="configuration_btn"> - <property name="text"> - <string>Configuration</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </item> </layout> </widget> <widget class="QWidget" name="plot_stackpage"> @@ -1353,48 +1388,48 @@ QListWidget::item::selected { <customwidget> <class>QgsCollapsibleGroupBox</class> <extends>QGroupBox</extends> - <header>qgis.gui</header> + <header>qgscollapsiblegroupbox.h</header> <container>1</container> </customwidget> <customwidget> <class>QgsColorButton</class> <extends>QToolButton</extends> - <header>qgis.gui</header> + <header>qgscolorbutton.h</header> <container>1</container> </customwidget> + <customwidget> + <class>QgsDoubleSpinBox</class> + <extends>QDoubleSpinBox</extends> + <header>qgsdoublespinbox.h</header> + </customwidget> <customwidget> <class>QgsFieldExpressionWidget</class> <extends>QWidget</extends> - <header>qgis.gui</header> + <header>qgsfieldexpressionwidget.h</header> </customwidget> <customwidget> <class>QgsMapLayerComboBox</class> <extends>QComboBox</extends> - <header>qgis.gui</header> + <header>qgsmaplayercombobox.h</header> + </customwidget> + <customwidget> + <class>QgsOpacityWidget</class> + <extends>QWidget</extends> + <header>qgsopacitywidget.h</header> + <container>1</container> </customwidget> <customwidget> <class>QgsPropertyOverrideButton</class> <extends>QToolButton</extends> - <header>qgis.gui</header> + <header>qgspropertyoverridebutton.h</header> <slots> <slot>setVectorLayer(QgsMapLayer*)</slot> </slots> </customwidget> - <customwidget> - <class>QgsDoubleSpinBox</class> - <extends>QDoubleSpinBox</extends> - <header>qgis.gui</header> - </customwidget> <customwidget> <class>QgsSpinBox</class> <extends>QSpinBox</extends> - <header>qgis.gui</header> - </customwidget> - <customwidget> - <class>QgsOpacityWidget</class> - <extends>QWidget</extends> - <header>qgis.gui</header> - <container>1</container> + <header>qgsspinbox.h</header> </customwidget> <customwidget> <class>QgsLayoutItemComboBox</class> From f14ca6683eff378452374e62d503ae9e43bda4d9 Mon Sep 17 00:00:00 2001 From: SGroe <simon.groechenig@salzburgresearch.at> Date: Mon, 22 Mar 2021 08:37:01 +0100 Subject: [PATCH 02/57] move layout properties to layout options group in widget --- DataPlotly/ui/dataplotly_dockwidget_base.ui | 838 ++++++++++---------- 1 file changed, 430 insertions(+), 408 deletions(-) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index 94c06439..426b8e9d 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>1072</width> + <width>1070</width> <height>845</height> </rect> </property> @@ -140,53 +140,6 @@ QListWidget::item::selected { </property> <item row="2" column="0"> <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="1" colspan="3"> - <widget class="QComboBox" name="subcombo"/> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="subcombo_label"> - <property name="text"> - <string>Type of plot</string> - </property> - </widget> - </item> - <item row="1" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="topMargin"> - <number>0</number> - </property> - <item> - <widget class="QRadioButton" name="radio_columns"> - <property name="text"> - <string>Plot in columns</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="radio_rows"> - <property name="text"> - <string>Plot in rows</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> <item row="2" column="0" colspan="4"> <layout class="QHBoxLayout" name="horizontalLayout_2"> <property name="topMargin"> @@ -253,6 +206,53 @@ QListWidget::item::selected { </item> </layout> </item> + <item row="1" column="0" colspan="4"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <widget class="QRadioButton" name="radio_columns"> + <property name="text"> + <string>Plot in columns</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radio_rows"> + <property name="text"> + <string>Plot in rows</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="0" column="1" colspan="3"> + <widget class="QComboBox" name="subcombo"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="subcombo_label"> + <property name="text"> + <string>Type of plot</string> + </property> + </widget> + </item> </layout> </item> <item row="0" column="0"> @@ -321,8 +321,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>804</width> - <height>719</height> + <width>801</width> + <height>713</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_9"> @@ -721,12 +721,12 @@ QListWidget::item::selected { <property name="geometry"> <rect> <x>0</x> - <y>-210</y> - <width>790</width> - <height>958</height> + <y>0</y> + <width>780</width> + <height>986</height> </rect> </property> - <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,1,0"> + <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,0,0"> <property name="leftMargin"> <number>0</number> </property> @@ -739,176 +739,107 @@ QListWidget::item::selected { <property name="bottomMargin"> <number>0</number> </property> - <item row="6" column="3"> - <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="16" column="0" colspan="4"> - <widget class="QgsCollapsibleGroupBox" name="y_axis_bounds_check"> - <property name="title"> - <string>Set Y Axis Bounds</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <layout class="QGridLayout" name="gridYAxisBounds"> - <item row="0" column="0"> - <widget class="QLabel" name="y_axis_min_label"> - <property name="text"> - <string>Minimum</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QgsDoubleSpinBox" name="y_axis_min"/> - </item> - <item row="0" column="2"> - <widget class="QgsPropertyOverrideButton" name="y_axis_min_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="y_axis_max_label"> - <property name="text"> - <string>Maximum</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QgsDoubleSpinBox" name="y_axis_max"/> - </item> - <item row="1" column="2"> - <widget class="QgsPropertyOverrideButton" name="y_axis_max_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="28" column="0"> - <widget class="QCheckBox" name="bins_check"> - <property name="text"> - <string>Manual bin size</string> - </property> - </widget> - </item> - <item row="23" column="0"> - <widget class="QLabel" name="violinSideLabel"> - <property name="text"> - <string>Violin side</string> - </property> - </widget> - </item> - <item row="26" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item row="31" column="1" colspan="3"> + <layout class="QHBoxLayout" name="horizontalLayout_8" stretch="1,1"> <item> - <widget class="QCheckBox" name="invert_hist_check"> + <widget class="QgsSpinBox" name="bins_value"> <property name="enabled"> - <bool>true</bool> + <bool>false</bool> </property> - <property name="text"> - <string>Invert histogram direction</string> + <property name="maximum"> + <number>1000</number> + </property> + <property name="value"> + <number>10</number> </property> </widget> </item> <item> - <widget class="QCheckBox" name="cumulative_hist_check"> - <property name="enabled"> - <bool>true</bool> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - <property name="text"> - <string>Cumulative histogram</string> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> </property> - </widget> + </spacer> </item> </layout> </item> - <item row="11" column="0"> - <widget class="QCheckBox" name="hover_as_text_check"> + <item row="23" column="1" colspan="3"> + <widget class="QComboBox" name="hist_norm_combo"/> + </item> + <item row="33" column="0"> + <widget class="QLabel" name="bar_gap_label"> <property name="text"> - <string>Hover label as text</string> + <string>Bar gap</string> </property> </widget> </item> - <item row="20" column="1" colspan="3"> - <widget class="QComboBox" name="hist_norm_combo"/> + <item row="10" column="1" colspan="3"> + <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> </item> - <item row="21" column="0"> - <widget class="QLabel" name="box_statistic_label"> + <item row="28" column="0" colspan="4"> + <widget class="QCheckBox" name="showMeanCheck"> <property name="text"> - <string>Show statistics</string> + <string>Show mean line</string> + </property> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> - <item row="18" column="0"> - <widget class="QLabel" name="orientation_label"> + <item row="26" column="0"> + <widget class="QLabel" name="violinSideLabel"> <property name="text"> - <string>Bar orientation</string> + <string>Violin side</string> </property> </widget> </item> - <item row="8" column="1" colspan="2"> - <widget class="QLineEdit" name="z_axis_title"/> + <item row="4" column="1" colspan="2"> + <widget class="QLineEdit" name="legend_title"/> + </item> + <item row="22" column="1" colspan="3"> + <widget class="QComboBox" name="bar_mode_combo"/> </item> - <item row="2" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item row="33" column="1" colspan="3"> + <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,1"> <item> - <widget class="QCheckBox" name="show_legend_check"> - <property name="text"> - <string>Show legend</string> + <widget class="QgsDoubleSpinBox" name="bar_gap"> + <property name="maximum"> + <double>1.000000000000000</double> </property> - <property name="checked"> - <bool>true</bool> + <property name="singleStep"> + <double>0.100000000000000</double> </property> </widget> </item> <item> - <widget class="QCheckBox" name="orientation_legend_check"> - <property name="text"> - <string>Horizontal legend</string> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="range_slider_combo"> - <property name="text"> - <string>Show range slider</string> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> </property> - </widget> + </spacer> </item> </layout> </item> - <item row="12" column="1" colspan="3"> - <widget class="QComboBox" name="combo_text_position"/> - </item> - <item row="30" column="0"> - <widget class="QLabel" name="bar_gap_label"> - <property name="text"> - <string>Bar gap</string> - </property> - </widget> - </item> - <item row="12" column="0"> - <widget class="QLabel" name="label_text_position"> + <item row="10" column="0"> + <widget class="QLabel" name="additional_info_label"> <property name="text"> - <string>Label text position</string> + <string>Additional hover label</string> </property> </widget> </item> - <item row="19" column="1" colspan="3"> - <widget class="QComboBox" name="bar_mode_combo"/> - </item> - <item row="24" column="0" colspan="4"> + <item row="27" column="0" colspan="4"> <widget class="QCheckBox" name="violinBox"> <property name="toolTip"> <string>If checked, box plots will be overlaid on top of violin plots</string> @@ -921,216 +852,97 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="23" column="1" colspan="3"> - <widget class="QComboBox" name="violinSideCombo"/> + <item row="21" column="0"> + <widget class="QLabel" name="orientation_label"> + <property name="text"> + <string>Bar orientation</string> + </property> + </widget> </item> - <item row="13" column="0"> - <widget class="QCheckBox" name="invert_x_check"> + <item row="24" column="0"> + <widget class="QLabel" name="box_statistic_label"> <property name="text"> - <string>Invert X axis</string> + <string>Show statistics</string> </property> </widget> </item> - <item row="28" column="1" colspan="3"> - <layout class="QHBoxLayout" name="horizontalLayout_8" stretch="1,1"> - <item> - <widget class="QgsSpinBox" name="bins_value"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="maximum"> - <number>1000</number> - </property> - <property name="value"> - <number>10</number> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="x_axis_label"> - <property name="text"> - <string>X label</string> - </property> - </widget> - </item> - <item row="18" column="1" colspan="3"> - <widget class="QComboBox" name="orientation_combo"/> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="legend_label"> - <property name="text"> - <string>Legend title</string> - </property> - </widget> - </item> - <item row="15" column="0" colspan="4"> - <widget class="QgsCollapsibleGroupBox" name="x_axis_bounds_check"> - <property name="title"> - <string>Set X Axis Bounds</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <layout class="QGridLayout" name="gridXAxisBounds"> - <item row="0" column="0"> - <widget class="QLabel" name="x_axis_min_label"> - <property name="text"> - <string>Minimum</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QgsDoubleSpinBox" name="x_axis_min"/> - </item> - <item row="0" column="2"> - <widget class="QgsPropertyOverrideButton" name="x_axis_min_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="x_axis_max_label"> - <property name="text"> - <string>Maximum</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QgsDoubleSpinBox" name="x_axis_max"/> - </item> - <item row="1" column="2"> - <widget class="QgsPropertyOverrideButton" name="x_axis_max_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="14" column="1"> - <widget class="QLabel" name="y_axis_mode_label"> + <item row="9" column="0"> + <widget class="QLabel" name="info_label"> <property name="text"> - <string>Y axis mode</string> + <string>Hover tooltip</string> </property> </widget> </item> - <item row="3" column="1" colspan="2"> - <widget class="QLineEdit" name="plot_title_line"/> + <item row="26" column="1" colspan="3"> + <widget class="QComboBox" name="violinSideCombo"/> </item> - <item row="22" column="0"> - <widget class="QLabel" name="outliers_label"> + <item row="12" column="0"> + <widget class="QLabel" name="label_text_position"> <property name="text"> - <string>Outliers</string> + <string>Label text position</string> </property> </widget> </item> - <item row="4" column="1" colspan="2"> - <widget class="QLineEdit" name="legend_title"/> + <item row="12" column="1" colspan="3"> + <widget class="QComboBox" name="combo_text_position"/> </item> - <item row="14" column="0"> - <widget class="QCheckBox" name="invert_y_check"> + <item row="4" column="0"> + <widget class="QLabel" name="legend_label"> <property name="text"> - <string>Invert Y axis</string> + <string>Legend title</string> </property> </widget> </item> - <item row="19" column="0"> - <widget class="QLabel" name="bar_mode_lab"> - <property name="text"> - <string>Bar mode</string> - </property> - </widget> + <item row="21" column="1" colspan="3"> + <widget class="QComboBox" name="orientation_combo"/> </item> - <item row="13" column="2" colspan="2"> - <widget class="QComboBox" name="x_axis_mode_combo"/> + <item row="24" column="1" colspan="3"> + <widget class="QComboBox" name="box_statistic_combo"/> </item> - <item row="25" column="0" colspan="4"> - <widget class="QCheckBox" name="showMeanCheck"> - <property name="text"> - <string>Show mean line</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> + <item row="9" column="1" colspan="3"> + <widget class="QComboBox" name="info_combo"/> </item> - <item row="30" column="1" colspan="3"> - <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,1"> + <item row="29" column="0" colspan="4"> + <layout class="QHBoxLayout" name="horizontalLayout_7"> <item> - <widget class="QgsDoubleSpinBox" name="bar_gap"> - <property name="maximum"> - <double>1.000000000000000</double> + <widget class="QCheckBox" name="invert_hist_check"> + <property name="enabled"> + <bool>true</bool> </property> - <property name="singleStep"> - <double>0.100000000000000</double> + <property name="text"> + <string>Invert histogram direction</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_5"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> + <widget class="QCheckBox" name="cumulative_hist_check"> + <property name="enabled"> + <bool>true</bool> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> + <property name="text"> + <string>Cumulative histogram</string> </property> - </spacer> + </widget> </item> </layout> </item> - <item row="21" column="1" colspan="3"> - <widget class="QComboBox" name="box_statistic_combo"/> - </item> - <item row="5" column="1" colspan="2"> - <widget class="QLineEdit" name="x_axis_title"/> - </item> - <item row="8" column="3"> - <widget class="QgsPropertyOverrideButton" name="z_axis_title_defined_button"> + <item row="22" column="0"> + <widget class="QLabel" name="bar_mode_lab"> <property name="text"> - <string>...</string> + <string>Bar mode</string> </property> </widget> </item> - <item row="13" column="1"> - <widget class="QLabel" name="x_axis_mode_label"> - <property name="text"> - <string>X axis mode</string> - </property> - </widget> + <item row="25" column="1" colspan="3"> + <widget class="QComboBox" name="outliers_combo"/> </item> - <item row="10" column="0"> - <widget class="QLabel" name="additional_info_label"> + <item row="31" column="0"> + <widget class="QCheckBox" name="bins_check"> <property name="text"> - <string>Additional hover label</string> + <string>Manual bin size</string> </property> </widget> </item> - <item row="14" column="2" colspan="2"> - <widget class="QComboBox" name="y_axis_mode_combo"/> - </item> <item row="4" column="3"> <widget class="QgsPropertyOverrideButton" name="legend_title_defined_button"> <property name="text"> @@ -1138,20 +950,21 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="6" column="1" rowspan="2" colspan="2"> - <widget class="QLineEdit" name="y_axis_title"/> - </item> - <item row="6" column="0" rowspan="2"> - <widget class="QLabel" name="y_axis_label"> + <item row="25" column="0"> + <widget class="QLabel" name="outliers_label"> <property name="text"> - <string>Y label</string> + <string>Outliers</string> </property> </widget> </item> - <item row="9" column="1" colspan="3"> - <widget class="QComboBox" name="info_combo"/> + <item row="23" column="0"> + <widget class="QLabel" name="hist_norm_label"> + <property name="text"> + <string>Normalization</string> + </property> + </widget> </item> - <item row="32" column="0" colspan="3"> + <item row="35" column="0" colspan="3"> <spacer name="verticalSpacer_6"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -1164,55 +977,14 @@ QListWidget::item::selected { </property> </spacer> </item> - <item row="3" column="3"> - <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="10" column="1" colspan="3"> - <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> - </item> - <item row="20" column="0"> - <widget class="QLabel" name="hist_norm_label"> - <property name="text"> - <string>Normalization</string> - </property> - </widget> - </item> - <item row="5" column="3"> - <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="8" column="0"> - <widget class="QLabel" name="z_axis_label"> - <property name="text"> - <string>Z label</string> - </property> - </widget> - </item> - <item row="22" column="1" colspan="3"> - <widget class="QComboBox" name="outliers_combo"/> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="plot_title_lab"> - <property name="text"> - <string>Plot title</string> - </property> - </widget> - </item> - <item row="9" column="0"> - <widget class="QLabel" name="info_label"> + <item row="11" column="0"> + <widget class="QCheckBox" name="hover_as_text_check"> <property name="text"> - <string>Hover tooltip</string> + <string>Hover label as text</string> </property> </widget> </item> - <item row="31" column="0" colspan="4"> + <item row="34" column="0" colspan="4"> <widget class="QgsCollapsibleGroupBox" name="layout_configuration_box"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> @@ -1223,21 +995,271 @@ QListWidget::item::selected { <property name="title"> <string>Layout Options</string> </property> - <layout class="QFormLayout" name="formLayout"> - <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout_10"> + <item row="3" column="1"> + <widget class="QLineEdit" name="x_axis_title"/> + </item> + <item row="7" column="2"> + <widget class="QgsPropertyOverrideButton" name="z_axis_title_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLineEdit" name="y_axis_title"/> + </item> + <item row="24" column="0" colspan="3"> + <widget class="QgsCollapsibleGroupBox" name="y_axis_bounds_check"> + <property name="title"> + <string>Set Y Axis Bounds</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridYAxisBounds"> + <item row="0" column="0"> + <widget class="QLabel" name="y_axis_min_label"> + <property name="text"> + <string>Minimum</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QgsDoubleSpinBox" name="y_axis_min"/> + </item> + <item row="0" column="2"> + <widget class="QgsPropertyOverrideButton" name="y_axis_min_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="y_axis_max_label"> + <property name="text"> + <string>Maximum</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QgsDoubleSpinBox" name="y_axis_max"/> + </item> + <item row="1" column="2"> + <widget class="QgsPropertyOverrideButton" name="y_axis_max_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="plot_title_line"/> + </item> + <item row="9" column="0"> <widget class="QLabel" name="grid_color_label"> <property name="text"> <string>Grid color</string> </property> </widget> </item> - <item row="0" column="1"> + <item row="12" column="0"> + <widget class="QCheckBox" name="invert_y_check"> + <property name="text"> + <string>Invert Y axis</string> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="z_axis_label"> + <property name="text"> + <string>Z label</string> + </property> + </widget> + </item> + <item row="9" column="1"> <widget class="QgsColorButton" name="layout_grid_axis_color"> <property name="allowOpacity"> <bool>true</bool> </property> </widget> </item> + <item row="23" column="0" colspan="3"> + <widget class="QgsCollapsibleGroupBox" name="x_axis_bounds_check"> + <property name="title"> + <string>Set X Axis Bounds</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridXAxisBounds"> + <item row="0" column="0"> + <widget class="QLabel" name="x_axis_min_label"> + <property name="text"> + <string>Minimum</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QgsPropertyOverrideButton" name="x_axis_min_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QgsPropertyOverrideButton" name="x_axis_max_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="x_axis_max_label"> + <property name="text"> + <string>Maximum</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QgsDoubleSpinBox" name="x_axis_max"/> + </item> + <item row="0" column="1"> + <widget class="QgsDoubleSpinBox" name="x_axis_min"/> + </item> + </layout> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLineEdit" name="z_axis_title"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="x_axis_label"> + <property name="text"> + <string>X label</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="5" column="2"> + <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="plot_title_lab"> + <property name="text"> + <string>Plot title</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="y_axis_label"> + <property name="text"> + <string>Y label</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="10" column="0"> + <widget class="QCheckBox" name="invert_x_check"> + <property name="text"> + <string>Invert X axis</string> + </property> + </widget> + </item> + <item row="10" column="1" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <item> + <widget class="QLabel" name="x_axis_mode_label"> + <property name="text"> + <string>X axis mode</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="x_axis_mode_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item row="12" column="1" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <widget class="QLabel" name="y_axis_mode_label"> + <property name="text"> + <string>Y axis mode</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="y_axis_mode_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="1" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QCheckBox" name="show_legend_check"> + <property name="text"> + <string>Show legend</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="orientation_legend_check"> + <property name="text"> + <string>Horizontal legend</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="range_slider_combo"> + <property name="text"> + <string>Show range slider</string> + </property> + </widget> + </item> + </layout> + </item> </layout> </widget> </item> From 8acb437f6292009969ca093d7a021fb04559dd31 Mon Sep 17 00:00:00 2001 From: SGroe <simon.groechenig@salzburgresearch.at> Date: Mon, 22 Mar 2021 14:20:07 +0100 Subject: [PATCH 03/57] hide axis min/max group and label if not needed --- DataPlotly/gui/plot_settings_widget.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index cc7e674b..0010be56 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -836,10 +836,16 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.y_axis_mode_combo: ['scatter', 'box'], self.invert_x_check: ['scatter', 'bar', 'box', 'histogram', '2dhistogram'], self.invert_y_check: ['scatter', 'bar', 'box', 'histogram', '2dhistogram'], + self.x_axis_bounds_check: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], + self.x_axis_min_label: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], + self.x_axis_max_label: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], self.x_axis_min: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], self.x_axis_max: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], self.x_axis_min_defined_button: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], self.x_axis_max_defined_button: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], + self.y_axis_bounds_check: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], + self.y_axis_min_label: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], + self.y_axis_max_label: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], self.y_axis_min: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], self.y_axis_max: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], self.y_axis_min_defined_button: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'violin'], From e518f0e45450b8085703479006719ba64f819b6f Mon Sep 17 00:00:00 2001 From: SGroe <simon.groechenig@salzburgresearch.at> Date: Mon, 22 Mar 2021 14:21:21 +0100 Subject: [PATCH 04/57] Remove spacer at manual bin size and bar gap properties To avoid empty space above layout option group --- DataPlotly/ui/dataplotly_dockwidget_base.ui | 302 +++++++++----------- 1 file changed, 134 insertions(+), 168 deletions(-) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index 426b8e9d..e2cb7a4b 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -723,7 +723,7 @@ QListWidget::item::selected { <x>0</x> <y>0</y> <width>780</width> - <height>986</height> + <height>982</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,0,0"> @@ -739,96 +739,41 @@ QListWidget::item::selected { <property name="bottomMargin"> <number>0</number> </property> - <item row="31" column="1" colspan="3"> - <layout class="QHBoxLayout" name="horizontalLayout_8" stretch="1,1"> - <item> - <widget class="QgsSpinBox" name="bins_value"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="maximum"> - <number>1000</number> - </property> - <property name="value"> - <number>10</number> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="23" column="1" colspan="3"> - <widget class="QComboBox" name="hist_norm_combo"/> - </item> - <item row="33" column="0"> - <widget class="QLabel" name="bar_gap_label"> - <property name="text"> - <string>Bar gap</string> - </property> - </widget> - </item> - <item row="10" column="1" colspan="3"> - <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> - </item> - <item row="28" column="0" colspan="4"> - <widget class="QCheckBox" name="showMeanCheck"> + <item row="22" column="0"> + <widget class="QLabel" name="bar_mode_lab"> <property name="text"> - <string>Show mean line</string> - </property> - <property name="checked"> - <bool>true</bool> + <string>Bar mode</string> </property> </widget> </item> - <item row="26" column="0"> - <widget class="QLabel" name="violinSideLabel"> + <item row="11" column="0"> + <widget class="QCheckBox" name="hover_as_text_check"> <property name="text"> - <string>Violin side</string> + <string>Hover label as text</string> </property> </widget> </item> - <item row="4" column="1" colspan="2"> - <widget class="QLineEdit" name="legend_title"/> - </item> - <item row="22" column="1" colspan="3"> - <widget class="QComboBox" name="bar_mode_combo"/> - </item> - <item row="33" column="1" colspan="3"> - <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,1"> + <item row="29" column="0" colspan="4"> + <layout class="QHBoxLayout" name="horiz_layout_histogram"> <item> - <widget class="QgsDoubleSpinBox" name="bar_gap"> - <property name="maximum"> - <double>1.000000000000000</double> + <widget class="QCheckBox" name="invert_hist_check"> + <property name="enabled"> + <bool>true</bool> </property> - <property name="singleStep"> - <double>0.100000000000000</double> + <property name="text"> + <string>Invert histogram direction</string> </property> </widget> </item> <item> - <spacer name="horizontalSpacer_5"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> + <widget class="QCheckBox" name="cumulative_hist_check"> + <property name="enabled"> + <bool>true</bool> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> + <property name="text"> + <string>Cumulative histogram</string> </property> - </spacer> + </widget> </item> </layout> </item> @@ -839,33 +784,36 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="27" column="0" colspan="4"> - <widget class="QCheckBox" name="violinBox"> - <property name="toolTip"> - <string>If checked, box plots will be overlaid on top of violin plots</string> - </property> + <item row="26" column="0"> + <widget class="QLabel" name="violinSideLabel"> <property name="text"> - <string>Include box plots</string> - </property> - <property name="checked"> - <bool>true</bool> + <string>Violin side</string> </property> </widget> </item> - <item row="21" column="0"> - <widget class="QLabel" name="orientation_label"> + <item row="4" column="3"> + <widget class="QgsPropertyOverrideButton" name="legend_title_defined_button"> <property name="text"> - <string>Bar orientation</string> + <string>...</string> </property> </widget> </item> - <item row="24" column="0"> - <widget class="QLabel" name="box_statistic_label"> + <item row="9" column="1" colspan="3"> + <widget class="QComboBox" name="info_combo"/> + </item> + <item row="25" column="1" colspan="3"> + <widget class="QComboBox" name="outliers_combo"/> + </item> + <item row="25" column="0"> + <widget class="QLabel" name="outliers_label"> <property name="text"> - <string>Show statistics</string> + <string>Outliers</string> </property> </widget> </item> + <item row="12" column="1" colspan="3"> + <widget class="QComboBox" name="combo_text_position"/> + </item> <item row="9" column="0"> <widget class="QLabel" name="info_label"> <property name="text"> @@ -873,118 +821,93 @@ QListWidget::item::selected { </property> </widget> </item> + <item row="23" column="1" colspan="3"> + <widget class="QComboBox" name="hist_norm_combo"/> + </item> <item row="26" column="1" colspan="3"> <widget class="QComboBox" name="violinSideCombo"/> </item> - <item row="12" column="0"> - <widget class="QLabel" name="label_text_position"> + <item row="28" column="0" colspan="4"> + <widget class="QCheckBox" name="showMeanCheck"> <property name="text"> - <string>Label text position</string> + <string>Show mean line</string> + </property> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> - <item row="12" column="1" colspan="3"> - <widget class="QComboBox" name="combo_text_position"/> + <item row="37" column="0" colspan="3"> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>255</width> + <height>222</height> + </size> + </property> + </spacer> </item> - <item row="4" column="0"> - <widget class="QLabel" name="legend_label"> + <item row="23" column="0"> + <widget class="QLabel" name="hist_norm_label"> <property name="text"> - <string>Legend title</string> + <string>Normalization</string> </property> </widget> </item> - <item row="21" column="1" colspan="3"> - <widget class="QComboBox" name="orientation_combo"/> - </item> - <item row="24" column="1" colspan="3"> - <widget class="QComboBox" name="box_statistic_combo"/> - </item> - <item row="9" column="1" colspan="3"> - <widget class="QComboBox" name="info_combo"/> - </item> - <item row="29" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <item> - <widget class="QCheckBox" name="invert_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Invert histogram direction</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cumulative_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Cumulative histogram</string> - </property> - </widget> - </item> - </layout> - </item> - <item row="22" column="0"> - <widget class="QLabel" name="bar_mode_lab"> + <item row="12" column="0"> + <widget class="QLabel" name="label_text_position"> <property name="text"> - <string>Bar mode</string> + <string>Label text position</string> </property> </widget> </item> - <item row="25" column="1" colspan="3"> - <widget class="QComboBox" name="outliers_combo"/> + <item row="4" column="1" colspan="2"> + <widget class="QLineEdit" name="legend_title"/> </item> - <item row="31" column="0"> - <widget class="QCheckBox" name="bins_check"> - <property name="text"> - <string>Manual bin size</string> + <item row="31" column="1" colspan="3"> + <widget class="QgsSpinBox" name="bins_value"> + <property name="enabled"> + <bool>false</bool> </property> - </widget> - </item> - <item row="4" column="3"> - <widget class="QgsPropertyOverrideButton" name="legend_title_defined_button"> - <property name="text"> - <string>...</string> + <property name="maximum"> + <number>1000</number> + </property> + <property name="value"> + <number>10</number> </property> </widget> </item> - <item row="25" column="0"> - <widget class="QLabel" name="outliers_label"> + <item row="4" column="0"> + <widget class="QLabel" name="legend_label"> <property name="text"> - <string>Outliers</string> + <string>Legend title</string> </property> </widget> </item> - <item row="23" column="0"> - <widget class="QLabel" name="hist_norm_label"> + <item row="24" column="0"> + <widget class="QLabel" name="box_statistic_label"> <property name="text"> - <string>Normalization</string> + <string>Show statistics</string> </property> </widget> </item> - <item row="35" column="0" colspan="3"> - <spacer name="verticalSpacer_6"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>255</width> - <height>222</height> - </size> - </property> - </spacer> + <item row="24" column="1" colspan="3"> + <widget class="QComboBox" name="box_statistic_combo"/> </item> - <item row="11" column="0"> - <widget class="QCheckBox" name="hover_as_text_check"> + <item row="10" column="1" colspan="3"> + <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> + </item> + <item row="21" column="0"> + <widget class="QLabel" name="orientation_label"> <property name="text"> - <string>Hover label as text</string> + <string>Bar orientation</string> </property> </widget> </item> - <item row="34" column="0" colspan="4"> + <item row="36" column="0" colspan="4"> <widget class="QgsCollapsibleGroupBox" name="layout_configuration_box"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> @@ -1263,6 +1186,49 @@ QListWidget::item::selected { </layout> </widget> </item> + <item row="31" column="0"> + <widget class="QCheckBox" name="bins_check"> + <property name="text"> + <string>Manual bin size</string> + </property> + </widget> + </item> + <item row="22" column="1" colspan="3"> + <widget class="QComboBox" name="bar_mode_combo"/> + </item> + <item row="21" column="1" colspan="3"> + <widget class="QComboBox" name="orientation_combo"/> + </item> + <item row="33" column="0"> + <widget class="QLabel" name="bar_gap_label"> + <property name="text"> + <string>Bar gap</string> + </property> + </widget> + </item> + <item row="27" column="0" colspan="4"> + <widget class="QCheckBox" name="violinBox"> + <property name="toolTip"> + <string>If checked, box plots will be overlaid on top of violin plots</string> + </property> + <property name="text"> + <string>Include box plots</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="33" column="1" colspan="3"> + <widget class="QgsDoubleSpinBox" name="bar_gap"> + <property name="maximum"> + <double>1.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.100000000000000</double> + </property> + </widget> + </item> </layout> </widget> </widget> From a0964152ee45295644d051c77933ac18726319c8 Mon Sep 17 00:00:00 2001 From: SGroe <simon.groechenig@salzburgresearch.at> Date: Tue, 23 Mar 2021 19:45:44 +0100 Subject: [PATCH 05/57] move more layout properties to layout option group --- DataPlotly/ui/dataplotly_dockwidget_base.ui | 485 ++++++++++---------- 1 file changed, 244 insertions(+), 241 deletions(-) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index e2cb7a4b..b236deef 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -721,7 +721,7 @@ QListWidget::item::selected { <property name="geometry"> <rect> <x>0</x> - <y>0</y> + <y>-240</y> <width>780</width> <height>982</height> </rect> @@ -739,55 +739,17 @@ QListWidget::item::selected { <property name="bottomMargin"> <number>0</number> </property> - <item row="22" column="0"> - <widget class="QLabel" name="bar_mode_lab"> - <property name="text"> - <string>Bar mode</string> - </property> - </widget> - </item> - <item row="11" column="0"> - <widget class="QCheckBox" name="hover_as_text_check"> - <property name="text"> - <string>Hover label as text</string> - </property> - </widget> - </item> - <item row="29" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horiz_layout_histogram"> - <item> - <widget class="QCheckBox" name="invert_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Invert histogram direction</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cumulative_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Cumulative histogram</string> - </property> - </widget> - </item> - </layout> - </item> - <item row="10" column="0"> - <widget class="QLabel" name="additional_info_label"> + <item row="23" column="0"> + <widget class="QLabel" name="hist_norm_label"> <property name="text"> - <string>Additional hover label</string> + <string>Normalization</string> </property> </widget> </item> - <item row="26" column="0"> - <widget class="QLabel" name="violinSideLabel"> + <item row="24" column="0"> + <widget class="QLabel" name="box_statistic_label"> <property name="text"> - <string>Violin side</string> + <string>Show statistics</string> </property> </widget> </item> @@ -798,44 +760,34 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="9" column="1" colspan="3"> - <widget class="QComboBox" name="info_combo"/> - </item> - <item row="25" column="1" colspan="3"> - <widget class="QComboBox" name="outliers_combo"/> + <item row="24" column="1" colspan="3"> + <widget class="QComboBox" name="box_statistic_combo"/> </item> - <item row="25" column="0"> - <widget class="QLabel" name="outliers_label"> + <item row="27" column="0" colspan="4"> + <widget class="QCheckBox" name="violinBox"> + <property name="toolTip"> + <string>If checked, box plots will be overlaid on top of violin plots</string> + </property> <property name="text"> - <string>Outliers</string> + <string>Include box plots</string> + </property> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> - <item row="12" column="1" colspan="3"> - <widget class="QComboBox" name="combo_text_position"/> - </item> - <item row="9" column="0"> - <widget class="QLabel" name="info_label"> + <item row="21" column="0"> + <widget class="QLabel" name="orientation_label"> <property name="text"> - <string>Hover tooltip</string> + <string>Bar orientation</string> </property> </widget> </item> - <item row="23" column="1" colspan="3"> - <widget class="QComboBox" name="hist_norm_combo"/> - </item> <item row="26" column="1" colspan="3"> <widget class="QComboBox" name="violinSideCombo"/> </item> - <item row="28" column="0" colspan="4"> - <widget class="QCheckBox" name="showMeanCheck"> - <property name="text"> - <string>Show mean line</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> + <item row="12" column="1" colspan="3"> + <widget class="QComboBox" name="combo_text_position"/> </item> <item row="37" column="0" colspan="3"> <spacer name="verticalSpacer_6"> @@ -850,13 +802,26 @@ QListWidget::item::selected { </property> </spacer> </item> - <item row="23" column="0"> - <widget class="QLabel" name="hist_norm_label"> + <item row="23" column="1" colspan="3"> + <widget class="QComboBox" name="hist_norm_combo"/> + </item> + <item row="26" column="0"> + <widget class="QLabel" name="violinSideLabel"> <property name="text"> - <string>Normalization</string> + <string>Violin side</string> </property> </widget> </item> + <item row="11" column="0"> + <widget class="QCheckBox" name="hover_as_text_check"> + <property name="text"> + <string>Hover label as text</string> + </property> + </widget> + </item> + <item row="21" column="1" colspan="3"> + <widget class="QComboBox" name="orientation_combo"/> + </item> <item row="12" column="0"> <widget class="QLabel" name="label_text_position"> <property name="text"> @@ -864,19 +829,27 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="4" column="1" colspan="2"> - <widget class="QLineEdit" name="legend_title"/> + <item row="25" column="0"> + <widget class="QLabel" name="outliers_label"> + <property name="text"> + <string>Outliers</string> + </property> + </widget> </item> - <item row="31" column="1" colspan="3"> - <widget class="QgsSpinBox" name="bins_value"> - <property name="enabled"> - <bool>false</bool> + <item row="9" column="0"> + <widget class="QLabel" name="info_label"> + <property name="text"> + <string>Hover tooltip</string> </property> - <property name="maximum"> - <number>1000</number> + </widget> + </item> + <item row="28" column="0" colspan="4"> + <widget class="QCheckBox" name="showMeanCheck"> + <property name="text"> + <string>Show mean line</string> </property> - <property name="value"> - <number>10</number> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> @@ -887,23 +860,49 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="24" column="0"> - <widget class="QLabel" name="box_statistic_label"> - <property name="text"> - <string>Show statistics</string> - </property> - </widget> + <item row="9" column="1" colspan="3"> + <widget class="QComboBox" name="info_combo"/> </item> - <item row="24" column="1" colspan="3"> - <widget class="QComboBox" name="box_statistic_combo"/> + <item row="29" column="0" colspan="4"> + <layout class="QHBoxLayout" name="horiz_layout_histogram"> + <item> + <widget class="QCheckBox" name="invert_hist_check"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Invert histogram direction</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="cumulative_hist_check"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Cumulative histogram</string> + </property> + </widget> + </item> + </layout> </item> - <item row="10" column="1" colspan="3"> - <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> + <item row="4" column="1" colspan="2"> + <widget class="QLineEdit" name="legend_title"/> </item> - <item row="21" column="0"> - <widget class="QLabel" name="orientation_label"> - <property name="text"> - <string>Bar orientation</string> + <item row="25" column="1" colspan="3"> + <widget class="QComboBox" name="outliers_combo"/> + </item> + <item row="31" column="1" colspan="3"> + <widget class="QgsSpinBox" name="bins_value"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximum"> + <number>1000</number> + </property> + <property name="value"> + <number>10</number> </property> </widget> </item> @@ -918,21 +917,28 @@ QListWidget::item::selected { <property name="title"> <string>Layout Options</string> </property> + <property name="collapsed"> + <bool>false</bool> + </property> <layout class="QGridLayout" name="gridLayout_10"> - <item row="3" column="1"> - <widget class="QLineEdit" name="x_axis_title"/> - </item> - <item row="7" column="2"> + <item row="7" column="3"> <widget class="QgsPropertyOverrideButton" name="z_axis_title_defined_button"> <property name="text"> <string>...</string> </property> </widget> </item> - <item row="5" column="1"> + <item row="5" column="3"> + <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="5" column="2"> <widget class="QLineEdit" name="y_axis_title"/> </item> - <item row="24" column="0" colspan="3"> + <item row="28" column="0" colspan="4"> <widget class="QgsCollapsibleGroupBox" name="y_axis_bounds_check"> <property name="title"> <string>Set Y Axis Bounds</string> @@ -981,23 +987,103 @@ QListWidget::item::selected { </layout> </widget> </item> - <item row="1" column="1"> - <widget class="QLineEdit" name="plot_title_line"/> + <item row="5" column="0"> + <widget class="QLabel" name="y_axis_label"> + <property name="text"> + <string>Y label</string> + </property> + </widget> </item> - <item row="9" column="0"> - <widget class="QLabel" name="grid_color_label"> + <item row="14" column="2" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <item> + <widget class="QLabel" name="x_axis_mode_label"> + <property name="text"> + <string>X axis mode</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="x_axis_mode_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item row="11" column="0"> + <widget class="QLabel" name="bar_gap_label"> <property name="text"> - <string>Grid color</string> + <string>Bar gap</string> </property> </widget> </item> - <item row="12" column="0"> + <item row="1" column="2"> + <widget class="QLineEdit" name="plot_title_line"/> + </item> + <item row="0" column="2" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QCheckBox" name="show_legend_check"> + <property name="text"> + <string>Show legend</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="orientation_legend_check"> + <property name="text"> + <string>Horizontal legend</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="range_slider_combo"> + <property name="text"> + <string>Show range slider</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="16" column="2" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <widget class="QLabel" name="y_axis_mode_label"> + <property name="text"> + <string>Y axis mode</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="y_axis_mode_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item row="16" column="0"> <widget class="QCheckBox" name="invert_y_check"> <property name="text"> <string>Invert Y axis</string> </property> </widget> </item> + <item row="3" column="2"> + <widget class="QLineEdit" name="x_axis_title"/> + </item> <item row="7" column="0"> <widget class="QLabel" name="z_axis_label"> <property name="text"> @@ -1005,14 +1091,7 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="9" column="1"> - <widget class="QgsColorButton" name="layout_grid_axis_color"> - <property name="allowOpacity"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="23" column="0" colspan="3"> + <item row="27" column="0" colspan="4"> <widget class="QgsCollapsibleGroupBox" name="x_axis_bounds_check"> <property name="title"> <string>Set X Axis Bounds</string> @@ -1061,27 +1140,47 @@ QListWidget::item::selected { </layout> </widget> </item> - <item row="7" column="1"> - <widget class="QLineEdit" name="z_axis_title"/> + <item row="14" column="0"> + <widget class="QCheckBox" name="invert_x_check"> + <property name="text"> + <string>Invert X axis</string> + </property> + </widget> </item> - <item row="3" column="0"> - <widget class="QLabel" name="x_axis_label"> + <item row="3" column="3"> + <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> <property name="text"> - <string>X label</string> + <string>...</string> </property> </widget> </item> - <item row="1" column="2"> + <item row="1" column="3"> <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> <property name="text"> <string>...</string> </property> </widget> </item> - <item row="5" column="2"> - <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> + <item row="11" column="2" colspan="2"> + <widget class="QgsDoubleSpinBox" name="bar_gap"> + <property name="maximum"> + <double>1.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.100000000000000</double> + </property> + </widget> + </item> + <item row="12" column="2"> + <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> + </item> + <item row="10" column="2" colspan="2"> + <widget class="QComboBox" name="bar_mode_combo"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="x_axis_label"> <property name="text"> - <string>...</string> + <string>X label</string> </property> </widget> </item> @@ -1092,96 +1191,36 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="5" column="0"> - <widget class="QLabel" name="y_axis_label"> + <item row="12" column="0"> + <widget class="QLabel" name="additional_info_label"> <property name="text"> - <string>Y label</string> + <string>Additional hover label</string> </property> </widget> </item> - <item row="3" column="2"> - <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> + <item row="7" column="2"> + <widget class="QLineEdit" name="z_axis_title"/> + </item> + <item row="10" column="0"> + <widget class="QLabel" name="bar_mode_lab"> <property name="text"> - <string>...</string> + <string>Bar mode</string> </property> </widget> </item> - <item row="10" column="0"> - <widget class="QCheckBox" name="invert_x_check"> + <item row="29" column="0"> + <widget class="QLabel" name="grid_color_label"> <property name="text"> - <string>Invert X axis</string> + <string>Grid color</string> </property> </widget> </item> - <item row="10" column="1" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_10"> - <item> - <widget class="QLabel" name="x_axis_mode_label"> - <property name="text"> - <string>X axis mode</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="x_axis_mode_combo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </item> - <item row="12" column="1" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_11"> - <item> - <widget class="QLabel" name="y_axis_mode_label"> - <property name="text"> - <string>Y axis mode</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="y_axis_mode_combo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </item> - <item row="0" column="1" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <item> - <widget class="QCheckBox" name="show_legend_check"> - <property name="text"> - <string>Show legend</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="orientation_legend_check"> - <property name="text"> - <string>Horizontal legend</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="range_slider_combo"> - <property name="text"> - <string>Show range slider</string> - </property> - </widget> - </item> - </layout> + <item row="29" column="2" colspan="2"> + <widget class="QgsColorButton" name="layout_grid_axis_color"> + <property name="allowOpacity"> + <bool>true</bool> + </property> + </widget> </item> </layout> </widget> @@ -1193,42 +1232,6 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="22" column="1" colspan="3"> - <widget class="QComboBox" name="bar_mode_combo"/> - </item> - <item row="21" column="1" colspan="3"> - <widget class="QComboBox" name="orientation_combo"/> - </item> - <item row="33" column="0"> - <widget class="QLabel" name="bar_gap_label"> - <property name="text"> - <string>Bar gap</string> - </property> - </widget> - </item> - <item row="27" column="0" colspan="4"> - <widget class="QCheckBox" name="violinBox"> - <property name="toolTip"> - <string>If checked, box plots will be overlaid on top of violin plots</string> - </property> - <property name="text"> - <string>Include box plots</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="33" column="1" colspan="3"> - <widget class="QgsDoubleSpinBox" name="bar_gap"> - <property name="maximum"> - <double>1.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> - </property> - </widget> - </item> </layout> </widget> </widget> From 25ad00ccaed16d74fa737f7ccce70c8a6b6697df Mon Sep 17 00:00:00 2001 From: SGroe <simon.groechenig@salzburgresearch.at> Date: Fri, 26 Mar 2021 08:44:34 +0100 Subject: [PATCH 06/57] Move non-layout properties to first page on widget --- DataPlotly/ui/dataplotly_dockwidget_base.ui | 1022 +++++++++---------- 1 file changed, 495 insertions(+), 527 deletions(-) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index b236deef..306f01a8 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>1070</width> + <width>955</width> <height>845</height> </rect> </property> @@ -258,7 +258,7 @@ QListWidget::item::selected { <item row="0" column="0"> <widget class="QStackedWidget" name="stackedNestedPlotWidget"> <property name="currentIndex"> - <number>0</number> + <number>1</number> </property> <widget class="QWidget" name="page"> <layout class="QGridLayout" name="gridLayout"> @@ -321,8 +321,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>801</width> - <height>713</height> + <width>665</width> + <height>1011</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_9"> @@ -338,7 +338,7 @@ QListWidget::item::selected { <property name="bottomMargin"> <number>0</number> </property> - <item row="2" column="0"> + <item row="5" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -351,130 +351,234 @@ QListWidget::item::selected { </property> </spacer> </item> - <item row="1" column="0"> - <widget class="QgsCollapsibleGroupBox" name="properties_group_box"> + <item row="0" column="0"> + <widget class="QgsCollapsibleGroupBox" name="mGroupBox"> <property name="title"> - <string>Properties</string> + <string>Plot Parameters</string> </property> - <layout class="QGridLayout" name="gridLayout_22"> - <item row="6" column="0"> - <widget class="QLabel" name="line_lab"> + <layout class="QGridLayout" name="gridLayout_23"> + <item row="8" column="0"> + <widget class="QLabel" name="y_label"> <property name="text"> - <string>Line type</string> + <string>Y field</string> </property> </widget> </item> - <item row="5" column="0"> - <widget class="QLabel" name="point_lab"> + <item row="4" column="1" colspan="2"> + <widget class="QgsLayoutItemComboBox" name="linked_map_combo"/> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="x_label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>70</width> + <height>16777215</height> + </size> + </property> <property name="text"> - <string>Point type</string> + <string>X field</string> </property> </widget> </item> - <item row="7" column="1" colspan="5"> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QComboBox" name="contour_type_combo"/> - </item> - <item> - <widget class="QCheckBox" name="show_lines_check"> - <property name="text"> - <string>Show lines</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> + <item row="6" column="1" colspan="2"> + <widget class="QCheckBox" name="filter_by_atlas_check"> + <property name="text"> + <string>Use only features inside atlas feature</string> + </property> + </widget> </item> - <item row="0" column="0"> - <widget class="QLabel" name="in_color_lab"> + <item row="9" column="0"> + <widget class="QLabel" name="z_label"> <property name="text"> - <string>Marker color</string> + <string>Z field</string> </property> </widget> </item> - <item row="3" column="0"> - <widget class="QLabel" name="out_color_lab"> + <item row="5" column="1" colspan="2"> + <widget class="QCheckBox" name="filter_by_map_check"> <property name="text"> - <string>Stroke color</string> + <string>Use only features visible in map</string> </property> </widget> </item> <item row="3" column="1"> - <widget class="QgsColorButton" name="out_color_combo"> + <widget class="QgsPropertyOverrideButton" name="feature_subset_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="8" column="1" colspan="2"> + <widget class="QgsFieldExpressionWidget" name="y_combo"/> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QgsMapLayerComboBox" name="layer_combo"> <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="3" column="2"> - <widget class="QgsPropertyOverrideButton" name="out_color_defined_button"> + <item row="4" column="0"> + <widget class="QLabel" name="label_linked_map"> <property name="text"> - <string>...</string> + <string>Linked map</string> </property> </widget> </item> - <item row="9" column="0"> - <widget class="QLabel" name="color_scale_label"> + <item row="2" column="1"> + <widget class="QCheckBox" name="selected_feature_check"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="text"> - <string>Color scale</string> + <string>Use only selected features</string> </property> </widget> </item> - <item row="5" column="1" colspan="5"> - <widget class="QComboBox" name="point_combo"/> + <item row="9" column="1" colspan="2"> + <widget class="QgsFieldExpressionWidget" name="z_combo"/> </item> - <item row="4" column="1" colspan="5"> - <widget class="QComboBox" name="marker_type_combo"/> + <item row="7" column="1" colspan="2"> + <widget class="QgsFieldExpressionWidget" name="x_combo"/> </item> - <item row="0" column="3"> - <widget class="QLabel" name="marker_size_lab"> + <item row="2" column="2"> + <widget class="QCheckBox" name="visible_feature_check"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="text"> - <string>Marker size</string> + <string>Use only visible features</string> </property> </widget> </item> - <item row="9" column="1" colspan="5"> - <widget class="QComboBox" name="color_scale_combo"/> + <item row="0" column="0"> + <widget class="QLabel" name="layer_label"> + <property name="text"> + <string>Layer</string> + </property> + </widget> </item> - <item row="1" column="1" colspan="5"> - <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0,0"> + <item row="3" column="0"> + <widget class="QLabel" name="label_feature_subset"> + <property name="text"> + <string>Feature subset</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <widget class="QgsCollapsibleGroupBox" name="properties_group_box"> + <property name="title"> + <string>Properties</string> + </property> + <layout class="QGridLayout" name="gridLayout_22"> + <item row="8" column="1" colspan="5"> + <layout class="QHBoxLayout" name="horizontalLayout_4"> <item> - <widget class="QComboBox" name="color_scale_data_defined_in"/> + <widget class="QComboBox" name="contour_type_combo"/> </item> <item> - <widget class="QCheckBox" name="color_scale_data_defined_in_check"> + <widget class="QCheckBox" name="show_lines_check"> <property name="text"> - <string>Visible</string> + <string>Show lines</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> + </layout> + </item> + <item row="6" column="1" colspan="5"> + <widget class="QComboBox" name="point_combo"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="in_color_lab"> + <property name="text"> + <string>Marker color</string> + </property> + </widget> + </item> + <item row="10" column="1" colspan="5"> + <widget class="QComboBox" name="color_scale_combo"/> + </item> + <item row="16" column="0"> + <widget class="QLabel" name="hist_norm_label"> + <property name="text"> + <string>Normalization</string> + </property> + </widget> + </item> + <item row="4" column="5"> + <widget class="QgsPropertyOverrideButton" name="stroke_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="QgsPropertyOverrideButton" name="out_color_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="15" column="1" colspan="5"> + <widget class="QComboBox" name="orientation_combo"/> + </item> + <item row="16" column="1" colspan="5"> + <widget class="QComboBox" name="hist_norm_combo"/> + </item> + <item row="22" column="0" colspan="6"> + <layout class="QHBoxLayout" name="horiz_layout_histogram"> <item> - <widget class="QCheckBox" name="color_scale_data_defined_in_invert_check"> + <widget class="QCheckBox" name="invert_hist_check"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="text"> - <string>Invert color</string> + <string>Invert histogram direction</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="cumulative_hist_check"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Cumulative histogram</string> </property> </widget> </item> </layout> </item> - <item row="1" column="0"> - <widget class="QLabel" name="color_scale_data_defined_in_label"> + <item row="6" column="0"> + <widget class="QLabel" name="point_lab"> <property name="text"> - <string>Color scale</string> + <string>Point type</string> </property> </widget> </item> - <item row="0" column="1"> - <widget class="QgsColorButton" name="in_color_combo"> + <item row="4" column="1"> + <widget class="QgsColorButton" name="out_color_combo"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -483,200 +587,257 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="0" column="2"> - <widget class="QgsPropertyOverrideButton" name="in_color_defined_button"> + <item row="7" column="0"> + <widget class="QLabel" name="line_lab"> <property name="text"> - <string>...</string> + <string>Line type</string> </property> </widget> </item> - <item row="0" column="4"> - <widget class="QgsDoubleSpinBox" name="marker_size"/> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="marker_type_lab"> + <item row="20" column="0"> + <widget class="QCheckBox" name="violinBox"> + <property name="toolTip"> + <string>If checked, box plots will be overlaid on top of violin plots</string> + </property> <property name="text"> - <string>Marker type</string> + <string>Include box plots</string> + </property> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> - <item row="6" column="1" colspan="5"> - <widget class="QComboBox" name="line_combo"/> - </item> - <item row="3" column="3"> + <item row="4" column="3"> <widget class="QLabel" name="marker_width_lab"> <property name="text"> <string>Stroke width</string> </property> </widget> </item> - <item row="10" column="0"> + <item row="19" column="0"> + <widget class="QLabel" name="violinSideLabel"> + <property name="text"> + <string>Violin side</string> + </property> + </widget> + </item> + <item row="17" column="0"> + <widget class="QLabel" name="box_statistic_label"> + <property name="text"> + <string>Show statistics</string> + </property> + </widget> + </item> + <item row="11" column="1" colspan="5"> + <widget class="QgsOpacityWidget" name="opacity_widget"> + <property name="focusPolicy"> + <enum>Qt::StrongFocus</enum> + </property> + </widget> + </item> + <item row="11" column="0"> <widget class="QLabel" name="alpha_lab"> <property name="text"> <string>Opacity</string> </property> </widget> </item> - <item row="3" column="4"> - <widget class="QgsDoubleSpinBox" name="marker_width"/> - </item> - <item row="0" column="5"> - <widget class="QgsPropertyOverrideButton" name="size_defined_button"> + <item row="10" column="0"> + <widget class="QLabel" name="color_scale_label"> <property name="text"> - <string>...</string> + <string>Color scale</string> </property> </widget> </item> - <item row="7" column="0"> - <widget class="QLabel" name="contour_type_label"> + <item row="1" column="3"> + <widget class="QLabel" name="marker_size_lab"> <property name="text"> - <string>Contour type</string> + <string>Marker size</string> </property> </widget> </item> - <item row="10" column="1" colspan="5"> - <widget class="QgsOpacityWidget" name="opacity_widget"> - <property name="focusPolicy"> - <enum>Qt::StrongFocus</enum> + <item row="23" column="1" colspan="5"> + <widget class="QgsSpinBox" name="bins_value"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximum"> + <number>1000</number> + </property> + <property name="value"> + <number>10</number> </property> </widget> </item> - <item row="3" column="5"> - <widget class="QgsPropertyOverrideButton" name="stroke_defined_button"> + <item row="2" column="0"> + <widget class="QLabel" name="color_scale_data_defined_in_label"> + <property name="text"> + <string>Color scale</string> + </property> + </widget> + </item> + <item row="1" column="5"> + <widget class="QgsPropertyOverrideButton" name="size_defined_button"> <property name="text"> <string>...</string> </property> </widget> </item> - </layout> - </widget> - </item> - <item row="0" column="0"> - <widget class="QgsCollapsibleGroupBox" name="mGroupBox"> - <property name="title"> - <string>Plot Parameters</string> - </property> - <layout class="QGridLayout" name="gridLayout_23"> - <item row="3" column="0"> - <widget class="QLabel" name="label_feature_subset"> + <item row="8" column="0"> + <widget class="QLabel" name="contour_type_label"> <property name="text"> - <string>Feature subset</string> + <string>Contour type</string> </property> </widget> </item> - <item row="3" column="1"> - <widget class="QgsPropertyOverrideButton" name="feature_subset_defined_button"> + <item row="1" column="2"> + <widget class="QgsPropertyOverrideButton" name="in_color_defined_button"> <property name="text"> <string>...</string> </property> </widget> </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_linked_map"> + <item row="4" column="4"> + <widget class="QgsDoubleSpinBox" name="marker_width"/> + </item> + <item row="12" column="0"> + <widget class="QLabel" name="info_label"> <property name="text"> - <string>Linked map</string> + <string>Hover tooltip</string> </property> </widget> </item> - <item row="2" column="2"> - <widget class="QCheckBox" name="visible_feature_check"> - <property name="enabled"> - <bool>true</bool> + <item row="7" column="1" colspan="5"> + <widget class="QComboBox" name="line_combo"/> + </item> + <item row="18" column="1" colspan="5"> + <widget class="QComboBox" name="outliers_combo"/> + </item> + <item row="1" column="1"> + <widget class="QgsColorButton" name="in_color_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="out_color_lab"> <property name="text"> - <string>Use only visible features</string> + <string>Stroke color</string> </property> </widget> </item> - <item row="2" column="1"> - <widget class="QCheckBox" name="selected_feature_check"> - <property name="enabled"> + <item row="14" column="1" colspan="5"> + <widget class="QComboBox" name="combo_text_position"/> + </item> + <item row="21" column="0"> + <widget class="QCheckBox" name="showMeanCheck"> + <property name="text"> + <string>Show mean line</string> + </property> + <property name="checked"> <bool>true</bool> </property> + </widget> + </item> + <item row="14" column="0"> + <widget class="QLabel" name="label_text_position"> <property name="text"> - <string>Use only selected features</string> + <string>Label text position</string> </property> </widget> </item> - <item row="0" column="0"> - <widget class="QLabel" name="layer_label"> + <item row="13" column="0"> + <widget class="QCheckBox" name="hover_as_text_check"> <property name="text"> - <string>Layer</string> + <string>Hover label as text</string> </property> </widget> </item> - <item row="4" column="1" colspan="2"> - <widget class="QgsLayoutItemComboBox" name="linked_map_combo"/> + <item row="1" column="4"> + <widget class="QgsDoubleSpinBox" name="marker_size"/> </item> - <item row="8" column="1" colspan="2"> - <widget class="QgsFieldExpressionWidget" name="y_combo"/> + <item row="2" column="1" colspan="5"> + <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0,0"> + <item> + <widget class="QComboBox" name="color_scale_data_defined_in"/> + </item> + <item> + <widget class="QCheckBox" name="color_scale_data_defined_in_check"> + <property name="text"> + <string>Visible</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="color_scale_data_defined_in_invert_check"> + <property name="text"> + <string>Invert color</string> + </property> + </widget> + </item> + </layout> </item> - <item row="9" column="0"> - <widget class="QLabel" name="z_label"> + <item row="15" column="0"> + <widget class="QLabel" name="orientation_label"> <property name="text"> - <string>Z field</string> + <string>Bar orientation</string> </property> </widget> </item> - <item row="7" column="1" colspan="2"> - <widget class="QgsFieldExpressionWidget" name="x_combo"/> - </item> - <item row="8" column="0"> - <widget class="QLabel" name="y_label"> + <item row="18" column="0"> + <widget class="QLabel" name="outliers_label"> <property name="text"> - <string>Y field</string> + <string>Outliers</string> </property> </widget> </item> - <item row="7" column="0"> - <widget class="QLabel" name="x_label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>20</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>70</width> - <height>16777215</height> - </size> - </property> + <item row="17" column="1" colspan="5"> + <widget class="QComboBox" name="box_statistic_combo"/> + </item> + <item row="19" column="1" colspan="5"> + <widget class="QComboBox" name="violinSideCombo"/> + </item> + <item row="23" column="0"> + <widget class="QCheckBox" name="bins_check"> <property name="text"> - <string>X field</string> + <string>Manual bin size</string> </property> </widget> </item> - <item row="9" column="1" colspan="2"> - <widget class="QgsFieldExpressionWidget" name="z_combo"/> + <item row="12" column="1" colspan="5"> + <widget class="QComboBox" name="info_combo"/> </item> - <item row="0" column="1" colspan="2"> - <widget class="QgsMapLayerComboBox" name="layer_combo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <item row="5" column="1" colspan="5"> + <widget class="QComboBox" name="marker_type_combo"/> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="marker_type_lab"> + <property name="text"> + <string>Marker type</string> </property> </widget> </item> - <item row="5" column="1" colspan="2"> - <widget class="QCheckBox" name="filter_by_map_check"> + <item row="0" column="0"> + <widget class="QLabel" name="legend_label"> <property name="text"> - <string>Use only features visible in map</string> + <string>Legend title</string> </property> </widget> </item> - <item row="6" column="1" colspan="2"> - <widget class="QCheckBox" name="filter_by_atlas_check"> + <item row="0" column="1" colspan="4"> + <widget class="QLineEdit" name="legend_title"/> + </item> + <item row="0" column="5"> + <widget class="QgsPropertyOverrideButton" name="legend_title_defined_button"> <property name="text"> - <string>Use only features inside atlas feature</string> + <string>...</string> </property> </widget> </item> @@ -721,12 +882,12 @@ QListWidget::item::selected { <property name="geometry"> <rect> <x>0</x> - <y>-240</y> - <width>780</width> - <height>982</height> + <y>0</y> + <width>686</width> + <height>742</height> </rect> </property> - <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,0,0"> + <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,0"> <property name="leftMargin"> <number>0</number> </property> @@ -739,174 +900,7 @@ QListWidget::item::selected { <property name="bottomMargin"> <number>0</number> </property> - <item row="23" column="0"> - <widget class="QLabel" name="hist_norm_label"> - <property name="text"> - <string>Normalization</string> - </property> - </widget> - </item> - <item row="24" column="0"> - <widget class="QLabel" name="box_statistic_label"> - <property name="text"> - <string>Show statistics</string> - </property> - </widget> - </item> - <item row="4" column="3"> - <widget class="QgsPropertyOverrideButton" name="legend_title_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="24" column="1" colspan="3"> - <widget class="QComboBox" name="box_statistic_combo"/> - </item> - <item row="27" column="0" colspan="4"> - <widget class="QCheckBox" name="violinBox"> - <property name="toolTip"> - <string>If checked, box plots will be overlaid on top of violin plots</string> - </property> - <property name="text"> - <string>Include box plots</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="21" column="0"> - <widget class="QLabel" name="orientation_label"> - <property name="text"> - <string>Bar orientation</string> - </property> - </widget> - </item> - <item row="26" column="1" colspan="3"> - <widget class="QComboBox" name="violinSideCombo"/> - </item> - <item row="12" column="1" colspan="3"> - <widget class="QComboBox" name="combo_text_position"/> - </item> - <item row="37" column="0" colspan="3"> - <spacer name="verticalSpacer_6"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>255</width> - <height>222</height> - </size> - </property> - </spacer> - </item> - <item row="23" column="1" colspan="3"> - <widget class="QComboBox" name="hist_norm_combo"/> - </item> - <item row="26" column="0"> - <widget class="QLabel" name="violinSideLabel"> - <property name="text"> - <string>Violin side</string> - </property> - </widget> - </item> - <item row="11" column="0"> - <widget class="QCheckBox" name="hover_as_text_check"> - <property name="text"> - <string>Hover label as text</string> - </property> - </widget> - </item> - <item row="21" column="1" colspan="3"> - <widget class="QComboBox" name="orientation_combo"/> - </item> - <item row="12" column="0"> - <widget class="QLabel" name="label_text_position"> - <property name="text"> - <string>Label text position</string> - </property> - </widget> - </item> - <item row="25" column="0"> - <widget class="QLabel" name="outliers_label"> - <property name="text"> - <string>Outliers</string> - </property> - </widget> - </item> - <item row="9" column="0"> - <widget class="QLabel" name="info_label"> - <property name="text"> - <string>Hover tooltip</string> - </property> - </widget> - </item> - <item row="28" column="0" colspan="4"> - <widget class="QCheckBox" name="showMeanCheck"> - <property name="text"> - <string>Show mean line</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="legend_label"> - <property name="text"> - <string>Legend title</string> - </property> - </widget> - </item> - <item row="9" column="1" colspan="3"> - <widget class="QComboBox" name="info_combo"/> - </item> - <item row="29" column="0" colspan="4"> - <layout class="QHBoxLayout" name="horiz_layout_histogram"> - <item> - <widget class="QCheckBox" name="invert_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Invert histogram direction</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cumulative_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string>Cumulative histogram</string> - </property> - </widget> - </item> - </layout> - </item> - <item row="4" column="1" colspan="2"> - <widget class="QLineEdit" name="legend_title"/> - </item> - <item row="25" column="1" colspan="3"> - <widget class="QComboBox" name="outliers_combo"/> - </item> - <item row="31" column="1" colspan="3"> - <widget class="QgsSpinBox" name="bins_value"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="maximum"> - <number>1000</number> - </property> - <property name="value"> - <number>10</number> - </property> - </widget> - </item> - <item row="36" column="0" colspan="4"> + <item row="35" column="0" colspan="3"> <widget class="QgsCollapsibleGroupBox" name="layout_configuration_box"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> @@ -928,63 +922,38 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="5" column="3"> - <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> + <item row="3" column="2"> + <widget class="QLineEdit" name="x_axis_title"/> + </item> + <item row="12" column="0"> + <widget class="QLabel" name="additional_info_label"> <property name="text"> - <string>...</string> + <string>Additional hover label</string> </property> </widget> </item> - <item row="5" column="2"> - <widget class="QLineEdit" name="y_axis_title"/> - </item> - <item row="28" column="0" colspan="4"> - <widget class="QgsCollapsibleGroupBox" name="y_axis_bounds_check"> - <property name="title"> - <string>Set Y Axis Bounds</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <layout class="QGridLayout" name="gridYAxisBounds"> - <item row="0" column="0"> - <widget class="QLabel" name="y_axis_min_label"> - <property name="text"> - <string>Minimum</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QgsDoubleSpinBox" name="y_axis_min"/> - </item> - <item row="0" column="2"> - <widget class="QgsPropertyOverrideButton" name="y_axis_min_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="y_axis_max_label"> - <property name="text"> - <string>Maximum</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QgsDoubleSpinBox" name="y_axis_max"/> - </item> - <item row="1" column="2"> - <widget class="QgsPropertyOverrideButton" name="y_axis_max_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> + <item row="10" column="0"> + <widget class="QLabel" name="bar_mode_lab"> + <property name="text"> + <string>Bar mode</string> + </property> + </widget> + </item> + <item row="7" column="2"> + <widget class="QLineEdit" name="z_axis_title"/> + </item> + <item row="1" column="3"> + <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="z_axis_label"> + <property name="text"> + <string>Z label</string> + </property> </widget> </item> <item row="5" column="0"> @@ -994,6 +963,20 @@ QListWidget::item::selected { </property> </widget> </item> + <item row="29" column="2" colspan="2"> + <widget class="QgsColorButton" name="layout_grid_axis_color"> + <property name="allowOpacity"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="plot_title_lab"> + <property name="text"> + <string>Plot title</string> + </property> + </widget> + </item> <item row="14" column="2" colspan="2"> <layout class="QHBoxLayout" name="horizontalLayout_10"> <item> @@ -1015,44 +998,13 @@ QListWidget::item::selected { </item> </layout> </item> - <item row="11" column="0"> - <widget class="QLabel" name="bar_gap_label"> + <item row="5" column="3"> + <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> <property name="text"> - <string>Bar gap</string> + <string>...</string> </property> </widget> </item> - <item row="1" column="2"> - <widget class="QLineEdit" name="plot_title_line"/> - </item> - <item row="0" column="2" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_6"> - <item> - <widget class="QCheckBox" name="show_legend_check"> - <property name="text"> - <string>Show legend</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="orientation_legend_check"> - <property name="text"> - <string>Horizontal legend</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="range_slider_combo"> - <property name="text"> - <string>Show range slider</string> - </property> - </widget> - </item> - </layout> - </item> <item row="16" column="2" colspan="2"> <layout class="QHBoxLayout" name="horizontalLayout_11"> <item> @@ -1074,23 +1026,19 @@ QListWidget::item::selected { </item> </layout> </item> - <item row="16" column="0"> - <widget class="QCheckBox" name="invert_y_check"> - <property name="text"> - <string>Invert Y axis</string> - </property> - </widget> - </item> - <item row="3" column="2"> - <widget class="QLineEdit" name="x_axis_title"/> + <item row="12" column="2"> + <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> </item> - <item row="7" column="0"> - <widget class="QLabel" name="z_axis_label"> + <item row="11" column="0"> + <widget class="QLabel" name="bar_gap_label"> <property name="text"> - <string>Z label</string> + <string>Bar gap</string> </property> </widget> </item> + <item row="5" column="2"> + <widget class="QLineEdit" name="y_axis_title"/> + </item> <item row="27" column="0" colspan="4"> <widget class="QgsCollapsibleGroupBox" name="x_axis_bounds_check"> <property name="title"> @@ -1140,39 +1088,64 @@ QListWidget::item::selected { </layout> </widget> </item> - <item row="14" column="0"> - <widget class="QCheckBox" name="invert_x_check"> - <property name="text"> - <string>Invert X axis</string> - </property> - </widget> - </item> - <item row="3" column="3"> - <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> + <item row="29" column="0"> + <widget class="QLabel" name="grid_color_label"> <property name="text"> - <string>...</string> + <string>Grid color</string> </property> </widget> </item> - <item row="1" column="3"> - <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> - <property name="text"> - <string>...</string> + <item row="28" column="0" colspan="4"> + <widget class="QgsCollapsibleGroupBox" name="y_axis_bounds_check"> + <property name="title"> + <string>Set Y Axis Bounds</string> </property> - </widget> - </item> - <item row="11" column="2" colspan="2"> - <widget class="QgsDoubleSpinBox" name="bar_gap"> - <property name="maximum"> - <double>1.000000000000000</double> + <property name="checkable"> + <bool>true</bool> </property> - <property name="singleStep"> - <double>0.100000000000000</double> + <property name="checked"> + <bool>false</bool> </property> + <layout class="QGridLayout" name="gridYAxisBounds"> + <item row="0" column="0"> + <widget class="QLabel" name="y_axis_min_label"> + <property name="text"> + <string>Minimum</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QgsDoubleSpinBox" name="y_axis_min"/> + </item> + <item row="0" column="2"> + <widget class="QgsPropertyOverrideButton" name="y_axis_min_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="y_axis_max_label"> + <property name="text"> + <string>Maximum</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QgsDoubleSpinBox" name="y_axis_max"/> + </item> + <item row="1" column="2"> + <widget class="QgsPropertyOverrideButton" name="y_axis_max_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> </widget> </item> - <item row="12" column="2"> - <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> + <item row="1" column="2"> + <widget class="QLineEdit" name="plot_title_line"/> </item> <item row="10" column="2" colspan="2"> <widget class="QComboBox" name="bar_mode_combo"/> @@ -1184,53 +1157,80 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="1" column="0"> - <widget class="QLabel" name="plot_title_lab"> + <item row="14" column="0"> + <widget class="QCheckBox" name="invert_x_check"> <property name="text"> - <string>Plot title</string> + <string>Invert X axis</string> </property> </widget> </item> - <item row="12" column="0"> - <widget class="QLabel" name="additional_info_label"> + <item row="3" column="3"> + <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> <property name="text"> - <string>Additional hover label</string> + <string>...</string> </property> </widget> </item> - <item row="7" column="2"> - <widget class="QLineEdit" name="z_axis_title"/> - </item> - <item row="10" column="0"> - <widget class="QLabel" name="bar_mode_lab"> + <item row="16" column="0"> + <widget class="QCheckBox" name="invert_y_check"> <property name="text"> - <string>Bar mode</string> + <string>Invert Y axis</string> </property> </widget> </item> - <item row="29" column="0"> - <widget class="QLabel" name="grid_color_label"> - <property name="text"> - <string>Grid color</string> + <item row="11" column="2" colspan="2"> + <widget class="QgsDoubleSpinBox" name="bar_gap"> + <property name="maximum"> + <double>1.000000000000000</double> </property> - </widget> - </item> - <item row="29" column="2" colspan="2"> - <widget class="QgsColorButton" name="layout_grid_axis_color"> - <property name="allowOpacity"> - <bool>true</bool> + <property name="singleStep"> + <double>0.100000000000000</double> </property> </widget> </item> + <item row="0" column="0" colspan="4"> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QCheckBox" name="show_legend_check"> + <property name="text"> + <string>Show legend</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="orientation_legend_check"> + <property name="text"> + <string>Horizontal legend</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="range_slider_combo"> + <property name="text"> + <string>Show range slider</string> + </property> + </widget> + </item> + </layout> + </item> </layout> </widget> </item> - <item row="31" column="0"> - <widget class="QCheckBox" name="bins_check"> - <property name="text"> - <string>Manual bin size</string> + <item row="36" column="0" colspan="3"> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> </property> - </widget> + <property name="sizeHint" stdset="0"> + <size> + <width>255</width> + <height>222</height> + </size> + </property> + </spacer> </item> </layout> </widget> @@ -1478,37 +1478,5 @@ QListWidget::item::selected { </hint> </hints> </connection> - <connection> - <sender>bins_check</sender> - <signal>toggled(bool)</signal> - <receiver>bins_value</receiver> - <slot>setEnabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>264</x> - <y>461</y> - </hint> - <hint type="destinationlabel"> - <x>393</x> - <y>464</y> - </hint> - </hints> - </connection> - <connection> - <sender>cumulative_hist_check</sender> - <signal>toggled(bool)</signal> - <receiver>invert_hist_check</receiver> - <slot>setEnabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>208</x> - <y>427</y> - </hint> - <hint type="destinationlabel"> - <x>302</x> - <y>423</y> - </hint> - </hints> - </connection> </connections> </ui> From a5a1d44094f69c4f15f90800993a18a190b8e7dd Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Tue, 30 Mar 2021 07:58:49 +0200 Subject: [PATCH 07/57] when opening point to the first widget page --- DataPlotly/ui/dataplotly_dockwidget_base.ui | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index 306f01a8..e4a86fe3 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -258,7 +258,7 @@ QListWidget::item::selected { <item row="0" column="0"> <widget class="QStackedWidget" name="stackedNestedPlotWidget"> <property name="currentIndex"> - <number>1</number> + <number>0</number> </property> <widget class="QWidget" name="page"> <layout class="QGridLayout" name="gridLayout"> @@ -321,8 +321,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>665</width> - <height>1011</height> + <width>673</width> + <height>989</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_9"> @@ -883,8 +883,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>686</width> - <height>742</height> + <width>687</width> + <height>748</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,0"> From c2fd3584dad0ab766649a268fef692852abe2332 Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Tue, 30 Mar 2021 08:04:58 +0200 Subject: [PATCH 08/57] Revert "when opening point to the first widget page" This reverts commit a5a1d44094f69c4f15f90800993a18a190b8e7dd. --- DataPlotly/ui/dataplotly_dockwidget_base.ui | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index e4a86fe3..306f01a8 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -258,7 +258,7 @@ QListWidget::item::selected { <item row="0" column="0"> <widget class="QStackedWidget" name="stackedNestedPlotWidget"> <property name="currentIndex"> - <number>0</number> + <number>1</number> </property> <widget class="QWidget" name="page"> <layout class="QGridLayout" name="gridLayout"> @@ -321,8 +321,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>673</width> - <height>989</height> + <width>665</width> + <height>1011</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_9"> @@ -883,8 +883,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>687</width> - <height>748</height> + <width>686</width> + <height>742</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,0"> From 0e288e425ea1d80d0d5558ae31a6b8f2e2997746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <gustrimaille@yahoo.fr> Date: Tue, 28 Sep 2021 15:02:21 +0200 Subject: [PATCH 09/57] Expose Dataplotly on QGIS Server for a GetPrint request (#266) * Expose Dataplotly on QGIS Server for a GetPrint request * Fix tests about lint --- .gitignore | 8 +++++++- DataPlotly/__init__.py | 19 +++++++++++++++++-- DataPlotly/core/plot_factory.py | 6 +++--- DataPlotly/core/plot_settings.py | 2 +- DataPlotly/gui/plot_settings_widget.py | 4 ++-- DataPlotly/metadata.txt | 1 + DataPlotly/test_suite.py | 7 +++---- Makefile | 4 ++-- pylintrc | 4 +++- 9 files changed, 39 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 8c692bf1..10082368 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,14 @@ +# Python *.pyc +.venv +venv +__pycache__/ + +# IDE .idea/* + .backuputils.py help/.tx/* *.zip -__pycache__/ .coverage .noseids diff --git a/DataPlotly/__init__.py b/DataPlotly/__init__.py index 1a001040..da566a30 100644 --- a/DataPlotly/__init__.py +++ b/DataPlotly/__init__.py @@ -22,8 +22,6 @@ This script initializes the plugin, making it known to QGIS. """ -from .data_plotly import DataPlotly - # noinspection PyPep8Naming def classFactory(iface): # pylint: disable=invalid-name @@ -32,4 +30,21 @@ def classFactory(iface): # pylint: disable=invalid-name :param iface: A QGIS interface instance. :type iface: QgsInterface """ + # pylint: disable=import-outside-toplevel + from .data_plotly import DataPlotly return DataPlotly(iface) + + +def serverClassFactory(server_iface): + """Load DataPlotly server. + + :param server_iface: A QGIS Server interface instance. + :type server_iface: QgsServerInterface + """ + _ = server_iface + # pylint: disable=import-outside-toplevel + from qgis.core import QgsApplication, QgsMessageLog, Qgis + from DataPlotly.layouts.plot_layout_item import PlotLayoutItemMetadata + + QgsApplication.layoutItemRegistry().addLayoutItemType(PlotLayoutItemMetadata()) + QgsMessageLog.logMessage("Custom DataPlotly layout item loaded", "DataPlotly", Qgis.Info) diff --git a/DataPlotly/core/plot_factory.py b/DataPlotly/core/plot_factory.py index e08e1611..0c7e7735 100644 --- a/DataPlotly/core/plot_factory.py +++ b/DataPlotly/core/plot_factory.py @@ -683,7 +683,7 @@ def build_figure(self) -> str: 'modeBarButtonsToRemove': ['toImage', 'sendDataToCloud', 'editInChartStudio'] } - with open(self.plot_path, "w") as f: + with open(self.plot_path, "w", encoding="utf8") as f: f.write(self.build_html(config)) return self.plot_path @@ -748,7 +748,7 @@ def build_figures(self, plot_type, ptrace, config=None) -> str: self.raw_plot = self.raw_plot.replace('ReplaceTheDiv', substr) self.plot_path = os.path.join(tempfile.gettempdir(), 'temp_plot_name.html') - with open(self.plot_path, "w") as f: + with open(self.plot_path, "w", encoding="utf8") as f: f.write(self.raw_plot) return self.plot_path @@ -807,7 +807,7 @@ def build_sub_plots(self, grid, row, column, ptrace): # pylint:disable=too-many self.raw_plot = self.raw_plot.replace('ReplaceTheDiv', substr) self.plot_path = os.path.join(tempfile.gettempdir(), 'temp_plot_name.html') - with open(self.plot_path, "w") as f: + with open(self.plot_path, "w", encoding="utf8") as f: f.write(self.raw_plot) return self.plot_path diff --git a/DataPlotly/core/plot_settings.py b/DataPlotly/core/plot_settings.py index aa2ac6b6..ff481f8d 100644 --- a/DataPlotly/core/plot_settings.py +++ b/DataPlotly/core/plot_settings.py @@ -247,7 +247,7 @@ def write_to_file(self, file_name: str) -> bool: document.appendChild(elem) try: - with open(file_name, "w") as f: + with open(file_name, "w", encoding="utf8") as f: f.write('<?xml version="1.0" encoding="UTF-8"?>\n') f.write(document.toString()) return True diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 0010be56..d171190c 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -697,7 +697,7 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch # according to the plot type, change the label names # BoxPlot - if self.ptype == 'box' or self.ptype == 'violin': + if self.ptype in ('box', 'violin'): self.x_label.setText(self.tr('Grouping field \n(optional)')) # set the horizontal and vertical size of the label and reduce the label font size ff = QFont() @@ -1282,7 +1282,7 @@ def refreshPlotView(self): self.layoutw.addWidget(self.plot_view) self.raw_plot_text.clear() - with open(self.plot_path, 'r') as myfile: + with open(self.plot_path, 'r', encoding="utf8") as myfile: plot_text = myfile.read() self.raw_plot_text.setPlainText(plot_text) diff --git a/DataPlotly/metadata.txt b/DataPlotly/metadata.txt index 7c501f9f..67254196 100644 --- a/DataPlotly/metadata.txt +++ b/DataPlotly/metadata.txt @@ -105,3 +105,4 @@ experimental=False deprecated=False hasProcessingProvider=yes +server=True diff --git a/DataPlotly/test_suite.py b/DataPlotly/test_suite.py index b5b1d795..28b1722e 100644 --- a/DataPlotly/test_suite.py +++ b/DataPlotly/test_suite.py @@ -53,12 +53,11 @@ def _run_tests(test_suite, package_name, with_coverage=False): if with_coverage: cov.stop() cov.save() - report = tempfile.NamedTemporaryFile(delete=False) - cov.report(file=report) + with tempfile.NamedTemporaryFile(delete=False) as report: + cov.report(file=report) # Produce HTML reports in the `htmlcov` folder and open index.html # cov.html_report() - report.close() - with open(report.name, 'r') as fin: + with open(report.name, 'r', encoding='utf8') as fin: print(fin.read()) diff --git a/Makefile b/Makefile index ef5fd290..81d9fe6d 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ EXTRAS = metadata.txt icon.png EXTRA_DIRS = -PEP8EXCLUDE=pydev,conf.py,third_party,ui +PEP8EXCLUDE=pydev,conf.py,third_party,ui,.venv,venv, ################################################# @@ -232,4 +232,4 @@ txcompile: txpull @echo "Compiled translation files to .qm files." @echo "----------------------------------------" @chmod +x scripts/compile-strings.sh - @scripts/compile-strings.sh $(LOCALES) \ No newline at end of file + @scripts/compile-strings.sh $(LOCALES) diff --git a/pylintrc b/pylintrc index 91057eb0..21ad392e 100644 --- a/pylintrc +++ b/pylintrc @@ -39,7 +39,9 @@ load-plugins= # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" # see http://stackoverflow.com/questions/21487025/pylint-locally-defined-disables-still-give-warnings-how-to-suppress-them -disable=locally-disabled,C0103,C0301,C0330,E0611,W0511,W0107,R0801,import-error +disable=locally-disabled,C0103,C0301,C0330,E0611,W0511,W0107,R0801,import-error, + # Wait for QGIS 3.18 minimum version for f-strings + C0209, [REPORTS] From 495eaa81b55afa943bb6829d86f64d17def70375 Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Tue, 28 Sep 2021 15:08:29 +0200 Subject: [PATCH 10/57] bump version 3.8 --- DataPlotly/metadata.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DataPlotly/metadata.txt b/DataPlotly/metadata.txt index 67254196..90a5acd8 100644 --- a/DataPlotly/metadata.txt +++ b/DataPlotly/metadata.txt @@ -11,7 +11,7 @@ name=Data Plotly qgisMinimumVersion=3.4 qgisMaximumVersion=3.98 description=D3 Plots for QGIS -version=3.7.1 +version=3.8 author=Matteo Ghetta (Faunalia) email=matteo.ghetta@gmail.com @@ -25,6 +25,8 @@ repository=https://github.com/ghtmtt/DataPlotly # Uncomment the following line and add your changelog: changelog= + Version 3.8 + - [feature] expose DataPlotly on QGIS Server for a GetPrint request kudos to @Gustry Version 3.7 - [feature] histogram and pie chart bar and slices with same color of category! kudos to @jdugge - [feature] plot background transparent in layouts! From 3ece8d6cda7d1cae6addb7fd3bf533fb1e4275f5 Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Tue, 28 Sep 2021 15:53:04 +0200 Subject: [PATCH 11/57] wrong panel on start fix #267 --- DataPlotly/ui/dataplotly_dockwidget_base.ui | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index 306f01a8..e4a86fe3 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -258,7 +258,7 @@ QListWidget::item::selected { <item row="0" column="0"> <widget class="QStackedWidget" name="stackedNestedPlotWidget"> <property name="currentIndex"> - <number>1</number> + <number>0</number> </property> <widget class="QWidget" name="page"> <layout class="QGridLayout" name="gridLayout"> @@ -321,8 +321,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>665</width> - <height>1011</height> + <width>673</width> + <height>989</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_9"> @@ -883,8 +883,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>686</width> - <height>742</height> + <width>687</width> + <height>748</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,0"> From 4e05ca48bd5f5372e30db8773a4e34b8458b5dfd Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Tue, 28 Sep 2021 15:53:40 +0200 Subject: [PATCH 12/57] bump version 3.8.1 --- DataPlotly/metadata.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataPlotly/metadata.txt b/DataPlotly/metadata.txt index 90a5acd8..5e2b57c4 100644 --- a/DataPlotly/metadata.txt +++ b/DataPlotly/metadata.txt @@ -11,7 +11,7 @@ name=Data Plotly qgisMinimumVersion=3.4 qgisMaximumVersion=3.98 description=D3 Plots for QGIS -version=3.8 +version=3.8.1 author=Matteo Ghetta (Faunalia) email=matteo.ghetta@gmail.com From 097742fcd35f6543f74b33a6570fdf1b2539f622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <gustrimaille@yahoo.fr> Date: Fri, 22 Oct 2021 15:25:08 +0200 Subject: [PATCH 13/57] Add plugin help button and remove extra menu (#268) --- DataPlotly/data_plotly.py | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/DataPlotly/data_plotly.py b/DataPlotly/data_plotly.py index 041d317a..624f0877 100644 --- a/DataPlotly/data_plotly.py +++ b/DataPlotly/data_plotly.py @@ -22,9 +22,10 @@ """ import os.path -from qgis.PyQt.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt -from qgis.PyQt.QtWidgets import QAction, QMenu -from qgis.core import QgsApplication +from qgis.PyQt.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QUrl +from qgis.PyQt.QtGui import QDesktopServices +from qgis.PyQt.QtWidgets import QAction +from qgis.core import Qgis, QgsApplication from qgis.gui import QgsGui # Import the code for the dialog @@ -77,7 +78,7 @@ def __init__(self, iface): self.dock_widget = None self.show_dock_action = None - self.menu = None + self.help_action = None self.toolbar = None self.plot_item_metadata = PlotLayoutItemMetadata() @@ -101,9 +102,7 @@ def tr(self, message): # pylint: disable=no-self-use def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" - - self.menu = QMenu(self.tr('&DataPlotly')) - self.iface.pluginMenu().addMenu(self.menu) + icon = GuiUtils.get_icon('dataplotly.svg') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar('DataPlotly') @@ -113,15 +112,13 @@ def initGui(self): self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget) self.dock_widget.hide() - self.show_dock_action = QAction( - GuiUtils.get_icon('dataplotly.svg'), - self.tr('DataPlotly')) + self.show_dock_action = QAction(icon, self.tr('DataPlotly')) self.show_dock_action.setToolTip(self.tr('Shows the DataPlotly dock')) self.show_dock_action.setCheckable(True) self.dock_widget.setToggleVisibilityAction(self.show_dock_action) - self.menu.addAction(self.show_dock_action) + self.iface.pluginMenu().addAction(self.show_dock_action) self.toolbar.addAction(self.show_dock_action) # Add processing provider @@ -131,22 +128,36 @@ def initGui(self): self.plot_item_gui_metadata = PlotLayoutItemGuiMetadata() QgsGui.layoutItemGuiRegistry().addLayoutItemGuiMetadata(self.plot_item_gui_metadata) + # Open the online help + if Qgis.QGIS_VERSION_INT >= 31000: + self.help_action = QAction(icon, 'DataPlotly', self.iface.mainWindow()) + self.iface.pluginHelpMenu().addAction(self.help_action) + self.help_action.triggered.connect(self.open_help) + def initProcessing(self): """Create the Processing provider""" QgsApplication.processingRegistry().addProvider(self.provider) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" + self.iface.pluginMenu().removeAction(self.show_dock_action) self.show_dock_action.deleteLater() self.show_dock_action = None - self.menu.deleteLater() - self.menu = None self.toolbar.deleteLater() self.toolbar = None + if Qgis.QGIS_VERSION_INT >= 31000 and self.help_action: + self.iface.pluginHelpMenu().removeAction(self.help_action) + self.help_action = None + # Remove processing provider QgsApplication.processingRegistry().removeProvider(self.provider) + @staticmethod + def open_help(): + """ Open the online help. """ + QDesktopServices.openUrl(QUrl('https://github.com/ghtmtt/DataPlotly/blob/master/README.md')) + def loadPlotFromDic(self, plot_dic): """ Calls the method to load the DataPlotly dialog with a given dictionary From 6c4b6d55335a007eeb6a01ce5d1211b32098c7ec Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Tue, 2 Nov 2021 14:05:57 +0100 Subject: [PATCH 14/57] enable bins box when checkbox is checked fix #269 (#273) --- DataPlotly/ui/dataplotly_dockwidget_base.ui | 46 ++++++++++++++------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index e4a86fe3..14ab5eac 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -320,7 +320,7 @@ QListWidget::item::selected { <property name="geometry"> <rect> <x>0</x> - <y>0</y> + <y>-270</y> <width>673</width> <height>989</height> </rect> @@ -883,8 +883,8 @@ QListWidget::item::selected { <rect> <x>0</x> <y>0</y> - <width>687</width> - <height>748</height> + <width>414</width> + <height>583</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_25" columnstretch="0,0,0"> @@ -1437,12 +1437,12 @@ QListWidget::item::selected { <slot>setText(QString)</slot> <hints> <hint type="sourcelabel"> - <x>532</x> - <y>226</y> + <x>903</x> + <y>-14</y> </hint> <hint type="destinationlabel"> - <x>504</x> - <y>-15</y> + <x>364</x> + <y>3</y> </hint> </hints> </connection> @@ -1453,12 +1453,12 @@ QListWidget::item::selected { <slot>setText(QString)</slot> <hints> <hint type="sourcelabel"> - <x>532</x> - <y>266</y> + <x>903</x> + <y>15</y> </hint> <hint type="destinationlabel"> - <x>504</x> - <y>18</y> + <x>364</x> + <y>20</y> </hint> </hints> </connection> @@ -1469,12 +1469,28 @@ QListWidget::item::selected { <slot>setText(QString)</slot> <hints> <hint type="sourcelabel"> - <x>532</x> - <y>306</y> + <x>903</x> + <y>44</y> + </hint> + <hint type="destinationlabel"> + <x>364</x> + <y>32</y> + </hint> + </hints> + </connection> + <connection> + <sender>bins_check</sender> + <signal>toggled(bool)</signal> + <receiver>bins_value</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>337</x> + <y>722</y> </hint> <hint type="destinationlabel"> - <x>504</x> - <y>51</y> + <x>438</x> + <y>721</y> </hint> </hints> </connection> From ac75e1e6a8b24736053a0bf425cea135147902da Mon Sep 17 00:00:00 2001 From: Matthias Kuhn <matthias@opengis.ch> Date: Mon, 14 Feb 2022 10:42:41 +0100 Subject: [PATCH 15/57] Fix TypeError with Python 3.10 (#276) Float now requires explicit cast to int --- DataPlotly/layouts/plot_layout_item.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DataPlotly/layouts/plot_layout_item.py b/DataPlotly/layouts/plot_layout_item.py index 334b537b..445f005a 100644 --- a/DataPlotly/layouts/plot_layout_item.py +++ b/DataPlotly/layouts/plot_layout_item.py @@ -218,8 +218,8 @@ def get_polygon_filter(self, index=0): def load_content(self): self.html_loaded = False base_url = QUrl.fromLocalFile(self.layout().project().absoluteFilePath()) - self.web_page.setViewportSize(QSize(self.rect().width() * self.html_units_to_layout_units, - self.rect().height() * self.html_units_to_layout_units)) + self.web_page.setViewportSize(QSize(int(self.rect().width()) * self.html_units_to_layout_units, + int(self.rect().height()) * self.html_units_to_layout_units)) self.web_page.mainFrame().setHtml(self.create_plot(), base_url) def writePropertiesToElement(self, element, document, _) -> bool: From 1132196b1686507fe7ce71e834bc19b64162e40a Mon Sep 17 00:00:00 2001 From: giliam <giliam@users.noreply.github.com> Date: Thu, 10 Mar 2022 14:31:01 +0100 Subject: [PATCH 16/57] Add options to change title, xticks and yticks font sizes. (#278) * Add options to change title, xticks and yticks font sizes. Insert options in graph parameters to change settings for all three parameters. Could be refined to also change x_label and y_label font sizes (if such parameters exist) * Add options for x/y labels and put all box in a collapsible group * Update UI parameters (title, collapsed state, default values) * Update default font size (ui and python). * Use QgsFontButton instead of size input only. Still needs some work to keep in mind the parameters between two sessions. * Separate parameters into family, size and color * Test if font related settings are correctly stored and restored. * Fix pylint issues Co-authored-by: Matthieu Denoux <matthieu.denoux@vivantes.fr> --- DataPlotly/core/plot_settings.py | 56 ++- DataPlotly/core/plot_types/plot_type.py | 48 ++- DataPlotly/gui/plot_settings_widget.py | 77 ++++ DataPlotly/test/test_data_plotly_dialog.py | 15 + DataPlotly/test/test_plot_settings.py | 9 +- DataPlotly/ui/dataplotly_dockwidget_base.ui | 397 +++++++++++++------- 6 files changed, 442 insertions(+), 160 deletions(-) diff --git a/DataPlotly/core/plot_settings.py b/DataPlotly/core/plot_settings.py index ff481f8d..b84f36a4 100644 --- a/DataPlotly/core/plot_settings.py +++ b/DataPlotly/core/plot_settings.py @@ -7,16 +7,9 @@ (at your option) any later version. """ -from qgis.PyQt.QtCore import ( - QFile, - QIODevice -) +from qgis.PyQt.QtCore import QFile, QIODevice from qgis.PyQt.QtXml import QDomDocument, QDomElement -from qgis.core import ( - QgsXmlUtils, - QgsPropertyCollection, - QgsPropertyDefinition -) +from qgis.core import QgsXmlUtils, QgsPropertyCollection, QgsPropertyDefinition class PlotSettings: # pylint: disable=too-many-instance-attributes @@ -39,6 +32,21 @@ class PlotSettings: # pylint: disable=too-many-instance-attributes PROPERTY_X_TITLE = 12 PROPERTY_Y_TITLE = 13 PROPERTY_Z_TITLE = 14 + PROPERTY_FONT_TITLE_SIZE = 15 + PROPERTY_FONT_TITLE_FAMILY = 16 + PROPERTY_FONT_TITLE_COLOR = 17 + PROPERTY_FONT_XLABEL_SIZE = 18 + PROPERTY_FONT_XLABEL_FAMILY = 19 + PROPERTY_FONT_XLABEL_COLOR = 20 + PROPERTY_FONT_XTICKS_SIZE = 21 + PROPERTY_FONT_XTICKS_FAMILY = 22 + PROPERTY_FONT_XTICKS_COLOR = 23 + PROPERTY_FONT_YLABEL_SIZE = 24 + PROPERTY_FONT_YLABEL_FAMILY = 25 + PROPERTY_FONT_YLABEL_COLOR = 26 + PROPERTY_FONT_YTICKS_SIZE = 27 + PROPERTY_FONT_YTICKS_FAMILY = 28 + PROPERTY_FONT_YTICKS_COLOR = 29 DYNAMIC_PROPERTIES = { PROPERTY_FILTER: QgsPropertyDefinition('filter', 'Feature filter', QgsPropertyDefinition.Boolean), @@ -50,6 +58,21 @@ class PlotSettings: # pylint: disable=too-many-instance-attributes QgsPropertyDefinition.DoublePositive), PROPERTY_TITLE: QgsPropertyDefinition('title', 'Plot title', QgsPropertyDefinition.String), PROPERTY_LEGEND_TITLE: QgsPropertyDefinition('legend_title', 'Legend title', QgsPropertyDefinition.String), + PROPERTY_FONT_TITLE_SIZE: QgsPropertyDefinition('font_title_size', 'Font title size', QgsPropertyDefinition.String), + PROPERTY_FONT_TITLE_FAMILY: QgsPropertyDefinition('font_title_family', 'Font title family', QgsPropertyDefinition.String), + PROPERTY_FONT_TITLE_COLOR: QgsPropertyDefinition('font_title_color', 'Font title color', QgsPropertyDefinition.ColorWithAlpha), + PROPERTY_FONT_XLABEL_SIZE: QgsPropertyDefinition('font_xlabel_size', 'Font xlabel size', QgsPropertyDefinition.String), + PROPERTY_FONT_XLABEL_FAMILY: QgsPropertyDefinition('font_xlabel_family', 'Font xlabel family', QgsPropertyDefinition.String), + PROPERTY_FONT_XLABEL_COLOR: QgsPropertyDefinition('font_xlabel_color', 'Font xlabel color', QgsPropertyDefinition.ColorWithAlpha), + PROPERTY_FONT_XTICKS_SIZE: QgsPropertyDefinition('font_xticks_size', 'Font xticks size', QgsPropertyDefinition.String), + PROPERTY_FONT_XTICKS_FAMILY: QgsPropertyDefinition('font_xticks_family', 'Font xticks family', QgsPropertyDefinition.String), + PROPERTY_FONT_XTICKS_COLOR: QgsPropertyDefinition('font_xticks_color', 'Font xticks color', QgsPropertyDefinition.ColorWithAlpha), + PROPERTY_FONT_YLABEL_SIZE: QgsPropertyDefinition('font_ylabel_size', 'Font ylabel size', QgsPropertyDefinition.String), + PROPERTY_FONT_YLABEL_FAMILY: QgsPropertyDefinition('font_ylabel_family', 'Font ylabel family', QgsPropertyDefinition.String), + PROPERTY_FONT_YLABEL_COLOR: QgsPropertyDefinition('font_ylabel_color', 'Font ylabel color', QgsPropertyDefinition.ColorWithAlpha), + PROPERTY_FONT_YTICKS_SIZE: QgsPropertyDefinition('font_yticks_size', 'Font yticks size', QgsPropertyDefinition.String), + PROPERTY_FONT_YTICKS_FAMILY: QgsPropertyDefinition('font_yticks_family', 'Font yticks family', QgsPropertyDefinition.String), + PROPERTY_FONT_YTICKS_COLOR: QgsPropertyDefinition('font_yticks_color', 'Font yticks color', QgsPropertyDefinition.ColorWithAlpha), PROPERTY_X_TITLE: QgsPropertyDefinition('x_title', 'X title', QgsPropertyDefinition.String), PROPERTY_Y_TITLE: QgsPropertyDefinition('y_title', 'Y title', QgsPropertyDefinition.String), PROPERTY_Z_TITLE: QgsPropertyDefinition('z_title', 'Z title', QgsPropertyDefinition.String), @@ -118,6 +141,21 @@ def __init__(self, plot_type: str = 'scatter', properties: dict = None, layout: 'x_title': '', 'y_title': '', 'z_title': '', + 'font_title_size': 10, + 'font_title_family': "Arial", + 'font_title_color': "#000000", + 'font_xlabel_size': 10, + 'font_xlabel_family': "Arial", + 'font_xlabel_color': "#000000", + 'font_xticks_size': 10, + 'font_xticks_family': "Arial", + 'font_xticks_color': "#000000", + 'font_ylabel_size': 10, + 'font_ylabel_family': "Arial", + 'font_ylabel_color': "#000000", + 'font_yticks_size': 10, + 'font_yticks_family': "Arial", + 'font_yticks_color': "#000000", 'xaxis': None, 'bar_mode': None, 'x_type': None, diff --git a/DataPlotly/core/plot_types/plot_type.py b/DataPlotly/core/plot_types/plot_type.py index 2e9ff249..c168e9cf 100644 --- a/DataPlotly/core/plot_types/plot_type.py +++ b/DataPlotly/core/plot_types/plot_type.py @@ -12,6 +12,22 @@ from qgis.PyQt.QtCore import QCoreApplication +def from_qfont_to_plotly(style, color): + """ + Converts a QFont to a Plotly basic font settings dictionary + """ + if style is not None and color is not None: + return { + "size": style.pointSize() or 10, + "color": color.name() or "black", + "family": style.family() or "Arial", + } + return { + "size": 10, + "color": "black", + "family": "Arial", + } + class PlotType: """ Base class for plot subclasses @@ -78,20 +94,50 @@ def create_layout(settings): bg_color = settings.layout.get('bg_color', 'rgb(255,255,255)') + # add font size parameter from the title setting + title = settings.data_defined_title if settings.data_defined_title else settings.layout['title'] + if isinstance(title, str): + title = {"text": title} + title["font"] = { + "size": settings.layout.get('font_title_size', 10), + "color": settings.layout.get('font_title_color', "#000"), + "family": settings.layout.get('font_title_family', "Arial"), + } + layout = graph_objs.Layout( showlegend=settings.layout['legend'], legend={'orientation': settings.layout['legend_orientation']}, - title=settings.data_defined_title if settings.data_defined_title else settings.layout['title'], + title=title, xaxis={ 'title': x_title, + 'titlefont': { + "size": settings.layout.get('font_xlabel_size', 10), + "color": settings.layout.get('font_xlabel_color', "#000"), + "family": settings.layout.get('font_xlabel_family', "Arial"), + }, 'autorange': settings.layout['x_inv'], 'range': range_x, + 'tickfont': { + "size": settings.layout.get('font_xticks_size', 10), + "color": settings.layout.get('font_xticks_color', "#000"), + "family": settings.layout.get('font_xticks_family', "Arial"), + }, 'gridcolor': settings.layout.get('gridcolor', '#bdbfc0') }, yaxis={ 'title': y_title, + 'titlefont': { + "size": settings.layout.get('font_ylabel_size', 10), + "color": settings.layout.get('font_ylabel_color', "#000"), + "family": settings.layout.get('font_ylabel_family', "Arial"), + }, 'autorange': settings.layout['y_inv'], 'range': range_y, + 'tickfont': { + "size": settings.layout.get('font_yticks_size', 10), + "color": settings.layout.get('font_yticks_color', "#000"), + "family": settings.layout.get('font_yticks_family', "Arial"), + }, 'gridcolor': settings.layout.get('gridcolor', '#bdbfc0') }, paper_bgcolor=bg_color, diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index d171190c..238b3b5d 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -275,6 +275,18 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b # better default colors self.in_color_combo.setColor(QColor('#8EBAD9')) self.out_color_combo.setColor(QColor('#1F77B4')) + self.font_title_color.setColor(QColor('#000000')) + self.font_xlabel_color.setColor(QColor('#000000')) + self.font_xticks_color.setColor(QColor('#000000')) + self.font_ylabel_color.setColor(QColor('#000000')) + self.font_yticks_color.setColor(QColor('#000000')) + + # default fonts + self.font_title_style.setCurrentFont(QFont('Arial', 10)) + self.font_xlabel_style.setCurrentFont(QFont('Arial', 10)) + self.font_xticks_style.setCurrentFont(QFont('Arial', 10)) + self.font_ylabel_style.setCurrentFont(QFont('Arial', 10)) + self.font_yticks_style.setCurrentFont(QFont('Arial', 10)) # set range of axis min/max spin boxes self.x_axis_min.setRange(sys.float_info.max * -1, sys.float_info.max) @@ -821,6 +833,21 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.plot_title_lab: ['all'], self.plot_title_line: ['all'], self.plot_title_defined_button: ['all'], + self.font_title_label: ['all'], + self.font_xlabel_label: ['all'], + self.font_xticks_label: ['all'], + self.font_ylabel_label: ['all'], + self.font_yticks_label: ['all'], + self.font_title_style: ['all'], + self.font_xlabel_style: ['all'], + self.font_xticks_style: ['all'], + self.font_ylabel_style: ['all'], + self.font_yticks_style: ['all'], + self.font_title_color: ['all'], + self.font_xlabel_color: ['all'], + self.font_xticks_color: ['all'], + self.font_ylabel_color: ['all'], + self.font_yticks_color: ['all'], self.x_axis_label: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'ternary', 'violin'], self.x_axis_title: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'ternary', 'violin'], self.x_axis_title_defined_button: ['scatter', 'bar', 'box', 'histogram', '2dhistogram', 'ternary', 'violin'], @@ -1028,6 +1055,31 @@ def get_settings(self) -> PlotSettings: # pylint: disable=R0915 layout_properties = {'legend': self.show_legend_check.isChecked(), 'legend_orientation': 'h' if self.orientation_legend_check.isChecked() else 'v', 'title': self.plot_title_line.text(), + 'font_title_size': max( + self.font_title_style.currentFont().pixelSize(), + self.font_title_style.currentFont().pointSize()), + 'font_title_family': self.font_title_style.currentFont().family(), + 'font_title_color': self.font_title_color.color().name(), + 'font_xlabel_size': max( + self.font_xlabel_style.currentFont().pixelSize(), + self.font_xlabel_style.currentFont().pointSize()), + 'font_xlabel_family': self.font_xlabel_style.currentFont().family(), + 'font_xlabel_color': self.font_xlabel_color.color().name(), + 'font_xticks_size': max( + self.font_xticks_style.currentFont().pixelSize(), + self.font_xticks_style.currentFont().pointSize()), + 'font_xticks_family': self.font_xticks_style.currentFont().family(), + 'font_xticks_color': self.font_xticks_color.color().name(), + 'font_ylabel_size': max( + self.font_ylabel_style.currentFont().pixelSize(), + self.font_ylabel_style.currentFont().pointSize()), + 'font_ylabel_family': self.font_ylabel_style.currentFont().family(), + 'font_ylabel_color': self.font_ylabel_color.color().name(), + 'font_yticks_size': max( + self.font_yticks_style.currentFont().pixelSize(), + self.font_yticks_style.currentFont().pointSize()), + 'font_yticks_family': self.font_yticks_style.currentFont().family(), + 'font_yticks_color': self.font_yticks_color.color().name(), 'x_title': self.x_axis_title.text(), 'y_title': self.y_axis_title.text(), 'z_title': self.z_axis_title.text(), @@ -1114,6 +1166,31 @@ def set_settings(self, settings: PlotSettings): # pylint: disable=too-many-stat self.plot_title_line.setText( settings.layout.get('title', 'Plot Title')) self.legend_title.setText(settings.properties.get('name', '')) + self.font_title_style.setCurrentFont( + QFont(settings.layout.get('font_title_family', "Arial"), + settings.layout.get('font_title_size', 10))) + self.font_title_color.setColor( + QColor(settings.layout.get('font_title_color', "#000000"))) + self.font_xticks_style.setCurrentFont( + QFont(settings.layout.get('font_xticks_family', "Arial"), + settings.layout.get('font_xticks_size', 10))) + self.font_xticks_color.setColor( + QColor(settings.layout.get('font_xticks_color', "#000000"))) + self.font_xlabel_style.setCurrentFont( + QFont(settings.layout.get('font_xlabel_family', "Arial"), + settings.layout.get('font_xlabel_size', 10))) + self.font_xlabel_color.setColor( + QColor(settings.layout.get('font_xlabel_color', "#000000"))) + self.font_yticks_style.setCurrentFont( + QFont(settings.layout.get('font_yticks_family', "Arial"), + settings.layout.get('font_yticks_size', 10))) + self.font_yticks_color.setColor( + QColor(settings.layout.get('font_yticks_color', "#000000"))) + self.font_ylabel_style.setCurrentFont( + QFont(settings.layout.get('font_ylabel_family', "Arial"), + settings.layout.get('font_ylabel_size', 10))) + self.font_ylabel_color.setColor( + QColor(settings.layout.get('font_ylabel_color', "#000000"))) self.x_axis_title.setText(settings.layout.get('x_title', '')) self.y_axis_title.setText(settings.layout.get('y_title', '')) self.z_axis_title.setText(settings.layout.get('z_title', '')) diff --git a/DataPlotly/test/test_data_plotly_dialog.py b/DataPlotly/test/test_data_plotly_dialog.py index cbe14a1d..39201b0e 100644 --- a/DataPlotly/test/test_data_plotly_dialog.py +++ b/DataPlotly/test/test_data_plotly_dialog.py @@ -127,6 +127,21 @@ def test_settings_round_trip(self): # pylint: disable=too-many-statements 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' diff --git a/DataPlotly/test/test_plot_settings.py b/DataPlotly/test/test_plot_settings.py index cde659e7..1ec20bc5 100644 --- a/DataPlotly/test/test_plot_settings.py +++ b/DataPlotly/test/test_plot_settings.py @@ -45,12 +45,13 @@ def test_constructor(self): # override base settings settings = PlotSettings('test', properties={'marker_width': 2, 'marker_size': 5}, - layout={'title': 'my plot', 'legend_orientation': 'v'}) + layout={'title': 'my plot', 'legend_orientation': 'v', 'font_title_size': 20}) # base settings should be inherited self.assertEqual(settings.properties['marker_size'], 5) self.assertEqual(settings.properties['marker_width'], 2) self.assertEqual(settings.layout['legend_orientation'], 'v') self.assertEqual(settings.layout['title'], 'my plot') + self.assertEqual(settings.layout['font_title_size'], 20) def test_readwrite(self): """ @@ -128,7 +129,7 @@ def test_read_write_project(self): doc = QDomDocument("test") doc.appendChild(doc.createElement('qgis')) original = PlotSettings('test', properties={'marker_width': 2, 'marker_size': 5}, - layout={'title': 'my plot', 'legend_orientation': 'v'}) + layout={'title': 'my plot', 'legend_orientation': 'v', 'font_xlabel_color': "#00FFFF"}) original.data_defined_properties.setProperty(PlotSettings.PROPERTY_FILTER, QgsProperty.fromExpression('"ap">50')) original.data_defined_properties.setProperty(PlotSettings.PROPERTY_MARKER_SIZE, @@ -193,7 +194,7 @@ def test_read_write_project2(self): """ p = QgsProject() original = PlotSettings('test', properties={'marker_width': 2, 'marker_size': 5}, - layout={'title': 'my plot', 'legend_orientation': 'v'}) + layout={'title': 'my plot', 'legend_orientation': 'v', 'font_xlabel_color': '#00FFFF'}) original.data_defined_properties.setProperty(PlotSettings.PROPERTY_FILTER, QgsProperty.fromExpression('"ap">50')) original.data_defined_properties.setProperty(PlotSettings.PROPERTY_MARKER_SIZE, @@ -280,7 +281,7 @@ def test_read_write_file(self): Test reading and writing configuration to files """ original = PlotSettings('test', properties={'marker_width': 2, 'marker_size': 5}, - layout={'title': 'my plot', 'legend_orientation': 'v'}) + layout={'title': 'my plot', 'legend_orientation': 'v', 'font_xlabel_color': '#00FFFF'}) original.data_defined_properties.setProperty(PlotSettings.PROPERTY_FILTER, QgsProperty.fromExpression('"ap">50')) original.data_defined_properties.setProperty(PlotSettings.PROPERTY_MARKER_SIZE, diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index 14ab5eac..91ac9eba 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -915,131 +915,14 @@ QListWidget::item::selected { <bool>false</bool> </property> <layout class="QGridLayout" name="gridLayout_10"> - <item row="7" column="3"> - <widget class="QgsPropertyOverrideButton" name="z_axis_title_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="3" column="2"> - <widget class="QLineEdit" name="x_axis_title"/> - </item> - <item row="12" column="0"> - <widget class="QLabel" name="additional_info_label"> - <property name="text"> - <string>Additional hover label</string> - </property> - </widget> - </item> - <item row="10" column="0"> - <widget class="QLabel" name="bar_mode_lab"> - <property name="text"> - <string>Bar mode</string> - </property> - </widget> - </item> - <item row="7" column="2"> - <widget class="QLineEdit" name="z_axis_title"/> - </item> - <item row="1" column="3"> - <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QLabel" name="z_axis_label"> - <property name="text"> - <string>Z label</string> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="y_axis_label"> - <property name="text"> - <string>Y label</string> - </property> - </widget> - </item> - <item row="29" column="2" colspan="2"> + <item row="32" column="2" colspan="2"> <widget class="QgsColorButton" name="layout_grid_axis_color"> <property name="allowOpacity"> <bool>true</bool> </property> </widget> </item> - <item row="1" column="0"> - <widget class="QLabel" name="plot_title_lab"> - <property name="text"> - <string>Plot title</string> - </property> - </widget> - </item> - <item row="14" column="2" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_10"> - <item> - <widget class="QLabel" name="x_axis_mode_label"> - <property name="text"> - <string>X axis mode</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="x_axis_mode_combo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </item> - <item row="5" column="3"> - <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item row="16" column="2" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_11"> - <item> - <widget class="QLabel" name="y_axis_mode_label"> - <property name="text"> - <string>Y axis mode</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="y_axis_mode_combo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - </layout> - </item> - <item row="12" column="2"> - <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> - </item> - <item row="11" column="0"> - <widget class="QLabel" name="bar_gap_label"> - <property name="text"> - <string>Bar gap</string> - </property> - </widget> - </item> - <item row="5" column="2"> - <widget class="QLineEdit" name="y_axis_title"/> - </item> - <item row="27" column="0" colspan="4"> + <item row="30" column="0" colspan="4"> <widget class="QgsCollapsibleGroupBox" name="x_axis_bounds_check"> <property name="title"> <string>Set X Axis Bounds</string> @@ -1088,14 +971,7 @@ QListWidget::item::selected { </layout> </widget> </item> - <item row="29" column="0"> - <widget class="QLabel" name="grid_color_label"> - <property name="text"> - <string>Grid color</string> - </property> - </widget> - </item> - <item row="28" column="0" colspan="4"> + <item row="31" column="0" colspan="4"> <widget class="QgsCollapsibleGroupBox" name="y_axis_bounds_check"> <property name="title"> <string>Set Y Axis Bounds</string> @@ -1144,47 +1020,96 @@ QListWidget::item::selected { </layout> </widget> </item> - <item row="1" column="2"> - <widget class="QLineEdit" name="plot_title_line"/> - </item> - <item row="10" column="2" colspan="2"> - <widget class="QComboBox" name="bar_mode_combo"/> - </item> - <item row="3" column="0"> + <item row="2" column="0"> <widget class="QLabel" name="x_axis_label"> <property name="text"> <string>X label</string> </property> </widget> </item> - <item row="14" column="0"> - <widget class="QCheckBox" name="invert_x_check"> + <item row="2" column="2"> + <widget class="QLineEdit" name="x_axis_title"/> + </item> + <item row="3" column="2"> + <widget class="QLineEdit" name="y_axis_title"/> + </item> + <item row="2" column="3"> + <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> <property name="text"> - <string>Invert X axis</string> + <string>...</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="y_axis_label"> + <property name="text"> + <string>Y label</string> </property> </widget> </item> <item row="3" column="3"> - <widget class="QgsPropertyOverrideButton" name="x_axis_title_defined_button"> + <widget class="QgsPropertyOverrideButton" name="y_axis_title_defined_button"> <property name="text"> <string>...</string> </property> </widget> </item> - <item row="16" column="0"> + <item row="19" column="0"> <widget class="QCheckBox" name="invert_y_check"> <property name="text"> <string>Invert Y axis</string> </property> </widget> </item> - <item row="11" column="2" colspan="2"> - <widget class="QgsDoubleSpinBox" name="bar_gap"> - <property name="maximum"> - <double>1.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> + <item row="19" column="2" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <widget class="QLabel" name="y_axis_mode_label"> + <property name="text"> + <string>Y axis mode</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="y_axis_mode_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item row="13" column="2" colspan="2"> + <widget class="QComboBox" name="bar_mode_combo"/> + </item> + <item row="17" column="2" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_10"> + <item> + <widget class="QLabel" name="x_axis_mode_label"> + <property name="text"> + <string>X axis mode</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="x_axis_mode_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="3"> + <widget class="QgsPropertyOverrideButton" name="plot_title_defined_button"> + <property name="text"> + <string>...</string> </property> </widget> </item> @@ -1216,6 +1141,181 @@ QListWidget::item::selected { </item> </layout> </item> + <item row="13" column="0"> + <widget class="QLabel" name="bar_mode_lab"> + <property name="text"> + <string>Bar mode</string> + </property> + </widget> + </item> + <item row="15" column="2"> + <widget class="QgsFieldExpressionWidget" name="additional_info_combo"/> + </item> + <item row="14" column="2" colspan="2"> + <widget class="QgsDoubleSpinBox" name="bar_gap"> + <property name="maximum"> + <double>1.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.100000000000000</double> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLineEdit" name="plot_title_line"/> + </item> + <item row="32" column="0"> + <widget class="QLabel" name="grid_color_label"> + <property name="text"> + <string>Grid color</string> + </property> + </widget> + </item> + <item row="17" column="0"> + <widget class="QCheckBox" name="invert_x_check"> + <property name="text"> + <string>Invert X axis</string> + </property> + </widget> + </item> + <item row="14" column="0"> + <widget class="QLabel" name="bar_gap_label"> + <property name="text"> + <string>Bar gap</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="plot_title_lab"> + <property name="text"> + <string>Plot title</string> + </property> + </widget> + </item> + <item row="15" column="0"> + <widget class="QLabel" name="additional_info_label"> + <property name="text"> + <string>Additional hover label</string> + </property> + </widget> + </item> + <item row="5" column="0" colspan="4"> + <widget class="QgsCollapsibleGroupBox" name="layout_font_sizes"> + <property name="title"> + <string>Title and labels customization</string> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="collapsed"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout_11"> + <item row="6" column="0"> + <widget class="QLabel" name="font_yticks_label"> + <property name="text"> + <string>Y ticks font</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="font_ylabel_label"> + <property name="text"> + <string>Y label font</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="font_xticks_label"> + <property name="text"> + <string>X ticks font</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="font_title_label"> + <property name="text"> + <string>Title font</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="font_xlabel_label"> + <property name="text"> + <string>X label font</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QgsColorButton" name="font_title_color"/> + </item> + <item row="0" column="2"> + <widget class="QgsFontButton" name="font_title_style"> + <property name="mode"> + <enum>QgsFontButton::ModeQFont</enum> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="QgsFontButton" name="font_xticks_style"> + <property name="mode"> + <enum>QgsFontButton::ModeQFont</enum> + </property> + </widget> + </item> + <item row="5" column="2"> + <widget class="QgsFontButton" name="font_ylabel_style"> + <property name="mode"> + <enum>QgsFontButton::ModeQFont</enum> + </property> + </widget> + </item> + <item row="6" column="2"> + <widget class="QgsFontButton" name="font_yticks_style"> + <property name="mode"> + <enum>QgsFontButton::ModeQFont</enum> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QgsColorButton" name="font_xlabel_color"/> + </item> + <item row="3" column="2"> + <widget class="QgsFontButton" name="font_xlabel_style"> + <property name="mode"> + <enum>QgsFontButton::ModeQFont</enum> + </property> + </widget> + </item> + <item row="4" column="3"> + <widget class="QgsColorButton" name="font_xticks_color"/> + </item> + <item row="5" column="3"> + <widget class="QgsColorButton" name="font_ylabel_color"/> + </item> + <item row="6" column="3"> + <widget class="QgsColorButton" name="font_yticks_color"/> + </item> + </layout> + </widget> + </item> + <item row="4" column="2"> + <widget class="QLineEdit" name="z_axis_title"/> + </item> + <item row="4" column="3"> + <widget class="QgsPropertyOverrideButton" name="z_axis_title_defined_button"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="z_axis_label"> + <property name="text"> + <string>Z label</string> + </property> + </widget> + </item> </layout> </widget> </item> @@ -1398,6 +1498,11 @@ QListWidget::item::selected { <extends>QWidget</extends> <header>qgsfieldexpressionwidget.h</header> </customwidget> + <customwidget> + <class>QgsFontButton</class> + <extends>QToolButton</extends> + <header>qgsfontbutton.h</header> + </customwidget> <customwidget> <class>QgsMapLayerComboBox</class> <extends>QComboBox</extends> From 1c20d52263bfda2fe1c4a742304a10bdbd4135e8 Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Mon, 11 Apr 2022 14:35:36 +0200 Subject: [PATCH 17/57] bump version 3.9 --- DataPlotly/metadata.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DataPlotly/metadata.txt b/DataPlotly/metadata.txt index 5e2b57c4..aabfac1a 100644 --- a/DataPlotly/metadata.txt +++ b/DataPlotly/metadata.txt @@ -11,7 +11,7 @@ name=Data Plotly qgisMinimumVersion=3.4 qgisMaximumVersion=3.98 description=D3 Plots for QGIS -version=3.8.1 +version=3.9 author=Matteo Ghetta (Faunalia) email=matteo.ghetta@gmail.com @@ -25,6 +25,8 @@ repository=https://github.com/ghtmtt/DataPlotly # Uncomment the following line and add your changelog: changelog= + Version 3.9 + - [feature] Customize font for plot title and plot axis. Kudos to @giliam Version 3.8 - [feature] expose DataPlotly on QGIS Server for a GetPrint request kudos to @Gustry Version 3.7 From be0691a236a493e4d0d7d5a62fbcffb71781c139 Mon Sep 17 00:00:00 2001 From: Julien Monticolo <20857031+jmonticolo@users.noreply.github.com> Date: Wed, 20 Apr 2022 08:30:52 +0200 Subject: [PATCH 18/57] Fix #237 add data-driven color to Polar Plot marker color (#283) Co-authored-by: julien.monticolo <monticolo@unistra.fr> --- DataPlotly/core/plot_types/polar.py | 30 +++++++++++++------------- DataPlotly/gui/plot_settings_widget.py | 4 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/DataPlotly/core/plot_types/polar.py b/DataPlotly/core/plot_types/polar.py index c2428eb9..ff4ffe24 100644 --- a/DataPlotly/core/plot_types/polar.py +++ b/DataPlotly/core/plot_types/polar.py @@ -38,22 +38,22 @@ def create_trace(settings): theta=settings.x, mode=settings.properties['marker'], name=settings.properties['y_name'], - marker=dict( - color=settings.properties['in_color'], - size=settings.data_defined_marker_sizes if settings.data_defined_marker_sizes else settings.properties['marker_size'], - symbol=settings.properties['marker_symbol'], - line=dict( - color=settings.properties['out_color'], - width=settings.properties['marker_width'] - ) - ), - line=dict( - color=settings.properties['in_color'], - width=settings.data_defined_stroke_widths if settings.data_defined_stroke_widths else settings.properties['marker_width'], - dash=settings.properties['line_dash'] - ), + marker={ + "color": settings.data_defined_colors if settings.data_defined_colors else settings.properties['in_color'], + "size": settings.data_defined_marker_sizes if settings.data_defined_marker_sizes else settings.properties['marker_size'], + "symbol": settings.properties['marker_symbol'], + "line": { + "color": settings.properties['out_color'], + "width": settings.properties['marker_width'] + } + }, + line={ + "color": settings.properties['in_color'], + "width": settings.data_defined_stroke_widths if settings.data_defined_stroke_widths else settings.properties['marker_width'], + "dash": settings.properties['line_dash'] + }, opacity=settings.properties['opacity'], - )] + )] @staticmethod def create_layout(settings): diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 238b3b5d..7d5780cf 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -793,7 +793,7 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.info_combo: ['scatter'], self.in_color_lab: ['scatter', 'bar', 'box', 'pie', 'histogram', 'polar', 'ternary', 'violin'], self.in_color_combo: ['scatter', 'bar', 'box', 'pie', 'histogram', 'polar', 'ternary', 'violin'], - self.in_color_defined_button: ['scatter', 'bar', 'box', 'pie', 'histogram', 'ternary'], + self.in_color_defined_button: ['scatter', 'bar', 'box', 'pie', 'histogram', 'polar', 'ternary'], self.color_scale_data_defined_in: ['scatter', 'bar', 'pie', 'histogram', 'ternary'], self.color_scale_data_defined_in_label: ['scatter', 'bar', 'ternary'], self.color_scale_data_defined_in_check: ['scatter', 'bar', 'ternary'], @@ -805,7 +805,7 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.stroke_defined_button: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin'], self.marker_size_lab: ['scatter', 'polar', 'ternary'], self.marker_size: ['scatter', 'polar', 'ternary'], - self.size_defined_button: ['scatter', 'ternary'], + self.size_defined_button: ['scatter', 'polar', 'ternary'], self.marker_type_lab: ['scatter', 'polar'], self.marker_type_combo: ['scatter', 'polar'], self.alpha_lab: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin', 'contour'], From e950661a551cf44feb62de11765258a1e16a39a7 Mon Sep 17 00:00:00 2001 From: Andrea Giudiceandrea <andreaerdna@libero.it> Date: Fri, 13 May 2022 08:33:38 +0200 Subject: [PATCH 19/57] Fix "Build a generic plot" processing algorithm (#285) * Fix "Build a generic plot" processing algorithm * Update DataPlotly/processing/dataplotly_algorithms.py --- DataPlotly/processing/dataplotly_algorithms.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DataPlotly/processing/dataplotly_algorithms.py b/DataPlotly/processing/dataplotly_algorithms.py index 7aee3e77..818b6aba 100644 --- a/DataPlotly/processing/dataplotly_algorithms.py +++ b/DataPlotly/processing/dataplotly_algorithms.py @@ -83,6 +83,9 @@ def tr(string, context=''): context = 'Processing' return QCoreApplication.translate(context, string) + def createInstance(self): + return DataPlotlyProcessingPlot() + def initAlgorithm(self, config=None): self.addParameter( From 17526f30bc7857991b1b58a09c6536be68e466a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <gustrimaille@yahoo.fr> Date: Wed, 1 Jun 2022 14:05:40 +0200 Subject: [PATCH 20/57] CI - Use QGIS-Plugin-CI for packaging the plugin (#281) --- .github/workflows/release.yml | 50 ++ .github/workflows/transifex.yml | 27 + .tx/config | 10 - CHANGELOG.md | 126 +++++ DataPlotly/data_plotly.py | 8 +- DataPlotly/i18n/DataPlotly_af.qm | Bin 95 -> 0 bytes DataPlotly/i18n/DataPlotly_af.ts | 874 ------------------------------ DataPlotly/i18n/DataPlotly_en.qm | 1 - DataPlotly/i18n/DataPlotly_en.ts | 874 ------------------------------ DataPlotly/i18n/DataPlotly_es.qm | Bin 10951 -> 0 bytes DataPlotly/i18n/DataPlotly_es.ts | 874 ------------------------------ DataPlotly/i18n/DataPlotly_fr.qm | Bin 11658 -> 0 bytes DataPlotly/i18n/DataPlotly_fr.ts | 874 ------------------------------ DataPlotly/i18n/DataPlotly_it.qm | Bin 16152 -> 0 bytes DataPlotly/i18n/DataPlotly_it.ts | 874 ------------------------------ DataPlotly/i18n/DataPlotly_nl.qm | Bin 10383 -> 0 bytes DataPlotly/i18n/DataPlotly_nl.ts | 876 ------------------------------- DataPlotly/i18n/DataPlotly_sv.qm | Bin 10255 -> 0 bytes DataPlotly/i18n/DataPlotly_sv.ts | 876 ------------------------------- DataPlotly/metadata.txt | 88 +--- Makefile | 162 +----- plugin_upload.py | 107 ---- scripts/compile-strings.sh | 12 - scripts/update-strings.sh | 59 --- setup.cfg | 8 + 25 files changed, 222 insertions(+), 6558 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/transifex.yml delete mode 100644 .tx/config create mode 100644 CHANGELOG.md delete mode 100644 DataPlotly/i18n/DataPlotly_af.qm delete mode 100644 DataPlotly/i18n/DataPlotly_af.ts delete mode 100644 DataPlotly/i18n/DataPlotly_en.qm delete mode 100644 DataPlotly/i18n/DataPlotly_en.ts delete mode 100644 DataPlotly/i18n/DataPlotly_es.qm delete mode 100644 DataPlotly/i18n/DataPlotly_es.ts delete mode 100644 DataPlotly/i18n/DataPlotly_fr.qm delete mode 100644 DataPlotly/i18n/DataPlotly_fr.ts delete mode 100644 DataPlotly/i18n/DataPlotly_it.qm delete mode 100644 DataPlotly/i18n/DataPlotly_it.ts delete mode 100644 DataPlotly/i18n/DataPlotly_nl.qm delete mode 100644 DataPlotly/i18n/DataPlotly_nl.ts delete mode 100644 DataPlotly/i18n/DataPlotly_sv.qm delete mode 100644 DataPlotly/i18n/DataPlotly_sv.ts delete mode 100644 plugin_upload.py delete mode 100755 scripts/compile-strings.sh delete mode 100755 scripts/update-strings.sh create mode 100644 setup.cfg diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..5e6af188 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,50 @@ +name: Release 🚀 + +on: + push: + tags: + - "*" + +jobs: + release: + + runs-on: ubuntu-latest + if: github.repository_owner == 'ghtmtt' && contains(github.ref, 'refs/tags/') + + steps: + - name: Set env + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + + - uses: actions/checkout@v2 + + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install Qt lrelease + run: | + sudo apt-get update + sudo apt-get install qt5-default qttools5-dev-tools + + - name: Install Python requirements + run: pip install qgis-plugin-ci + + - name : Get current changelog + run: qgis-plugin-ci changelog ${{ env.CI_COMMIT_TAG }} >> release.md + + - name: Create release on GitHub + uses: ncipollo/release-action@v1.10.0 + with: + bodyFile: release.md + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Package and deploy the zip + run: >- + qgis-plugin-ci + release ${{ env.RELEASE_VERSION }} + --github-token ${{ secrets.GITHUB_TOKEN }} + --transifex-token ${{ secrets.TRANSIFEX_TOKEN }} + --osgeo-username ${{ secrets.OSGEO_USERNAME }} + --osgeo-password ${{ secrets.OSGEO_PASSWORD }} + --create-plugin-repo diff --git a/.github/workflows/transifex.yml b/.github/workflows/transifex.yml new file mode 100644 index 00000000..d0bdca36 --- /dev/null +++ b/.github/workflows/transifex.yml @@ -0,0 +1,27 @@ +name: Transifex 🗺 + +on: + push: + branches: + - master + paths: + - '**.py' + - '**.ui' + +jobs: + build: + runs-on: ubuntu-latest + if: github.repository_owner == 'ghtmtt' + steps: + - uses: actions/checkout@v2 + + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install Python requirements + run: pip install qgis-plugin-ci + + - name: Push to Transifex + run: qgis-plugin-ci push-translation ${{ secrets.TRANSIFEX_TOKEN }} diff --git a/.tx/config b/.tx/config deleted file mode 100644 index b3df46d1..00000000 --- a/.tx/config +++ /dev/null @@ -1,10 +0,0 @@ -[main] -host = https://www.transifex.com - -[dataplotly-ui.application] -file_filter = DataPlotly/i18n/DataPlotly_<lang>.ts -source_file = DataPlotly/i18n/DataPlotly_en.ts -source_lang = en - -trans.it = DataPlotly/i18n/DataPlotly_it.ts -type = QT diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..bc0afeab --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,126 @@ +# Changelog + +## Unreleased + +- Fix "Build a generic plot" processing algorithm. Kudos to @agiudiceandrea +- Fix #237 add data-driven color to Polar Plot marker color. Kudos to @jmonticolo + +## 3.9.0 - 2022-04-11 + +- Customize font for plot title and plot axis. Kudos to @giliam +- Support for Python 3.10 + +## 3.8.1 - 2021-09-28 + +- bugfix + +## 3.8.0 - 2021-09-28 + +- [feature] expose DataPlotly on QGIS Server for a GetPrint request kudos to @Gustry + +## 3.7.1 - 2020-05-15 + +- bugfix + +## 3.7.0 + +- [feature] histogram and pie chart bar and slices with same color of category! kudos to @jdugge +- [feature] plot background transparent in layouts! + +## 3.6.0 + +- [feature] Multi Plot in layout composer! Ultra kudos to @SGroe +- [bugfix] Fix layout composer issue with many plots (ref #207). Thanks to the Italian Community for testing +- [bugfix] Fix categorical bar plot wrong behavior +- [bugfix] code cleaning + +## 3.5.0 + +- [bugfix] Fix loading old projects + +## 3.4.0 + +- [feature] get labels within the plot itself +- [bugfix] Native datetime support! thanks @jdugge +- [bugfix] Fix histogram selection + +## 3.3.0 + +- [bugfix] better loading project part 2 + +## 3.2.0 + +- [bugfix] fix violin plot bug +- [bugfix] better loading project handling + +## 3.1.0 + +- [feature] more data defined options available (in layout customization). Thanks @SGroe +- [feature] X and Y axis bounds limits. Thanks @SGroe +- [feature] add box plot within violin plots +- [feature] renaming of plugin metadata to better search. Thanks @Gustry +- [bugfix] Box plot not working when no group is selected +- [bugfix] Data-defined property overrides do not work in layout + +## 3.0.0 + +- [feature] total refactoring of the code +- [feature] plots also in print composer +- [feature] atlas based plots +- [feature] chance to save/load configuration file of plot setting +- [feature] plot settings saved together with the project +- [feature] more datadefined properties +- [feature] show only selected/visible/filtered features +- [feature] unit tests and continuous integration + +## 2.3.0 + +- [feature] tweaks polar plots, thanks @josephholler + +## 2.2.0 + +- [feature] UI tweaks, thanks @nyalldawson + +## 2.1.0 + +- [fix] typos in UI (thanks @leonmvd and @nyalldawson) +- [fix] better python packages imports (thanks @nyalldawson) + +## 2.0.0 + +- [feature] DataPlotly is updated with plotly 3.3 version + +## 1.6.0 + +- [feature] wheel zoom! Give it a try +- [feature] Edit plot title and X/Y labels in place + +## 1.5.1 + +- [feature] Spanish translation. Special thanks to Luca Bellani +- [bugfix] always open English manual if locale not translated + +## 1.5.0 + +- [feature] **new** Violin plots! +- [feature] **new** Polar plot layout! +- [feature] better default color choice + +## 1.4.3 + +- [bugfix] correct interaction with pie plot +- update plotly.js to v 1.34.0 + +## 1.4.2 + +- [bugfix] correct saving html plot + +## 1.4.1 + +- [bugfixing] adaptation for new API + +## 1.4.0 + +- [feature] update plotly.js to v 1.33.1 +- [feature] multiple selection with Shift + selection tool +- [feature] DataPlotly as Processing provider, thanks to Michaël Douchin of 3Liz diff --git a/DataPlotly/data_plotly.py b/DataPlotly/data_plotly.py index 624f0877..97e0e523 100644 --- a/DataPlotly/data_plotly.py +++ b/DataPlotly/data_plotly.py @@ -22,7 +22,7 @@ """ import os.path -from qgis.PyQt.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QUrl +from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt, QUrl from qgis.PyQt.QtGui import QDesktopServices from qgis.PyQt.QtWidgets import QAction from qgis.core import Qgis, QgsApplication @@ -67,14 +67,12 @@ def __init__(self, iface): locale_path = os.path.join( self.plugin_dir, 'i18n', - 'DataPlotly_{}.qm'.format(locale)) + 'application_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) - - if qVersion() > '4.3.3': - QCoreApplication.installTranslator(self.translator) + QCoreApplication.installTranslator(self.translator) self.dock_widget = None self.show_dock_action = None diff --git a/DataPlotly/i18n/DataPlotly_af.qm b/DataPlotly/i18n/DataPlotly_af.qm deleted file mode 100644 index 5f6ea32fb5f2cd4b2af738cd25657feaf2c8e2e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95 zcmcE7ks@*G{hX<16=n7(EZlq7iGhKEgQH){97r={0<kSKkPu;TXUJzr1q!4xC@|y# o*+mSg93UlZK+NNwpP!<Tn_rZdnU~HE6yR`3Nli;E%_(670G%HeTmS$7 diff --git a/DataPlotly/i18n/DataPlotly_af.ts b/DataPlotly/i18n/DataPlotly_af.ts deleted file mode 100644 index 925c6ece..00000000 --- a/DataPlotly/i18n/DataPlotly_af.ts +++ /dev/null @@ -1,874 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS><TS version="2.0"> -<context> - <name>@default</name> - <message> - <location filename="../test/test_translations.py" line="48"/> - <source>Good morning</source> - <translation>Goeie more</translation> - </message> -</context> -<context> - <name>DataPlotly</name> - <message> - <location filename="../data_plotly.py" line="116"/> - <source>DataPlotly</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="272"/> - <source>Plot Item</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../data_plotly.py" line="105"/> - <source>&DataPlotly</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../data_plotly.py" line="119"/> - <source>Shows the DataPlotly dock</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyDock</name> - <message> - <location filename="../gui/dock.py" line="24"/> - <source>DataPlotly</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyDockWidgetBase</name> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="14"/> - <source>DataPlotly</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="440"/> - <source>Plot Parameters</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="500"/> - <source>Z field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="480"/> - <source>Use only selected features</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="487"/> - <source>Layer</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="240"/> - <source>Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="382"/> - <source>Marker type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1022"/> - <source>...</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="336"/> - <source>Visible</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="742"/> - <source>Bar orientation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1078"/> - <source>Normalization</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="710"/> - <source>Outliers</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="914"/> - <source>Bar gap</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1015"/> - <source>Violin side</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1157"/> - <source>Clean Plot Canvas</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1180"/> - <source>Update Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1202"/> - <source>Create Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1261"/> - <source>Export as image</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1280"/> - <source>Export as html</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="169"/> - <source>Plot type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="246"/> - <source>Line type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="253"/> - <source>Point type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="265"/> - <source>Show lines</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="277"/> - <source>Marker color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="284"/> - <source>Stroke color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="355"/> - <source>Color scale</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="321"/> - <source>Marker size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="346"/> - <source>Invert color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="392"/> - <source>Stroke width</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="399"/> - <source>Opacity</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="416"/> - <source>Contour type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="460"/> - <source>Linked map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="470"/> - <source>Use only visible features</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="446"/> - <source>Feature subset</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="510"/> - <source>Y field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="535"/> - <source>X field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="555"/> - <source>Use only features visible in map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="562"/> - <source>Use only features inside atlas feature</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1108"/> - <source>Type of plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1120"/> - <source>Plot in columns</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1127"/> - <source>Plot in rows</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1209"/> - <source>Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1297"/> - <source>Dynamically update size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="677"/> - <source>Show legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="687"/> - <source>Horizontal legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="694"/> - <source>Show range slider</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="813"/> - <source>Invert histogram direction</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="823"/> - <source>Cumulative histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="856"/> - <source>Hover tooltip</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="849"/> - <source>Bar mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="877"/> - <source>Show statistics</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1008"/> - <source>Z label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="752"/> - <source>Set X Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="954"/> - <source>Minimum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="971"/> - <source>Maximum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="870"/> - <source>X axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="991"/> - <source>Y axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="897"/> - <source>Show mean line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="921"/> - <source>Invert Y axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="890"/> - <source>Legend title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="907"/> - <source>X label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="665"/> - <source>Additional hover label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1001"/> - <source>Manual bin size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="842"/> - <source>Invert X axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="703"/> - <source>Plot title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="935"/> - <source>Y label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="942"/> - <source>Set Y Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1065"/> - <source>If checked, box plots will be overlaid on top of violin plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1068"/> - <source>Include box plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="863"/> - <source>Hover label as text</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1085"/> - <source>Label text position</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyPanelWidget</name> - <message> - <location filename="../gui/plot_settings_widget.py" line="104"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="131"/> - <source>Load Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="133"/> - <source>Save Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="572"/> - <source>None</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="176"/> - <source>Single Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="177"/> - <source>Subplots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="560"/> - <source>Vertical</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="561"/> - <source>Horizontal</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="565"/> - <source>No Outliers</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="566"/> - <source>Standard Outliers</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="567"/> - <source>Suspected Outliers</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="568"/> - <source>All Points</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="573"/> - <source>Mean</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="574"/> - <source>Standard Deviation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="582"/> - <source>Linear</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="583"/> - <source>Logarithmic</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="584"/> - <source>Categorized</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="887"/> - <source>Points</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="896"/> - <source>Lines</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="587"/> - <source>Points and Lines</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Solid Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dash Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Dash Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Dot Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="647"/> - <source>Grouped</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="648"/> - <source>Stacked</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="649"/> - <source>Overlay</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="653"/> - <source>Enumerated</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="654"/> - <source>Percents</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="655"/> - <source>Probability</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="656"/> - <source>Density</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="657"/> - <source>Prob Density</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Fill</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Heatmap</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Only Lines</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="696"/> - <source>Grouping field -(optional)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="702"/> - <source>Box orientation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="703"/> - <source>Box color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="706"/> - <source>X field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="710"/> - <source>Marker color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="712"/> - <source>Bar orientation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="713"/> - <source>Bar color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="716"/> - <source>Grouping field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="724"/> - <source>All Values</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="725"/> - <source>X Values</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="726"/> - <source>Y Values</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="727"/> - <source>No Data</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="737"/> - <source>Both Sides</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="738"/> - <source>Only Left</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="739"/> - <source>Only right</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1208"/> - <source>{} plot is not compatible for subplotting - see </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1295"/> - <source>Save Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>DataPlotly</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1284"/> - <source>Plot saved to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1303"/> - <source>Saved plot to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1420"/> - <source>Load Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1427"/> - <source>Could not read settings from file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1433"/> - <source>Save Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>Saved configuration to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="731"/> - <source>Automatic</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="732"/> - <source>Inside bar</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="733"/> - <source>Outside bar</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyProcessingPlot</name> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="88"/> - <source>Input layer</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="95"/> - <source>Plot type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="103"/> - <source>Plot title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="111"/> - <source>X Field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="121"/> - <source>Y Field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="131"/> - <source>Color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="140"/> - <source>Color (any valid HTML color) If set, this is used instead of the color set in the previous input.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML File</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML files (*.html)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON Files (*.json)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="170"/> - <source>Build a generic plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="176"/> - <source>Plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="209"/> - <source>The chosen plot type needs a X field !</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="211"/> - <source>The chosen plot type needs a Y field !</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="173"/> - <source>Creates a generic Plotly plot</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PlotLayoutItemWidget</name> - <message> - <location filename="../gui/layout_item_gui.py" line="82"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="77"/> - <source>Setup Selected Plot</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PlotType</name> - <message> - <location filename="../core/plot_types/histogram2d.py" line="28"/> - <source>2D Histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/box.py" line="28"/> - <source>Box Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/histogram.py" line="28"/> - <source>Histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/bar_plot.py" line="27"/> - <source>Bar Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/scatter.py" line="28"/> - <source>Scatter Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/violin.py" line="28"/> - <source>Violin Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/polar.py" line="28"/> - <source>Polar Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/contour.py" line="28"/> - <source>Contour Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/ternary.py" line="28"/> - <source>Ternary Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/pie.py" line="28"/> - <source>Pie Chart</source> - <translation type="unfinished"></translation> - </message> -</context> -</TS> diff --git a/DataPlotly/i18n/DataPlotly_en.qm b/DataPlotly/i18n/DataPlotly_en.qm deleted file mode 100644 index be651eed..00000000 --- a/DataPlotly/i18n/DataPlotly_en.qm +++ /dev/null @@ -1 +0,0 @@ -<�d��!�`��� \ No newline at end of file diff --git a/DataPlotly/i18n/DataPlotly_en.ts b/DataPlotly/i18n/DataPlotly_en.ts deleted file mode 100644 index e23ea855..00000000 --- a/DataPlotly/i18n/DataPlotly_en.ts +++ /dev/null @@ -1,874 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS><TS version="2.0"> -<context> - <name>@default</name> - <message> - <location filename="../test/test_translations.py" line="48"/> - <source>Good morning</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotly</name> - <message> - <location filename="../data_plotly.py" line="116"/> - <source>DataPlotly</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="272"/> - <source>Plot Item</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../data_plotly.py" line="105"/> - <source>&DataPlotly</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../data_plotly.py" line="119"/> - <source>Shows the DataPlotly dock</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyDock</name> - <message> - <location filename="../gui/dock.py" line="24"/> - <source>DataPlotly</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyDockWidgetBase</name> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="14"/> - <source>DataPlotly</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="440"/> - <source>Plot Parameters</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="500"/> - <source>Z field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="480"/> - <source>Use only selected features</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="487"/> - <source>Layer</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="240"/> - <source>Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="382"/> - <source>Marker type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1022"/> - <source>...</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="336"/> - <source>Visible</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="742"/> - <source>Bar orientation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1078"/> - <source>Normalization</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="710"/> - <source>Outliers</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="914"/> - <source>Bar gap</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1015"/> - <source>Violin side</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1157"/> - <source>Clean Plot Canvas</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1180"/> - <source>Update Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1202"/> - <source>Create Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1261"/> - <source>Export as image</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1280"/> - <source>Export as html</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="169"/> - <source>Plot type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="246"/> - <source>Line type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="253"/> - <source>Point type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="265"/> - <source>Show lines</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="277"/> - <source>Marker color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="284"/> - <source>Stroke color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="355"/> - <source>Color scale</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="321"/> - <source>Marker size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="346"/> - <source>Invert color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="392"/> - <source>Stroke width</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="399"/> - <source>Opacity</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="416"/> - <source>Contour type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="460"/> - <source>Linked map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="470"/> - <source>Use only visible features</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="446"/> - <source>Feature subset</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="510"/> - <source>Y field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="535"/> - <source>X field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="555"/> - <source>Use only features visible in map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="562"/> - <source>Use only features inside atlas feature</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1108"/> - <source>Type of plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1120"/> - <source>Plot in columns</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1127"/> - <source>Plot in rows</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1209"/> - <source>Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1297"/> - <source>Dynamically update size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="677"/> - <source>Show legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="687"/> - <source>Horizontal legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="694"/> - <source>Show range slider</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="813"/> - <source>Invert histogram direction</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="823"/> - <source>Cumulative histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="856"/> - <source>Hover tooltip</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="849"/> - <source>Bar mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="877"/> - <source>Show statistics</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1008"/> - <source>Z label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="752"/> - <source>Set X Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="954"/> - <source>Minimum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="971"/> - <source>Maximum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="870"/> - <source>X axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="991"/> - <source>Y axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="897"/> - <source>Show mean line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="921"/> - <source>Invert Y axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="890"/> - <source>Legend title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="907"/> - <source>X label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="665"/> - <source>Additional hover label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1001"/> - <source>Manual bin size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="842"/> - <source>Invert X axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="703"/> - <source>Plot title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="935"/> - <source>Y label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="942"/> - <source>Set Y Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1065"/> - <source>If checked, box plots will be overlaid on top of violin plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1068"/> - <source>Include box plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="863"/> - <source>Hover label as text</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1085"/> - <source>Label text position</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyPanelWidget</name> - <message> - <location filename="../gui/plot_settings_widget.py" line="104"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="131"/> - <source>Load Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="133"/> - <source>Save Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="572"/> - <source>None</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="176"/> - <source>Single Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="177"/> - <source>Subplots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="560"/> - <source>Vertical</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="561"/> - <source>Horizontal</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="565"/> - <source>No Outliers</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="566"/> - <source>Standard Outliers</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="567"/> - <source>Suspected Outliers</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="568"/> - <source>All Points</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="573"/> - <source>Mean</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="574"/> - <source>Standard Deviation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="582"/> - <source>Linear</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="583"/> - <source>Logarithmic</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="584"/> - <source>Categorized</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="887"/> - <source>Points</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="896"/> - <source>Lines</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="587"/> - <source>Points and Lines</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Solid Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dash Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Dash Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Dot Line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="647"/> - <source>Grouped</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="648"/> - <source>Stacked</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="649"/> - <source>Overlay</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="653"/> - <source>Enumerated</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="654"/> - <source>Percents</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="655"/> - <source>Probability</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="656"/> - <source>Density</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="657"/> - <source>Prob Density</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Fill</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Heatmap</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Only Lines</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="696"/> - <source>Grouping field -(optional)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="702"/> - <source>Box orientation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="703"/> - <source>Box color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="706"/> - <source>X field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="710"/> - <source>Marker color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="712"/> - <source>Bar orientation</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="713"/> - <source>Bar color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="716"/> - <source>Grouping field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="724"/> - <source>All Values</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="725"/> - <source>X Values</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="726"/> - <source>Y Values</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="727"/> - <source>No Data</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="737"/> - <source>Both Sides</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="738"/> - <source>Only Left</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="739"/> - <source>Only right</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1208"/> - <source>{} plot is not compatible for subplotting - see </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1295"/> - <source>Save Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>DataPlotly</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1284"/> - <source>Plot saved to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1303"/> - <source>Saved plot to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1420"/> - <source>Load Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1427"/> - <source>Could not read settings from file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1433"/> - <source>Save Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>Saved configuration to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="731"/> - <source>Automatic</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="732"/> - <source>Inside bar</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="733"/> - <source>Outside bar</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyProcessingPlot</name> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="88"/> - <source>Input layer</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="95"/> - <source>Plot type</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="103"/> - <source>Plot title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="111"/> - <source>X Field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="121"/> - <source>Y Field</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="131"/> - <source>Color</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="140"/> - <source>Color (any valid HTML color) If set, this is used instead of the color set in the previous input.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML File</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML files (*.html)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON Files (*.json)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="170"/> - <source>Build a generic plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="176"/> - <source>Plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="209"/> - <source>The chosen plot type needs a X field !</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="211"/> - <source>The chosen plot type needs a Y field !</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="173"/> - <source>Creates a generic Plotly plot</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PlotLayoutItemWidget</name> - <message> - <location filename="../gui/layout_item_gui.py" line="82"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="77"/> - <source>Setup Selected Plot</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PlotType</name> - <message> - <location filename="../core/plot_types/histogram2d.py" line="28"/> - <source>2D Histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/box.py" line="28"/> - <source>Box Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/histogram.py" line="28"/> - <source>Histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/bar_plot.py" line="27"/> - <source>Bar Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/scatter.py" line="28"/> - <source>Scatter Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/violin.py" line="28"/> - <source>Violin Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/polar.py" line="28"/> - <source>Polar Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/contour.py" line="28"/> - <source>Contour Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/ternary.py" line="28"/> - <source>Ternary Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../core/plot_types/pie.py" line="28"/> - <source>Pie Chart</source> - <translation type="unfinished"></translation> - </message> -</context> -</TS> diff --git a/DataPlotly/i18n/DataPlotly_es.qm b/DataPlotly/i18n/DataPlotly_es.qm deleted file mode 100644 index 3cf4c7f2eaae131a519edf61caa204fda6b36dc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10951 zcmcIqdu-hF9slNW@5`l4(~yR=xDQI&W#Li8G!06d2W`5viAY)+B+#5YCvoeu51%h- z%G$vI?TL_>Itt<sx`DbOrcIzuFb&2iMH?y`8XbeJLt;bP5Q7a^hYC#W^ZohG_9b^` zvoW<7$3Fi)zwi6?%jJ(|+MoUVy@#G#+4-|C9C`eYy+jR%i7rkN)g_1y-%7OjC)D_S zH?CJu=yL~&mR?AqT?0gI5gJ&!fheNVmbO-+_%hm-o*-KO5M6!8Q$&p?XteP-(Gr8M zx$F_5RaemN!Whxor|8<d4-q8{dgp?diKIn!Ef4*TsO62it51E0C^T$eTYp#g{oC#* zI`8tjQxhABmYuA7MO^{94%yeHC+c3i<ruzysy?#(0qoaOKmM)Npr@|>_~dOwi#FCD z|E)<BGwNT=K8owp4Lv*hK<D!f*&n`x_j3)$uEc%E>kY>afX}wRhLgh<*1gwQ|F2t! z&Uw2rd^2!YZfx9e2K?6VZQS#zKM^$<jkE76SpQMuH#Vn1&)HDx_uhtFvZ0GU|7GyI zAvEzKzK<RZ-SCxBqU4FtObGm+b1ZcGb^Vafg`uY(TMe9Lp<iso`g8BXHBZ#p5$=7d z9`g8Nc>MU?M090XKKu$%`1-KYeFk(L4Ntwd6S!UWb>&~ev*Nuk6|c|Q*9P6bHXjS$ zbTRhr=n3DnAM~&MX83{Ge-f?vAbj#p$o-tI@W~gy3%p-PB=uhC{jtc)Cq7Hmek8i- ze9(FRtI>hk*YN(s(Oa`mg3ry-J32lCx+wbU2O-Gg=g~iJYs7nFvGHGl{v{8_W^V*u ztTXn&<O!nYiP#HA4`96!JAE8_T5=|K`u(S&|26S-%YYj<<5#|qYePqT=tIbT^&9c) zG{_@$UVKkC<d9P18b42bWM9wyL;UCwyua-B_%X&k|7iTgeP^-HzZ0SRbCBQl34ycb z(}`=2ybFEanGoxfn-kVQZh>7qmpE`3`?sA=+_hl|<Z>w4x_&9_?ZIU0U;%OtCp#j* zUpt$$*WHpV4B@{0t>o99d;#*xChz(1r_k5V<ilryAAYzg@;a_df7BE^i}i`eo8rG* z20QL-`u$7rpXGl|t-7ZX^es(&`x(f6@m%WBM<B<R`%-65t%II_(>(EY*vYcZ%?BTn z;U70QAN&EXt1oLleF}WF4>rHD=LyK+$IWlaXNX#FP>C)`H9!Gv)Jp|YNGF5xBvFRm zB$@J2R!$h7<QBuoNLj<wRedUg2hmL#Wl}C^R-L_kE%jr8h0h3S0I~3M&RL#V+b>)4 zh-O&Y9IuYMw_^P&tX8phicI{>;=?2;;wPhmC<n{4wh~lpO+w}^PPugS8|l4*mN513 zKWD#&o}M1wsJ;B%Yt+n?V)e>-MXZu&0D{Yb@-#Rx9Qu3l#AL1<yhyKXN>g&qAG3>w zu~HRkVaYP`yHHU{HVd(v8QU;bMYm*2HFW<yE~O!$W<fd2-vl<_vmxyFa4}Ci4lj%Q zG)2}WR;<(~>oaoRf5#O<Qfcg_;Zx$J54*A5m=1QL&(I80%BN*b@kf<t40Pu_G&7<u zY{z7?c5st@hHe=JQ?llA0f0NH4`NY@!l@>RM4ze1mLeqKPwdCC(b{&$(%dKbHih@G z23e|GahD~{;W{<2FK3vRB<H1RE35g_xT*^9pm5JAHW3HB*#%d#@>C$H4niq2Kw+{~ zVR#EoAUUYdC?Gn`mf%lv6snTh2OYvfL-L#wU}eVw>lq>@5Nda@VneE~1T>meprmNe zj)iX*Cd781DYNtBcG=vkm_eCb15)h}`L@T{tAQtq;CXd_0Ie)^B0t<<KGZ=wm}Ox( z8nnG192A3@Bi^PRhMAQ$b$`IX)j_*}B0>g4%uZklKh1hvJvv;lG*vMJM5S)zEslS$ zf=ER`l@cLmp=xg5EF#~CY|2^13baqxd@P`Iw3Uh$Q^5W@C~@<hy@#r^ffTZO0A4C( zQ+toAAbgIxE_zaM0Cdxs4FJ8+LaK=-CV+$5$Nb<uf@(wrZ^u63BZjJ50sXHH+B9Ku zoYfTg8~dE%;W|EI8aYH3RSCdzCv68*UKoX&B1LfULXJ)wvyz4w5eRZ&d>8}8GG|?f z<>aVk8he$Xk)e||LuP53_QZwiptEYmn)Z*W!4;kyLq3&^NhybFz#n)ms7*tr1u$KT z37ovD*;8U?E)zV%?xvm4n60fm<iT-5vP~aX4#F&K-k&p&DzvML=Un~f@l?YnjelIs zu|u*E<vnF#$Id*s)wMY(uV_lzQZmvcN`QhHME`B5vg|w{A&l`B8VYVVp(b{z224rH ztC;{{J0&pkz?opO9s7ywQuFFWkm@NVGACDoET-Kq!ft6&RkV!1I?EBpU4-%f4&hoC z;o6`GY^#RIuB=2>IbU<7P~vsg&6*~OfFhiAsax8Q$hxB0wSBQOsf6jKp0cRIsJmpX zV4FY<R4yv#*9Qx$`50I8PVG|z?vrU0YHZL3XU)R8Y>Ad^*UcjFUc;J}Mq#af^6aR< zIah6ayp>k3u`dwcYkeA|`M}K#Jg+^f!F9Xv3Jwud;GDw*7cQvY9NSFvAtX%!alayb zqy`u_R&a5ExlPX&n5G?Hyk->Zm-EvSSDWm1H6TA$8&Lyi5rQt)2OL2}u5|c|^ecK^ zwM5Te1K<)r-r$CF_&8bJ<BCoF=pBP{yrRNJl|Z8m8bE?AC>(Vtfonca2wvUB2lPT# zF`-~T)u!lbtk*d90?oCK#;a6KbXqk;w+NoaQ;!1oEoJ*hwwOjC=ezm(ve0c0O}vm< zD3!^=5XDhzN<d?h<3`pRByI}619Z%>DCfzW8m)8o?I_<@igy_~9#hELIv-Q-Kn*5Z zJM3Wd$i7`ZFo<kL{>|Ehl^X1{qBkyivppdIkV9g8D|<601hSvzlCVV;f@Ozx*N55a zWYKcgpn=zxf`J=FL%h~6fO6?zz+||Bc@tV?{iZ#-O$-@RvZ-3rSvBn=)J+~LN@DeR zQ_*S5f)t){^fyIBbSZBcGGI)?ivxOIPldgM?38kM3gF-WQy*SKe~XI!1;>pH6yUm6 z<8}<heB|Cjqr!5y*quM!jO;KVM@#mBSmi*trAW0dH~~m+BV2>86dHB5=_ye&dAQnP z_-3O{kW?zP2azdn5Xp_>DsqbBU$J2>nTM1~(IV6!rOg9Z$ywqyPyml<_aJei<7pmu zNiI<~mZ?rn`%%>jEDqI-!o@PXzdN#w3}alS$$sgQyHk!pX)NZz%+-�Emt#W*Q@0 zzfh2@m{7xk>e?0FwM9>_B<4jnnk4HPkx>0;;@Jap<<t_uwtMjj@LArUB+-RWNWn^s z_A(TnV$82q5{xEKsG5JhA`yog4r5&I)ap88qw<V9)vaN!?Pc+76m$9_g^uONN72&R zLiBO&6lwyVT=1mETaiRYEjhi{w<6%97?=~Lt31+o4-NR4g#lNQYlpBF!0H*<%s>@0 zsxyA8!EAT+*&Eb7P-UOR&OQO7QKdOnmfnY4cx0Tz)$MhoqlF0`Jowq?MKww1Q30Rg z*a3oncVl47Xd$1o8~uRvFT!3ND41FvIk;6qbQcewaI)cJ2`#i60(C=tS(Mlvtk*2> z%q#cyHFVuV<JCzR4@Sa1x{(eD%h2$1-h>BF_|%cdpxmybmO)L!#W0Ia1dQTS9+I+4 zNW!w&mfcQ@qw>T8WcLv7!W$2Wxs;^lB^|v%+Q{Z$=@^bklYGcz8;^yOIF5OaBKhd$ za?!<dl;fc@H*p+9cw||Ly)9r(r`PdLd8yXgTTr!(Bui6@u9#}N(&P+5Ev@A9AdKg! zVk8k4o0r$VA#qs7RC|t#Dy)6RT?<mXaA(io++<xEM00}TW27-u-b46p29d)KX$Gys zJqLI`YGOCE&AS`-whjyUR)j9`#MWD(ShL!NCffmPT5y5i?V^J-v%6A;&`R?;riP0x z`-!VpS@11&$@-i$gVTeIv~_IzkUczDCk;+QnO3)CO+)SYU&v!hr|Nl2kuyB0w5E&0 zRelX$hzB_nQP3!0fu1W^^N)Tj$n=vjhUNANV%}p8tZ@`e73QfGsAxyh;F4k*vYZkA zRMedl=VL-N=t<{~6f2;0&qHI+bZw!F*5inL8rs1Tqo==HB6gU>4tc3-eGeZripH+C zO|F0ymiKl8LeF+X?pA4uK~{)_`f9<EUO*1Ep?VueiOZJH9PEL$aSi8os7tnu4)2gy zMuLMqc|#At!9v*=cXDMfa9J|`KFTM2Dr8#_-cf4I=0!~hInGuhS*jHTI`}ld>hVnl zQMW7zyl!V0V)8^%u5APpbOeP1hXp&gyMIA3k8!+V59g;KBvePZ=OUbIX%0ztQm`X2 z=Uiu|O)DLdtsP^(pEmM}ZYKpkrIK_-$*}hoN8Zv(e@*?ri5?G3baBcagy<Uez*QAy z{T1|Gj!-u14~Wo#U}7J-@F;^FJ&TV-mr%c>rQ{|3(pEKZ8B;i2WnDzsl=zTIWWhBH zjIQJ<+-QhDx$#UHqdZFI^$US6tqR2UgSj;5;^E~4DCRjZrzF?DqdZcs47|PuuswL< ztj4vE3+McCN@Yl%T`iECBe7TwadlQ8hPzNMsN4n?hpbvvL9IvE#0TV)Ac1ptN!~mF zv5RI?xFG&S$ss8@nwBk`j8_p+r3!xx@@28G61|g^<d|aWvN=};s=7Ut4%kp*ICPZ` P*cOWUtFW~Cy1M@WFY&v^ diff --git a/DataPlotly/i18n/DataPlotly_es.ts b/DataPlotly/i18n/DataPlotly_es.ts deleted file mode 100644 index aa29f09f..00000000 --- a/DataPlotly/i18n/DataPlotly_es.ts +++ /dev/null @@ -1,874 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS><TS version="2.0" language="es" sourcelanguage=""> -<context> - <name>@default</name> - <message> - <location filename="../test/test_translations.py" line="48"/> - <source>Good morning</source> - <translation>Buenos días</translation> - </message> -</context> -<context> - <name>DataPlotly</name> - <message> - <location filename="../data_plotly.py" line="116"/> - <source>DataPlotly</source> - <translation>Diagrama de datos</translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="272"/> - <source>Plot Item</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../data_plotly.py" line="105"/> - <source>&DataPlotly</source> - <translation>&DataPlotly</translation> - </message> - <message> - <location filename="../data_plotly.py" line="119"/> - <source>Shows the DataPlotly dock</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyDock</name> - <message> - <location filename="../gui/dock.py" line="24"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> -</context> -<context> - <name>DataPlotlyDockWidgetBase</name> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="14"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="440"/> - <source>Plot Parameters</source> - <translation>Parámetros de Diagrama</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="500"/> - <source>Z field</source> - <translation>Campo Z</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="480"/> - <source>Use only selected features</source> - <translation>Usar solo las caracteristicas seleccionadas.</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="487"/> - <source>Layer</source> - <translation>Capa</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="240"/> - <source>Properties</source> - <translation>Propiedades</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="382"/> - <source>Marker type</source> - <translation>Tipo de Marcador</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1022"/> - <source>...</source> - <translation>...</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="336"/> - <source>Visible</source> - <translation>Visible</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="742"/> - <source>Bar orientation</source> - <translation>Orientación de Barra</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1078"/> - <source>Normalization</source> - <translation>Normalización</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="710"/> - <source>Outliers</source> - <translation>Valor Extremo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="914"/> - <source>Bar gap</source> - <translation>Espacio de Barra</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1015"/> - <source>Violin side</source> - <translation>Lado Violín</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1157"/> - <source>Clean Plot Canvas</source> - <translation>Limpiar Lienzo de Diagrama</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1180"/> - <source>Update Plot</source> - <translation>Actualizar Diagrama</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1202"/> - <source>Create Plot</source> - <translation>Crear Diagrama</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1261"/> - <source>Export as image</source> - <translation>Exportar a Imagen</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1280"/> - <source>Export as html</source> - <translation>Exportar a Html</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="169"/> - <source>Plot type</source> - <translation>Tipo de Diagrama</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="246"/> - <source>Line type</source> - <translation>Tipo de LInea</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="253"/> - <source>Point type</source> - <translation>Tipo de Punto</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="265"/> - <source>Show lines</source> - <translation>Mostrar Lineas</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="277"/> - <source>Marker color</source> - <translation>Color de Marcador</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="284"/> - <source>Stroke color</source> - <translation>Color de Trazo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="355"/> - <source>Color scale</source> - <translation>Escala de Color</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="321"/> - <source>Marker size</source> - <translation>Tamaño de Marcador</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="346"/> - <source>Invert color</source> - <translation>Invertir Color</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="392"/> - <source>Stroke width</source> - <translation>Ancho de Trazo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="399"/> - <source>Opacity</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="416"/> - <source>Contour type</source> - <translation>Tipo de Contorno</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="460"/> - <source>Linked map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="470"/> - <source>Use only visible features</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="446"/> - <source>Feature subset</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="510"/> - <source>Y field</source> - <translation>Campo Y</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="535"/> - <source>X field</source> - <translation>Campo X</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="555"/> - <source>Use only features visible in map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="562"/> - <source>Use only features inside atlas feature</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1108"/> - <source>Type of plot</source> - <translation>Tipo de Diagrama</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1120"/> - <source>Plot in columns</source> - <translation>Diagrama en Columnas</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1127"/> - <source>Plot in rows</source> - <translation>Diagrama en Filas</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1209"/> - <source>Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1297"/> - <source>Dynamically update size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="677"/> - <source>Show legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="687"/> - <source>Horizontal legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="694"/> - <source>Show range slider</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="813"/> - <source>Invert histogram direction</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="823"/> - <source>Cumulative histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="856"/> - <source>Hover tooltip</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="849"/> - <source>Bar mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="877"/> - <source>Show statistics</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1008"/> - <source>Z label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="752"/> - <source>Set X Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="954"/> - <source>Minimum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="971"/> - <source>Maximum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="870"/> - <source>X axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="991"/> - <source>Y axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="897"/> - <source>Show mean line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="921"/> - <source>Invert Y axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="890"/> - <source>Legend title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="907"/> - <source>X label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="665"/> - <source>Additional hover label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1001"/> - <source>Manual bin size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="842"/> - <source>Invert X axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="703"/> - <source>Plot title</source> - <translation type="unfinished">Titulo de Diagrama</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="935"/> - <source>Y label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="942"/> - <source>Set Y Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1065"/> - <source>If checked, box plots will be overlaid on top of violin plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1068"/> - <source>Include box plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="863"/> - <source>Hover label as text</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1085"/> - <source>Label text position</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyPanelWidget</name> - <message> - <location filename="../gui/plot_settings_widget.py" line="104"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="131"/> - <source>Load Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="133"/> - <source>Save Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="572"/> - <source>None</source> - <translation>Ninguno</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="176"/> - <source>Single Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="177"/> - <source>Subplots</source> - <translation>Diagrama múltiple</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="560"/> - <source>Vertical</source> - <translation>Vertical</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="561"/> - <source>Horizontal</source> - <translation>Horizontal</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="565"/> - <source>No Outliers</source> - <translation>Sin Valor Extremo</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="566"/> - <source>Standard Outliers</source> - <translation>Valor Extremo Estárdar</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="567"/> - <source>Suspected Outliers</source> - <translation>Valor Extremo sospechoso</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="568"/> - <source>All Points</source> - <translation>Todos los puntos</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="573"/> - <source>Mean</source> - <translation>Promedio</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="574"/> - <source>Standard Deviation</source> - <translation>Desviación estárdar</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="582"/> - <source>Linear</source> - <translation>Lineal</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="583"/> - <source>Logarithmic</source> - <translation>Logarítmico</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="584"/> - <source>Categorized</source> - <translation>Categorizado</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="887"/> - <source>Points</source> - <translation>Puntos</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="896"/> - <source>Lines</source> - <translation>Líneas</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="587"/> - <source>Points and Lines</source> - <translation>Puntos y Líneas</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Solid Line</source> - <translation>Línea Sólida</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Line</source> - <translation>Línea de Puntos</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dash Line</source> - <translation>Línea de Guiones</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Line</source> - <translation>Línea de Guiones Largos</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Dash Line</source> - <translation>Línea de Guiones y Puntos</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Dot Line</source> - <translation>Línea de Puntos y Guiones Largos</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="647"/> - <source>Grouped</source> - <translation>Agrupado</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="648"/> - <source>Stacked</source> - <translation>Apilado</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="649"/> - <source>Overlay</source> - <translation>Superponer</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="653"/> - <source>Enumerated</source> - <translation>Enumerado</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="654"/> - <source>Percents</source> - <translation>Porcentajes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="655"/> - <source>Probability</source> - <translation>Probabilidad</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="656"/> - <source>Density</source> - <translation>Densidad</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="657"/> - <source>Prob Density</source> - <translation>Densidad Probable</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Fill</source> - <translation>Relleno</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Heatmap</source> - <translation>Mapa de Calor</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Only Lines</source> - <translation>Solo Líneas</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="696"/> - <source>Grouping field -(optional)</source> - <translation>Campo de Agrupamiento (Opcional)</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="702"/> - <source>Box orientation</source> - <translation>Orientación de Caja</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="703"/> - <source>Box color</source> - <translation>Color de Caja</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="706"/> - <source>X field</source> - <translation>Campo X</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="710"/> - <source>Marker color</source> - <translation>Color de Marcador</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="712"/> - <source>Bar orientation</source> - <translation>Orientación de Barra</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="713"/> - <source>Bar color</source> - <translation>Color de Barra</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="716"/> - <source>Grouping field</source> - <translation>Campo de Agrupamiento</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="724"/> - <source>All Values</source> - <translation>Todos los Valores</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="725"/> - <source>X Values</source> - <translation>X Valores</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="726"/> - <source>Y Values</source> - <translation>Y Valores</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="727"/> - <source>No Data</source> - <translation>Sin Datos</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="737"/> - <source>Both Sides</source> - <translation>Ambos Lados</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="738"/> - <source>Only Left</source> - <translation>Solo Izquierda</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="739"/> - <source>Only right</source> - <translation>Solo Derecha</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1208"/> - <source>{} plot is not compatible for subplotting - see </source> - <translation>{} El Diagrama no es compatible con la vista de SubDiagrama.</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1295"/> - <source>Save Plot</source> - <translation>Guardar Diagrama</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1284"/> - <source>Plot saved to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1303"/> - <source>Saved plot to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1420"/> - <source>Load Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1427"/> - <source>Could not read settings from file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1433"/> - <source>Save Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>Saved configuration to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="731"/> - <source>Automatic</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="732"/> - <source>Inside bar</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="733"/> - <source>Outside bar</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyProcessingPlot</name> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="88"/> - <source>Input layer</source> - <translation>Capa de Entrada</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="95"/> - <source>Plot type</source> - <translation>Tipo de Diagrama</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="103"/> - <source>Plot title</source> - <translation>Titulo de Diagrama</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="111"/> - <source>X Field</source> - <translation>Campo X</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="121"/> - <source>Y Field</source> - <translation>Campo Y</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="131"/> - <source>Color</source> - <translation>Color</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="140"/> - <source>Color (any valid HTML color) If set, this is used instead of the color set in the previous input.</source> - <translation>Color (Cualquier Color HTML válido) si aplica, es usado en lugar del color ingresado anteriormente.</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML File</source> - <translation>Archivo HTML</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML files (*.html)</source> - <translation>Archivos HTML (*.html)</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON file</source> - <translation>Archivo JSON</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON Files (*.json)</source> - <translation>Archivos JSON (*.json)</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="170"/> - <source>Build a generic plot</source> - <translation>Construir un Diagrama Genérico</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="176"/> - <source>Plots</source> - <translation>Diagramas</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="209"/> - <source>The chosen plot type needs a X field !</source> - <translation>¡El tipo de Diagrama elegido necesita un campo X!</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="211"/> - <source>The chosen plot type needs a Y field !</source> - <translation>¡El tipo de Diagrama elegido necesita un campo Y!</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="173"/> - <source>Creates a generic Plotly plot</source> - <translation>Construir un Diagrama Genérico</translation> - </message> -</context> -<context> - <name>PlotLayoutItemWidget</name> - <message> - <location filename="../gui/layout_item_gui.py" line="82"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="77"/> - <source>Setup Selected Plot</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PlotType</name> - <message> - <location filename="../core/plot_types/histogram2d.py" line="28"/> - <source>2D Histogram</source> - <translation>Histograma 2D</translation> - </message> - <message> - <location filename="../core/plot_types/box.py" line="28"/> - <source>Box Plot</source> - <translation>Diagrama de caja y bigotes</translation> - </message> - <message> - <location filename="../core/plot_types/histogram.py" line="28"/> - <source>Histogram</source> - <translation>Histograma</translation> - </message> - <message> - <location filename="../core/plot_types/bar_plot.py" line="27"/> - <source>Bar Plot</source> - <translation>Diagrama de barras</translation> - </message> - <message> - <location filename="../core/plot_types/scatter.py" line="28"/> - <source>Scatter Plot</source> - <translation>Gráfico de dispersión</translation> - </message> - <message> - <location filename="../core/plot_types/violin.py" line="28"/> - <source>Violin Plot</source> - <translation>Diagrama de Violin</translation> - </message> - <message> - <location filename="../core/plot_types/polar.py" line="28"/> - <source>Polar Plot</source> - <translation>Diagrama Polar</translation> - </message> - <message> - <location filename="../core/plot_types/contour.py" line="28"/> - <source>Contour Plot</source> - <translation>Diagrama de contornos</translation> - </message> - <message> - <location filename="../core/plot_types/ternary.py" line="28"/> - <source>Ternary Plot</source> - <translation>Diagrama Ternario</translation> - </message> - <message> - <location filename="../core/plot_types/pie.py" line="28"/> - <source>Pie Chart</source> - <translation type="unfinished"></translation> - </message> -</context> -</TS> diff --git a/DataPlotly/i18n/DataPlotly_fr.qm b/DataPlotly/i18n/DataPlotly_fr.qm deleted file mode 100644 index 9910b43d43028262a7ed155f84b8a236c045c66e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11658 zcmd5?d2Afj8UK9jy<P{$NgR`e$z`12IviCHY9U}dCyry`5Mop+#=GP7B)c=q?5rJ! zCWWS`2coD&oT8MQwxWlik*L%HYM?C$5GsK}MN=*bTvfE?syKT5zV~)#cD?J_q0Jwa zlbzk!eZTkJ*PG8jl<Ii$ueV<R^ztQ-TzbbZ|JX;=^eoY738IGY65aGwqP8zl^Rqp; zhA8m4gG38vD6nfI(ZZ)`<AO7Y!Y#CUVLMUu_p~iJMs(6RU2yHMhytTD(tL!d{cO5u z{ewg+AEDiaokVNSr;BgCo+y4c-T%Goh&ry6*RB}7bMi|>%O7ZHyZ<jl^A9&%aP&^# zyeY2>u4(weRd*99Z!{boJBR4RFE$+0mk~9dCa;Mb8s0c`80%Awp{4f_HQ&~_ZVL2w zeyefxx|KwsyBd#-Uqy7nvc@CNTcCG!;|tk`a6Q=6JJe4UyR9kvlXtN0qo%_f@Og>Z zboc<)FKTLfYKM(=k2g1daENH}s^;L8z+drj^BM0$4vjO-dro<cD6ye=>Rk==-q?Kg zc}d(q6lnkc-yx^ffm6@_3i$bFVC)5aAL$KT_O%hBmg@tP0m!A}t-v*x3=l1QJ@DAi zSK|Jgf#05k^-EXcn#c9tVBd?4*e@O&J#sS<of%YbIz|-yAgJ}c54xs;+9lWE{?CHx ze_RNCydbYD)4?h6`zd*C_=3DPeI&2*ZVX;=8umZ&$H6Q1gO8Q*;5}3C5uJQ#@Tu=W z4~sqsKJ~&~p!drmMZXnt*%;dTaEhpVS?Hz5&w?CY37@+fba!XM8>imDx<%oyW*>#! zJQu#U^Gwh~;a5Knz@9dTU*Fb@@9&F@J_CN*_eG{IXWS<v_l!SIG;d4fx%&<fb^R{# z@)78-{Wp=9KY9$fhofs212=Yhbi+ruHr*B-`~-SfeQorT4CIseIJ&0?a%t_4X83;m zIeA^0j^1|%et+Wf=wZe^`L*cdw||Iz{uF&?@M@6tb}Vpr4s!i-OyWHqyXcO0!S7H^ z;Iu4=*?&6(>I<<0H-U~tKaAaY#(dbrN%8iz3n2GR@%F6+T<?r`hOkffzv9bVkAnWo z;&S~(@xmbPcb*de#-q<czh}j7`Q#T^|7!e!53x^ZTT5sL*M&w)<U`=ZzugjjVln*d zSj!(?gx{TXZ(_wQ&EV_bi5q?meY9;zJoF&sIzN^8@aP)YL8^7^o3NwK=UWfnuM({a zv>yBsU!QD!`6&2Ye6aP{o`<pime#k`_u;SWbU5A3P2fC1ePohBd+=HyD~wwd#Q*qa z(@ZH@(=v1;9m0+9xhZX2EoAHlUbc|BXn<6*@qd^ySZw2U+F2g!8c=O@IAhwGX<i+5 zKZ^D3o~z4#U2Achv!y~hHr6QXY#iY|m94gxt+jGJok!#N(<w<4SZ9#}vNgPB@oLaC z-g&XLcx1wy$}9GSrnn3#DKojZ)^4AQ$%G3y06Zb3AocQ}!(3BuZ!d4uQTf}8^i*22 z`_#N9R;{Itl&2gtlVs5d#%wT_!n-`KWBA6xA3izAp+418(rT_g`a;@)wR#biEkI`j za*$dX$+UFMuvJ?(jrxe)pqG^*>2+0-#y%?en7|H~!8kQ%j}!VcnrbLQ)%~h5spjkN z(nU`cm7Xc8oaLe59veOz0nEQlBC&omV_Hf+sb;kL=*ws)j3*}$U0egwndMgfreT`} zOR=YOK44c-KZu$EtRJz&`YlbhH6fS!B!4RF^tQNV(BM9BZ-PvAM<%u#db44D8Cv7$ zEwOQ5&a`Yr%_|djHdCKQr6#ZrSe4S)$c1ioq4lhq_95FY+6s@K6y)X|39GYB!XZAs z)tJ;ke3I>=KIw6&j&&~rjRO)GRHro`t2?XgDFZJ^gJ9PSB7?f2`81@iA~hvD=V(v> zt1L)MdKcTjLuY)uYVFl5zs#-zxhe>BUCRqRRs_%M`+ewXNtGxh(R*2E4#6c%e}2_T zL&8`Yi3OX-b#@?Y88WS`n$h?B3}dTkmq0595(rmCsGWg$IgD{AC=a;d9R)k1YnG45 z)r)k;T2i5{w*Vs|H{hiPQy`z6L4J>D?}(&T#K&RPQnQ-vYo{LCEO5$VuE-di8fB#9 zOmDCimPJark8ZHB6tad7j=DYfaV))TkGS9kdsxW7^__1;mCekZOk~C2*KTHqc@BCy zYu6EbblB7l+oxZ)L$?+na(LBYEH?hTSvfjvnK{H9UGu^7D%viTBMqdKFF4`X5@?hw z86|@V;saWlBYN;w?Dj76@e$iH_iBFQhC+kFv^kb@`Yjpt+`v<M%APpB1`ywgT&$Sm zN)DxCedy0Z&KeXY<*d*vpt@K+3t4kfF}JnFF3hF;=jh#ZA@<?8$}vhNR=&!D#VzeP zth1)sQTg}6jPN-RbK>uk;;wXEt|nX)>%1@z-i^$(lGid?($-SSIEsjZ<;O0Tz%Jes zo0SwdiOo%HSzZywcIhSzP08yiAK^ZMFv`s82%aF_ajVcSJ+F`Xsl^hYYC=TI97M3& zMcA#3>slsNU&WOOqb|azUxX+cjeQWbLKnNMFZR2dt4XdMr1MJEI)SE4dC~JS8AXH} z;lvBvwqRH_w2bTvL{Gp8nh`}30#zl0nS`A9eP!({aCfPhf;0k8Tv_FmFxU<xy<_wm zc4L!sjV;2xfm1(u!1mN`GC;T&e67~QV-qfbne%;sO&0Cgr8U}T+7rqMY_`5^=azv< zZ%dgwRuJhk_Z>GGRKvG2{H*rNQwII801g*v=!$a?LWV<YtRJB&4Yd85@EQ-GB`~96 zfm+m(0$3f8h?NdtWI)YNC|tL)6MDdXs^-K4Cn0nU8w4rf(jg=?pc#4H7PASD<tr+< za$Rs;4c=M?FnI9GUoCMt@D7z>hV&t=1llA6mYjti(JngcqZ^GvR<oeQdg_ack%|T> zxt)CTCOsp1G!FsAMJ30PC0Dj@XtQM&a&<RdTM?*b+syXD*;7I~;|qtSgn-6O%8jKS z<n{UA0an|MU2{USr6RYydF`y+S&4R=IUaDRnKgBcnZpYg@Em+)1mioLqKaYD;V!fV zxi>4vFdl5R)0U#Q?#Go=KA;?s=oa=^%o)^r+M9>+i;LG8tQW58U<BFfRMDt<&=D8w zMORuD<paF7UeN5sQWKhHxv*<az<6hmd18ZRTD5e0BC99sh`47?N0l8*8iKD5M{R>9 z3`zK`PfzQr*hiYIgNr?iyE$@9xI6gp<Nvu!_s~^Bv<K5LLD9cC6gF?iD6NikJ7@%o z;wZ}IE1jdVj0_E#Vj@}xXl)r#dFfH3S9S=D0lK_d_TVur+WPVtN%N3dH`jC^hN*~P zawN<}bFsj7NQms<0(npy7wv%u0o~wl?&{plkY#0tg!bVv9Y|#y7uj1lj#QHw6<C&@ zo~TD>8&-43=8l5XPI=M~?ZB8Tqt;7}3z0E6NL!GbY&*nA&XHMoShJEC0@n)!Jl&}3 zfQ6m$2x;y{syN-KXplWL6Bp!)PQ5Ht1$`CIO8Ht4#ob@+u6mxtQ&b}*@^(Gudn(Hl z!8Yrb#{s4o)Q>^mY&Ye_OB`c?F~wg6!)o%viZPZtrf2FGL#GPoEr^k+4BQ<5N`nS3 zT}4LJNp~#mp{2I!!H{E6u@Pkbj4zmuiYT4KCsEmyb(7H%w4_o;bwXAgwN(}hVKumw zRcORklY8q{IPF+m%Ke;x#1VnRQ5!&vlxn4*%SqiCGkVBpy`LE)>?e=CIAEtleoZ+$ zp5W~0Gomho&e_ZJ^qFd3EOVsrNMVe}C-n@zk^vd^<&ady5ZOC&aN-jzIk+evSG0{3 z@;N!C@X5hEh>We2vox#1t&_sLc(jJ|ojMlKRwZ<IrV!q(`0A4@CkpQRP}xkvL+{lj zxI>BXs6P^JN5#dlr7EQ2-sN-vuLhlrU$E_P1XA%%4t?4D<$PR>WW={J^ea#l4}%p1 z1su?o{azjg$+@@NwdXyINpY-n-Q@?wEKbq$ih&L&X=Zcq4h(;kaXylhre-4?L@~9} zlsfw3CP2&~z?cOxWm76iuPu%=Dq^mRxiqajd2H`1=$VwFDrwEoEInCkW{8NI)be?d z$3tr|eqr^q#Aes~0ddI4^p_p5)mZ=2%Jq<QHx5i$#(aXo`f?82s0W|8-Bs`{I~CUn zvNNB-Jx<o8?t}Fz>j)m>vOw5LINR{tP);^8;u{X3@_3eY$%$F^FA{;X)eP>;i0KTs zBkqy4DmYZSRbyJ2#A!-O*|Kx{pd5g#QMQglfp!lL)S+tpE95bM)Q!BYsVSbw@<F?p z7xB;Vg}9Nk5G~CD78tpLJ^MhshV<4$dh!(Yzf<~Bd9Io-Q#)%GC1H(;agF^uXcJ`0 z660fYPMBLTj@wRyj>SiWP|$DB9+1{R>zswgUOF3ZzQ7v?US8>5+slWoqDl3(veKBp zR0y;6lxE68eh$5{tt@&4Rbtg)rca8uA+hYBAqR2(wvin}3QIsxyeDrOJ}9o1>}=eK zz-39)_c9)ma;3$7Q?m1_Xz5TKWgAdz-Sz{0Tn?mah_=1DU@FVX0VYwTWN*b=9;u=B z5rXUkSy*n0kRhJ~2iJvFy<*XnFp<Z*<&GG;cCwF8n0d{RL7z|J6hqTe>~F>Ns4TCq zz5ib(il+vCm~hVxDr$sHHO?(+ScALTEe}GY@T%%lj~c6wXD8OqmWO8@%!19&VwIgl z^cJ%*KZKP=Dq&~ikjRBZjcn}LNpwWB3pwZ6mbo`rf@sJYj1M2A_hykL*`rUV0S7LA z`hc=U&)a4i$Kz~VVWyZ*0*mJ*0|2QwR|kL$h|cp<4p^AaHF$kB&<gQ<U8!g1v%;*X z1Z0ISB5fHAX7{yW+VHRn7f+ms`56E_yyh&6m!2uAy>wx1c{s}>9%AT5e_AbuB<^wB z&-Kjg!C_=r*OdMV)v76rT4+3fsK&u5dS*_cDwy*Wgmy}ChSlrL&&wiUd?cybc=%xs tv97AgAJ11TnB#2T;yX3VP_5}X!1#&CYGFy6@j4f+R@>KMkBv<Y{{hH=eeD1M diff --git a/DataPlotly/i18n/DataPlotly_fr.ts b/DataPlotly/i18n/DataPlotly_fr.ts deleted file mode 100644 index a0fc596f..00000000 --- a/DataPlotly/i18n/DataPlotly_fr.ts +++ /dev/null @@ -1,874 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS><TS version="2.0" language="fr" sourcelanguage=""> -<context> - <name>@default</name> - <message> - <location filename="../test/test_translations.py" line="48"/> - <source>Good morning</source> - <translation>Bonjour</translation> - </message> -</context> -<context> - <name>DataPlotly</name> - <message> - <location filename="../data_plotly.py" line="116"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="272"/> - <source>Plot Item</source> - <translation>Plot item</translation> - </message> - <message> - <location filename="../data_plotly.py" line="105"/> - <source>&DataPlotly</source> - <translation>&DataPlotly</translation> - </message> - <message> - <location filename="../data_plotly.py" line="119"/> - <source>Shows the DataPlotly dock</source> - <translation>Afficher le meny DataPlotly</translation> - </message> -</context> -<context> - <name>DataPlotlyDock</name> - <message> - <location filename="../gui/dock.py" line="24"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> -</context> -<context> - <name>DataPlotlyDockWidgetBase</name> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="14"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="440"/> - <source>Plot Parameters</source> - <translation>Paramètres du diagramme</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="500"/> - <source>Z field</source> - <translation>Axe Z</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="480"/> - <source>Use only selected features</source> - <translation>Utiliser seulement les entités sélectionnées</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="487"/> - <source>Layer</source> - <translation>Couche</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="240"/> - <source>Properties</source> - <translation>Propriétés</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="382"/> - <source>Marker type</source> - <translation>Type de marker</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1022"/> - <source>...</source> - <translation>...</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="336"/> - <source>Visible</source> - <translation>Visible</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="742"/> - <source>Bar orientation</source> - <translation>Orientation</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1078"/> - <source>Normalization</source> - <translation>Normalisation</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="710"/> - <source>Outliers</source> - <translation>Valeurs abérrantes</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="914"/> - <source>Bar gap</source> - <translation>Espacement des barres</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1015"/> - <source>Violin side</source> - <translation>Côté du violon</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1157"/> - <source>Clean Plot Canvas</source> - <translation>Effacer le graphique</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1180"/> - <source>Update Plot</source> - <translation>Mettre à jour le graphique</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1202"/> - <source>Create Plot</source> - <translation>Créer le graphique</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1261"/> - <source>Export as image</source> - <translation>Exporter (image)</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1280"/> - <source>Export as html</source> - <translation>Exporter (html)</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="169"/> - <source>Plot type</source> - <translation>Type de graphique</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="246"/> - <source>Line type</source> - <translation>Type de ligne</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="253"/> - <source>Point type</source> - <translation>Type de point</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="265"/> - <source>Show lines</source> - <translation>Montrer les lignes</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="277"/> - <source>Marker color</source> - <translation>Couleur du marqueur</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="284"/> - <source>Stroke color</source> - <translation>Couleur du trait</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="355"/> - <source>Color scale</source> - <translation>Échelle de couleurs</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="321"/> - <source>Marker size</source> - <translation>Taille du marqueur</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="346"/> - <source>Invert color</source> - <translation>Inverser la couleur</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="392"/> - <source>Stroke width</source> - <translation>Largeur du trait</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="399"/> - <source>Opacity</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="416"/> - <source>Contour type</source> - <translation>Type de contour</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="460"/> - <source>Linked map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="470"/> - <source>Use only visible features</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="446"/> - <source>Feature subset</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="510"/> - <source>Y field</source> - <translation>Champ Y</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="535"/> - <source>X field</source> - <translation>Champ X</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="555"/> - <source>Use only features visible in map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="562"/> - <source>Use only features inside atlas feature</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1108"/> - <source>Type of plot</source> - <translation>Type de graphique</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1120"/> - <source>Plot in columns</source> - <translation>Graphiques en colonnes</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1127"/> - <source>Plot in rows</source> - <translation>Graphiques en lignes</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1209"/> - <source>Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1297"/> - <source>Dynamically update size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="677"/> - <source>Show legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="687"/> - <source>Horizontal legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="694"/> - <source>Show range slider</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="813"/> - <source>Invert histogram direction</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="823"/> - <source>Cumulative histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="856"/> - <source>Hover tooltip</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="849"/> - <source>Bar mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="877"/> - <source>Show statistics</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1008"/> - <source>Z label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="752"/> - <source>Set X Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="954"/> - <source>Minimum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="971"/> - <source>Maximum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="870"/> - <source>X axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="991"/> - <source>Y axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="897"/> - <source>Show mean line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="921"/> - <source>Invert Y axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="890"/> - <source>Legend title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="907"/> - <source>X label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="665"/> - <source>Additional hover label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1001"/> - <source>Manual bin size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="842"/> - <source>Invert X axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="703"/> - <source>Plot title</source> - <translation type="unfinished">Titre du graphique</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="935"/> - <source>Y label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="942"/> - <source>Set Y Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1065"/> - <source>If checked, box plots will be overlaid on top of violin plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1068"/> - <source>Include box plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="863"/> - <source>Hover label as text</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1085"/> - <source>Label text position</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyPanelWidget</name> - <message> - <location filename="../gui/plot_settings_widget.py" line="104"/> - <source>Plot Properties</source> - <translation>Propriétés du graphique</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="131"/> - <source>Load Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="133"/> - <source>Save Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="572"/> - <source>None</source> - <translation>None</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="176"/> - <source>Single Plot</source> - <translation>Graphique</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="177"/> - <source>Subplots</source> - <translation>Sous-graphiques</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="560"/> - <source>Vertical</source> - <translation>Vertical</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="561"/> - <source>Horizontal</source> - <translation>Horizontal</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="565"/> - <source>No Outliers</source> - <translation>Sans valeur abérrante</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="566"/> - <source>Standard Outliers</source> - <translation>Valeurs abérrantes standard</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="567"/> - <source>Suspected Outliers</source> - <translation>Valeur abbérentes suspectes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="568"/> - <source>All Points</source> - <translation>Tous les points</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="573"/> - <source>Mean</source> - <translation>Moyenne</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="574"/> - <source>Standard Deviation</source> - <translation>Ecart type</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="582"/> - <source>Linear</source> - <translation>Linéaire</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="583"/> - <source>Logarithmic</source> - <translation>Logarithmique</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="584"/> - <source>Categorized</source> - <translation>Catégorisé</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="887"/> - <source>Points</source> - <translation>Points</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="896"/> - <source>Lines</source> - <translation>Lignes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="587"/> - <source>Points and Lines</source> - <translation>Points et lignes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Solid Line</source> - <translation>ligne pleine</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Line</source> - <translation>ligne de point</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dash Line</source> - <translation>ligne de tiret</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Line</source> - <translation>ligne de tiret long</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Dash Line</source> - <translation>ligne point/tiret</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Dot Line</source> - <translation>ligne point/long tiret</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="647"/> - <source>Grouped</source> - <translation>Groupé</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="648"/> - <source>Stacked</source> - <translation>Empilé</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="649"/> - <source>Overlay</source> - <translation>superposé</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="653"/> - <source>Enumerated</source> - <translation>Enuméré</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="654"/> - <source>Percents</source> - <translation>Pourcentage</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="655"/> - <source>Probability</source> - <translation>Probabilité</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="656"/> - <source>Density</source> - <translation>Densité</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="657"/> - <source>Prob Density</source> - <translation>Densité de probabilité</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Fill</source> - <translation>Plein</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Heatmap</source> - <translation>carte de chaleur</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Only Lines</source> - <translation>Seulement les lignes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="696"/> - <source>Grouping field -(optional)</source> - <translation>Champ de regroupement (optionnel)</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="702"/> - <source>Box orientation</source> - <translation>Orientation des boîtes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="703"/> - <source>Box color</source> - <translation>Couleur des boîtes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="706"/> - <source>X field</source> - <translation>Champ X</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="710"/> - <source>Marker color</source> - <translation>Couleur du marqueur</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="712"/> - <source>Bar orientation</source> - <translation>Orientation des bâtons</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="713"/> - <source>Bar color</source> - <translation>Couleur des bâtons</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="716"/> - <source>Grouping field</source> - <translation>Champ de regroupement</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="724"/> - <source>All Values</source> - <translation>Toutes les valeurs</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="725"/> - <source>X Values</source> - <translation>Valeurs X</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="726"/> - <source>Y Values</source> - <translation>Valeurs Y</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="727"/> - <source>No Data</source> - <translation>Sans données</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="737"/> - <source>Both Sides</source> - <translation>Deux côtés</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="738"/> - <source>Only Left</source> - <translation>Gauche seule</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="739"/> - <source>Only right</source> - <translation>Droite seule</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1208"/> - <source>{} plot is not compatible for subplotting - see </source> - <translation>Le graphique {} n'est pas compatible pour une vue comportant des sous-graphique </translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1295"/> - <source>Save Plot</source> - <translation>Sauvegarder le graphique</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1284"/> - <source>Plot saved to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1303"/> - <source>Saved plot to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1420"/> - <source>Load Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1427"/> - <source>Could not read settings from file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1433"/> - <source>Save Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>Saved configuration to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="731"/> - <source>Automatic</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="732"/> - <source>Inside bar</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="733"/> - <source>Outside bar</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyProcessingPlot</name> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="88"/> - <source>Input layer</source> - <translation>Couche en entrée</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="95"/> - <source>Plot type</source> - <translation>Type de graphique</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="103"/> - <source>Plot title</source> - <translation>Titre du graphique</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="111"/> - <source>X Field</source> - <translation>Axe X</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="121"/> - <source>Y Field</source> - <translation>Axe Y</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="131"/> - <source>Color</source> - <translation>Couleur</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="140"/> - <source>Color (any valid HTML color) If set, this is used instead of the color set in the previous input.</source> - <translation>Couleur (format html), si renseigné ce champ sera utilisé à la place du champ précédent.</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML File</source> - <translation>Fichier HTML</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML files (*.html)</source> - <translation>Fichiers HTML</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON file</source> - <translation>Fichier JSON</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON Files (*.json)</source> - <translation>Fichiers JSON</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="170"/> - <source>Build a generic plot</source> - <translation>Construire un graphique générique</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="176"/> - <source>Plots</source> - <translation>Graphiques</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="209"/> - <source>The chosen plot type needs a X field !</source> - <translation>Le graphique sélectionné doit comporté des données en X !</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="211"/> - <source>The chosen plot type needs a Y field !</source> - <translation>Le graphique sélectionné doit comporté des données en X !</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="173"/> - <source>Creates a generic Plotly plot</source> - <translation>Crée un graphique générique</translation> - </message> -</context> -<context> - <name>PlotLayoutItemWidget</name> - <message> - <location filename="../gui/layout_item_gui.py" line="82"/> - <source>Plot Properties</source> - <translation>Propriétés du graphique</translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="77"/> - <source>Setup Selected Plot</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PlotType</name> - <message> - <location filename="../core/plot_types/histogram2d.py" line="28"/> - <source>2D Histogram</source> - <translation>Histogramme 2D</translation> - </message> - <message> - <location filename="../core/plot_types/box.py" line="28"/> - <source>Box Plot</source> - <translation>Boite à moustache</translation> - </message> - <message> - <location filename="../core/plot_types/histogram.py" line="28"/> - <source>Histogram</source> - <translation>Histogramme</translation> - </message> - <message> - <location filename="../core/plot_types/bar_plot.py" line="27"/> - <source>Bar Plot</source> - <translation>Diagramme en barre</translation> - </message> - <message> - <location filename="../core/plot_types/scatter.py" line="28"/> - <source>Scatter Plot</source> - <translation>Nuages de points</translation> - </message> - <message> - <location filename="../core/plot_types/violin.py" line="28"/> - <source>Violin Plot</source> - <translation>Diagramme en violon</translation> - </message> - <message> - <location filename="../core/plot_types/polar.py" line="28"/> - <source>Polar Plot</source> - <translation>Diagramme polaire</translation> - </message> - <message> - <location filename="../core/plot_types/contour.py" line="28"/> - <source>Contour Plot</source> - <translation>Isoplèthe</translation> - </message> - <message> - <location filename="../core/plot_types/ternary.py" line="28"/> - <source>Ternary Plot</source> - <translation>Diagramme ternaire</translation> - </message> - <message> - <location filename="../core/plot_types/pie.py" line="28"/> - <source>Pie Chart</source> - <translation>Diagramme circulaire</translation> - </message> -</context> -</TS> diff --git a/DataPlotly/i18n/DataPlotly_it.qm b/DataPlotly/i18n/DataPlotly_it.qm deleted file mode 100644 index 718dba0c80f13effe4462219c62a71ed409f2b10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16152 zcmcgz4R9RQeSiA658a(kwk!)-80A^Wwj_k?*ujC;7~7IR<j9t4*~a$RGpz1b(%O5s zm%TmtYYc>srX+w%QX0r44Nf4?hBQrpgv>NRF=T+D44t^-qlUDF=_F~AHW0#?P}<-B zy}R8#-RgGbq#0RW-Ra)%{lDJ-^J(ql>9!aC>vMPi<C4WsUU&LCuWn>4#2NcwlChd^ zF?P=_jPXBW^)L4^_JOal&>vsVSl6Gh(4I|<EnUPKGrJjU+sTsjT(pjDTDY3Aru*5J z))vNE-elWS<BY9%j_o}4G-L5LHdcRzu_fPO*RFYlu@7Ct_7-+AcGVqh|GjrJcF{N4 z!3~{^Ex3g}{Dn_5w(LpyT%)izm;aElRh>1>5C0tNuc+C1_KS=qo|Df@->KR4(EE&a zpR2iP;p>bwwAB3dt@ne6>uMfJy^MYTr{?VVI>!2V&1+f*V|8`%dGQx&-njWOeC|gz z=P$zgCBLbST=D>8;k#;A90A{#t*zbn=}W=Sy4ol1yaIB0q4vzgt&DX%Tzlr9P4Kt2 z_La=zc-~#tzhi*0)_<tm`F$1p?XAmv?M=pFgLS9sf5BMekLw=02EV_&r|z+nz+F04 z_u_~Jd202wzqy&Q<^NJ2qR%Cl)Q3NY{a0_TU;Xwb(D`Kjq09cAv5R-rA9;&#zgqvv z4Jo{z3b6yw&+=HP<)L3eAGd{8e&i<5e?w^GOD{3j`#@;?6?}evBJ|OZk1^K%&CqlR z@?L&AbjQI#=;PYZGvB@xxb>mu)&cMG=kd%l*1s+Ev#qNkzh8#l70-LZ>%Ni!-!0*d zKd6QL|1`Yqe^)XVc{IH5%)N}U4PoV;*Fd)tR{P!tKMTX^!8`E&6XD7Gev0?M9iDt= zH)Hc2m(SJz89pM`eM~-UrsXqqgM4-@4d3`d(AjrW_{QVlf8Ig)T>a<a2af!ju@B!K ze(_VVgJrA2FTV06@OLo$a|L><Ul`%q=b*O_MTVY8Gj`>nh}nOZvF7Q>51+jXc5zp< zru9+KJsMrV6#QTLx6w^U-T>ZEbjyaNjMaW4I`UU{GS>4>^p?z1c)d4zs{O;@gGK-C zw;|vkj=sLF9-n``A$t3D(DTZMeJ?>?ozFGo_CwAK7Bw6>0eYHWXn0`aS;j7Tso{GM zp2X+F4d>3lzAjzRaPHk_u<x&8J&UmK!lBqT@8VhiOl<f)*ufRA#t!Px!^Q8#4)sCK zi+99ydcW-<`RtF!%%iaTwx7iwJdJgi{W$jZ-oMBB{6*|B+ULrZv1ji)54+67UK;)+ z$bLT_x<3bf-X356=yyTqf%sKNA=irr<6^%xABbOj`YqVueQ~kRqQ8g>{6(+Ct^d9m za<7k{ya)6y{Ym^2A*}CNAOFni1<=c@@xNOGc_a=b>TZVKWA`RndKbdJmnK?<3V7a@ zXpexts|FK%H|P()lUUMpma#QoNr-*gc|z>dKAtEH<8wWKleq1v??Io(5}$n!{9Jx( z;v45dSMs-sf4U2}muzp0{1mUdUT$nS5B#=dW9<1w@JH7-e*OT~EjZWsqaWZLtPCeR zKU)vEy`TKc@BSKg_*U}4Pdx(r_;T{`N1npx|08++Y!B@Bji%b>O_2ZTrtwceZ<n2F zy8dAWe&~j#>%WTU75z<OU30SO`8$ChUEFl;Eacj~qUp6mPXPb(O}|v$hCWYeVDkHQ zkaQc{!VG++8D|+hO_pUEz9*yjB@5#_vBfabJY$$yEjt;(8`1S?bwVlVRt*8PvSn<L zDa^w6DANI9;s0ay^7yhr#ZpFf!_tq@>X`FVtZ%8h+VyF##cgZ=6sy>pvq}7<unAC~ zVurna1MSR*EH&e`em&a`g7YAm)^e=X@qZ3KXYr-t6*0si9S#3iV{_5ilyM}_ttpi| z4Dz&*I_$OYoS05JfP=sjQVX+w`m))q>+kQUjoQjTd##q9RIQClUKOjl*(R_`0-6GI z7QTpS1)`h8y9KaJznx}^joZ2*oz^VP$SOLYGNx6N>&m#Q`){?3jR`p(2Ovpsq9|b< z8*?^}O-+2M_C}G7ipeLHoImnnp|dm)bYNTTUtM?(;ZefN7-`iXu#1g=6b*zC{|b(Q z{E5ge5$XUp5wKxuYSvOnF#h-*I2Q#$Y#x#)Lvov{W{Y6{fUYW8E(~@+$xbWzAlPHT zBvFtirJ2I~h1r598#_K==!VJjDMb$;k;OPx2BblUX%e*4;gE{Np|CL<2aN25Hd!zO z%7L?8z{|M~6j4etmu|;7v<V<vM#1FPv0MOh{k=eZz*H4W6|(ggYA+iSKEWs|Dg%=s z@unb(j8G-HJ31&1$t?qgOhJbvrd2+r<t<~<RD{c^ej?}O2&zMo8`g@(o5xQiS~_cF z6j{)p!4sxptM8)0V_7Am!6NiyypT(ieDd1y0P^mH8_5ern&QBaWDK!0hhwqulWy;l z+;lW&m=;&^e9FoMa2&l=z==Il1$isCB{n&mXc=WP01F*#Gca@zD;+<%dR4F>e4s=A zX4p-^gk%cidDZf_on>qoK$F6SkdNZRxHTM~<3c0kV6c_F!Thc8CC6dzaIm^Msb<su zd-TJ%7O)5HLXOMruqvIoW222*g$K6`L$|a5p7u`cLl#83mcfDS-e7%rPew|&BO`Y? zjrYm<kb3BK>3|cRCL>QxIMODGQWAdYbdjvcLCQU(Lo3CK335fY%&s1q;HfD!by!XJ z@p0oQ&mqR=`4LUm`MAo7NnO#>+{kjv$Z=zWPiuy*W##Am<+~Z@KMP89P%B+3{eR)~ z&L7IA^g>#7X!WOIv7ljEXqbErh3P!LNFsY}Ni+^+!K}sia^<KNAY4>K-B*FS?}AZD z@02;YLr|hfYl<R~zW}bR5CAEGl07>TK@=K9LMG`lC7X@*;)b?6=4s7TQ^A6ElI_7( zlp+xq&Up<DE63CT<S!P%j#kSIlH7~!6>Jg{!{W$uOS6K+<@SmQDvufxU>mYwSj(yb z17|l<DFug{65dkwKn`UB#FjZ08$AYe96O!~lBunnB_fdv&*E$ePl$~@lC14Ywg8Vf zjzb$PCUuFFMcSN<dgRi{qmX|bmwK?-NNiWk!$@WW+G5`<jHDr_**A$7Hwnf-M}=;^ zNiU%WOO293!{j(f3{EJBY=^_h6ar)@2_TR=pSfPk23z03c8DWHN+)ZjK<JrG?l8=Z zqHD(kW|K)|?PRx<QKJa3RT~+}DJjhowPy8%i4Y1{OH{$$ZG`AZ!O}I=4B$_Dk=j!w zBZ~$~CdgBl%%Uth+VD*x!5>wSAF5WMUAj=C(;mgz7CVqaWOOBq7q#jPd>kAYcOjDv zzy+TLpSYQ%Qqjgv2-<;dqS*EK;axMFV0FR71b9GKSb1E$r7i3KV27pBy_WJG=itOf z4J~U0^smh@4-*Q?3B#ap;@D|y)HHI4-I^LekW`Um03&-9<gCePDWjh~H<&-BQev<H zi2>he6td~x>po7lAokfew|!&{@AO@~qhp+UDuJ`&HaIGGFQ*h59qWxrJjBNUqF6Z# zoQ#yRHAFvC@-5Os`;a8XHW{krk#q(qM%rg=l^5Ej!{Rul`2y5bvXiJqbS)hu2kEN7 zrRsw$h9qBX1KDIZi5>FP)yP{~Du9UiEHRg&tqGwxrzSCGnZ{u?XuR!0;gJLT6t_hB z1v!^|$L!!ow6rzl@05aij>IlBAE<bs>cStEvkh>TRGAXRRB)H~c^qNHcgtd%+?_w} zTF9c5M9!#Ei&CMAmAni&h2=uQR6NnUj_EJkod+*jRQeOLpv`kFn}->3#nMrm7vJ?K zXRs<cRR2+`F^+FKe;j1Ek4iDwv~7-8k~OX6wQ*eqdBKv*wQM)GBx#ea$Yh%mZP}2J zAz2o&QhKH8fewNrpLUy&ysD!{K#E%ul)p^+<{}fD_eJ)WC6<Hl$kAnxb+U6X%4%<W zm-rr8`jW2wIhlv5$E`s}K#@ICFa8)E!t0dxXT56IxGY)&HffXaHI!w^_MuY&NA~gw zP1OT*P53O$@5-tgm;t-o)p>PdWL%cg7sRWB64@7&*H%wn%a8(cST6Vdwp~T`2c^YN z?q!$(siI7cQg@mCke?}KYEG9ZwgK%Rk*$ePw$Pc3j4D}Gm!lCe7NJ_b91SB7;YyGJ z+Z+qLJ&InC*+UgP>PJggMC}T%`nG|F2zK#V1?qR7O;iEzfR)JLK_`oRHdPiBMnsn2 zaK6#7ruY~<h`%JuIWOzy*?0{b(X$J}eK#sJDnh&_Gv3fm1U+LqQ$+&p!mA(<AaGOI zE|sU~+t}2`2hbUxq%N&0yi66iHLf(>34>$;GQpJ%TY4?qr&Q3no54#4jDnu#SxhW3 zuSj!roGlDp5uQyWgYzbPL{$jrLR_HQP)<Z;bDK^H@kgl%>DARL8dUOAoccxN)vLhH zX-ZKACy71^>5^pQu7x6lDv}XdvsYQZs*F1d`IQ`UY~bY$8V4cNp!{~0ZB%kC-a?EL zZ~z%Li^E0(B<ih+;BA{&Y*V(7Q87pJwXjyU6SAX8MGjB9@oyv5Z$=Z`N1KEp#{?$a zp6vd)4L-8PGzvLiQWBzTAOW1yk`#+!v`%=aqEXq|C}OY}>&7X}*$rOVAMCN2YcI#< zv2G(LXVX1CEK{7G+31vGQ&C>nJ4Ci3J1+J%tB~DV^h>i1bz;s?$A_?_%hKF!<}g{5 zBKpi#=!n^?okT4}EB*X*ukd^1???)zISsj^*~h)j!v<VZ#mu(~c^9%vTjefizWDTw zPk-4*kgX5}jRB||N6tk~I~}`>4;zz;saaE)c=|xCx1~y=na$16a0u6A&>o|Z>FsnN zG8_cqbpm>cm2=(OHr=GNR{(GHJGRTKC_RRwHnSsAza7mGAE~#ZPb@3`(ulC!M@DuS z;%1ExOp9nY)6~_gwHpVBySrP3j|6~9nTK<_>US8v(X!oD4pO9}-nndbIp)|fLbdp? zIw3j$Rmf;@fq8VaBus!4-|E7lR?19*Vgkw3Ca3%;l1S4ch*9v6JvWE7$cUJ~iUxdD z#zsL#3g4817KcH$HAhEPGleTQevYhKhqc&fFKe?_A!xXw3r=kXovuTHKx(hZuKQZy z5~jevijMr%tdpH!C-MI}@m$MR;P>lnMwW=Cc3zoAN5L}qT7^%U>crKZCr);*J8^RD z3T2&-LC3`HA(D|(ii87|HSNyIqKB$9pm`FBE7`P2V*KRYSL|rh$gb4nK_&-$>Ve8; zL}h-LK(Bk82TSr=y?3w$8Ye7eT+{vY#ctSqNrM4n+!z!!rx-W)J=!Yw2o&MStvKAw zGVKu9rN&|vW8W`I)LCwLL62_JrwDi<rr%4%q*3U(Zi!vk8TfxXnvy<h?_L;L9UdNo z1VyzZ8j+64jv*gLOEZ987MI2U()Aevg@?2OV`I3^A`h&O_n23#NU6@85l_b~g>KOJ z0MM;6Rov@w4Q+*i&@3T~V^0}Z+9s_Tu-UX?rg7Y-HG7s@#T0q@7`6)bd>cDp45z^g z-Mo}-BJU#;9V?8J3HW(FFET0g(VRjwqFf><<a4rz9FWdtaoL0})5(O~-4lrJp&=n| z>G>#X9x%u~$To)il2CLn57f3QZ}oY%SgYu9CIL>jF}g1p0j7wcGsY&c2f9l}^X{ME zn~nq(zhum%IRho%@~Ft(mAuJb-hr0)HffEw8LT*QQVe=Hrlr(>Ng0_Otd}Mc6LfJ_ z8VPk{Vra{#+(#QL;a@31Am1tT*|Kf%uDlE+@7aKO+j?3y7BuvL6pp)qs;Q;C#!m== zDK(!5G2~K24>KVgx>UcDu7(CYE?ar5e$l-e#B~dKQb?x+O-i?jjaM=lY(>{}JKR+d zE~0b9Ci)z;BuW`!DQlv+1SNU&`+^88GMoA+UdcSPbW^Z=2fF(vcbB6-a$xd?APsWJ z`%s^UgiN2J&xnzi>r%WTxaZwU_86bW)si&dx@-F|RErB}Jsg(^(O>Jsm3^oj{|b2o zD-6Xf>bzm>M_2j9N9kiUj-oemCcK(az=CY9V9mU8?;+U>H-t;%o#njC6iC}B8^~Re z{kg8Uc<kI<yy8l7FY3xRvIZdt^onNAggkJ%Dsh0=&3d8t;%#5%^k^0cWNKCBd3SF= z-T4*Gnd-DIE5B_Ad}(7cnv#yiDA=YyK1AZjl&117o(~7xV5uW0?MfUR0y23Q7YEzM zMs{$Ljo{!=-pB^vz%A|K9yYZN0+D3mueIOTl^G8)1RZ?OdS%7~Gg+1bITcEXOjU%` z>WV*r{Df}MQ5(u0?%_4LdU6?bv`O`{twWB2;;o6N?4Zx|sx%dl?!jP7Yy~XaMQ3@+ z$gA=Wu(-a%v#Oe=(^Z@x@+JP-@gjHMADG<Y5HJY2RU-OkkD;lje%)hNC!}K(84zKv z6?zL<4ldam1&jV_%QdF!c1>5v{g)>BRCkuyfvxu#u0R!XcHTWZbUUD_BT{ye7_h6@ zpbeH-HORNR|FR=Wl+q;;5r8X;0SZv1tF2B*7JryTE6Li*Ay$<gCNlO?#FMd9MnLlC z1Y3S5K1zcxZ`jJ~g9KZuEht|^g5|JT`r8|Cuof>#*^3+IEFhA(_$v|zV^l*4KBbr* z5?Wj#A<8yLE{G8}0`BPPiaCokdMhAE8kFkDT;9a9_{TFgU}7w#Sh%Y>3uNW}Nt(FH jOF-0(b_sWvYGxJl*epPup0riJ*iosbKZ9Y_*3|qT+WL<k diff --git a/DataPlotly/i18n/DataPlotly_it.ts b/DataPlotly/i18n/DataPlotly_it.ts deleted file mode 100644 index c9dc1762..00000000 --- a/DataPlotly/i18n/DataPlotly_it.ts +++ /dev/null @@ -1,874 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE TS><TS language="it" version="2.0"> -<context> - <name>@default</name> - <message> - <location filename="../test/test_translations.py" line="48"/> - <source>Good morning</source> - <translation>Good morning</translation> - </message> -</context> -<context> - <name>DataPlotly</name> - <message> - <location filename="../data_plotly.py" line="116"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="272"/> - <source>Plot Item</source> - <translation>Crea grafico</translation> - </message> - <message> - <location filename="../data_plotly.py" line="105"/> - <source>&DataPlotly</source> - <translation>&DataPlotly</translation> - </message> - <message> - <location filename="../data_plotly.py" line="119"/> - <source>Shows the DataPlotly dock</source> - <translation>Mostra il pannello di DataPlotly</translation> - </message> -</context> -<context> - <name>DataPlotlyDock</name> - <message> - <location filename="../gui/dock.py" line="24"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> -</context> -<context> - <name>DataPlotlyDockWidgetBase</name> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="14"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="440"/> - <source>Plot Parameters</source> - <translation>Parametri del grafico</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="500"/> - <source>Z field</source> - <translation>Campo Z</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="480"/> - <source>Use only selected features</source> - <translation>Usa solo geometrie selezionate</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="487"/> - <source>Layer</source> - <translation>Vettore</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="240"/> - <source>Properties</source> - <translation>Proprietà</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="382"/> - <source>Marker type</source> - <translation>Tipo di simbolo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1022"/> - <source>...</source> - <translation>...</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="336"/> - <source>Visible</source> - <translation>Visibile</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="742"/> - <source>Bar orientation</source> - <translation>Orientamento barra</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1078"/> - <source>Normalization</source> - <translation>Normalizzazione</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="710"/> - <source>Outliers</source> - <translation>Outlier</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="914"/> - <source>Bar gap</source> - <translation>Spazio fra le barre</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1015"/> - <source>Violin side</source> - <translation>Lato del violino</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1157"/> - <source>Clean Plot Canvas</source> - <translation>Pulisci grafici</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1180"/> - <source>Update Plot</source> - <translation>Aggiorna grafico</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1202"/> - <source>Create Plot</source> - <translation>Crea grafico</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1261"/> - <source>Export as image</source> - <translation>Esporta come immagine</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1280"/> - <source>Export as html</source> - <translation>Esporta come html</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="169"/> - <source>Plot type</source> - <translation>Tipo di grafico</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="246"/> - <source>Line type</source> - <translation>Tipo di linea</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="253"/> - <source>Point type</source> - <translation>Tipo di punto</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="265"/> - <source>Show lines</source> - <translation>Mostra linee</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="277"/> - <source>Marker color</source> - <translation>Colore del simbolo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="284"/> - <source>Stroke color</source> - <translation>Colore del bordo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="355"/> - <source>Color scale</source> - <translation>Scala di colori</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="321"/> - <source>Marker size</source> - <translation>Dimensione del simbolo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="346"/> - <source>Invert color</source> - <translation>Inverti colori</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="392"/> - <source>Stroke width</source> - <translation>Spessore del bordo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="399"/> - <source>Opacity</source> - <translation>Opacità</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="416"/> - <source>Contour type</source> - <translation>Tipo di contorno</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="460"/> - <source>Linked map</source> - <translation>Mappa di riferimento</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="470"/> - <source>Use only visible features</source> - <translation>Solo elementi visibili</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="446"/> - <source>Feature subset</source> - <translation>Filtra elementi</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="510"/> - <source>Y field</source> - <translation>Campo Y</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="535"/> - <source>X field</source> - <translation>Campo X</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="555"/> - <source>Use only features visible in map</source> - <translation>Solo elementi visibili nella mappa</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="562"/> - <source>Use only features inside atlas feature</source> - <translation>Solo elementi dentro l'atlante</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1108"/> - <source>Type of plot</source> - <translation>Tipo di grafico</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1120"/> - <source>Plot in columns</source> - <translation>Grafico in colonne</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1127"/> - <source>Plot in rows</source> - <translation>Grafico in righe</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1209"/> - <source>Configuration</source> - <translation>Configurazione</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1297"/> - <source>Dynamically update size</source> - <translation>Dimensione dinamica</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="677"/> - <source>Show legend</source> - <translation>Mostra legenda</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="687"/> - <source>Horizontal legend</source> - <translation>Legenda orizzontale</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="694"/> - <source>Show range slider</source> - <translation>Mostra slider</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="813"/> - <source>Invert histogram direction</source> - <translation>Inverti direzione istogramma</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="823"/> - <source>Cumulative histogram</source> - <translation>Istogramma cumulativo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="856"/> - <source>Hover tooltip</source> - <translation>Suggerimento aggiuntivo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="849"/> - <source>Bar mode</source> - <translation>Modalità barra</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="877"/> - <source>Show statistics</source> - <translation>Mostra statistiche</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1008"/> - <source>Z label</source> - <translation>Etichetta asse Z</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="752"/> - <source>Set X Axis Bounds</source> - <translation>Imposta limiti asse X</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="954"/> - <source>Minimum</source> - <translation>Minimo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="971"/> - <source>Maximum</source> - <translation>Massimo</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="870"/> - <source>X axis mode</source> - <translation>Modalità asse X</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="991"/> - <source>Y axis mode</source> - <translation>Modalità asse Y</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="897"/> - <source>Show mean line</source> - <translation>Mostra linea della media</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="921"/> - <source>Invert Y axis</source> - <translation>Inverti asse Y</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="890"/> - <source>Legend title</source> - <translation>Titolo legenda</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="907"/> - <source>X label</source> - <translation>Etichetta asse X</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="665"/> - <source>Additional hover label</source> - <translation>Etichetta aggiuntiva</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1001"/> - <source>Manual bin size</source> - <translation>Dimensione manuale barra</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="842"/> - <source>Invert X axis</source> - <translation>Inverti asse X</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="703"/> - <source>Plot title</source> - <translation>Titolo del grafico</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="935"/> - <source>Y label</source> - <translation>Etichetta Y</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="942"/> - <source>Set Y Axis Bounds</source> - <translation>Imposta limiti asse Y</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1065"/> - <source>If checked, box plots will be overlaid on top of violin plots</source> - <translation>Se spuntato, il grafico violino conterrà un diagramma a scatola e baffi</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1068"/> - <source>Include box plots</source> - <translation>Includi diagramma a scatola e baffi</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="863"/> - <source>Hover label as text</source> - <translation>Suggerimento come etichetta</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1085"/> - <source>Label text position</source> - <translation>Posizione etichetta</translation> - </message> -</context> -<context> - <name>DataPlotlyPanelWidget</name> - <message> - <location filename="../gui/plot_settings_widget.py" line="104"/> - <source>Plot Properties</source> - <translation>Proprietà</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="131"/> - <source>Load Configurationâ¦</source> - <translation>Carica configurazione</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="133"/> - <source>Save Configurationâ¦</source> - <translation>Salva configurazione</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="572"/> - <source>None</source> - <translation>Niente</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="176"/> - <source>Single Plot</source> - <translation>Grafico singolo</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="177"/> - <source>Subplots</source> - <translation>Multi grafico</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="560"/> - <source>Vertical</source> - <translation>Verticale</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="561"/> - <source>Horizontal</source> - <translation>Orizzontale</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="565"/> - <source>No Outliers</source> - <translation>No outlier</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="566"/> - <source>Standard Outliers</source> - <translation>Outlier standard</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="567"/> - <source>Suspected Outliers</source> - <translation>Outlier sospetti</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="568"/> - <source>All Points</source> - <translation>Tutti i punti</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="573"/> - <source>Mean</source> - <translation>Media</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="574"/> - <source>Standard Deviation</source> - <translation>Deviazione standard</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="582"/> - <source>Linear</source> - <translation>Lineare</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="583"/> - <source>Logarithmic</source> - <translation>Logaritmico</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="584"/> - <source>Categorized</source> - <translation>Categorizzato</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="887"/> - <source>Points</source> - <translation>Punti</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="896"/> - <source>Lines</source> - <translation>Linee</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="587"/> - <source>Points and Lines</source> - <translation>Punti e linee</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Solid Line</source> - <translation>Linea continua</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Line</source> - <translation>Linea punteggiata</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dash Line</source> - <translation>Linea tratteggiata</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Line</source> - <translation>Linea a tratteggi lunghi</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Dash Line</source> - <translation>Linea a tratteggi e punti</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Dot Line</source> - <translation>Linea a tratteggi lunghi e punti</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="647"/> - <source>Grouped</source> - <translation>Raggruppato</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="648"/> - <source>Stacked</source> - <translation>Impilato</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="649"/> - <source>Overlay</source> - <translation>Sovrapposto</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="653"/> - <source>Enumerated</source> - <translation>Enumerato</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="654"/> - <source>Percents</source> - <translation>Pecentuale</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="655"/> - <source>Probability</source> - <translation>Probabilità</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="656"/> - <source>Density</source> - <translation>Densità</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="657"/> - <source>Prob Density</source> - <translation>Probabilità di densità</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Fill</source> - <translation>Riempimento</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Heatmap</source> - <translation>Mappa di calore</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Only Lines</source> - <translation>Solo linee</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="696"/> - <source>Grouping field -(optional)</source> - <translation>Gruppo -(opzionale)</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="702"/> - <source>Box orientation</source> - <translation>Orientamento scatola</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="703"/> - <source>Box color</source> - <translation>Colore scatola</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="706"/> - <source>X field</source> - <translation>Campo X</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="710"/> - <source>Marker color</source> - <translation>Colore del simbolo</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="712"/> - <source>Bar orientation</source> - <translation>Orientamento barra</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="713"/> - <source>Bar color</source> - <translation>Colore barra</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="716"/> - <source>Grouping field</source> - <translation>Gruppo</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="724"/> - <source>All Values</source> - <translation>Tutti i valori</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="725"/> - <source>X Values</source> - <translation>Valori X</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="726"/> - <source>Y Values</source> - <translation>Valori Y</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="727"/> - <source>No Data</source> - <translation>Nessun dato</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="737"/> - <source>Both Sides</source> - <translation>Entrambi i lati</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="738"/> - <source>Only Left</source> - <translation>Solo sinistro</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="739"/> - <source>Only right</source> - <translation>Solo destro</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1208"/> - <source>{} plot is not compatible for subplotting - see </source> - <translation>{} grafico non è compatibile con la modalità multigrafico</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1295"/> - <source>Save Plot</source> - <translation>Salva grafico</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1284"/> - <source>Plot saved to <a href="{}">{}</a></source> - <translation>Grafico salvato in <a href="{}">{}</a></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1303"/> - <source>Saved plot to <a href="{}">{}</a></source> - <translation>Grafico salvato in <a href="{}">{}</a></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1420"/> - <source>Load Configuration</source> - <translation>Carica configurazione</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1427"/> - <source>Could not read settings from file</source> - <translation>Impossibile leggere il file</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1433"/> - <source>Save Configuration</source> - <translation>Salva configurazione</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>Saved configuration to <a href="{}">{}</a></source> - <translation>Configurazione salvata in <a href="{}">{}</a></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="731"/> - <source>Automatic</source> - <translation>Automatica</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="732"/> - <source>Inside bar</source> - <translation>Dentro la barra</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="733"/> - <source>Outside bar</source> - <translation>Estera alla barra</translation> - </message> -</context> -<context> - <name>DataPlotlyProcessingPlot</name> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="88"/> - <source>Input layer</source> - <translation>Vettore in ingresso</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="95"/> - <source>Plot type</source> - <translation>Tipo di grafico</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="103"/> - <source>Plot title</source> - <translation>Titolo del grafico</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="111"/> - <source>X Field</source> - <translation>Campo X</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="121"/> - <source>Y Field</source> - <translation>Campo Y</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="131"/> - <source>Color</source> - <translation>Colore</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="140"/> - <source>Color (any valid HTML color) If set, this is used instead of the color set in the previous input.</source> - <translation>Colore (codice colore in HTML). Se impostato viene usato questo colore invece della scelta precedente.</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML File</source> - <translation>File HTML</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML files (*.html)</source> - <translation>File HTML (*.html)</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON file</source> - <translation>File JSON</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON Files (*.json)</source> - <translation>File JSON (*.json)</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="170"/> - <source>Build a generic plot</source> - <translation>Crea un grafico generico</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="176"/> - <source>Plots</source> - <translation>Grafici</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="209"/> - <source>The chosen plot type needs a X field !</source> - <translation>Il campo X è necessario per il grafico scelto!</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="211"/> - <source>The chosen plot type needs a Y field !</source> - <translation>Il campo Y è necessario per il grafico scelto!</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="173"/> - <source>Creates a generic Plotly plot</source> - <translation>Crea un grafico generico</translation> - </message> -</context> -<context> - <name>PlotLayoutItemWidget</name> - <message> - <location filename="../gui/layout_item_gui.py" line="82"/> - <source>Plot Properties</source> - <translation>Proprietà</translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="77"/> - <source>Setup Selected Plot</source> - <translation>Imposta il grafico selezionato</translation> - </message> -</context> -<context> - <name>PlotType</name> - <message> - <location filename="../core/plot_types/histogram2d.py" line="28"/> - <source>2D Histogram</source> - <translation>Istogramma 2D</translation> - </message> - <message> - <location filename="../core/plot_types/box.py" line="28"/> - <source>Box Plot</source> - <translation>Grafico a scatola e baffi</translation> - </message> - <message> - <location filename="../core/plot_types/histogram.py" line="28"/> - <source>Histogram</source> - <translation>Istogramma</translation> - </message> - <message> - <location filename="../core/plot_types/bar_plot.py" line="27"/> - <source>Bar Plot</source> - <translation>Grafico a barre</translation> - </message> - <message> - <location filename="../core/plot_types/scatter.py" line="28"/> - <source>Scatter Plot</source> - <translation>Grafico a dispersione</translation> - </message> - <message> - <location filename="../core/plot_types/violin.py" line="28"/> - <source>Violin Plot</source> - <translation>Grafico a violino</translation> - </message> - <message> - <location filename="../core/plot_types/polar.py" line="28"/> - <source>Polar Plot</source> - <translation>Grafico polare</translation> - </message> - <message> - <location filename="../core/plot_types/contour.py" line="28"/> - <source>Contour Plot</source> - <translation>Grafico a contorno</translation> - </message> - <message> - <location filename="../core/plot_types/ternary.py" line="28"/> - <source>Ternary Plot</source> - <translation>Grafico ternario</translation> - </message> - <message> - <location filename="../core/plot_types/pie.py" line="28"/> - <source>Pie Chart</source> - <translation>Grafico a torta</translation> - </message> -</context> -</TS> \ No newline at end of file diff --git a/DataPlotly/i18n/DataPlotly_nl.qm b/DataPlotly/i18n/DataPlotly_nl.qm deleted file mode 100644 index 18a3933350191d7639bf16d54dbee28d840b0b33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10383 zcmb_i3yd6P9sl2B-+Omudp)j4Dbt6wElq`1MT6ndUg=%A_Ab5a^`S)OcIWQqZgysw zneFwC6p%s$69a0B<zWH>K@7x4(})Qwv0y9$F`+h~wLwJ_A`zrkQiSO5|9yKiyW72; zX)t$tvpYB6@B6=B-+tklT<44LJaq8oC5wJ><0C)&;|8Lpdx<V@C8Cdr4&6aCZx1#9 zb`4S6>lC^27NYrgQ)GA(QM*Q)7OW?VK1rK9+KCdE(w6K9(M505_IrLw)O-aEHXkLr z;2qle*~3K20oqj@B3k}1?YaLTQS!_5-X~utT6|+e=Bc;w+*rf*<KM-)pUCU{D;u7? z^D&}}?`t?daureM=NeAwi-{U;mDlvW4R0Peg7ulk*u{^7Zntswx0ZpP-o~S&cM`R} z+j#VMHc|Xw<B9w;xW3V}cH2hK`ASp%2k+teH=2%Ijn50OZ#uFce6~N>^isbIJ`XlG z{`&w?M{jfVE5N<vuIBY;z;DAJnkO#(Gf}#?dFr$VI&X@!fA61=$8RE+U4J|1|50S* z1n$Rv7`f@IgG8yrk-ZV{-O&>H`VHNX%XH-VpMt*BN0DD&mBqgA<LVG~?Tc=Btr2{@ z65W0De#rgmsCwuWQRMqkZOs|bvo$*Q{tn>g<W;#MIwhXFwRC+}UK?MO*H$fh+vV7| z^HB7*8PI*niRj}~{~}tpF#6IrA@2pZM_)SeDDd8oDf&Z@!-ClBFMJ+!o{nGh3DCLh zSbWpen?y@b#_z~K2fo+G@9DY%bW!|I|A`PaUK;<)mS#NHm)QLZ=+CT9Ox+B;cu(T- z(H9_hCGqML`?3DP#L1)3Pi87{@`LB0_jGdALf|H5l2?C#YvW9^??cFY=|#yK49Fw> zR&rtu<k0e&q`~)-r{%Tl%H$J|;Q0&BB#$uevTr0`c=#;#c{&w&tN{5vo02$ROznK+ zH1znllvtlypK{+l06tTx{fDssf={Quy?#FA^51m(>IIN*Jl)<~#Pv(*t{Cu_?@Y^e zPP*8~`}L*oe(qJQJC=Un!)Kwd!|5NN1%Bkime^aoPisr!EY>HVZb=?n2tRqM<@c|_ zZx*d=UHU*X_;|VXzF$G^^X9ica~N{GU}@{w<Ex;LuC|e{!A>sxPTMU{sql+qZMQs) z>k_-|<Z<xT@o3wriJxQrzP5j;XCS}7>LBh^6BN)vo5>=La(LzO&ZaTEGvlnBC|>E! zmX%ZTmTl_hSPVDf*W|QOwP?5va`_7CCY4;g2FL(_i@(#}^3;lM)l~-!%QdEXb<+PR z*0<MPUH0_HUfk;M+-+qi#qLpB%Re5qO>5V#<&8QkpWUhF#x!?>>S$tBCk+aIRT?D) z0xOaZ(Yd5~II#_?t&FLKU@WBqs~>1O{hdsK@8Z3W*~XZbt!t*My1HcsV|UW^(1iy2 zY}$*fE%aki!J{*^(K0Msak8qR1><$lM(CGmvjnC~(^M#<Ful<-U8`s-?sOppTqkXX z(Wo>DA$EgR6_#h?Z@!E?TT@+4Ve<(l@4QT@zJ{06CfWzy*d3r(Av*=68RUT2aoo$3 z;gQ+8X<xyzT}5@2aW`)SQ+iolcs8pMv8e&C)FJROZ>u(cD?P7{g^==M>IH&Szt4(i z7#?!E*W9ati7Z=0Fbi?&gFK)z4<OQ~PHQ1n&cjNbCWIYT+E1cSH?`2lGYIR;Lr@le z3>Z<#(mi_8TUC2fv%@m92##0|$hOGPE*pRcnks=h`b-GfcT{0kJIpLvSby0DdTcPw zhN#07Iqa5)h?Z@ZomUNgCUk(<f%PtsvM_2OF|XLc@%WAR7hOZwY$w<vmRCA4{A2(G z3Wu%%+{Qkw45+r6*W6I}oM*~{1n}846vQ~zzXh@6v5%j)<PN&Y22jkKAvmZCL*5SC zvC~8ac3MymY}=X&0o+kVdbJ%S1Y9^Pm<O>Ih4WOSBnK?rbVK@27ebIOQ+-MOD&ifY zd6@*01GZH_OwhGZJPtt#oE{X<!7IQ9$E_*FfQN?w%Xknq{Cd!}tw}AcU;9uTOD8M5 zIbDL9(sS;3u!RSyF+GI5r&yy(AymFvL^~kxobX}|QmZg;&jV9C3c2t(a0{wA4M9;B zC7f9~R&Z#9F7SzKI|nbmlNH|1{?4_Z0^N-WGne;$N9x+)fGg9ORvgXHvaXg>Mv<0_ zb{I`|&@jZ#9xA=n!4=#2><#M{j6!krT!?_0p*>j7!O8`(oPTT&DK@M-`bd~MCQZA* z?ywL;&R@Sv8Pzo-7i<S<+Ffh??(pmP)LOqM?D`J6wxm>!u`(D`xZ1Ubp@?80Ty240 z%nqogX2@!`RLS~CJEc5@G584}$ymdxQIyKAgVkPE$)4-A39eqf+M*83$18~I0C&;` zXk1tyq(6gq6V<$Ku-tKF5SADuw|T&_P$Aah)7lq`&qXB&h3XgmfU7F{>+rZ(xPKO! z<U~FO8o8ffhZk<{*?MXtLdqC$XEb5&bs#fBt+s$Di1^?eN1|JG#ucvG*lFs3oL6aH z2PY$fr1bxBkOXadJjJ>-)6regW!8aMA^6ct$<BZ&I1tt>e~JiHC{8`tmTuH3Vfo~O zk4rL{NjdO}O4kF6Ggt_D&4W=CO2L{d8=uSMCbO8=Y^X0tacM-jVku7e>@;7e8=^z0 zBO)FNu=Q{OtbvYd>xpf)tzsdNfG)sPLMWmSL097mq*Xv+vf#(QI)ts88<CQ<666+y z__+#Uq77Q*?bKDdlagF%6}XL7ja7lh+XFR<J^&6ck`B2ZZmb8nFfUvEI;3|{Pstl+ zaFzW%QnLq>>|t+2|EvaSr&ZKO%%BRg{QMVXyHZ61R)>zXS6P*3j0mp{3VNMbYQZeH zsAqZP@mF*X9uuiPYfQCucRa6W1BAK`U@GLm1xd9FR{D@vPI}v9`YafX@X3(=w0O?l zxUTmDTC0y7!b^D$RNgY4n+?wCLF;IyU3eV}H7D{CH~)T})Vx(w#mJ`)LPj9SLQj^J zswcD9HVYDS)d00DErZ~(R=wUZ1<3ODunuMMSy+#r=51DB*68%=9LW>U4NSP8udhTu zm!*B$s2C5`A)u=YsuY-^d_OcMC0Gbgs7Bik9GR4S(j=O#kBtY>)`4I@JD&5Ju(B8# z>&IZmP=gX%2DKoE+blB$#g(%bAJFV928Tf|o~~I>Mnlz-6}2dQTI#Hppyx?EMKyCG z83s|+g&v<{g#(Y6t^TXCe;U2&h!U;@SWdIG?(E=$r%{s9N%R(#bw!Gi)e+qYt}PZ< z_HYmaXCw#EoHcw)OAM-e{i$Xhv*nozH`Q_|&t-}Q`=6|ot>;t8L9|j*qycU&BLx>e zY;c??{gfOVbk*!+V0K?FN*z`UhZ@cad>y4JsAvKtva9;T!3;pnoNDKwqP@B|o~pz8 zni}{DI_CN@=>l(`kddhi+Z54DvSoP#=&DIle6TpeEq#!kt`R+@4H2lNaKO1OD2!$X zi%vnd)gfull=k6DlWYC*IwC&I0~^fq11*4i;8{Q50e~O6;=96ie8GKm9sOoR6Fmn3 zyTcKXqnl|z*r=GC;4{}H3hYl#G-szCa>mIMAg)8DTXE?zhx$=b^02{A!JoQ$znJVO zx}%t=<Fi)2087TmK^f&k6lo+birFM4C7KeTfpulaALZj2uI#wL(%?i&rCoZS-oBxz z8#zT)#xzs2^=z$)6T((ja~zPv(?!wlC;bB<4=N&#fSA^@Bas?w-|*Lhtd$~Ya3Eq? z!T>?AoFetm5E$#jeXks%Rrti3Ht{2y2|2u#(<n|=T<omDQ&S??<%EtHZ$|9kBS~HQ z^DWk;jw8GRUVHIkfiX?xE0{i>eaZi@=2^V5@Z=~}fCac^hk&Y(h_X^Or<J{!rstHN zp{;$gsb8h^jzYQa8pR!l8Q{0*U>>HMj;pCTp8dJwrO_lmhJT0~1shS%Dq?|ID7w{0 zj5VbFag5{QjpEeIDKihY02E3!=8`q`?nJ9Ht3w`{$TWdC@7YX32n3yE^~kOU+S)QS zKGpKj@Se4@l2$`+r6aYner>+kV-$Nh%F5Mi`Cv^nYW1zOU7U7FjdCx~!O_n`sa_Vp zf?DdFgQ}X8Z$WbCr){9JLJk#_&pzXKn)9~|_HR>II)d^E$1+1u-bu4aRlE687q~2u zU~gRw4RWSr&ypU>vgXo;J*FaFdiY7U62;ZsFdGET!sk5Fs3B;c4$Yl?BTSY^z4cW; z3`3Lbv1?Dl%{h2T$1g`O9h(TTaHQpGkByQmR{1<<MlQ%XC@t~Cvto!nd)#s~Q>Fnv zuTe}*%dw}GhR4d1VBP%x2<0*K`4U>1QimaQ&isB|jX8M@z0Nr&54paR*1<9q=v8Wn zhYyus5J<1<R(f>DwZ?Fc$dZq<vG6g>IbYPMDDXU`#(6BwYtCKVS{l$6U<Wt`E?a_; zZ0#kBs=gpmdr$9c6171xb@)xxVRjLEH$G<(Qz1yL_U1SwH0ES^DdJtB<PyA`$1}3& z@=9Y*4C%qF>f+>f4pDHBkyXq%sA7Md6KF`YP1T;B1E~4{sq`fykB(I70O?#|-UWMT HY-so&T^Ur$ diff --git a/DataPlotly/i18n/DataPlotly_nl.ts b/DataPlotly/i18n/DataPlotly_nl.ts deleted file mode 100644 index 940024a4..00000000 --- a/DataPlotly/i18n/DataPlotly_nl.ts +++ /dev/null @@ -1,876 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS><TS version="2.0" language="nl" sourcelanguage=""> -<context> - <name>@default</name> - <message> - <location filename="../test/test_translations.py" line="48"/> - <source>Good morning</source> - <translation>Goedemorgen</translation> - </message> -</context> -<context> - <name>DataPlotly</name> - <message> - <location filename="../data_plotly.py" line="116"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="272"/> - <source>Plot Item</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../data_plotly.py" line="105"/> - <source>&DataPlotly</source> - <translation>&DataPlotly</translation> - </message> - <message> - <location filename="../data_plotly.py" line="119"/> - <source>Shows the DataPlotly dock</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyDock</name> - <message> - <location filename="../gui/dock.py" line="24"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> -</context> -<context> - <name>DataPlotlyDockWidgetBase</name> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="14"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="440"/> - <source>Plot Parameters</source> - <translation>Diagram Parameters</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="500"/> - <source>Z field</source> - <translation>Z Veld</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="480"/> - <source>Use only selected features</source> - <translation>Gebruik alleen geselecteerde objecten</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="487"/> - <source>Layer</source> - <translation>Laag</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="240"/> - <source>Properties</source> - <translation>Eigenschappen</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="382"/> - <source>Marker type</source> - <translation>Symbooltype</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1022"/> - <source>...</source> - <translation>...</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="336"/> - <source>Visible</source> - <translation>Zichtbaar</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="742"/> - <source>Bar orientation</source> - <translation>Staaf Oriëntatie</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1078"/> - <source>Normalization</source> - <translation>Normalisatie</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="710"/> - <source>Outliers</source> - <translation>Uitschieters</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="914"/> - <source>Bar gap</source> - <translation>Staaf ruimte</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1015"/> - <source>Violin side</source> - <translation>Violin side</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1157"/> - <source>Clean Plot Canvas</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1180"/> - <source>Update Plot</source> - <translation>Update Diagram</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1202"/> - <source>Create Plot</source> - <translation>Maak Diagram</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1261"/> - <source>Export as image</source> - <translation>Exporteer als afbeelding</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1280"/> - <source>Export as html</source> - <translation>Exporteer als html</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="169"/> - <source>Plot type</source> - <translation>Diagramtype</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="246"/> - <source>Line type</source> - <translation>Lijntype</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="253"/> - <source>Point type</source> - <translation>Punttype</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="265"/> - <source>Show lines</source> - <translation>Toon Lijnen</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="277"/> - <source>Marker color</source> - <translation>Symboolkleur</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="284"/> - <source>Stroke color</source> - <translation>Lijnkleur</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="355"/> - <source>Color scale</source> - <translation>Kleurverloop</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="321"/> - <source>Marker size</source> - <translation>Symboolgrootte</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="346"/> - <source>Invert color</source> - <translation>Inverteer Kleur</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="392"/> - <source>Stroke width</source> - <translation>Lijndikte</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="399"/> - <source>Opacity</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="416"/> - <source>Contour type</source> - <translation>Contourtype</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="460"/> - <source>Linked map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="470"/> - <source>Use only visible features</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="446"/> - <source>Feature subset</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="510"/> - <source>Y field</source> - <translation>Y Veld</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="535"/> - <source>X field</source> - <translation>X Veld</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="555"/> - <source>Use only features visible in map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="562"/> - <source>Use only features inside atlas feature</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1108"/> - <source>Type of plot</source> - <translation>Diagramtype</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1120"/> - <source>Plot in columns</source> - <translation>Diagram in Kolommen</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1127"/> - <source>Plot in rows</source> - <translation>Diagram in Rijen</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1209"/> - <source>Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1297"/> - <source>Dynamically update size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="677"/> - <source>Show legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="687"/> - <source>Horizontal legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="694"/> - <source>Show range slider</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="813"/> - <source>Invert histogram direction</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="823"/> - <source>Cumulative histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="856"/> - <source>Hover tooltip</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="849"/> - <source>Bar mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="877"/> - <source>Show statistics</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1008"/> - <source>Z label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="752"/> - <source>Set X Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="954"/> - <source>Minimum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="971"/> - <source>Maximum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="870"/> - <source>X axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="991"/> - <source>Y axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="897"/> - <source>Show mean line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="921"/> - <source>Invert Y axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="890"/> - <source>Legend title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="907"/> - <source>X label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="665"/> - <source>Additional hover label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1001"/> - <source>Manual bin size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="842"/> - <source>Invert X axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="703"/> - <source>Plot title</source> - <translation type="unfinished">Titel van het Diagram</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="935"/> - <source>Y label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="942"/> - <source>Set Y Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1065"/> - <source>If checked, box plots will be overlaid on top of violin plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1068"/> - <source>Include box plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="863"/> - <source>Hover label as text</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1085"/> - <source>Label text position</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyPanelWidget</name> - <message> - <location filename="../gui/plot_settings_widget.py" line="104"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="131"/> - <source>Load Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="133"/> - <source>Save Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="572"/> - <source>None</source> - <translation>Geen</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="176"/> - <source>Single Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="177"/> - <source>Subplots</source> - <translation>Subdiagrammen</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="560"/> - <source>Vertical</source> - <translation>Verticaal</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="561"/> - <source>Horizontal</source> - <translation>Horizontaal</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="565"/> - <source>No Outliers</source> - <translation>Geen uitschieters</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="566"/> - <source>Standard Outliers</source> - <translation>Standaard Uitschieters</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="567"/> - <source>Suspected Outliers</source> - <translation>Verwachte uitschieters</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="568"/> - <source>All Points</source> - <translation>Alle Punten</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="573"/> - <source>Mean</source> - <translation>Gemiddelde</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="574"/> - <source>Standard Deviation</source> - <translation>Standaardafwijking</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="582"/> - <source>Linear</source> - <translation>Lineair</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="583"/> - <source>Logarithmic</source> - <translation>Logaritmisch</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="584"/> - <source>Categorized</source> - <translation>Gecategoriseerd</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="887"/> - <source>Points</source> - <translation>Punten</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="896"/> - <source>Lines</source> - <translation>Lijnen</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="587"/> - <source>Points and Lines</source> - <translation>Punten en lijnen</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Solid Line</source> - <translation>Doorgetrokken lijn</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Line</source> - <translation>Stippellijn</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dash Line</source> - <translation>Streepjes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Line</source> - <translation>Lange streepjes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Dash Line</source> - <translation>Stippel streep lijn</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Dot Line</source> - <translation>Lange streep Stippel Lijn</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="647"/> - <source>Grouped</source> - <translation>Gegroepeerd</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="648"/> - <source>Stacked</source> - <translation>Gestapeld</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="649"/> - <source>Overlay</source> - <translation>Overlappend</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="653"/> - <source>Enumerated</source> - <translation>Opgesomd</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="654"/> - <source>Percents</source> - <translation>Procenten</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="655"/> - <source>Probability</source> - <translation>Waarschijnlijkheid</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="656"/> - <source>Density</source> - <translation>Dichtheid</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="657"/> - <source>Prob Density</source> - <translation>Kansdichtheid</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Fill</source> - <translation>Vullen</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Heatmap</source> - <translation>Hittekaart</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Only Lines</source> - <translation>Alleen lijnen</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="696"/> - <source>Grouping field -(optional)</source> - <translation>Groepeer veld -(optioneel)</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="702"/> - <source>Box orientation</source> - <translation>Box Oriëntatie</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="703"/> - <source>Box color</source> - <translation>Boxkleur</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="706"/> - <source>X field</source> - <translation>X Veld</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="710"/> - <source>Marker color</source> - <translation>Symboolkleur</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="712"/> - <source>Bar orientation</source> - <translation>Staaf Oriëntatie</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="713"/> - <source>Bar color</source> - <translation>Staafkleur</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="716"/> - <source>Grouping field</source> - <translation>Groepeer veld</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="724"/> - <source>All Values</source> - <translation>Alle Waardes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="725"/> - <source>X Values</source> - <translation>X Waardes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="726"/> - <source>Y Values</source> - <translation>Y Waardes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="727"/> - <source>No Data</source> - <translation>Geen data</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="737"/> - <source>Both Sides</source> - <translation>Beide zijdes</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="738"/> - <source>Only Left</source> - <translation>Alleen Links</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="739"/> - <source>Only right</source> - <translation>Alleen Rechts</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1208"/> - <source>{} plot is not compatible for subplotting - see </source> - <translation>{} Diagram is niet geschikt voor subdiagrammen -Zie</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1295"/> - <source>Save Plot</source> - <translation>Diagram opslaan</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1284"/> - <source>Plot saved to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1303"/> - <source>Saved plot to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1420"/> - <source>Load Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1427"/> - <source>Could not read settings from file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1433"/> - <source>Save Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>Saved configuration to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="731"/> - <source>Automatic</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="732"/> - <source>Inside bar</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="733"/> - <source>Outside bar</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyProcessingPlot</name> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="88"/> - <source>Input layer</source> - <translation>Input laag</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="95"/> - <source>Plot type</source> - <translation>Diagramtype</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="103"/> - <source>Plot title</source> - <translation>Titel van het Diagram</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="111"/> - <source>X Field</source> - <translation>X Veld</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="121"/> - <source>Y Field</source> - <translation>Y Veld</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="131"/> - <source>Color</source> - <translation>Kleur</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="140"/> - <source>Color (any valid HTML color) If set, this is used instead of the color set in the previous input.</source> - <translation>Kleur (elke valide HTML kleur) Wanneer ingesteld, wordt deze kleur gebruikt i.p.v. de kleur van de vorige input.</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML File</source> - <translation>HTML Bestand</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML files (*.html)</source> - <translation>HTML bestanden (*.html)</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON file</source> - <translation>JSON Bestand</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON Files (*.json)</source> - <translation>JSON Bestanden (*.JSON)</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="170"/> - <source>Build a generic plot</source> - <translation>Maak een generiek diagram</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="176"/> - <source>Plots</source> - <translation>Diagrammen</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="209"/> - <source>The chosen plot type needs a X field !</source> - <translation>Het gekozen diagramtype vereist een X veld!</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="211"/> - <source>The chosen plot type needs a Y field !</source> - <translation>Het gekozen diagramtype vereist een Y veld!</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="173"/> - <source>Creates a generic Plotly plot</source> - <translation>Maak een generiek diagram</translation> - </message> -</context> -<context> - <name>PlotLayoutItemWidget</name> - <message> - <location filename="../gui/layout_item_gui.py" line="82"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="77"/> - <source>Setup Selected Plot</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PlotType</name> - <message> - <location filename="../core/plot_types/histogram2d.py" line="28"/> - <source>2D Histogram</source> - <translation>2D Histogram</translation> - </message> - <message> - <location filename="../core/plot_types/box.py" line="28"/> - <source>Box Plot</source> - <translation>Boxplot</translation> - </message> - <message> - <location filename="../core/plot_types/histogram.py" line="28"/> - <source>Histogram</source> - <translation>Histogram</translation> - </message> - <message> - <location filename="../core/plot_types/bar_plot.py" line="27"/> - <source>Bar Plot</source> - <translation>Staafdiagram</translation> - </message> - <message> - <location filename="../core/plot_types/scatter.py" line="28"/> - <source>Scatter Plot</source> - <translation>Spreidingsdiagram</translation> - </message> - <message> - <location filename="../core/plot_types/violin.py" line="28"/> - <source>Violin Plot</source> - <translation>Violin Plot</translation> - </message> - <message> - <location filename="../core/plot_types/polar.py" line="28"/> - <source>Polar Plot</source> - <translation>Polair diagram</translation> - </message> - <message> - <location filename="../core/plot_types/contour.py" line="28"/> - <source>Contour Plot</source> - <translation>Contourdiagram</translation> - </message> - <message> - <location filename="../core/plot_types/ternary.py" line="28"/> - <source>Ternary Plot</source> - <translation>Driehoeksdiagram</translation> - </message> - <message> - <location filename="../core/plot_types/pie.py" line="28"/> - <source>Pie Chart</source> - <translation type="unfinished"></translation> - </message> -</context> -</TS> diff --git a/DataPlotly/i18n/DataPlotly_sv.qm b/DataPlotly/i18n/DataPlotly_sv.qm deleted file mode 100644 index c2b3c2a4322971dee5efa93824e52890d9b52e36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10255 zcmbtadyE`)9sl0lzIX4@>-Ks*N|`>aS7>T^M5FTRJ^JF>yL7MDmIUM6?%eM5W@na} z**mUH5iKf6l*9%pgcyqu)L@K4BN7#2fvBmkw3J6`4N(3d5g%YN1)_ewzuBAFz3%Ny zC3m;8ukUBR@7M3HeJa=e+rK|_-|v<$edhB=e(~o%qL#x%SGEz+2SkVOB<i@6LVsL~ zYYT-xdpps>qZA$+BuamQ1{YmT6gfwmy3$1PB5lo%6J2tOcHH|bqR=7AgpLt)UP8M* z`2>-)oOYK-iB@&f%@5p1l(?7P`S>eD%X*tSAO9=Sg8Q0woP3xlyvVsOoNW63mmeXz zG}m-;{CcA9fu=L+GNPt~&NcO9)7gVZ@%ih`(Mul%->)|BIkXb|+~0g`;>$$s>E>fE znnbY|n@<&=0)JA=y6yeAZ@Q)Uqj$jHXIhTlfY(a~TaF%poav)2$A@ju{WR44-a(=+ zITZOKa4+i%U40JnHs281d&TQSsbXmQT?O=i2;H+G3w~Y;r@!}4=;iJ3`kTH4IsOtJ zKZVbu?}cyuYKAEJQg|v1`MXwzzkbUA^dpC#``Jq1tPKD9deAR<3s;M%rx59Txf%NS zMr6;i2cZA!BJ$xg(8qrw%Gz__>()sA-#dZ(xO2VirO34S-hs;XY3JIq-nq8j6S?C` z+_(GT$Q}E@|7CYY9-aOd(TYQn<KKkd7kxW&{M2`$pX;KM`VjQDKl;k^pC($oICkU5 zz~{<MvBBxH`2J|@&f>F>^UB!0J)Z(!6npK1F!XVE?2WA<e11H>=l9^hb1Xi+pYiUB zKRWR|QQNig6OSFh=L_SfkHJozN8+d7e-5}`Nvv4{-1yUp8{WsY`AlNyL+E|^p~Nj3 z^wHX$*t-^bXx)|2`2FN!=h|~c;;|$6es@daDC4edPdxvf^SIB6WcZO1^!J0LgL5Le z>&Uy1FO+oXcO~tA9E9F>CJ!9O{TJ;>-hcH%;QTk0zI+k%JDy5!DdYNNswWEkm48Y( zboZyqLwLP7m%97e6QFw|_27p;hrJ$4{p39GBRg87Z{eC=-x@y;`ov4EiQg<ioV?ol z>dT0qr5$Z69t=T_x7)t;0`%Uoq3x+BpvMIxZRby}ft^pckADq*viQgCw?8f;KIHb> zf5_MO+fSc_TwTw!pV|9M&>wF9n|u!b)v6+R##&&2G;Jb-awJg^SCjI1)MIR#2>w!= z3?nBM4O3V3d=ziQZp<kYa#^#Rn7E5p(*Vh2<8OpCklJ{hamkab2V`3w(F|LgVd{kU zQqZRxQdfQZBNMlIcOEdZlj80XTE{;ww=L_|t>YVY*M4`Gn#(J8pKK|DY8hpOyd_c~ zYf(IEkY9)L%2agGqJ6R{<>it;;))tXHi8ON9d}X0bDi=oYCEGErmE<+Y^#Ruk1h%H zvoNs?BM$&uhLKG?7HNhhaj_TlYl^H(Y%Zx^)~964AH9<{(pjM8$)ZVMLK7}tvft1Q zQ?jzMruZW*rJLCGz)=}^8u-*{FEn6-%aV(k>Nj-TD4UW!Qwjju1L2vi68`20??NW~ zO+~g9A-6x97v-{zJ!usU(rsXkE$-NwnY8e_h-(4w6-jg1Y#Y3-WSF)jTT;O;YW|!y zh98H5HOjg0?H;^Zl=A^}E72C1Xi7M#$NsE4z;#{h)E0e80qa@z2Y<#BGz4?y8Q6sg z56Lr10NM`F*7uzFkg6*I-6l=jz<~+Zc@K{hj)%Lvq_)ZCq+$jYr>6$Yf?3(%8pNA) zA(ItIOWhYh^PM$_wE;4V6f{1z3vP-KmqX4H)?@{GDW`S2VHRag-4`(7bkHzDm<s`? zF_SD;%Ghw()>Op|kXKgB$y6M`PR`<tz|TD2Xcrl4L^kE3Vh2KBH3wY+tCGk+8s~6` zU+sGizN)jq%SAl^_si<y?*P}i8swDV9LT0I9RQYdPj&jPwR~KF1+#kx%5@oHPC}Wr zD2Wk6)$PD>GAQCyuVjC&iJn~&Bc@S8+^b3e*}7;<_#dZ0FNCYWG6iE=(h$P|z&fiS zE{NWYZ5oqG(CAH9L5;)l6qwM<nyCudw3@RE{+X?@0aK%>X_7G^l~95G!B)^t6pxZ9 z>|Xw@@enuik~>Se;5F_V+8{FfSv+!Q$j!*O2tXUJrtl1v1CJ7N$G9lc@FVwLJv%K( zp=&derD#glR&vq=3T)X7V!00V6DnXec$CUFabc5VssZy$mYNHYB2y^*GhmyOkeAA$ zW2&W&2kAyqv>W1aG1IC<i|&>tR7K1A8z)73>e25BPJeSf`kRB&cf*7le%MGQH`HsQ zbAzTyBG^ShE%KV)5m{F>r|YeB`5xAksD+%xydfdMNMo{Ab`0DADJ^<YZpXNHo*S8Q z?rq&3p#jWCZI~NCr>T$LtT=Z@cp!?k>w}3t!!Ae}c%Yxo+K@IF=Rz5c+XBhBv;x4r zLZfj2aC63i2GaGQ#__bKAZt6oPQgcAa%D{RBT?jmxla*(-T-c?Fem54tmv{iSGc*` z1&j~KRzc$Ki^HY?+(ot44RAV8COKts24Pvf)D#_1bW63xEZP8Ibyaobe$7w9)&WdR z!KL&{FJ~t)<+#d<F;oCubwl+$!Exipljm6&K*w{>j)_6NTvSXL)6a~Yb7w@h&;>tU zz6@<tH8E*4P*x`v2t4_6DdKjonuq8n(<qmG8CW(4LiC?79|uo$`fU?%*hF|)umNLN zHAaQ6Ca4!(2UoKRFs{-X*9<+icajplMv2F5SzF`l#9LqpcDuR`xEYnO=qv>qu--+R z-S~87V$PS|EST8L@rg-T_OnjP4M<Gsu6PmlFj<UK4Y=@VtLsLXY5me)7jA1H$#B!o zL0H5i76dK>$sr>zo2p$Xs#za}t`~_A0|^Y~MNW{g>>M)SDk3feM%C)7du0Lyew%lP z05N-!Q)L6oBrpJSBMPr@RT|oc<&BRnJH^P(X5nRs*xR}E(d`CwWy?MgJyj6%&3Q>c zRgZcNB#F(!xqO7S8@`odDK;nEn#yo0Zb`?GC^+0i8|)&*hq(zIQYJ(*-GGT60q1qN zZVjsnnS=ut!1uf7Ft-^?gxY0>gJr7uf*)sTI#t=Qa4YAm?YtBp9mZNkll{tB8{)=9 zIA%ps@~UBML@~2iB>Dw2)6Wiz)tMj?sC!&hOATu=Ck0&Vsky_!lw>_8%Ag-_+zN69 z)Pc&?bW(VB{p6d%JUT7~YXO}4%D5hK0s8Z_mt-_~T-E&h3Eo1^E-)mxZPg6#Icr9q z@^+97oOKy$16PBbsI}}^dbKWHz(fY)lA}bQknRv|9CzjHWXLKmMl@r~*-78}J=>2v zA!&-hoPyu7Iha*6nJ#1}AoZMV=3s~^)m<qy5cooLY2FRf0vA1C{^5zFj3KuE*c{80 z$9Wj{^TO50$6Vkz192wewF>9h`4VJjrfij*(KsNV9msLqUD-mZXjxo^#>RNXf*rfB zm3gA&Ovwg<*LVoKgH3P#GjRhec8Gzv?(O#kyZz^AKOKMwHSvSjyx->#;I5GifFxe? zpgLP3yrsG&j9rV6VE-h^RmUgx9}pWDNwp*$-FVh0mf)vY8%Ps;oZ+~HjW#ra4TmE6 z==~Z@lru=(+`sVdlIxWdwQNt(7K!(2m~xp(_mx#GC&^M?(G^q8*4qss5oHz20z<q3 z6eD|V_E^RR3X8)S=C$fjq7LN?vy@=7x3cSTx?>56XB3V;gik7CEv>=xVRUzn&hrq5 z&jWN?TX|>J3Km`qr^9C)7`$$Ef`yk9tQN-PWxI#%BsR9KhwD%}-{c|oO>s9yp7jep zgv?hR>d8WGsaMu#q$zB%bJFI~Z9~oozDC+I0TbG5CA$D)<F{;KTczrjt;jjv#My<) zqL9Ca55yZK6Pe2>gFr8p?YT#Wb#(gCT;NjYe9EeF0=6?+n>u^KI(P4=vKuegywnjF zs=$mlccE4XWpx$G1fxLbY^`3p9EYft!>XzYYN5cM0JbIdUcQcxti<Tl*!#LfJIIY4 zCs3#7sct!vTUg~1dY%gogX;3U73qDLwu4V0c@58d;ek9{c~jrQt(oEN66-_oyw@`H z06ce)cNd`<H|F93k9FW5cipum2=Y723(r~!wz_1ib`ZG6o920s3hF4at(GxYxG=LL z3S(oFZmf*hyd0{@aS#zFyLfjTW+@=}oufoAOLD!ctN>`ad*9Wg9FqmZQgkOx^NEL~ zD@u+dq_Uuumiue`|7VO>yBEt?W%C<^v3cw4#yY#_Iu@IE_Z*PEo34V*Io)%0;^WH7 z{|mS_NL@7`ZB{MY$m7h7H63GT;NuHXeYoG{_;uF2HAZ(KV!Z5Sstd{a$c1;O^ATd@ zS)Y*Co8G?=)F*fUfuKG_X9KC@4Mgt7l*1E<(_PhT@NuxF%_}nZxFyjJ<dBhO_h0i! zkjct6&N=5%!ZH+T?kk+a=}Zds_(_c_rY@T^^T2e8jL9O^=VJCa=0Y{z1%GI6YWg3m CcU9#8 diff --git a/DataPlotly/i18n/DataPlotly_sv.ts b/DataPlotly/i18n/DataPlotly_sv.ts deleted file mode 100644 index b11c5cbc..00000000 --- a/DataPlotly/i18n/DataPlotly_sv.ts +++ /dev/null @@ -1,876 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE TS><TS version="2.0" language="sv" sourcelanguage=""> -<context> - <name>@default</name> - <message> - <location filename="../test/test_translations.py" line="48"/> - <source>Good morning</source> - <translation>God morgon</translation> - </message> -</context> -<context> - <name>DataPlotly</name> - <message> - <location filename="../data_plotly.py" line="116"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="272"/> - <source>Plot Item</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../data_plotly.py" line="105"/> - <source>&DataPlotly</source> - <translation>&DataPlotly</translation> - </message> - <message> - <location filename="../data_plotly.py" line="119"/> - <source>Shows the DataPlotly dock</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyDock</name> - <message> - <location filename="../gui/dock.py" line="24"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> -</context> -<context> - <name>DataPlotlyDockWidgetBase</name> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="14"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="440"/> - <source>Plot Parameters</source> - <translation>Diagramparametrar</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="500"/> - <source>Z field</source> - <translation>Z Fält</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="480"/> - <source>Use only selected features</source> - <translation>Använd enbart valda objekt</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="487"/> - <source>Layer</source> - <translation>Lager</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="240"/> - <source>Properties</source> - <translation>Egenskaper</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="382"/> - <source>Marker type</source> - <translation>Markörtyp</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1022"/> - <source>...</source> - <translation>...</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="336"/> - <source>Visible</source> - <translation>Synlig</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="742"/> - <source>Bar orientation</source> - <translation>Stapelorientering</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1078"/> - <source>Normalization</source> - <translation>Normalisering</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="710"/> - <source>Outliers</source> - <translation>Outliers</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="914"/> - <source>Bar gap</source> - <translation>Stapelmellanrum</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1015"/> - <source>Violin side</source> - <translation>Fiolsida</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1157"/> - <source>Clean Plot Canvas</source> - <translation>Städa Diagramyta</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1180"/> - <source>Update Plot</source> - <translation>Uppdatera Diagram</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1202"/> - <source>Create Plot</source> - <translation>Skapa Diagram</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1261"/> - <source>Export as image</source> - <translation>Exportera som bild</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1280"/> - <source>Export as html</source> - <translation>Exportera som html</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="169"/> - <source>Plot type</source> - <translation>Diagramtyp</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="246"/> - <source>Line type</source> - <translation>Linjetyp</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="253"/> - <source>Point type</source> - <translation>Punkttyp</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="265"/> - <source>Show lines</source> - <translation>Visa Linjer</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="277"/> - <source>Marker color</source> - <translation>Markörfärg</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="284"/> - <source>Stroke color</source> - <translation>Linjefärg</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="355"/> - <source>Color scale</source> - <translation>Färgskala</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="321"/> - <source>Marker size</source> - <translation>Markörstorlek</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="346"/> - <source>Invert color</source> - <translation>Invertera Färger</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="392"/> - <source>Stroke width</source> - <translation>Linjebredd</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="399"/> - <source>Opacity</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="416"/> - <source>Contour type</source> - <translation>Konturlinjetyp</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="460"/> - <source>Linked map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="470"/> - <source>Use only visible features</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="446"/> - <source>Feature subset</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="510"/> - <source>Y field</source> - <translation>Y Fält</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="535"/> - <source>X field</source> - <translation>X Fält</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="555"/> - <source>Use only features visible in map</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="562"/> - <source>Use only features inside atlas feature</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1108"/> - <source>Type of plot</source> - <translation>Diagramtyp</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1120"/> - <source>Plot in columns</source> - <translation>Diagram i Kolumner</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1127"/> - <source>Plot in rows</source> - <translation>Diagram i Rader</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1209"/> - <source>Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1297"/> - <source>Dynamically update size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="677"/> - <source>Show legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="687"/> - <source>Horizontal legend</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="694"/> - <source>Show range slider</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="813"/> - <source>Invert histogram direction</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="823"/> - <source>Cumulative histogram</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="856"/> - <source>Hover tooltip</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="849"/> - <source>Bar mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="877"/> - <source>Show statistics</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1008"/> - <source>Z label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="752"/> - <source>Set X Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="954"/> - <source>Minimum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="971"/> - <source>Maximum</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="870"/> - <source>X axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="991"/> - <source>Y axis mode</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="897"/> - <source>Show mean line</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="921"/> - <source>Invert Y axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="890"/> - <source>Legend title</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="907"/> - <source>X label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="665"/> - <source>Additional hover label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1001"/> - <source>Manual bin size</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="842"/> - <source>Invert X axis</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="703"/> - <source>Plot title</source> - <translation type="unfinished">Diagramtitel</translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="935"/> - <source>Y label</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="942"/> - <source>Set Y Axis Bounds</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1065"/> - <source>If checked, box plots will be overlaid on top of violin plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1068"/> - <source>Include box plots</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="863"/> - <source>Hover label as text</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../ui/dataplotly_dockwidget_base.ui" line="1085"/> - <source>Label text position</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyPanelWidget</name> - <message> - <location filename="../gui/plot_settings_widget.py" line="104"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="131"/> - <source>Load Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="133"/> - <source>Save Configuration…</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="572"/> - <source>None</source> - <translation>Inga</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="176"/> - <source>Single Plot</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="177"/> - <source>Subplots</source> - <translation>SubDiagram</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="560"/> - <source>Vertical</source> - <translation>Vertikal</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="561"/> - <source>Horizontal</source> - <translation>Horisontell</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="565"/> - <source>No Outliers</source> - <translation>Inga Outliers</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="566"/> - <source>Standard Outliers</source> - <translation>Standard Outliers</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="567"/> - <source>Suspected Outliers</source> - <translation>Misstänkta Outliers</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="568"/> - <source>All Points</source> - <translation>Alla punkter</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="573"/> - <source>Mean</source> - <translation>Medel</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="574"/> - <source>Standard Deviation</source> - <translation>Standardavvikelse</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="582"/> - <source>Linear</source> - <translation>Linjär</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="583"/> - <source>Logarithmic</source> - <translation>Logaritmisk</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="584"/> - <source>Categorized</source> - <translation>Kategoriserad</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="887"/> - <source>Points</source> - <translation>Punkter</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="896"/> - <source>Lines</source> - <translation>Linjer</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="587"/> - <source>Points and Lines</source> - <translation>Punkter och Linjer</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Solid Line</source> - <translation>Heldragen Linje</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Line</source> - <translation>Punktlinje</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dash Line</source> - <translation>Streckad Linje</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Line</source> - <translation>Lång Streckad Linje</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Dot Dash Line</source> - <translation>Punktstreckad Linje</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="632"/> - <source>Long Dash Dot Line</source> - <translation>Lång Punktstreckad Linje</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="647"/> - <source>Grouped</source> - <translation>Grupperad</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="648"/> - <source>Stacked</source> - <translation>Staplade</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="649"/> - <source>Overlay</source> - <translation>Överlagrad</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="653"/> - <source>Enumerated</source> - <translation>Sammanräknad</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="654"/> - <source>Percents</source> - <translation>Procent</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="655"/> - <source>Probability</source> - <translation>Sannnolikhet</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="656"/> - <source>Density</source> - <translation>Densitet</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="657"/> - <source>Prob Density</source> - <translation>Sannolik Densitet</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Fill</source> - <translation>Fyllning</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Heatmap</source> - <translation>Intensitet</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="660"/> - <source>Only Lines</source> - <translation>Enbart Linjer</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="696"/> - <source>Grouping field -(optional)</source> - <translation>Grupperingsfält -(Valfri)</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="702"/> - <source>Box orientation</source> - <translation>Lådorientering</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="703"/> - <source>Box color</source> - <translation>Lådfärg</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="706"/> - <source>X field</source> - <translation>X Fält</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="710"/> - <source>Marker color</source> - <translation>Markörfärg</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="712"/> - <source>Bar orientation</source> - <translation>Stapelorientering</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="713"/> - <source>Bar color</source> - <translation>Stapelfärg</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="716"/> - <source>Grouping field</source> - <translation>Grupperingsfält</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="724"/> - <source>All Values</source> - <translation>Alla värden</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="725"/> - <source>X Values</source> - <translation>X Värden</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="726"/> - <source>Y Values</source> - <translation>Y Värden</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="727"/> - <source>No Data</source> - <translation>Inga Data</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="737"/> - <source>Both Sides</source> - <translation>Båda Sidor</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="738"/> - <source>Only Left</source> - <translation>Endast Vänster</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="739"/> - <source>Only right</source> - <translation>Endast Höger</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1208"/> - <source>{} plot is not compatible for subplotting - see </source> - <translation>{} diagram kan inte användas som subdiagram -se </translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1295"/> - <source>Save Plot</source> - <translation>Spara diagram</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>DataPlotly</source> - <translation>DataPlotly</translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1284"/> - <source>Plot saved to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1303"/> - <source>Saved plot to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1420"/> - <source>Load Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1427"/> - <source>Could not read settings from file</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1433"/> - <source>Save Configuration</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="1438"/> - <source>Saved configuration to <a href="{}">{}</a></source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="731"/> - <source>Automatic</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="732"/> - <source>Inside bar</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/plot_settings_widget.py" line="733"/> - <source>Outside bar</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>DataPlotlyProcessingPlot</name> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="88"/> - <source>Input layer</source> - <translation>Indatalager</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="95"/> - <source>Plot type</source> - <translation>Diagramtyp</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="103"/> - <source>Plot title</source> - <translation>Diagramtitel</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="111"/> - <source>X Field</source> - <translation>X Fält</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="121"/> - <source>Y Field</source> - <translation>Y Fält</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="131"/> - <source>Color</source> - <translation>Färg</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="140"/> - <source>Color (any valid HTML color) If set, this is used instead of the color set in the previous input.</source> - <translation>Färg (valfri HTML färg) Om angiven, används denna i stället för färgen angiven i föregående dialog.</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML File</source> - <translation>HTML Fil</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="149"/> - <source>HTML files (*.html)</source> - <translation>HTML filer (*.html)</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON file</source> - <translation>JSON fil</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="157"/> - <source>JSON Files (*.json)</source> - <translation>JSON Filer (*.json)</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="170"/> - <source>Build a generic plot</source> - <translation>Bygg ett generiskt diagram</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="176"/> - <source>Plots</source> - <translation>Diagram</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="209"/> - <source>The chosen plot type needs a X field !</source> - <translation>Vald diagramtyp behöver ett X fält!</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="211"/> - <source>The chosen plot type needs a Y field !</source> - <translation>Vald diagramtyp behöver ett Y fält!</translation> - </message> - <message> - <location filename="../processing/dataplotly_algorithms.py" line="173"/> - <source>Creates a generic Plotly plot</source> - <translation>Bygg ett generiskt diagram</translation> - </message> -</context> -<context> - <name>PlotLayoutItemWidget</name> - <message> - <location filename="../gui/layout_item_gui.py" line="82"/> - <source>Plot Properties</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../gui/layout_item_gui.py" line="77"/> - <source>Setup Selected Plot</source> - <translation type="unfinished"></translation> - </message> -</context> -<context> - <name>PlotType</name> - <message> - <location filename="../core/plot_types/histogram2d.py" line="28"/> - <source>2D Histogram</source> - <translation>2D Histogram</translation> - </message> - <message> - <location filename="../core/plot_types/box.py" line="28"/> - <source>Box Plot</source> - <translation>Låddiagram</translation> - </message> - <message> - <location filename="../core/plot_types/histogram.py" line="28"/> - <source>Histogram</source> - <translation>Histogram</translation> - </message> - <message> - <location filename="../core/plot_types/bar_plot.py" line="27"/> - <source>Bar Plot</source> - <translation>Stapeldiagram</translation> - </message> - <message> - <location filename="../core/plot_types/scatter.py" line="28"/> - <source>Scatter Plot</source> - <translation>Spridningsdiagram</translation> - </message> - <message> - <location filename="../core/plot_types/violin.py" line="28"/> - <source>Violin Plot</source> - <translation>Fioldiagram</translation> - </message> - <message> - <location filename="../core/plot_types/polar.py" line="28"/> - <source>Polar Plot</source> - <translation>Polärdiagram</translation> - </message> - <message> - <location filename="../core/plot_types/contour.py" line="28"/> - <source>Contour Plot</source> - <translation>Konturdiagram</translation> - </message> - <message> - <location filename="../core/plot_types/ternary.py" line="28"/> - <source>Ternary Plot</source> - <translation>Triangeldiagram</translation> - </message> - <message> - <location filename="../core/plot_types/pie.py" line="28"/> - <source>Pie Chart</source> - <translation type="unfinished"></translation> - </message> -</context> -</TS> diff --git a/DataPlotly/metadata.txt b/DataPlotly/metadata.txt index aabfac1a..78a50f13 100644 --- a/DataPlotly/metadata.txt +++ b/DataPlotly/metadata.txt @@ -1,17 +1,8 @@ -# This file contains metadata for your plugin. Since -# version 2.0 of QGIS this is the proper way to supply -# information about a plugin. The old method of -# embedding metadata in __init__.py will -# is no longer supported since version 2.0. - -# This file should be included when you package your plugin.# Mandatory items: - [general] name=Data Plotly qgisMinimumVersion=3.4 qgisMaximumVersion=3.98 description=D3 Plots for QGIS -version=3.9 author=Matteo Ghetta (Faunalia) email=matteo.ghetta@gmail.com @@ -21,80 +12,15 @@ tracker=https://github.com/ghtmtt/DataPlotly/issues repository=https://github.com/ghtmtt/DataPlotly # End of mandatory metadata -# Recommended items: - -# Uncomment the following line and add your changelog: +# Done by qgis-plugin-ci +version=master changelog= - Version 3.9 - - [feature] Customize font for plot title and plot axis. Kudos to @giliam - Version 3.8 - - [feature] expose DataPlotly on QGIS Server for a GetPrint request kudos to @Gustry - Version 3.7 - - [feature] histogram and pie chart bar and slices with same color of category! kudos to @jdugge - - [feature] plot background transparent in layouts! - Version 3.6 - - [feature] Multi Plot in layout composer! Ultra kudos to @SGroe - - [bugfix] Fix layout composer issue with many plots (ref #207). Thanks to the Italian Community for testing - - [bugfix] Fix categorical bar plot wrong behavior - - [bugfix] code cleaning - Version 3.5 - - [bugfix] Fix loading old projects - Version 3.4 - - [feature] get labels within the plot itself - - [bugfix] Native datetime support! thanks @jdugge - - [bugfix] Fix histogram selection - Version 3.3 - - [bugfix] better loading project part 2 - Version 3.2 - - [bugfix] fix violin plot bug - - [bugfix] better loading project handling - Version 3.1 - - [feature] more data defined options available (in layout customization). Thanks @SGroe - - [feature] X and Y axis bounds limits. Thanks @SGroe - - [feature] add box plot within violin plots - - [feature] renaming of plugin metadata to better search. Thanks @Gustry - - [bugfix] Box plot not working when no group is selected - - [bugfix] Data-defined property overrides do not work in layout +commitNumber= +commitSha1= +dateTime= +# End of qgis-plugin-ci - Version 3.0 - - [feature] total refactoring of the code - - [feature] plots also in print composer - - [feature] atlas based plots - - [feature] chance to save/load configuration file of plot setting - - [feature] plot settings saved together with the project - - [feature] more datadefined properties - - [feature] show only selected/visible/filtered features - - [feature] unit tests and continuous integration - Version 2.3 - - [feature] tweaks polar plots, thanks @josephholler - Version 2.2 - - [feature] UI tweaks, thanks @nyalldawson - Version 2.1 - - [fix] typos in UI (thanks @leonmvd and @nyalldawson) - - [fix] better python packages imports (thanks @nyalldawson) - Version 2.0 - - [feature] DataPlotly is updated with plotly 3.3 version - Version 1.6 - - [feature] wheel zoom! Give it a try - - [feature] Edit plot title and X/Y labels in place - Version 1.5.1 - - [feature] Spanish translation. Special thanks to Luca Bellani - - [bugfix] always open English manual if locale not translated - Version 1.5 - - [feature] **new** Violin plots! - - [feature] **new** Polar plot layout! - - [feature] better default color choice - Version 1.4.3 - - [bugfix] correct interaction with pie plot - - update plotly.js to v 1.34.0 - Version 1.4.2 - - [bugfix] correct saving html plot - Version 1.4.1 - - [bugfixing] adaptation for new API - Version 1.4 - - [feature] update plotly.js to v 1.33.1 - - [feature] multiple selection with Shift + selection tool - - [feature] DataPlotly as Processing provider, thanks to Michaël Douchin of 3Liz +# Recommended items: # Tags are comma separated with spaces allowed tags=python, d3, plots, vector, graphs, datavis, dataviz, dataplotly diff --git a/Makefile b/Makefile index 81d9fe6d..8f4d560f 100644 --- a/Makefile +++ b/Makefile @@ -23,33 +23,6 @@ ################################################# -#Add iso code for any locales you want to support here (space separated) -# default is no locales -LOCALES = en it nl sv fr es af - -# If locales are enabled, set the name of the lrelease binary on your system. If -# you have trouble compiling the translations, you may have to specify the full path to -# lrelease -LRELEASE ?= lrelease-qt5 - - -# translation -SOURCES = \ - __init__.py \ - data_plotly.py data_plotly_dialog.py - -PLUGINNAME = DataPlotly - -PY_FILES = \ - __init__.py \ - data_plotly.py data_plotly_dialog.py - -UI_FILES = dataplotly_dockwidget_base.ui - -EXTRAS = metadata.txt icon.png - -EXTRA_DIRS = - PEP8EXCLUDE=pydev,conf.py,third_party,ui,.venv,venv, @@ -57,18 +30,7 @@ PEP8EXCLUDE=pydev,conf.py,third_party,ui,.venv,venv, # Normally you would not need to edit below here ################################################# -HELP = help/build/html - -PLUGIN_UPLOAD = $(c)/plugin_upload.py - -QGISDIR=.qgis2 - -default: compile - -%.qm : %.ts - $(LRELEASE) $< - -test: transcompile +test: @echo @echo "----------------------" @echo "Regression Test Suite" @@ -86,104 +48,6 @@ test: transcompile @echo "e.g. source run-env-linux.sh <path to qgis install>; make test" @echo "----------------------" -deploy: compile doc txpull transcompile - @echo - @echo "------------------------------------------" - @echo "Deploying plugin to your .qgis2 directory." - @echo "------------------------------------------" - # The deploy target only works on unix like operating system where - # the Python plugin directory is located at: - # $HOME/$(QGISDIR)/python/plugins - mkdir -p $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) - cp -vf $(PY_FILES) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) - cp -vf $(UI_FILES) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) - cp -vf $(COMPILED_RESOURCE_FILES) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) - cp -vf $(EXTRAS) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) - cp -vfr i18n $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) - cp -vfr $(HELP) $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME)/help - # Copy extra directories if any - (foreach EXTRA_DIR,(EXTRA_DIRS), cp -R (EXTRA_DIR) (HOME)/(QGISDIR)/python/plugins/(PLUGINNAME)/;) - - -# The dclean target removes compiled python files from plugin directory -# also deletes any .git entry -dclean: - @echo - @echo "-----------------------------------" - @echo "Removing any compiled python files." - @echo "-----------------------------------" - find $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) -iname "*.pyc" -delete - find $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) -iname ".git" -prune -exec rm -Rf {} \; - - -derase: - @echo - @echo "-------------------------" - @echo "Removing deployed plugin." - @echo "-------------------------" - rm -Rf $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) - -zip: deploy dclean - @echo - @echo "---------------------------" - @echo "Creating plugin zip bundle." - @echo "---------------------------" - # The zip target deploys the plugin and creates a zip file with the deployed - # content. You can then upload the zip file on http://plugins.qgis.org - rm -f $(PLUGINNAME).zip - cd $(HOME)/$(QGISDIR)/python/plugins; zip -9r $(CURDIR)/$(PLUGINNAME).zip $(PLUGINNAME) - -package: - # Create a zip package of the plugin named $(PLUGINNAME).zip. - # This requires use of git (your plugin development directory must be a - # git repository). - # To use, pass a valid commit or tag as follows: - # make package VERSION=Version_0.3.2 - @echo - @echo "------------------------------------" - @echo "Exporting plugin to zip package. " - @echo "------------------------------------" - rm -f $(PLUGINNAME).zip - cd $(PLUGINNAME) && git archive --prefix=$(PLUGINNAME)/ -o $(PLUGINNAME).zip $(VERSION) - echo "Created package: $(PLUGINNAME).zip" - -upload: zip - @echo - @echo "-------------------------------------" - @echo "Uploading plugin to QGIS Plugin repo." - @echo "-------------------------------------" - $(PLUGIN_UPLOAD) $(PLUGINNAME).zip - -transup: - @echo - @echo "------------------------------------------------" - @echo "Updating translation files with any new strings." - @echo "------------------------------------------------" - @chmod +x scripts/update-strings.sh - @scripts/update-strings.sh $(LOCALES) - -transcompile: - @echo - @echo "----------------------------------------" - @echo "Compiled translation files to .qm files." - @echo "----------------------------------------" - @chmod +x scripts/compile-strings.sh - @scripts/compile-strings.sh $(LOCALES) - -transclean: - @echo - @echo "------------------------------------" - @echo "Removing compiled translation files." - @echo "------------------------------------" - rm -f $(PLUGINNAME)/i18n/*.qm - -doc: - @echo - @echo "------------------------------------" - @echo "Building documentation using sphinx." - @echo "------------------------------------" - cd help; make html - pylint: @echo @echo "-----------------" @@ -209,27 +73,3 @@ pycodestyle: @echo "-----------" @echo "Ignored in PEP8 check:" @echo $(PEP8EXCLUDE) - -txpush: transup - @echo - @echo "------------------------------------------------" - @echo "Pushing translation files with any new strings. " - @echo "------------------------------------------------" - tx push -s - -txpull: - @echo - @echo "------------------------------------------------" - @echo "Pulling translation files with any new strings. " - @echo "------------------------------------------------" - tx pull -a - @echo - @echo "Pull completed" - -txcompile: txpull - @echo - @echo "----------------------------------------" - @echo "Compiled translation files to .qm files." - @echo "----------------------------------------" - @chmod +x scripts/compile-strings.sh - @scripts/compile-strings.sh $(LOCALES) diff --git a/plugin_upload.py b/plugin_upload.py deleted file mode 100644 index 3f102304..00000000 --- a/plugin_upload.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -"""This script uploads a plugin package on the server. - Authors: A. Pasotti, V. Picavet - git sha : $TemplateVCSFormat -""" - -import sys -import getpass -import xmlrpc.client -from optparse import OptionParser - -# Configuration -PROTOCOL = 'http' -SERVER = 'plugins.qgis.org' -PORT = '80' -ENDPOINT = '/plugins/RPC2/' -VERBOSE = False - - -def main(parameters, arguments): - """Main entry point. - - :param parameters: Command line parameters. - :param arguments: Command line arguments. - """ - address = "%s://%s:%s@%s:%s%s" % ( - PROTOCOL, - parameters.username, - parameters.password, - parameters.server, - parameters.port, - ENDPOINT) - print("Connecting to: %s" % hide_password(address)) - - server = xmlrpc.client.ServerProxy(address, verbose=VERBOSE) - - try: - plugin_id, version_id = server.plugin.upload( - xmlrpc.client.Binary(open(arguments[0]).read())) - print("Plugin ID: %s" % plugin_id) - print("Version ID: %s" % version_id) - except xmlrpc.client.ProtocolError as err: - print("A protocol error occurred") - print("URL: %s" % hide_password(err.url, 0)) - print("HTTP/HTTPS headers: %s" % err.headers) - print("Error code: %d" % err.errcode) - print("Error message: %s" % err.errmsg) - except xmlrpc.client.Fault as err: - print("A fault occurred") - print("Fault code: %d" % err.faultCode) - print("Fault string: %s" % err.faultString) - - -def hide_password(url, start=6): - """Returns the http url with password part replaced with '*'. - - :param url: URL to upload the plugin to. - :type url: str - - :param start: Position of start of password. - :type start: int - """ - start_position = url.find(':', start) + 1 - end_position = url.find('@') - return "%s%s%s" % ( - url[:start_position], - '*' * (end_position - start_position), - url[end_position:]) - - -if __name__ == "__main__": - parser = OptionParser(usage="%prog [options] plugin.zip") - parser.add_option( - "-w", "--password", dest="password", - help="Password for plugin site", metavar="******") - parser.add_option( - "-u", "--username", dest="username", - help="Username of plugin site", metavar="user") - parser.add_option( - "-p", "--port", dest="port", - help="Server port to connect to", metavar="80") - parser.add_option( - "-s", "--server", dest="server", - help="Specify server name", metavar="plugins.qgis.org") - options, args = parser.parse_args() - if len(args) != 1: - print("Please specify zip file.\n") - parser.print_help() - sys.exit(1) - if not options.server: - options.server = SERVER - if not options.port: - options.port = PORT - if not options.username: - # interactive mode - username = getpass.getuser() - print("Please enter user name [%s] :" % username, end=' ') - res = input() - if res != "": - options.username = res - else: - options.username = username - if not options.password: - # interactive mode - options.password = getpass.getpass() - main(options, args) diff --git a/scripts/compile-strings.sh b/scripts/compile-strings.sh deleted file mode 100755 index 963b1552..00000000 --- a/scripts/compile-strings.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -PLUGINNAME="DataPlotly" -LOCALES=$* -LRELEASE=lrelease - -for LOCALE in ${LOCALES} -do - echo "Processing: ${PLUGINNAME}/i18n/${PLUGINNAME}_${LOCALE}.ts" - # Note we don't use pylupdate with qt .pro file approach as it is flakey - # about what is made available. - ${LRELEASE} ${PLUGINNAME}/i18n/${PLUGINNAME}_${LOCALE}.ts -done diff --git a/scripts/update-strings.sh b/scripts/update-strings.sh deleted file mode 100755 index be5b95f0..00000000 --- a/scripts/update-strings.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -LOCALES=$* -PLUGINNAME="DataPlotly" - -PYLUPDATE=${PYLUPDATE:-pylupdate5} - -# Get newest .py files so we don't update strings unnecessarily - -CHANGED_FILES=0 -PYTHON_FILES=`find . -regex ".*\(ui\|py\)$" -type f` -for PYTHON_FILE in $PYTHON_FILES -do - CHANGED=$(stat -c %Y $PYTHON_FILE) - if [ ${CHANGED} -gt ${CHANGED_FILES} ] - then - CHANGED_FILES=${CHANGED} - fi -done - -# Qt translation stuff -# for .ts file -UPDATE=false -for LOCALE in ${LOCALES} -do - TRANSLATION_FILE="${PLUGINNAME}/i18n/${PLUGINNAME}_${LOCALE}.ts" - if [ ! -f ${TRANSLATION_FILE} ] - then - # Force translation string collection as we have a new language file - touch ${TRANSLATION_FILE} - UPDATE=true - break - fi - - MODIFICATION_TIME=$(stat -c %Y ${TRANSLATION_FILE}) - if [ ${CHANGED_FILES} -gt ${MODIFICATION_TIME} ] - then - # Force translation string collection as a .py file has been updated - UPDATE=true - break - fi -done - -if [ ${UPDATE} == true ] -# retrieve all python files -then - print ${PYTHON_FILES} - # update .ts - echo "Please provide translations by editing the translation files below:" - for LOCALE in ${LOCALES} - do - echo "${PLUGINNAME}/i18n/"${PLUGINNAME}_${LOCALE}".ts" - # Note we don't use pylupdate with qt .pro file approach as it is flakey - # about what is made available. - ${PYLUPDATE} -noobsolete ${PYTHON_FILES} -ts ${PLUGINNAME}/i18n/${PLUGINNAME}_${LOCALE}.ts - done -else - echo "No need to edit any translation files (.ts) because no python files" - echo "has been updated since the last update translation. " -fi diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..05301948 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,8 @@ +[qgis-plugin-ci] +plugin_path = DataPlotly +github_organization_slug = ghtmtt +project_slug = DataPlotly +transifex_organization = dataplotly +transifex_project = dataplotly-ui +transifex_resource = application +transifex_coordinator = ghtmtt From 606603bfc667737f5b13b6c1d094550878e42e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <gustrimaille@yahoo.fr> Date: Wed, 1 Jun 2022 14:07:47 +0200 Subject: [PATCH 21/57] Lint - Fix tests (#287) --- DataPlotly/core/plot_types/plot_type.py | 1 + DataPlotly/test/test_translations.py | 4 ++-- DataPlotly/test/utilities.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/DataPlotly/core/plot_types/plot_type.py b/DataPlotly/core/plot_types/plot_type.py index c168e9cf..19fe91ed 100644 --- a/DataPlotly/core/plot_types/plot_type.py +++ b/DataPlotly/core/plot_types/plot_type.py @@ -28,6 +28,7 @@ def from_qfont_to_plotly(style, color): "family": "Arial", } + class PlotType: """ Base class for plot subclasses diff --git a/DataPlotly/test/test_translations.py b/DataPlotly/test/test_translations.py index 9cb37671..51abc552 100644 --- a/DataPlotly/test/test_translations.py +++ b/DataPlotly/test/test_translations.py @@ -25,12 +25,12 @@ class SafeTranslationsTest(unittest.TestCase): def setUp(self): """Runs before each test.""" - if 'LANG' in iter(os.environ.keys()): + if 'LANG' in os.environ: os.environ.__delitem__('LANG') def tearDown(self): """Runs after each test.""" - if 'LANG' in iter(os.environ.keys()): + if 'LANG' in os.environ: os.environ.__delitem__('LANG') def test_qgis_translations(self): diff --git a/DataPlotly/test/utilities.py b/DataPlotly/test/utilities.py index e320483f..a67b368f 100644 --- a/DataPlotly/test/utilities.py +++ b/DataPlotly/test/utilities.py @@ -41,7 +41,7 @@ def get_qgis_app(cleanup=True): global QGISAPP # pylint: disable=global-variable-undefined try: - QGISAPP + QGISAPP # pylint: disable=used-before-assignment except NameError: myGuiFlag = True # All test will run qgis in gui mode From b8398961b11114b29b8b585a30a01eec3b5cc2ca Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Wed, 1 Jun 2022 14:12:56 +0200 Subject: [PATCH 22/57] update QGIS release in testing suite (#279) --- .github/workflows/test_plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_plugin.yaml b/.github/workflows/test_plugin.yaml index 7c135e07..949b23a0 100644 --- a/.github/workflows/test_plugin.yaml +++ b/.github/workflows/test_plugin.yaml @@ -27,7 +27,7 @@ jobs: strategy: matrix: - docker_tags: [release-3_16, release-3_18, latest] + docker_tags: [release-3_16, release-3_22, latest] steps: From fa8a93afddf0ae4d7525794f6c45190b9302762a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <gustrimaille@yahoo.fr> Date: Tue, 21 Jun 2022 11:32:23 +0200 Subject: [PATCH 23/57] Update .gitignore with files from qgis-plugin-ci (#289) --- .gitignore | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 10082368..88f1fa4c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,10 @@ __pycache__/ .idea/* .backuputils.py -help/.tx/* -*.zip + +# QGIS-Plugin-CI +DataPlotly.*.zip +DataPlotly/i18n/ + .coverage .noseids From c31674f56fd754fe00731d87edb08bb7362097db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <gustrimaille@yahoo.fr> Date: Wed, 22 Jun 2022 11:13:01 +0200 Subject: [PATCH 24/57] Update some deprecated notices about subplots (#290) --- DataPlotly/core/plot_factory.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DataPlotly/core/plot_factory.py b/DataPlotly/core/plot_factory.py index 0c7e7735..3b725dd1 100644 --- a/DataPlotly/core/plot_factory.py +++ b/DataPlotly/core/plot_factory.py @@ -13,7 +13,7 @@ import re import plotly import plotly.graph_objs as go -from plotly import tools +from plotly import subplots from qgis.core import ( QgsProject, @@ -777,17 +777,17 @@ def build_sub_plots(self, grid, row, column, ptrace): # pylint:disable=too-many if grid == 'row': - fig = tools.make_subplots(rows=row, cols=column) + fig = subplots.make_subplots(rows=row, cols=column) for i, itm in enumerate(ptrace): - fig.append_trace(itm, row, i + 1) + fig.add_trace(itm, row, i + 1) elif grid == 'col': - fig = tools.make_subplots(rows=row, cols=column) + fig = subplots.make_subplots(rows=row, cols=column) for i, itm in enumerate(ptrace): - fig.append_trace(itm, i + 1, column) + fig.add_trace(itm, i + 1, column) # set some configurations config = {'scrollZoom': True, 'editable': True} From 8638168f03afd74aa9ada01a9104683584f5d921 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Sat, 20 Aug 2022 18:01:35 +0200 Subject: [PATCH 25/57] [feature] New custom function to get the colors from categories used (#288) * new custom function to get the colors from categories used * update the expression to be more generic --- DataPlotly/core/plot_expressions.py | 54 +++++++++++++++++++++++++++++ DataPlotly/data_plotly.py | 11 +++++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 DataPlotly/core/plot_expressions.py diff --git a/DataPlotly/core/plot_expressions.py b/DataPlotly/core/plot_expressions.py new file mode 100644 index 00000000..b02a3417 --- /dev/null +++ b/DataPlotly/core/plot_expressions.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DataPlotly + A QGIS plugin + D3 Plots for QGIS + ------------------- + begin : 2022-06-08 + git sha : $Format:%H$ + copyright : (C) 2020 by matteo ghetta + email : matteo.ghetta@faunalia.it + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +from qgis.utils import qgsfunction +from qgis.core import QgsRenderContext + + +@qgsfunction(args='auto', group='DataPlotly') +def get_symbol_colors(feature, parent, context): + """ + Retrieve the color of each category as html code. You can use this function + to set the plot items (pie slices, bars, points, etc) to the same color + of the feature visible in the map. + <h4>Syntax</h4> + <p> + get_symbol_colors() -> '#da1ddd' + </p> + """ + + layer = context.variable('layer') + renderer_context = QgsRenderContext() + renderer = layer.renderer() + renderer.startRender(renderer_context, layer.fields()) + + symbols = renderer.originalSymbolsForFeature(feature, renderer_context) + + if symbols: + color = symbols[0].color().name() + else: + color = '#000000' + + renderer.stopRender(renderer_context) + + return color \ No newline at end of file diff --git a/DataPlotly/data_plotly.py b/DataPlotly/data_plotly.py index 97e0e523..5ef0e921 100644 --- a/DataPlotly/data_plotly.py +++ b/DataPlotly/data_plotly.py @@ -25,7 +25,7 @@ from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt, QUrl from qgis.PyQt.QtGui import QDesktopServices from qgis.PyQt.QtWidgets import QAction -from qgis.core import Qgis, QgsApplication +from qgis.core import Qgis, QgsApplication, QgsExpression from qgis.gui import QgsGui # Import the code for the dialog @@ -39,6 +39,9 @@ from DataPlotly.layouts.plot_layout_item import PlotLayoutItemMetadata from DataPlotly.gui.layout_item_gui import PlotLayoutItemGuiMetadata +# import custom expressions +from .core.plot_expressions import get_symbol_colors + class DataPlotly: # pylint: disable=too-many-instance-attributes """QGIS Plugin Implementation.""" @@ -132,6 +135,9 @@ def initGui(self): self.iface.pluginHelpMenu().addAction(self.help_action) self.help_action.triggered.connect(self.open_help) + # register the function + QgsExpression.registerFunction(get_symbol_colors) + def initProcessing(self): """Create the Processing provider""" QgsApplication.processingRegistry().addProvider(self.provider) @@ -151,6 +157,9 @@ def unload(self): # Remove processing provider QgsApplication.processingRegistry().removeProvider(self.provider) + # unregister the function + QgsExpression.unregisterFunction('get_symbol_colors') + @staticmethod def open_help(): """ Open the online help. """ From b37aaee0c1e70d0faf44b6123f97402cc3dffa0d Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Sat, 20 Aug 2022 18:02:21 +0200 Subject: [PATCH 26/57] release 3.9.1 --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc0afeab..fc53e8cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,12 @@ ## Unreleased -- Fix "Build a generic plot" processing algorithm. Kudos to @agiudiceandrea + +## 3.9.1 - 2022-08-20 + +- Add custom function to have plot color the same as map color - Fix #237 add data-driven color to Polar Plot marker color. Kudos to @jmonticolo +- Fix "Build a generic plot" processing algorithm. Kudos to @agiudiceandrea ## 3.9.0 - 2022-04-11 From 3372e72b831017a8f9d25b343f2a9a1863ea32d0 Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Sat, 20 Aug 2022 18:06:53 +0200 Subject: [PATCH 27/57] fix action and release 3.9.1 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5e6af188..895d524e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: run: pip install qgis-plugin-ci - name : Get current changelog - run: qgis-plugin-ci changelog ${{ env.CI_COMMIT_TAG }} >> release.md + run: qgis-plugin-ci changelog ${{ env.RELEASE_VERSION }} >> release.md - name: Create release on GitHub uses: ncipollo/release-action@v1.10.0 From cb0f635a7e0e2737a5e350cbe916286480839c9a Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Sun, 21 Aug 2022 16:00:34 +0200 Subject: [PATCH 28/57] fixing tests (#296) * fixing tests [1] * fixing tests * fixing comment * fix datetime test --- DataPlotly/core/plot_expressions.py | 6 +-- DataPlotly/core/plot_factory.py | 15 ++++++++ DataPlotly/test/test_plot_factory.py | 37 ++++++++++--------- DataPlotly/test/test_translations.py | 55 ---------------------------- pylintrc | 20 +++++----- 5 files changed, 48 insertions(+), 85 deletions(-) delete mode 100644 DataPlotly/test/test_translations.py diff --git a/DataPlotly/core/plot_expressions.py b/DataPlotly/core/plot_expressions.py index b02a3417..336ea78c 100644 --- a/DataPlotly/core/plot_expressions.py +++ b/DataPlotly/core/plot_expressions.py @@ -36,7 +36,7 @@ def get_symbol_colors(feature, parent, context): get_symbol_colors() -> '#da1ddd' </p> """ - + _ = parent layer = context.variable('layer') renderer_context = QgsRenderContext() renderer = layer.renderer() @@ -48,7 +48,7 @@ def get_symbol_colors(feature, parent, context): color = symbols[0].color().name() else: color = '#000000' - + renderer.stopRender(renderer_context) - return color \ No newline at end of file + return color diff --git a/DataPlotly/core/plot_factory.py b/DataPlotly/core/plot_factory.py index 3b725dd1..f241aab1 100644 --- a/DataPlotly/core/plot_factory.py +++ b/DataPlotly/core/plot_factory.py @@ -811,3 +811,18 @@ def build_sub_plots(self, grid, row, column, ptrace): # pylint:disable=too-many f.write(self.raw_plot) return self.plot_path + + def build_plot_dict(self) -> dict: + """ + Returns a python dictionary of the whole Figure object. + + This method is not used in the plugin itself, but it is used in the + testing suite to avoid finding the Figure parameters with weird regex + from the html + + :return: dictionary of the Figure object + """ + + fig = go.Figure(data=self.trace, layout=self.layout) + + return fig.to_dict() diff --git a/DataPlotly/test/test_plot_factory.py b/DataPlotly/test/test_plot_factory.py index 43378e49..3e676249 100644 --- a/DataPlotly/test/test_plot_factory.py +++ b/DataPlotly/test/test_plot_factory.py @@ -10,8 +10,6 @@ import unittest import os -import re -import json from qgis.core import ( QgsProject, QgsVectorLayer, @@ -26,7 +24,8 @@ from qgis.PyQt.QtTest import QSignalSpy from qgis.PyQt.QtCore import ( QDate, - QDateTime + QDateTime, + Qt ) from DataPlotly.core.plot_settings import PlotSettings from DataPlotly.core.plot_factory import PlotFactory @@ -648,29 +647,33 @@ def test_dates(self): # pylint: disable=too-many-statements settings.y = [4, 5, 6] factory = PlotFactory(settings) - # Build the HTML/JavaScript for the plot - plot_html = factory.build_html({}) + # Build the dictionary from teh figure + plot_dict = factory.build_plot_dict() - # Find the plot specification in the HTML - match = re.search(r'\[(.*?\]})\]', plot_html) - plot_dictionary = json.loads(match.group(1)) + # get the x and y fields as list + for items in plot_dict['data']: + # converts the QDate into strings + x = [str(i.toPyDate()) for i in items['x']] + y = items['y'] - self.assertEqual(plot_dictionary['x'], ["2020-01-01", "2020-02-01", "2020-03-01"]) - self.assertEqual(plot_dictionary['y'], [4, 5, 6]) + self.assertEqual(x, ["2020-01-01", "2020-02-01", "2020-03-01"]) + self.assertEqual(y, [4, 5, 6]) settings.x = [QDateTime(2020, 1, 1, 11, 21), QDateTime(2020, 2, 1, 0, 15), QDateTime(2020, 3, 1, 17, 23, 11)] settings.y = [4, 5, 6] factory = PlotFactory(settings) - # Build the HTML/JavaScript for the plot - plot_html = factory.build_html({}) + # Build the dictionary from teh figure + plot_dict = factory.build_plot_dict() - # Find the plot specification in the HTML - match = re.search(r'\[(.*?\]})\]', plot_html) - plot_dictionary = json.loads(match.group(1)) + # get the x and y fields as list + for items in plot_dict['data']: + # converts the QDate into strings + x = [str(i.toString(Qt.ISODate)) for i in items['x']] + y = items['y'] - self.assertEqual(plot_dictionary['x'], ["2020-01-01T11:21:00", "2020-02-01T00:15:00", "2020-03-01T17:23:11"]) - self.assertEqual(plot_dictionary['y'], [4, 5, 6]) + self.assertEqual(x, ["2020-01-01T11:21:00", "2020-02-01T00:15:00", "2020-03-01T17:23:11"]) + self.assertEqual(y, [4, 5, 6]) @unittest.skip('Fragile') def test_data_defined_histogram_color(self): diff --git a/DataPlotly/test/test_translations.py b/DataPlotly/test/test_translations.py deleted file mode 100644 index 51abc552..00000000 --- a/DataPlotly/test/test_translations.py +++ /dev/null @@ -1,55 +0,0 @@ -# coding=utf-8 -"""Safe Translations Test. - -.. note:: This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - -""" - -__author__ = 'ismailsunni@yahoo.co.id' -__date__ = '12/10/2011' -__copyright__ = ('Copyright 2012, Australia Indonesia Facility for ' - 'Disaster Reduction') -import unittest -import os -from qgis.PyQt.QtCore import QCoreApplication, QTranslator -from DataPlotly.test.utilities import get_qgis_app - -QGIS_APP = get_qgis_app() - - -class SafeTranslationsTest(unittest.TestCase): - """Test translations work.""" - - def setUp(self): - """Runs before each test.""" - if 'LANG' in os.environ: - os.environ.__delitem__('LANG') - - def tearDown(self): - """Runs after each test.""" - if 'LANG' in os.environ: - os.environ.__delitem__('LANG') - - def test_qgis_translations(self): - """Test that translations work.""" - parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir) - dir_path = os.path.abspath(parent_path) - file_path = os.path.join( - dir_path, 'i18n', 'DataPlotly_af.qm') - self.assertTrue(os.path.exists(file_path), file_path) - translator = QTranslator() - translator.load(file_path) - QCoreApplication.installTranslator(translator) - - expected_message = 'Goeie more' - real_message = QCoreApplication.translate("@default", 'Good morning') - self.assertEqual(real_message, expected_message) - - -if __name__ == "__main__": - suite = unittest.makeSuite(SafeTranslationsTest) - runner = unittest.TextTestRunner(verbosity=2) - runner.run(suite) diff --git a/pylintrc b/pylintrc index 21ad392e..7fb6ff52 100644 --- a/pylintrc +++ b/pylintrc @@ -8,7 +8,7 @@ #init-hook= # Profiled execution. -profile=no +# profile=no # Add files or directories to the blacklist. They should be base names, not # paths. @@ -19,7 +19,7 @@ persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. -load-plugins= +load-plugins=pylint.extensions.no_self_use [MESSAGES CONTROL] @@ -39,7 +39,7 @@ load-plugins= # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" # see http://stackoverflow.com/questions/21487025/pylint-locally-defined-disables-still-give-warnings-how-to-suppress-them -disable=locally-disabled,C0103,C0301,C0330,E0611,W0511,W0107,R0801,import-error, +disable=locally-disabled,C0103,C0301,E0611,W0511,W0107,R0801,import-error, # Wait for QGIS 3.18 minimum version for f-strings C0209, @@ -54,7 +54,7 @@ output-format=text # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be # written in a file name "pylint_global.[txt|html]". -files-output=no +# files-output=no # Tells whether to display a full report or only the messages reports=yes @@ -68,7 +68,7 @@ evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / stateme # Add a comment according to your evaluation note. This is used by the global # evaluation report (RP0004). -comment=no +# comment=no # Template used to display messages. This is a python new-style format string # used to format the message information. See doc for all details @@ -78,10 +78,10 @@ comment=no [BASIC] # Required attributes for module, separated by a comma -required-attributes= +# required-attributes= # List of builtins function names that should not be used, separated by a comma -bad-functions=map,filter,apply,input +# bad-functions=map,filter,apply,input # Regular expression which should only match correct module names module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ @@ -148,7 +148,7 @@ ignored-classes=SQLObject # When zope mode is activated, add a predefined set of Zope acquired attributes # to generated-members. -zope=no +# zope=no # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E0201 when accessed. Python regular @@ -183,7 +183,7 @@ ignore-long-lines=^\s*(# )?<?https?://\S+>?$ single-line-if-stmt=no # List of optional constructs for which whitespace checking is disabled -no-space-check=trailing-comma,dict-separator +# no-space-check=trailing-comma,dict-separator # Maximum number of lines in a module max-module-lines=1000 @@ -264,7 +264,7 @@ max-public-methods=20 # List of interface methods to ignore, separated by a comma. This is used for # instance to not check methods defines in Zope's Interface base class. -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by +# ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__,__new__,setUp From d48fc260cf52b61d96ff2eab5af2424c05de5063 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Sun, 21 Aug 2022 16:04:09 +0200 Subject: [PATCH 29/57] add test badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5378b42..56305319 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DataPlotly -[](https://travis-ci.org/ghtmtt/DataPlotly) +[](https://github.com/ghtmtt/DataPlotly/actions/workflows/test_plugin.yaml) The DataPlotly plugin allows creation of -like interactive plots directly within QGIS, thanks to the  From 07976c1ade86ec4fb192685619ecd7646b85b278 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Sun, 21 Aug 2022 16:15:36 +0200 Subject: [PATCH 30/57] fix wrong button for 2dhistogram and contour (#297) --- DataPlotly/gui/plot_settings_widget.py | 1 + 1 file changed, 1 insertion(+) diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 7d5780cf..c452afa9 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -800,6 +800,7 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.color_scale_data_defined_in_invert_check: ['bar', 'ternary'], self.out_color_lab: ['scatter', 'bar', 'box', 'pie', 'histogram', 'polar', 'ternary', 'violin'], self.out_color_combo: ['scatter', 'bar', 'box', 'pie', 'histogram', 'polar', 'ternary', 'violin'], + self.out_color_defined_button: ['scatter', 'bar', 'box', 'pie', 'histogram', 'polar', 'ternary', 'violin'], self.marker_width_lab: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin'], self.marker_width: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin'], self.stroke_defined_button: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin'], From d626e4376923632ac1005e2f19df6356ff7556a4 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Sun, 21 Aug 2022 16:42:29 +0200 Subject: [PATCH 31/57] fix stacktrace when removing all the plots in the print layout (#298) --- DataPlotly/layouts/plot_layout_item.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/DataPlotly/layouts/plot_layout_item.py b/DataPlotly/layouts/plot_layout_item.py index 445f005a..1e19cc21 100644 --- a/DataPlotly/layouts/plot_layout_item.py +++ b/DataPlotly/layouts/plot_layout_item.py @@ -200,18 +200,19 @@ def create_plot(self): return myfile.read() def get_polygon_filter(self, index=0): - if self.linked_map and self.plot_settings[index].properties.get('layout_filter_by_map', False): - polygon_filter = FilterRegion(QgsGeometry.fromQPolygonF(self.linked_map.visibleExtentPolygon()), - self.linked_map.crs()) - visible_features_only = True - elif self.plot_settings[index].properties.get('layout_filter_by_atlas', False) and \ - self.layout().reportContext().layer() and self.layout().reportContext().feature().isValid(): - - polygon_filter = FilterRegion(self.layout().reportContext().currentGeometry(), self.layout().reportContext().layer().crs()) - visible_features_only = True - else: - polygon_filter = None - visible_features_only = False + polygon_filter = None + visible_features_only = False + + if self.plot_settings: + if self.linked_map and self.plot_settings[index].properties.get('layout_filter_by_map', False): + polygon_filter = FilterRegion(QgsGeometry.fromQPolygonF(self.linked_map.visibleExtentPolygon()), + self.linked_map.crs()) + visible_features_only = True + elif self.plot_settings[index].properties.get('layout_filter_by_atlas', False) and \ + self.layout().reportContext().layer() and self.layout().reportContext().feature().isValid(): + + polygon_filter = FilterRegion(self.layout().reportContext().currentGeometry(), self.layout().reportContext().layer().crs()) + visible_features_only = True return polygon_filter, visible_features_only From 9f628433123030a7b8bf6d2b5c8a80f1ac5fe9f1 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Tue, 23 Aug 2022 11:41:11 +0200 Subject: [PATCH 32/57] Refactor Processing algorithm (#300) * using plotly.express provider and scatterplot algorithm * json output optional * fix lint * remove useless utils file * fix lint again * add faceting --- .../processing/dataplotly_algorithms.py | 291 -------------- DataPlotly/processing/dataplotly_provider.py | 5 +- .../processing/dataplotly_scatterplot.py | 375 ++++++++++++++++++ 3 files changed, 377 insertions(+), 294 deletions(-) delete mode 100644 DataPlotly/processing/dataplotly_algorithms.py create mode 100644 DataPlotly/processing/dataplotly_scatterplot.py diff --git a/DataPlotly/processing/dataplotly_algorithms.py b/DataPlotly/processing/dataplotly_algorithms.py deleted file mode 100644 index 818b6aba..00000000 --- a/DataPlotly/processing/dataplotly_algorithms.py +++ /dev/null @@ -1,291 +0,0 @@ -# -*- coding: utf-8 -*- -""" -/*************************************************************************** - DataPlotly - A QGIS plugin - D3 Plots for QGIS - ------------------- - begin : 2017-03-05 - git sha : $Format:%H$ - copyright : (C) 2017 by matteo ghetta - email : matteo.ghetta@gmail.com - ***************************************************************************/ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -""" - -import os -from shutil import copyfile -import json -import codecs - -from qgis.core import ( - QgsProcessingUtils, - QgsProcessingException, - QgsProcessingAlgorithm, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterString, - QgsProcessingParameterEnum, - QgsProcessingParameterFileDestination, - QgsProcessingOutputHtml, - QgsProcessingOutputFile, - QgsSettings, - QgsFeatureRequest, - QgsProcessingAlgorithm -) - -from qgis.PyQt.QtCore import QCoreApplication - -from DataPlotly.core.plot_factory import PlotFactory -from DataPlotly.core.plot_settings import PlotSettings - - -class DataPlotlyProcessingPlot(QgsProcessingAlgorithm): - """ - Create a simple plot with DataPlotly plugin - """ - - # Constants used to refer to parameters and outputs. They will be - # used when calling the algorithm from another algorithm, or when - # calling from the QGIS console. - - INPUT = 'INPUT' - PLOT_TYPE = 'PLOT_TYPE' - PLOT_TITLE = 'PLOT_TITLE' - PLOT_TYPE_OPTIONS = ['scatter', 'box', 'bar', 'histogram', 'pie', '2dhistogram', 'polar', 'contour'] - X_MANDATORY = ['scatter', 'bar', 'histogram', '2dhistogram', 'polar', 'contour'] - Y_MANDATORY = ['scatter', 'box', 'bar', 'pie', '2dhistogram', 'polar', 'contour'] - XFIELD = 'XFIELD' - YFIELD = 'YFIELD' - IN_COLOR = 'IN_COLOR' - IN_COLOR_OPTIONS = ['Black', 'Blue', 'Brown', 'Cyan', 'DarkBlue', 'Grey', 'Green', 'LightBlue', 'Lime', 'Magenta', - 'Maroon', 'Olive', 'Orange', 'Purple', 'Red', 'Silver', 'White', 'Yellow'] - IN_COLOR_HTML = 'IN_COLOR_HTML' - OUTPUT_HTML_FILE = 'OUTPUT_HTML_FILE' - OUTPUT_JSON_FILE = 'OUTPUT_JSON_FILE' - - def __init__(self): - super().__init__() - """Here we define the inputs and output of the algorithm, along - with some other properties. - """ - - @staticmethod - def tr(string, context=''): - if context == '': - context = 'Processing' - return QCoreApplication.translate(context, string) - - def createInstance(self): - return DataPlotlyProcessingPlot() - - def initAlgorithm(self, config=None): - - self.addParameter( - QgsProcessingParameterFeatureSource( - self.INPUT, - self.tr('Input layer') - ) - ) - - self.addParameter( - QgsProcessingParameterEnum( - self.PLOT_TYPE, - self.tr('Plot type'), - options=self.PLOT_TYPE_OPTIONS - ) - ) - - self.addParameter( - QgsProcessingParameterString( - self.PLOT_TITLE, - self.tr('Plot title'), - optional=True - ) - ) - - self.addParameter( - QgsProcessingParameterField( - self.XFIELD, - self.tr('X Field'), - parentLayerParameterName=self.INPUT, - type=QgsProcessingParameterField.Any, - optional=True - ) - ) - - self.addParameter( - QgsProcessingParameterField( - self.YFIELD, - self.tr('Y Field'), - parentLayerParameterName=self.INPUT, - type=QgsProcessingParameterField.Any, - optional=True - ) - ) - - self.addParameter( - QgsProcessingParameterEnum( - self.IN_COLOR, - self.tr('Color'), - optional=True, - options=self.IN_COLOR_OPTIONS - ) - ) - - self.addParameter( - QgsProcessingParameterString( - self.IN_COLOR_HTML, - self.tr( - 'Color (any valid HTML color) If set, this is used instead of the color set in the previous input.'), - optional=True - ) - ) - - self.addParameter( - QgsProcessingParameterFileDestination(self.OUTPUT_HTML_FILE, - self.tr('HTML File'), - self.tr('HTML files (*.html)') - ) - ) - - # Add an file to return a response in JSON format - self.addParameter( - QgsProcessingParameterFileDestination(self.OUTPUT_JSON_FILE, - self.tr('JSON file'), - self.tr('JSON Files (*.json)') - ) - ) - - def name(self): - # Unique (non-user visible) name of algorithm - return 'build_generic_plot' - - def displayName(self): - # The name that the user will see in the toolbox - return self.tr('Build a generic plot') - - def shortDescription(self): - return self.tr('Creates a generic Plotly plot') - - def group(self): - return self.tr('Plots') - - def groupId(self): - return 'plots' - - def processAlgorithm(self, parameters, context, feedback): - """ - :param parameters: - :param context: - """ - - layer = self.parameterAsSource(parameters, self.INPUT, context) - fields = layer.fields() - - xfieldname = self.parameterAsString(parameters, self.XFIELD, context) - yfieldname = self.parameterAsString(parameters, self.YFIELD, context) - - outputHtmlFile = self.parameterAsFileOutput(parameters, self.OUTPUT_HTML_FILE, context) - outputJsonFile = self.parameterAsFileOutput(parameters, self.OUTPUT_JSON_FILE, context) - - plot_type = 'bar' - plot_type_input = self.parameterAsInt(parameters, self.PLOT_TYPE, context) - plot_type = self.PLOT_TYPE_OPTIONS[plot_type_input] - - plot_title = self.parameterAsString(parameters, self.PLOT_TITLE, context) - - in_color_input = self.parameterAsInt(parameters, self.IN_COLOR, context) - in_color_hex = self.IN_COLOR_OPTIONS[in_color_input] - in_color_html = self.parameterAsString(parameters, self.IN_COLOR_HTML, context) - - # Some controls - msg = [] - if plot_type in self.X_MANDATORY and not xfieldname: - msg.append(self.tr("The chosen plot type needs a X field !")) - if plot_type in self.Y_MANDATORY and not yfieldname: - msg.append(self.tr("The chosen plot type needs a Y field !")) - if msg: - feedback.reportError(' '.join(msg)) - raise QgsProcessingException(msg) - - # Build needed dictionary - settings = PlotSettings(plot_type) - properties = {} - - # Add X dimension - x_title = '' - if xfieldname: - # get field index for x - idxX = layer.fields().lookupField(xfieldname) - # get list of values for x - x_var = [i[xfieldname] for i in layer.getFeatures( - QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([idxX]))] - fieldTypeX = fields[idxX].type() - x_title = fields[idxX].alias() or xfieldname - properties.x = x_var - - # Add Y dimension - y_title = '' - if yfieldname: - # get field index for y - idxY = layer.fields().lookupField(yfieldname) - # get list of values for y - y_var = [i[yfieldname] for i in layer.getFeatures( - QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([idxY]))] - y_title = fields[idxY].alias() or yfieldname - properties.y = y_var - - # Draw only markers for scatter plot - if plot_type in ['scatter', 'polar']: - properties['marker'] = 'markers' - - # Colours - properties['in_color'] = in_color_html or in_color_hex or 'DodgerBlue' - - # Add layout - layout = { - 'title': plot_title or layer.sourceName() - } - if plot_type in self.X_MANDATORY: - layout['x_title'] = x_title - if plot_type in self.Y_MANDATORY: - layout['y_title'] = y_title - - settings = PlotSettings(plot_type, properties=properties, layout=layout) - - # Create plot instance - factory = PlotFactory(settings) - - # Prepare results - results = { - self.OUTPUT_HTML_FILE: None, - self.OUTPUT_JSON_FILE: None - } - - # Save plot as HTML - if outputHtmlFile: - standalone_plot_path = factory.build_figure() - if os.path.isfile(standalone_plot_path): - # html file output - copyfile(standalone_plot_path, outputHtmlFile) - results[self.OUTPUT_HTML_FILE] = outputHtmlFile - - # Save plot as JSON - if outputJsonFile: - ojson = { - 'data': trace, - 'layout': plot_layout - } - with codecs.open(outputJsonFile, 'w', encoding='utf-8') as f: - f.write(json.dumps(ojson)) - results[self.OUTPUT_JSON_FILE] = outputJsonFile - - return results diff --git a/DataPlotly/processing/dataplotly_provider.py b/DataPlotly/processing/dataplotly_provider.py index 23ebbb2d..44d921d1 100644 --- a/DataPlotly/processing/dataplotly_provider.py +++ b/DataPlotly/processing/dataplotly_provider.py @@ -21,12 +21,11 @@ ***************************************************************************/ """ from qgis.core import QgsProcessingProvider -from DataPlotly.processing.dataplotly_algorithms import DataPlotlyProcessingPlot from DataPlotly.gui.gui_utils import GuiUtils +from DataPlotly.processing.dataplotly_scatterplot import DataPlotlyProcessingScatterPlot class DataPlotlyProvider(QgsProcessingProvider): - MY_DUMMY_SETTING = 'MY_DUMMY_SETTING' def __init__(self, plugin_version): super().__init__() @@ -78,4 +77,4 @@ def loadAlgorithms(self): even if the list does not change, since the self.algs list is cleared before calling this method. """ - self.addAlgorithm(DataPlotlyProcessingPlot()) + self.addAlgorithm(DataPlotlyProcessingScatterPlot()) diff --git a/DataPlotly/processing/dataplotly_scatterplot.py b/DataPlotly/processing/dataplotly_scatterplot.py new file mode 100644 index 00000000..cab6119f --- /dev/null +++ b/DataPlotly/processing/dataplotly_scatterplot.py @@ -0,0 +1,375 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + DataPlotly + A QGIS plugin + D3 Plots for QGIS + ------------------- + begin : 2022-08-20 + git sha : $Format:%H$ + copyright : (C) 2022 by matteo ghetta + email : matteo.ghetta@gmail.com + ***************************************************************************/ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + + +from qgis.core import ( + QgsProcessingParameterFeatureSource, + QgsProcessingParameterExpression, + QgsProcessingParameterNumber, + QgsExpression, + QgsProcessingParameters, + QgsProcessingException, + QgsProcessingParameterFileDestination, + QgsProcessingParameterDefinition, + QgsProcessingParameterColor, + QgsProcessingAlgorithm, + QgsFeatureRequest, + QgsPropertyDefinition, + QgsProcessingParameterBoolean +) + +from qgis.PyQt.QtCore import QCoreApplication + +import pandas as pd +import plotly.express as px + + +class DataPlotlyProcessingScatterPlot(QgsProcessingAlgorithm): + """ + Create a scatter with DataPlotly plugin + """ + + # Constants used to refer to parameters and outputs. They will be + # used when calling the algorithm from another algorithm, or when + # calling from the QGIS console. + + INPUT = 'INPUT' + XEXPRESSION = 'XEXPRESSION' + YEXPRESSION = 'YEXPRESSION' + OFFLINE = 'OFFLINE' + COLOR = 'COLOR' + SIZE = 'SIZE' + FACET_COL = 'FACET_ROW' + FACET_ROW = 'FACET_COL' + OUTPUT_HTML_FILE = 'OUTPUT_HTML_FILE' + OUTPUT_JSON_FILE = 'OUTPUT_JSON_FILE' + + def tr(self, string): + return QCoreApplication.translate('DataPlotly', string) + + def createInstance(self): + return DataPlotlyProcessingScatterPlot() + + def initAlgorithm(self, config=None): + + # layer + self.addParameter( + QgsProcessingParameterFeatureSource( + self.INPUT, + self.tr('Input layer') + ) + ) + + # x fields (or expression) + self.addParameter( + QgsProcessingParameterExpression( + self.XEXPRESSION, + self.tr('X Field'), + parentLayerParameterName=self.INPUT + ) + ) + + # y field (or expression) + self.addParameter( + QgsProcessingParameterExpression( + self.YEXPRESSION, + self.tr('Y Field'), + parentLayerParameterName=self.INPUT + ) + ) + + # size + size_param = QgsProcessingParameterNumber( + self.SIZE, + self.tr('Marker size'), + defaultValue=10 + ) + size_param.setIsDynamic(True) + size_param.setDynamicLayerParameterName(self.INPUT) + size_param.setDynamicPropertyDefinition( + QgsPropertyDefinition( + "SIZE", + self.tr("Size"), + QgsPropertyDefinition.Double, + ) + ) + self.addParameter(size_param) + + # color + color_param = QgsProcessingParameterColor( + self.COLOR, + self.tr('Color'), + optional=True, + defaultValue='#8ebad9' + ) + color_param.setIsDynamic(True) + color_param.setDynamicLayerParameterName(self.INPUT) + color_param.setDynamicPropertyDefinition( + QgsPropertyDefinition( + "COLOR", + self.tr("Color"), + QgsPropertyDefinition.Double, + ) + ) + self.addParameter(color_param) + + facet_row = QgsProcessingParameterExpression( + self.FACET_ROW, + self.tr('Facet row'), + parentLayerParameterName=self.INPUT + ) + facet_row.setFlags(QgsProcessingParameterDefinition.FlagAdvanced | QgsProcessingParameterDefinition.FlagOptional) + self.addParameter(facet_row) + + facet_col = QgsProcessingParameterExpression( + self.FACET_COL, + self.tr('Facet col'), + optional=True, + parentLayerParameterName=self.INPUT + ) + facet_col.setFlags(QgsProcessingParameterDefinition.FlagAdvanced | QgsProcessingParameterDefinition.FlagOptional) + self.addParameter(facet_col) + + # offline parameter + offline_param = QgsProcessingParameterBoolean( + self.OFFLINE, + self.tr('Complete offline usage'), + defaultValue=False + ) + offline_param.setFlags(QgsProcessingParameterDefinition.FlagAdvanced) + self.addParameter(offline_param) + + # html file output + self.addParameter( + QgsProcessingParameterFileDestination( + self.OUTPUT_HTML_FILE, + self.tr('Scatter Plot'), + self.tr('HTML files (*.html)') + ) + ) + + # json file output + self.addParameter( + QgsProcessingParameterFileDestination( + self.OUTPUT_JSON_FILE, + self.tr('JSON file'), + self.tr('JSON Files (*.json)'), + createByDefault=False, + optional=True + ) + ) + + def name(self): + # Unique (non-user visible) name of algorithm + return 'dataplotly_scatterplot' + + def displayName(self): + # The name that the user will see in the toolbox + return self.tr('Scatter Plot') + + def group(self): + return self.tr('Plots') + + def groupId(self): + return 'plots' + + def type_name(self): + return 'scatter' + + def processAlgorithm(self, parameters, context, feedback): + + source = self.parameterAsSource( + parameters, + self.INPUT, + context + ) + + expressionContext = self.createExpressionContext( + parameters, + context, + source + ) + + x_expression = self.parameterAsString( + parameters, + self.XEXPRESSION, + context + ) + x_expression = QgsExpression(x_expression) + + if x_expression.hasParserError(): + x_expression.prepare(expressionContext) + raise QgsProcessingException(x_expression.parserErrorString()) + + y_expression = self.parameterAsString( + parameters, + self.YEXPRESSION, + context + ) + y_expression = QgsExpression(y_expression) + + if y_expression.hasParserError(): + y_expression.prepare(expressionContext) + raise QgsProcessingException(y_expression.parserErrorString()) + + size = self.parameterAsDouble( + parameters, + self.SIZE, + context + ) + size_property = None + if QgsProcessingParameters.isDynamic(parameters, "SIZE"): + size_property = parameters["SIZE"] + + color = self.parameterAsColor( + parameters, + self.COLOR, + context + ) + color_property = None + if QgsProcessingParameters.isDynamic(parameters, "COLOR"): + color_property = parameters["COLOR"] + + facet_row = self.parameterAsString( + parameters, + self.FACET_ROW, + context + ) + facet_row_expression = QgsExpression(facet_row) + + if facet_row and facet_row_expression.hasParserError(): + facet_row_expression.prepare(expressionContext) + raise QgsProcessingException(facet_row_expression.parserErrorString()) + + facet_col = self.parameterAsString( + parameters, + self.FACET_COL, + context + ) + facet_col_expression = QgsExpression(facet_col) + + if facet_col and facet_col_expression.hasParserError(): + facet_col_expression.prepare(expressionContext) + raise QgsProcessingException(facet_col_expression.parserErrorString()) + + offline = self.parameterAsBool( + parameters, + self.OFFLINE, + context + ) + if offline is not True: + offline = 'cdn' + + output_html = self.parameterAsFileOutput( + parameters, + self.OUTPUT_HTML_FILE, + context + ) + + output_json = self.parameterAsFileOutput( + parameters, + self.OUTPUT_JSON_FILE, + context + ) + + colnames = ['x', 'y', 'customdata'] + data = [] + + request = QgsFeatureRequest() + request.setFlags(QgsFeatureRequest.NoGeometry) + + for current, f in enumerate(source.getFeatures(request)): + + tl = [] + + expressionContext.setFeature(f) + + x_val = x_expression.evaluate(expressionContext) + y_val = y_expression.evaluate(expressionContext) + ids = f.id() + + tl.append(x_val) + tl.append(y_val) + tl.append(ids) + + if facet_row: + facet_row_val = facet_row_expression.evaluate(expressionContext) + tl.append(facet_row_val) + + if facet_col: + facet_col_val = facet_col_expression.evaluate(expressionContext) + tl.append(facet_col_val) + + if size_property: + the_size, _ = size_property.valueAsDouble(expressionContext, size) + tl.append(the_size) + + if color_property: + the_color, _ = color_property.value(expressionContext, color) + tl.append(the_color) + + data.append(tl) + + if facet_row: + colnames.append('facet_row') + + if facet_col: + colnames.append('facet_col') + + if size_property: + colnames.append('size') + + if color_property: + colnames.append('color') + + df = pd.DataFrame(data=data, columns=colnames) + + feedback.pushDebugInfo(f'{df}') + + fig = px.scatter( + df, + x='x', + y='y', + size='size' if size_property else None, + color='color' if color_property else None, + facet_row="facet_row" if facet_row else None, + facet_col="facet_col" if facet_col else None + ) + + if size_property is None: + fig.update_traces(marker_size=size) + + if color_property is None: + fig.update_traces(marker_color=color.name()) + + fig.update_layout(showlegend=True) + + results = {} + + fig.write_html(output_html, include_plotlyjs=offline) + results[self.OUTPUT_HTML_FILE] = output_html + + if output_json: + fig.write_json(output_json, pretty=True) + results[self.OUTPUT_JSON_FILE] = output_json + + return results From bfc4e5a4b8bf0eef8edde75c7187fd56c92113e9 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Tue, 23 Aug 2022 11:47:51 +0200 Subject: [PATCH 33/57] fix signal when changing the plot idenx combobox (#301) --- DataPlotly/gui/plot_settings_widget.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index c452afa9..06c37c80 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -391,9 +391,18 @@ def data_defined_color_updated(self): """ refreshing function for color data defined button + sets the vector layer to the data defined buttons + checks is the datadefined button is active and check also the plot type in order to deactivate the color when not needed """ + + # set the vector layer for all the data defined buttons + layer = self.layer_combo.currentLayer() + buttons = self.findChildren(QgsPropertyOverrideButton) + for button in buttons: + button.setVectorLayer(layer) + # if data defined button is active if self.in_color_defined_button.isActive(): # if plot is type for which using an expression for the color selection makes sense From d0ad3f433e1fb89ce57f564f51a9928555809149 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Tue, 30 Aug 2022 08:23:16 +0200 Subject: [PATCH 34/57] More Processing (#302) * add icon and remove some useless methods and strings * add Processing test for scatterplot * update changelog * update copy info (thanks Etienne :) ) * lint * add pandas to the requirement testing packages * fix test with self.maxDiff * use json instead of html for test, too unpredictable * remove useless function * try another test approach --- CHANGELOG.md | 6 + .../processing/dataplotly_scatterplot.py | 12 +- DataPlotly/test/processing_scatter.html | 7 + DataPlotly/test/scatterplot.json | 888 ++++++++++++++++++ DataPlotly/test/test_processing.py | 71 ++ REQUIREMENTS_TESTING.txt | 3 +- 6 files changed, 982 insertions(+), 5 deletions(-) create mode 100644 DataPlotly/test/processing_scatter.html create mode 100644 DataPlotly/test/scatterplot.json create mode 100644 DataPlotly/test/test_processing.py diff --git a/CHANGELOG.md b/CHANGELOG.md index fc53e8cb..4fc1ba45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +## 3.10 - 2022-08-23 + +- test added for Processing +- Processing algorithm refactored using plotly.express (scatter plot) +- fix stacktrace when removing all the plots from the layout +- fix signal not updating the fields in the data defined buttons automatically ## 3.9.1 - 2022-08-20 diff --git a/DataPlotly/processing/dataplotly_scatterplot.py b/DataPlotly/processing/dataplotly_scatterplot.py index cab6119f..094984c1 100644 --- a/DataPlotly/processing/dataplotly_scatterplot.py +++ b/DataPlotly/processing/dataplotly_scatterplot.py @@ -38,7 +38,9 @@ ) from qgis.PyQt.QtCore import QCoreApplication +from qgis.PyQt.QtGui import QIcon +import os import pandas as pd import plotly.express as px @@ -192,8 +194,8 @@ def group(self): def groupId(self): return 'plots' - def type_name(self): - return 'scatter' + def icon(self): + return QIcon(os.path.join(os.path.dirname(__file__), '..', 'core', 'plot_types', 'icons', 'scatterplot.svg')) def processAlgorithm(self, parameters, context, feedback): @@ -297,6 +299,8 @@ def processAlgorithm(self, parameters, context, feedback): request = QgsFeatureRequest() request.setFlags(QgsFeatureRequest.NoGeometry) + total = source.featureCount() if source else 0 + for current, f in enumerate(source.getFeatures(request)): tl = [] @@ -329,6 +333,8 @@ def processAlgorithm(self, parameters, context, feedback): data.append(tl) + feedback.setProgress(int(total * current)) + if facet_row: colnames.append('facet_row') @@ -343,8 +349,6 @@ def processAlgorithm(self, parameters, context, feedback): df = pd.DataFrame(data=data, columns=colnames) - feedback.pushDebugInfo(f'{df}') - fig = px.scatter( df, x='x', diff --git a/DataPlotly/test/processing_scatter.html b/DataPlotly/test/processing_scatter.html new file mode 100644 index 00000000..857cff5c --- /dev/null +++ b/DataPlotly/test/processing_scatter.html @@ -0,0 +1,7 @@ +<html> +<head><meta charset="utf-8" /></head> +<body> + <div> <script type="text/javascript">window.PlotlyConfig = {MathJaxConfig: 'local'};</script> + <script src="https://cdn.plot.ly/plotly-2.6.3.min.js"></script> <div id="ReplaceTheDiv" class="plotly-graph-div" style="height:100%; width:100%;"></div> <script type="text/javascript"> window.PLOTLYENV=window.PLOTLYENV || {}; if (document.getElementById("ReplaceTheDiv")) { Plotly.newPlot( "ReplaceTheDiv", [{"hovertemplate":"x=%{x}<br>y=%{y}<extra></extra>","legendgroup":"","marker":{"color":"#8ebad9","symbol":"circle","size":10.0},"mode":"markers","name":"","orientation":"v","showlegend":false,"x":[98,88,267,329,319,137,350,151,203],"xaxis":"x","y":[81.87,22.26,74.16,35.05,46.64,126.73,116.44,108.25,110.45],"yaxis":"y","type":"scatter"}], {"template":{"data":{"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"choropleth":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"choropleth"}],"contour":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"contour"}],"contourcarpet":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"contourcarpet"}],"heatmap":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"heatmap"}],"heatmapgl":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"heatmapgl"}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"histogram2d":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"histogram2d"}],"histogram2dcontour":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"histogram2dcontour"}],"mesh3d":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"mesh3d"}],"parcoords":[{"line":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"parcoords"}],"pie":[{"automargin":true,"type":"pie"}],"scatter":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatter"}],"scatter3d":[{"line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatter3d"}],"scattercarpet":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattercarpet"}],"scattergeo":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattergeo"}],"scattergl":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattergl"}],"scattermapbox":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattermapbox"}],"scatterpolar":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterpolar"}],"scatterpolargl":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterpolargl"}],"scatterternary":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterternary"}],"surface":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"type":"surface"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}]},"layout":{"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"autotypenumbers":"strict","coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]],"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]},"colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"geo":{"bgcolor":"white","lakecolor":"white","landcolor":"#E5ECF6","showlakes":true,"showland":true,"subunitcolor":"white"},"hoverlabel":{"align":"left"},"hovermode":"closest","mapbox":{"style":"light"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"bgcolor":"#E5ECF6","radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"ternary":{"aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"bgcolor":"#E5ECF6","caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"title":{"x":0.05},"xaxis":{"automargin":true,"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","zerolinewidth":2},"yaxis":{"automargin":true,"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","zerolinewidth":2}}},"xaxis":{"anchor":"y","domain":[0.0,1.0],"title":{"text":"x"}},"yaxis":{"anchor":"x","domain":[0.0,1.0],"title":{"text":"y"}},"legend":{"tracegroupgap":0},"margin":{"t":60},"showlegend":true}, {"responsive": true} ) }; </script> </div> +</body> +</html> \ No newline at end of file diff --git a/DataPlotly/test/scatterplot.json b/DataPlotly/test/scatterplot.json new file mode 100644 index 00000000..9bd56456 --- /dev/null +++ b/DataPlotly/test/scatterplot.json @@ -0,0 +1,888 @@ +{ + "data": [ + { + "hovertemplate": "x=%{x}<br>y=%{y}<extra></extra>", + "legendgroup": "", + "marker": { + "color": "#8ebad9", + "symbol": "circle", + "size": 10.0 + }, + "mode": "markers", + "name": "", + "orientation": "v", + "showlegend": false, + "x": [ + 98, + 88, + 267, + 329, + 319, + 137, + 350, + 151, + 203 + ], + "xaxis": "x", + "y": [ + 81.87, + 22.26, + 74.16, + 35.05, + 46.64, + 126.73, + 116.44, + 108.25, + 110.45 + ], + "yaxis": "y", + "type": "scatter" + } + ], + "layout": { + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0.0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1.0, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0.0, + 1.0 + ], + "title": { + "text": "x" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0.0, + 1.0 + ], + "title": { + "text": "y" + } + }, + "legend": { + "tracegroupgap": 0 + }, + "margin": { + "t": 60 + }, + "showlegend": true + } +} \ No newline at end of file diff --git a/DataPlotly/test/test_processing.py b/DataPlotly/test/test_processing.py new file mode 100644 index 00000000..2b1ff435 --- /dev/null +++ b/DataPlotly/test/test_processing.py @@ -0,0 +1,71 @@ +"""Tests for processing algorithms.""" + +import os +import json + +import processing + +from qgis.core import QgsApplication, QgsVectorLayer +from qgis.testing import unittest +from qgis.PyQt.QtGui import QColor + +from DataPlotly.processing.dataplotly_provider import DataPlotlyProvider + +__copyright__ = 'Copyright 2022, Faunalia' +__license__ = 'GPL version 3' +__email__ = 'info@faunalia.eu' + + +class TestProcessing(unittest.TestCase): + """Tests for processing algorithms.""" + + def setUp(self) -> None: + """Set up the processing tests.""" + if not QgsApplication.processingRegistry().providers(): + self.provider = DataPlotlyProvider(plugin_version='2.3') + QgsApplication.processingRegistry().addProvider(self.provider) + self.maxDiff = None + + def test_scatterplot_figure(self): + """Test for the Processing scatterplot""" + + layer_path = os.path.join( + os.path.dirname(__file__), 'test_layer.shp') + + vl = QgsVectorLayer(layer_path, 'test_layer', 'ogr') + + # plot_path = os.path.join( + # os.path.dirname(__file__), 'scatterplot.json') + # with open(plot_path, 'r') as f: + # template_dict = json.load(f) + + plot_param = { + 'INPUT': vl, + 'XEXPRESSION': '"so4"', + 'YEXPRESSION': '"ca"', + 'SIZE': 10, + 'COLOR': QColor(142, 186, 217), + 'FACET_COL': '', + 'FACET_ROW': '', + 'OFFLINE': False, + 'OUTPUT_HTML_FILE': 'TEMPORARY_OUTPUT', + 'OUTPUT_JSON_FILE': 'TEMPORARY_OUTPUT' + } + + result = processing.run("DataPlotly:dataplotly_scatterplot", plot_param) + + with open(result['OUTPUT_JSON_FILE'], 'r', encoding='utf8') as f: + result_dict = json.load(f) + + self.assertListEqual( + result_dict['data'][0]['x'], + [98, 88, 267, 329, 319, 137, 350, 151, 203] + ) + self.assertListEqual( + result_dict['data'][0]['y'], + [81.87, 22.26, 74.16, 35.05, 46.64, 126.73, 116.44, 108.25, 110.45] + ) + + +if __name__ == '__main__': + unittest.main() diff --git a/REQUIREMENTS_TESTING.txt b/REQUIREMENTS_TESTING.txt index 500731bd..466eb346 100644 --- a/REQUIREMENTS_TESTING.txt +++ b/REQUIREMENTS_TESTING.txt @@ -4,4 +4,5 @@ mock flake8 pep257 plotly -pylint \ No newline at end of file +pylint +pandas \ No newline at end of file From ce4b3b1f96e8c1daa0eb2cc127eb842fab7000bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <etienne.trimaille@gmail.com> Date: Tue, 30 Aug 2022 10:46:03 +0200 Subject: [PATCH 35/57] Fix correct version in the changelog (#303) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fc1ba45..1c3ed68e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -## 3.10 - 2022-08-23 +## 3.9.2 - 2022-08-30 - test added for Processing - Processing algorithm refactored using plotly.express (scatter plot) From f4cc7d4165a4e69de6abae78a6d53ad5489f80f8 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Wed, 31 Aug 2022 17:54:51 +0200 Subject: [PATCH 36/57] Bar width data defined (#304) * add bar width with custom data and standard value * update the attribute table of the test layer * restore label and marker size when the scatter plot is chosen --- DataPlotly/core/plot_types/bar_plot.py | 1 + DataPlotly/gui/plot_settings_widget.py | 16 +++++++++++++--- DataPlotly/test/test_layer.dbf | Bin 3349 -> 3480 bytes 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/DataPlotly/core/plot_types/bar_plot.py b/DataPlotly/core/plot_types/bar_plot.py index 2e6db616..1a5a94ad 100644 --- a/DataPlotly/core/plot_types/bar_plot.py +++ b/DataPlotly/core/plot_types/bar_plot.py @@ -62,6 +62,7 @@ def create_trace(settings): 'color': settings.data_defined_stroke_colors if settings.data_defined_stroke_colors else settings.properties['out_color'], 'width': settings.data_defined_stroke_widths if settings.data_defined_stroke_widths else settings.properties['marker_width']} }, + width=settings.data_defined_marker_sizes if settings.data_defined_marker_sizes else settings.properties['marker_size'], opacity=settings.properties['opacity'] )] diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 06c37c80..1f687576 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -768,6 +768,16 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch ), None, False ) + # change the label and the spin box value when the bar plot is chosen + if self.ptype == 'bar': + self.marker_size_lab.setText(self.tr('Bar width')) + self.marker_size.setValue(0.5) + + # change the label and the spin box value when the scatter plot is chosen + if self.ptype == 'scatter': + self.marker_size_lab.setText(self.tr('Marker size')) + self.marker_size.setValue(10) + # info combo for data hovering self.info_combo.clear() self.info_combo.addItem(self.tr('All Values'), 'all') @@ -813,9 +823,9 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.marker_width_lab: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin'], self.marker_width: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin'], self.stroke_defined_button: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin'], - self.marker_size_lab: ['scatter', 'polar', 'ternary'], - self.marker_size: ['scatter', 'polar', 'ternary'], - self.size_defined_button: ['scatter', 'polar', 'ternary'], + self.marker_size_lab: ['scatter', 'polar', 'ternary', 'bar'], + self.marker_size: ['scatter', 'polar', 'ternary', 'bar'], + self.size_defined_button: ['scatter', 'polar', 'ternary', 'bar'], self.marker_type_lab: ['scatter', 'polar'], self.marker_type_combo: ['scatter', 'polar'], self.alpha_lab: ['scatter', 'bar', 'box', 'histogram', 'polar', 'ternary', 'violin', 'contour'], diff --git a/DataPlotly/test/test_layer.dbf b/DataPlotly/test/test_layer.dbf index 1bb62bc6dc79b5439941e9f5807edd54a609cf1d..624b3522b4f2d8a745f60788e5e98eca5a58f5c4 100644 GIT binary patch delta 214 zcmbO#HA9-4xr#%clYxPOkuhx|_f?_t%#@N0AQuSyKm<3_#!H2a0tR}P1`2Rsk+NBk zlZkP%7jp=Ufu4!+=IP8yAT<^ia3u<6#b7m)*g^yh^$g7s5~fhi(d;2CKpCUWE7*aW p4fRY65o(N~Y6Q7JYK%=b$8kZ_7$ejeLe(7S@#TSv8UQVl0swY7DLeoG delta 111 zcmbOsJynXExtvRklYxQZAw%>;?yH*^lNnhR6cj9qHy3iUFitLK4%&Q$IT|cx1`=as oob19D2vTAS<*s56+|0%SQDO`d3uD}Ti3`Fvgc{?>>&++y03u@>xc~qF From b9003c83bb4fe65d26a929c4e3dea1eeeee0a39d Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Tue, 4 Apr 2023 10:35:34 +0200 Subject: [PATCH 37/57] update QGIS release in docker (#315) --- .github/workflows/test_plugin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_plugin.yaml b/.github/workflows/test_plugin.yaml index 949b23a0..a0b341ad 100644 --- a/.github/workflows/test_plugin.yaml +++ b/.github/workflows/test_plugin.yaml @@ -27,7 +27,7 @@ jobs: strategy: matrix: - docker_tags: [release-3_16, release-3_22, latest] + docker_tags: [release-3_22, release-3_28, latest] steps: From 985f1131e90b8ff547a22ae94e78ee29b6ee219f Mon Sep 17 00:00:00 2001 From: jdlom <jdaniel.lomenede@gmail.com> Date: Thu, 13 Apr 2023 09:13:14 +0200 Subject: [PATCH 38/57] WIP : Add multiple docks (#314) * version control ignores vscode settings * first implementation * add dock_id argument to loadDocFromDic * disconnect signals when unloading * try to create plot immediatly after dock init * docks state and geometry can be restored from project * remove extra comma * feat : add new dock * dock_title can be restored too * dock title with space can be restored now * resize add_dock_dlg * feat : implementation remove dock * fix: main dataplotly panel read_from_project * Update .gitignore Co-authored-by: Matteo Ghetta <matteo.ghetta@gmail.com> * Update DataPlotly/data_plotly.py Co-authored-by: Matteo Ghetta <matteo.ghetta@gmail.com> * Update DataPlotly/gui/remove_dock_dlg.py Co-authored-by: Matteo Ghetta <matteo.ghetta@gmail.com> * Update DataPlotly/data_plotly.py Co-authored-by: Matteo Ghetta <matteo.ghetta@gmail.com> * fix : remove the return value dlg * pylint : start remove unnecessary import and define variable in init * move utils functoin in core_utils * move restore in core_utils * style : pylint * format: pylint * format: pylint * format: pylint * format : pylint * format: pylint * test: add removeDockWidget to QgisInterface * test : add override_iface to DataPlotlyDock const * test : add first tests to dock_manager * test : add other tests * style: pylint use-dict-literal * style: pylint remove superflous parens * test: add test on utils xml function * ignore .qgs~ * test : add test on DataPlotlyNewDockIdValidator * Update .gitignore * Update DataPlotly/test/test_dock_manager.py * fix pycodestyle --------- Co-authored-by: Jean-Daniel LOMENEDE <jean-daniel.lomenede@agriculture-equipement.gouv.fr> Co-authored-by: Matteo Ghetta <matteo.ghetta@gmail.com> --- .gitignore | 6 + DataPlotly/core/core_utils.py | 32 ++ DataPlotly/core/plot_factory.py | 48 +- DataPlotly/core/plot_settings.py | 19 +- DataPlotly/core/plot_types/contour.py | 10 +- DataPlotly/core/plot_types/histogram.py | 28 +- DataPlotly/core/plot_types/pie.py | 8 +- DataPlotly/core/plot_types/ternary.py | 60 +-- DataPlotly/core/plot_types/violin.py | 17 +- DataPlotly/data_plotly.py | 166 ++++++- DataPlotly/gui/add_new_dock_dlg.py | 88 ++++ DataPlotly/gui/dock.py | 173 ++++++- DataPlotly/gui/plot_settings_widget.py | 430 +++++++++++------- DataPlotly/gui/remove_dock_dlg.py | 28 ++ DataPlotly/test/qgis_interface.py | 12 + DataPlotly/test/test_dock_manager.py | 188 ++++++++ DataPlotly/test/test_project_with_state.qgs | 427 +++++++++++++++++ .../test/test_project_without_state.qgs | 421 +++++++++++++++++ DataPlotly/ui/add_dock_dlg.ui | 192 ++++++++ DataPlotly/ui/remove_dock_dlg.ui | 122 +++++ 20 files changed, 2212 insertions(+), 263 deletions(-) create mode 100644 DataPlotly/core/core_utils.py create mode 100644 DataPlotly/gui/add_new_dock_dlg.py create mode 100644 DataPlotly/gui/remove_dock_dlg.py create mode 100644 DataPlotly/test/test_dock_manager.py create mode 100644 DataPlotly/test/test_project_with_state.qgs create mode 100644 DataPlotly/test/test_project_without_state.qgs create mode 100644 DataPlotly/ui/add_dock_dlg.ui create mode 100644 DataPlotly/ui/remove_dock_dlg.ui diff --git a/.gitignore b/.gitignore index 88f1fa4c..61f853b1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,9 @@ DataPlotly/i18n/ .coverage .noseids + +# Vscode +.vscode/* + +# Test +*.qgs~ diff --git a/DataPlotly/core/core_utils.py b/DataPlotly/core/core_utils.py new file mode 100644 index 00000000..76e5f067 --- /dev/null +++ b/DataPlotly/core/core_utils.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +"""COre Utilities + +.. note:: This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +""" +import uuid +from qgis.PyQt.QtCore import QByteArray + + +def safe_str_xml(s): + """ replaces spaces by . + """ + return s.replace(" ", ".") + + +def restore_safe_str_xml(s): + """ replaces . by spaces + """ + return s.replace(".", " ") + + +def restore(b_str_64): + """state and geom are stored in str(Base64) in project xml file""" + return QByteArray.fromBase64(QByteArray(b_str_64.encode())) + + +def uuid_suffix(string: str) -> str: + """ uuid4 suffix""" + return f"{string}{uuid.uuid4()}" diff --git a/DataPlotly/core/plot_factory.py b/DataPlotly/core/plot_factory.py index f241aab1..f1ddbc7e 100644 --- a/DataPlotly/core/plot_factory.py +++ b/DataPlotly/core/plot_factory.py @@ -109,6 +109,9 @@ def __init__(self, settings: PlotSettings = None, context_generator: QgsExpressi self.layout = None self.source_layer = QgsProject.instance().mapLayer( self.settings.source_layer_id) if self.settings.source_layer_id else None + self.plot_path = os.path.join( + tempfile.gettempdir(), + f'temp_plot_name_{self.settings.dock_id}.html') self.rebuild() @@ -126,13 +129,15 @@ def fetch_values_from_layer(self): # pylint: disable=too-many-locals, too-many- if not self.context_generator: context = QgsExpressionContext() - context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(self.source_layer)) + context.appendScopes( + QgsExpressionContextUtils.globalProjectLayerScopes(self.source_layer)) else: context = self.context_generator.createExpressionContext() # add a new scope corresponding to the source layer -- this will potentially overwrite any other # layer scopes which may be present in the context (e.g. from atlas layers), but we need to ensure # that source layer fields and attributes are present in the context - context.appendScope(self.source_layer.createExpressionContextScope()) + context.appendScope( + self.source_layer.createExpressionContextScope()) self.settings.data_defined_properties.prepare(context) @@ -170,7 +175,8 @@ def add_source_field_or_expression(field_or_expression): request = QgsFeatureRequest() if self.settings.data_defined_properties.property(PlotSettings.PROPERTY_FILTER).isActive(): - expression = self.settings.data_defined_properties.property(PlotSettings.PROPERTY_FILTER).asExpression() + expression = self.settings.data_defined_properties.property( + PlotSettings.PROPERTY_FILTER).asExpression() request.setFilterExpression(expression) request.setExpressionContext(context) @@ -192,12 +198,14 @@ def add_source_field_or_expression(field_or_expression): ct = QgsCoordinateTransform(self.polygon_filter.crs(), self.source_layer.crs(), QgsProject.instance().transformContext()) try: - rect = ct.transformBoundingBox(self.polygon_filter.geometry.boundingBox()) + rect = ct.transformBoundingBox( + self.polygon_filter.geometry.boundingBox()) request.setFilterRect(rect) g = self.polygon_filter.geometry g.transform(ct) - visible_geom_engine = QgsGeometry.createGeometryEngine(g.constGet()) + visible_geom_engine = QgsGeometry.createGeometryEngine( + g.constGet()) visible_geom_engine.prepareGeometry() except QgsCsException: pass @@ -259,9 +267,11 @@ def add_source_field_or_expression(field_or_expression): continue if additional_info_expression: - additional_hover_text.append(additional_info_expression.evaluate(context)) + additional_hover_text.append( + additional_info_expression.evaluate(context)) elif self.settings.layout['additional_info_expression']: - additional_hover_text.append(f[self.settings.layout['additional_info_expression']]) + additional_hover_text.append( + f[self.settings.layout['additional_info_expression']]) if x is not None: xx.append(x) @@ -293,8 +303,10 @@ def add_source_field_or_expression(field_or_expression): else: try: # Attempt to interpret the value as a list of color specifications - value_list = self.settings.data_defined_properties.value(PlotSettings.PROPERTY_COLOR, context) - color_list = [QgsSymbolLayerUtils.decodeColor(item).name() for item in value_list] + value_list = self.settings.data_defined_properties.value( + PlotSettings.PROPERTY_COLOR, context) + color_list = [QgsSymbolLayerUtils.decodeColor( + item).name() for item in value_list] colors.extend(color_list) except TypeError: # Not a list of color specifications, use the default color instead @@ -310,8 +322,10 @@ def add_source_field_or_expression(field_or_expression): else: try: # Attempt to interpret the value as a list of color specifications - value_list = self.settings.data_defined_properties.value(PlotSettings.PROPERTY_STROKE_COLOR, context) - color_list = [QgsSymbolLayerUtils.decodeColor(item).name() for item in value_list] + value_list = self.settings.data_defined_properties.value( + PlotSettings.PROPERTY_STROKE_COLOR, context) + color_list = [QgsSymbolLayerUtils.decodeColor( + item).name() for item in value_list] stroke_colors.extend(color_list) except TypeError: # Not a list of color specifications, use the default color instead @@ -639,7 +653,7 @@ def build_html(self, config) -> str: # first lines of additional html with the link to the local javascript raw_plot = '<head><meta charset="utf-8" /><script src="{}">' \ '</script><script src="{}"></script></head>'.format( - self.POLY_FILL_PATH, self.PLOTLY_PATH) + self.POLY_FILL_PATH, self.PLOTLY_PATH) # set some configurations # call the plot method without all the javascript code raw_plot += plotly.offline.plot(fig, output_type='div', include_plotlyjs=False, show_link=False, @@ -676,7 +690,6 @@ def build_figure(self) -> str: path_to_output = factory.build_figure() """ - self.plot_path = os.path.join(tempfile.gettempdir(), 'temp_plot_name.html') config = { 'scrollZoom': True, 'editable': True, @@ -723,7 +736,8 @@ def build_figures(self, plot_type, ptrace, config=None) -> str: # check if the plot type and render the correct figure if plot_type in ('bar', 'histogram'): del self.layout - self.layout = PlotFactory.PLOT_TYPES[plot_type].create_layout(self.settings) + self.layout = PlotFactory.PLOT_TYPES[plot_type].create_layout( + self.settings) figures = go.Figure(data=ptrace, layout=self.layout) else: @@ -735,7 +749,7 @@ def build_figures(self, plot_type, ptrace, config=None) -> str: # first lines of additional html with the link to the local javascript self.raw_plot = '<head><meta charset="utf-8" /><script src="{}">' \ '</script><script src="{}"></script></head>'.format( - self.POLY_FILL_PATH, self.PLOTLY_PATH) + self.POLY_FILL_PATH, self.PLOTLY_PATH) # call the plot method without all the javascript code self.raw_plot += plotly.offline.plot(figures, output_type='div', include_plotlyjs=False, show_link=False, config=config) @@ -747,7 +761,6 @@ def build_figures(self, plot_type, ptrace, config=None) -> str: substr = match.group(1) self.raw_plot = self.raw_plot.replace('ReplaceTheDiv', substr) - self.plot_path = os.path.join(tempfile.gettempdir(), 'temp_plot_name.html') with open(self.plot_path, "w", encoding="utf8") as f: f.write(self.raw_plot) @@ -794,7 +807,7 @@ def build_sub_plots(self, grid, row, column, ptrace): # pylint:disable=too-many # first lines of additional html with the link to the local javascript self.raw_plot = '<head><meta charset="utf-8" /><script src="{}"></script>' \ '<script src="{}"></script></head>'.format( - self.POLY_FILL_PATH, self.PLOTLY_PATH) + self.POLY_FILL_PATH, self.PLOTLY_PATH) # call the plot method without all the javascript code self.raw_plot += plotly.offline.plot(fig, output_type='div', include_plotlyjs=False, show_link=False, config=config) @@ -806,7 +819,6 @@ def build_sub_plots(self, grid, row, column, ptrace): # pylint:disable=too-many substr = match.group(1) self.raw_plot = self.raw_plot.replace('ReplaceTheDiv', substr) - self.plot_path = os.path.join(tempfile.gettempdir(), 'temp_plot_name.html') with open(self.plot_path, "w", encoding="utf8") as f: f.write(self.raw_plot) diff --git a/DataPlotly/core/plot_settings.py b/DataPlotly/core/plot_settings.py index b84f36a4..32dbfa07 100644 --- a/DataPlotly/core/plot_settings.py +++ b/DataPlotly/core/plot_settings.py @@ -82,8 +82,9 @@ class PlotSettings: # pylint: disable=too-many-instance-attributes PROPERTY_Y_MAX: QgsPropertyDefinition('y_max', 'Y axis maximum', QgsPropertyDefinition.Double) } + # pylint: disable=too-many-arguments def __init__(self, plot_type: str = 'scatter', properties: dict = None, layout: dict = None, - source_layer_id=None): + source_layer_id=None, dock_title: str = None, dock_id: str = None): # Define default plot dictionary used as a basis for plot initialization # prepare the default dictionary with None values # plot properties @@ -218,6 +219,10 @@ def __init__(self, plot_type: str = 'scatter', properties: dict = None, layout: self.data_defined_y_max = None self.source_layer_id = source_layer_id + # multiple_dock + self.dock_title = dock_title + self.dock_id = dock_id + def write_xml(self, document: QDomDocument): """ Writes the plot settings to an XML element @@ -255,7 +260,10 @@ def write_to_project(self, document: QDomDocument): Writes the settings to a project (represented by the given DOM document) """ elem = self.write_xml(document) - parent_elem = document.createElement('DataPlotly') + if self.dock_id == 'DataPlotly': + parent_elem = document.createElement('DataPlotly') + else: + parent_elem = document.createElement(f'DataPlotly_{self.dock_title}_{self.dock_id}') parent_elem.appendChild(elem) root_node = document.elementsByTagName("qgis").item(0) @@ -268,8 +276,11 @@ def read_from_project(self, document: QDomDocument): root_node = document.elementsByTagName("qgis").item(0) if root_node.isNull(): return False - - node = root_node.toElement().firstChildElement('DataPlotly') + if self.dock_id == 'DataPlotly': + tag = "DataPlotly" + else: + tag = f'DataPlotly_{self.dock_title}_{self.dock_id}' + node = root_node.toElement().firstChildElement(tag) if node.isNull(): return False diff --git a/DataPlotly/core/plot_types/contour.py b/DataPlotly/core/plot_types/contour.py index 7e7cadd3..4487d655 100644 --- a/DataPlotly/core/plot_types/contour.py +++ b/DataPlotly/core/plot_types/contour.py @@ -35,10 +35,10 @@ def icon(): def create_trace(settings): return [graph_objs.Contour( z=[settings.x, settings.y], - contours=dict( - coloring=settings.properties['cont_type'], - showlines=settings.properties['show_lines'] - ), + contours={ + 'coloring': settings.properties['cont_type'], + 'showlines': settings.properties['show_lines'] + }, colorscale=settings.properties['color_scale'], opacity=settings.properties['opacity'] - )] + )] diff --git a/DataPlotly/core/plot_types/histogram.py b/DataPlotly/core/plot_types/histogram.py index ca66b20a..1d68eb30 100644 --- a/DataPlotly/core/plot_types/histogram.py +++ b/DataPlotly/core/plot_types/histogram.py @@ -33,27 +33,29 @@ def icon(): @staticmethod def create_trace(settings): - return [graph_objs.Histogram( + return [ + graph_objs.Histogram( x=settings.x, y=settings.x, name=settings.data_defined_legend_title if settings.data_defined_legend_title != '' else settings.properties['name'], orientation=settings.properties['box_orientation'], nbinsx=settings.properties['bins'], nbinsy=settings.properties['bins'], - marker=dict( - color=settings.data_defined_colors if settings.data_defined_colors else settings.properties['in_color'], - line=dict( - color=settings.data_defined_stroke_colors if settings.data_defined_stroke_colors else settings.properties['out_color'], - width=settings.data_defined_stroke_widths if settings.data_defined_stroke_widths else settings.properties['marker_width'] - ) - ), + marker={ + 'color': settings.data_defined_colors if settings.data_defined_colors else settings.properties['in_color'], + 'line': { + 'color': settings.data_defined_stroke_colors if settings.data_defined_stroke_colors else settings.properties['out_color'], + 'width': settings.data_defined_stroke_widths if settings.data_defined_stroke_widths else settings.properties['marker_width'] + } + }, histnorm=settings.properties['normalization'], opacity=settings.properties['opacity'], - cumulative=dict( - enabled=settings.properties['cumulative'], - direction=settings.properties['invert_hist'] - ) - )] + cumulative={ + 'enabled': settings.properties['cumulative'], + 'direction': settings.properties['invert_hist'] + } + ) + ] @staticmethod def create_layout(settings): diff --git a/DataPlotly/core/plot_types/pie.py b/DataPlotly/core/plot_types/pie.py index cbc754e5..b45df2a1 100644 --- a/DataPlotly/core/plot_types/pie.py +++ b/DataPlotly/core/plot_types/pie.py @@ -36,11 +36,11 @@ def create_trace(settings): return [graph_objs.Pie( labels=settings.x, values=settings.y, - marker=dict( - colors=settings.data_defined_colors if settings.data_defined_colors else [settings.properties['in_color']] - ), + marker={ + 'colors': settings.data_defined_colors if settings.data_defined_colors else [settings.properties['in_color']] + }, name=settings.properties['custom'][0], - )] + )] @staticmethod def create_layout(settings): diff --git a/DataPlotly/core/plot_types/ternary.py b/DataPlotly/core/plot_types/ternary.py index b7cf23e6..eefe77d4 100644 --- a/DataPlotly/core/plot_types/ternary.py +++ b/DataPlotly/core/plot_types/ternary.py @@ -65,21 +65,21 @@ def create_trace(settings): hoverinfo='text', text=text, mode='markers', - marker=dict( - color=settings.data_defined_colors if settings.data_defined_colors else settings.properties['in_color'], - colorscale=settings.properties['color_scale'], - showscale=settings.properties['show_colorscale_legend'], - reversescale=settings.properties['invert_color_scale'], - colorbar=dict( - len=0.8 - ), - size=settings.data_defined_marker_sizes if settings.data_defined_marker_sizes else settings.properties['marker_size'], - symbol=settings.properties['marker_symbol'], - line=dict( - color=settings.data_defined_stroke_colors if settings.data_defined_stroke_colors else settings.properties['out_color'], - width=settings.data_defined_stroke_widths if settings.data_defined_stroke_widths else settings.properties['marker_width'] - ) - ), + marker={ + 'color': settings.data_defined_colors if settings.data_defined_colors else settings.properties['in_color'], + 'colorscale': settings.properties['color_scale'], + 'showscale': settings.properties['show_colorscale_legend'], + 'reversescale':settings.properties['invert_color_scale'], + 'colorbar': { + 'len': 0.8 + }, + 'size': settings.data_defined_marker_sizes if settings.data_defined_marker_sizes else settings.properties['marker_size'], + 'symbol': settings.properties['marker_symbol'], + 'line': { + 'color': settings.data_defined_stroke_colors if settings.data_defined_stroke_colors else settings.properties['out_color'], + 'width': settings.data_defined_stroke_widths if settings.data_defined_stroke_widths else settings.properties['marker_width'] + } + }, opacity=settings.properties['opacity'] )] @@ -111,20 +111,20 @@ def create_layout(settings): layout['yaxis'].update(zeroline=False) layout['yaxis'].update(showline=False) layout['yaxis'].update(showticklabels=False) - layout['ternary'] = dict( - sum=100, - aaxis=dict( - title=x_title, - ticksuffix='%', - ), - baxis=dict( - title=y_title, - ticksuffix='%' - ), - caxis=dict( - title=z_title, - ticksuffix='%' - ), - ) + layout['ternary'] = { + 'sum': 100, + 'aaxis': { + 'title': x_title, + 'ticksuffix': '%', + }, + 'baxis': { + 'title': y_title, + 'ticksuffix': '%' + }, + 'caxis': { + 'title': z_title, + 'ticksuffix': '%' + }, + } return layout diff --git a/DataPlotly/core/plot_types/violin.py b/DataPlotly/core/plot_types/violin.py index bb77fbdc..b0bd4a2a 100644 --- a/DataPlotly/core/plot_types/violin.py +++ b/DataPlotly/core/plot_types/violin.py @@ -44,19 +44,20 @@ def create_trace(settings): return [graph_objs.Violin( x=x or None, y=y, - name=settings.data_defined_legend_title if settings.data_defined_legend_title != '' else settings.properties['name'], + name=settings.data_defined_legend_title if settings.data_defined_legend_title != '' else settings.properties[ + 'name'], customdata=settings.properties['custom'], orientation=settings.properties['box_orientation'], points=settings.properties['box_outliers'], fillcolor=settings.properties['in_color'], - line=dict( - color=settings.properties['out_color'], - width=settings.properties['marker_width'] - ), + line={ + 'color': settings.properties['out_color'], + 'width': settings.properties['marker_width'] + }, opacity=settings.properties['opacity'], - meanline=dict( - visible=settings.properties['show_mean_line'] - ), + meanline={ + 'visible': settings.properties['show_mean_line'] + }, side=settings.properties['violin_side'], box_visible=settings.properties['violin_box'] )] diff --git a/DataPlotly/data_plotly.py b/DataPlotly/data_plotly.py index 5ef0e921..2aeeb3d8 100644 --- a/DataPlotly/data_plotly.py +++ b/DataPlotly/data_plotly.py @@ -21,15 +21,16 @@ ***************************************************************************/ """ import os.path +from functools import partial -from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt, QUrl -from qgis.PyQt.QtGui import QDesktopServices -from qgis.PyQt.QtWidgets import QAction -from qgis.core import Qgis, QgsApplication, QgsExpression +from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, QUrl +from qgis.PyQt.QtGui import QDesktopServices, QIcon +from qgis.PyQt.QtWidgets import QAction, QMenu, QToolButton +from qgis.core import Qgis, QgsApplication, QgsExpression, QgsProject from qgis.gui import QgsGui # Import the code for the dialog -from DataPlotly.gui.dock import DataPlotlyDock +from DataPlotly.gui.dock import DataPlotlyDockManager from DataPlotly.gui.gui_utils import GuiUtils # import processing provider @@ -46,7 +47,7 @@ class DataPlotly: # pylint: disable=too-many-instance-attributes """QGIS Plugin Implementation.""" - VERSION = '2.3' + VERSION = '4.0' def __init__(self, iface): """Constructor. @@ -81,10 +82,26 @@ def __init__(self, iface): self.show_dock_action = None self.help_action = None self.toolbar = None + self.dock_project_empty = True + + # initialize variable setup in initGui + self.actions = None + self.toolButton = None + self.toolButtonMenu = None + self.toolBtnAction = None + + # dock_widgets + self.dock_widgets = {} + self.dock_manager = DataPlotlyDockManager( + self.iface, self.dock_widgets) self.plot_item_metadata = PlotLayoutItemMetadata() self.plot_item_gui_metadata = None QgsApplication.layoutItemRegistry().addLayoutItemType(self.plot_item_metadata) + QgsProject.instance().cleared.connect(self.dock_manager.removeDocks) + QgsProject.instance().readProject.connect( + self.dock_manager.addDocksFromProject) + QgsProject.instance().writeProject.connect(self.dock_manager.write_to_project) # noinspection PyMethodMayBeStatic def tr(self, message): # pylint: disable=no-self-use @@ -105,13 +122,13 @@ def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon = GuiUtils.get_icon('dataplotly.svg') - # TODO: We are going to let the user set this up in a future iteration - self.toolbar = self.iface.addToolBar('DataPlotly') - self.toolbar.setObjectName('DataPlotly') + # # TODO: We are going to let the user set this up in a future iteration + # self.toolbar = self.iface.addToolBar('DataPlotly') + # self.toolbar.setObjectName('DataPlotly') - self.dock_widget = DataPlotlyDock(message_bar=self.iface.messageBar()) - self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget) - self.dock_widget.hide() + self.actions = [] + + self.dock_widget = self.dock_manager.addNewDock() self.show_dock_action = QAction(icon, self.tr('DataPlotly')) self.show_dock_action.setToolTip(self.tr('Shows the DataPlotly dock')) @@ -119,8 +136,32 @@ def initGui(self): self.dock_widget.setToggleVisibilityAction(self.show_dock_action) - self.iface.pluginMenu().addAction(self.show_dock_action) - self.toolbar.addAction(self.show_dock_action) + self.toolButton = QToolButton() + self.toolButtonMenu = QMenu() + self.toolButton.setMenu(self.toolButtonMenu) + self.toolButton.setPopupMode(QToolButton.MenuButtonPopup) + self.toolBtnAction = self.iface.addToolBarWidget(self.toolButton) + self.toolButton.setDefaultAction(self.show_dock_action) + + sub_actions = [ + { + "text": self.tr("Add a new dock"), + "icon_path": icon, + "callback": self.dock_manager.addNewDockFromDlg, + "parent": self.iface.mainWindow(), + "toolbutton": self.toolButton + }, + { + "text": self.tr("Remove a dock"), + "icon_path": icon, + "callback": self.dock_manager.removeDockFromDlg, + "parent": self.iface.mainWindow(), + "toolbutton": self.toolButton + } + ] + + for action in sub_actions: + self.add_action(**action) # Add processing provider self.initProcessing() @@ -131,13 +172,82 @@ def initGui(self): # Open the online help if Qgis.QGIS_VERSION_INT >= 31000: - self.help_action = QAction(icon, 'DataPlotly', self.iface.mainWindow()) + self.help_action = QAction( + icon, 'DataPlotly', self.iface.mainWindow()) self.iface.pluginHelpMenu().addAction(self.help_action) self.help_action.triggered.connect(self.open_help) # register the function QgsExpression.registerFunction(get_symbol_colors) + def add_action( # pylint: disable = too-many-arguments + self, + icon_path, + text, + callback, + enabled_flag=True, + add_to_toolbar=True, + toolbutton=None, + status_tip=None, + whats_this=None, + parent=None, + args=None): + """Add a toolbar icon to the toolbar. + :param icon_path: Path to the icon for this action. Can be a resource + path (e.g. ':/plugins/foo/bar.png') or a normal file system path. + :type icon_path: str + :param text: Text that should be shown in menu items for this action. + :type text: str + :param callback: Function to be called when the action is triggered. + :type callback: function + :param enabled_flag: A flag indicating if the action should be enabled + by default. Defaults to True. + :type enabled_flag: bool + :param add_to_menu: Flag indicating whether the action should also + be added to the menu. Defaults to True. + :type add_to_menu: bool + :param add_to_toolbar: Flag indicating whether the action should also + be added to the toolbar. Defaults to True. + :type add_to_toolbar: bool + :param status_tip: Optional text to show in a popup when mouse pointer + hovers over the action. + :type status_tip: str + :param parent: Parent widget for the new action. Defaults None. + :type parent: QWidget + :param whats_this: Optional text to show in the status bar when the + mouse pointer hovers over the action. + :returns: The action that was created. Note that the action is also + added to self.actions list. + :rtype: QAction + """ + if not icon_path: + action = QAction(text, parent) + else: + icon = QIcon(icon_path) if isinstance( + icon_path, str) else icon_path + action = QAction(icon, text, parent) + if args: + callback = partial(callback, action, *args) + action.triggered.connect(callback) + action.setEnabled(enabled_flag) + + if status_tip is not None: + action.setStatusTip(status_tip) + + if whats_this is not None: + action.setWhatsThis(whats_this) + + if toolbutton: + self.toolButtonMenu.addAction(action) + else: + if add_to_toolbar: + # Adds plugin icon to Plugins toolbar + self.iface.addToolBarIcon(action) + + self.actions.append(action) + + return action + def initProcessing(self): """Create the Processing provider""" QgsApplication.processingRegistry().addProvider(self.provider) @@ -147,8 +257,8 @@ def unload(self): self.iface.pluginMenu().removeAction(self.show_dock_action) self.show_dock_action.deleteLater() self.show_dock_action = None - self.toolbar.deleteLater() - self.toolbar = None + self.toolButton.deleteLater() + self.toolButton = None if Qgis.QGIS_VERSION_INT >= 31000 and self.help_action: self.iface.pluginHelpMenu().removeAction(self.help_action) @@ -160,14 +270,28 @@ def unload(self): # unregister the function QgsExpression.unregisterFunction('get_symbol_colors') + # disconnect signals for easy dev when using plugin reloader + QgsProject.instance().cleared.disconnect(self.dock_manager.removeDocks) + QgsProject.instance().readProject.disconnect( + self.dock_manager.addDocksFromProject) + QgsProject.instance().writeProject.disconnect( + self.dock_manager.write_to_project) + + # remove all docks + for dock in self.dock_widgets.values(): + self.iface.removeDockWidget(dock) + @staticmethod def open_help(): """ Open the online help. """ - QDesktopServices.openUrl(QUrl('https://github.com/ghtmtt/DataPlotly/blob/master/README.md')) + QDesktopServices.openUrl( + QUrl('https://github.com/ghtmtt/DataPlotly/blob/master/README.md')) - def loadPlotFromDic(self, plot_dic): + def loadPlotFromDic(self, plot_dic, dock_id='DataPlotly'): """ Calls the method to load the DataPlotly dialog with a given dictionary """ - self.dock_widget.main_panel.showPlotFromDic(plot_dic) - self.dock_widget.setUserVisible(True) + dock = self.dock_manager.getDock(dock_id) + if dock: + dock.main_panel.showPlotFromDic(plot_dic) + dock.setUserVisible(True) diff --git a/DataPlotly/gui/add_new_dock_dlg.py b/DataPlotly/gui/add_new_dock_dlg.py new file mode 100644 index 00000000..9c8c2ab6 --- /dev/null +++ b/DataPlotly/gui/add_new_dock_dlg.py @@ -0,0 +1,88 @@ +""" +Dialog to add new DataPlotlyDock with custom validator +""" +from qgis.PyQt import uic +from qgis.PyQt.QtCore import pyqtSignal +from qgis.PyQt.QtGui import QValidator +from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox + +from DataPlotly.core.core_utils import uuid_suffix +from DataPlotly.gui.gui_utils import GuiUtils + +WIDGET, _ = uic.loadUiType(GuiUtils.get_ui_file_path('add_dock_dlg.ui')) + + +class DataPlotlyNewDockDialog(QDialog, WIDGET): + """Dialog to add new dock""" + + def __init__(self, dock_widgets=None, parent=None): + super().__init__(parent) + self.setupUi(self) + + self.DockIdInformationLabel.hide() + validator = DataPlotlyNewDockIdValidator(dock_widgets=dock_widgets) + self.DockIdLineEdit.setValidator(validator) + validator.validationChanged.connect(self.update_dlg) + self.DockTitleLineEdit.valueChanged.connect(self.updateDockIdLineEdit) + self.mCustomizeGroupBox.clicked.connect(self.updateDockIdLineEdit) + + def update_dlg(self, state, msg): + """validator slot""" + is_valid = state != QValidator.Intermediate + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(is_valid) + label = self.DockIdInformationLabel + lineEdit = self.DockIdLineEdit + style_border = "" + if not is_valid: + style_border = "border: 3px solid red" + label.show() + else: + label.hide() + label.setText(msg) + lineEdit.setStyleSheet(style_border) + + def updateDockIdLineEdit(self): + """update the dockid with uuid suffix when + <Customize dockid> checkbox is unchecked + """ + if not self.mCustomizeGroupBox.isChecked(): + title = self.DockTitleLineEdit.value() + self.DockIdLineEdit.setValue(uuid_suffix(title)) + + def get_params(self): + """greturn dock_title and dock_id""" + dock_title = self.DockTitleLineEdit.value() + dock_id = self.DockIdLineEdit.value() + return dock_title, dock_id + + +# pylint: disable=too-few-public-methods +class DataPlotlyNewDockIdValidator(QValidator): + """Custom validator to prevent some users action""" + validationChanged = pyqtSignal(QValidator.State, str) + + def __init__(self, parent=None, dock_widgets=None): + """Constructor.""" + super().__init__(parent) + self.dock_widgets = dock_widgets + + def validate(self, dock_id, pos): + """Checks if dock_id is not empty and not is already present""" + state = QValidator.Acceptable + msg = None + + if dock_id == "": + state = QValidator.Intermediate + msg = self.tr('DockId can not be empty') + + if dock_id in self.dock_widgets: + state = QValidator.Intermediate + msg = self.tr(f'DockId {dock_id} is already taken') + + if '_' in dock_id: + state = QValidator.Intermediate + msg = self.tr('The underscore _ is not allowed') + + self.validationChanged.emit(state, msg) + + return state, dock_id, pos diff --git a/DataPlotly/gui/dock.py b/DataPlotly/gui/dock.py index 003d09ab..b37959ab 100644 --- a/DataPlotly/gui/dock.py +++ b/DataPlotly/gui/dock.py @@ -6,11 +6,17 @@ the Free Software Foundation; either version 2 of the License, or (at your option) any later version. """ +from qgis.PyQt.QtCore import QCoreApplication, Qt +from qgis.PyQt.QtXml import QDomDocument, QDomElement +from qgis.core import QgsXmlUtils from qgis.gui import ( QgsDockWidget, QgsPanelWidgetStack ) +from DataPlotly.core.core_utils import restore, restore_safe_str_xml, safe_str_xml +from DataPlotly.gui.add_new_dock_dlg import DataPlotlyNewDockDialog +from DataPlotly.gui.remove_dock_dlg import DataPlotlyRemoveDockDialog from DataPlotly.gui.plot_settings_widget import DataPlotlyPanelWidget @@ -19,14 +25,173 @@ class DataPlotlyDock(QgsDockWidget): # pylint: disable=too-few-public-methods Plot settings dock widget """ - def __init__(self, parent=None, message_bar=None): + def __init__(self, parent=None, message_bar=None, # pylint: disable=too-many-arguments + dock_title: str = 'DataPlotly', dock_id: str = 'DataPlotly', + project: QDomDocument = None, override_iface=None): super().__init__(parent) - self.setWindowTitle(self.tr('DataPlotly')) - self.setObjectName('DataPlotlyDock') + self.title = restore_safe_str_xml(dock_title) + self.setWindowTitle(self.title) + self.setObjectName(f'DataPlotly-{dock_id}-Dock') self.panel_stack = QgsPanelWidgetStack() self.setWidget(self.panel_stack) - self.main_panel = DataPlotlyPanelWidget(message_bar=message_bar) + self.main_panel = DataPlotlyPanelWidget( + message_bar=message_bar, dock_title=dock_title, dock_id=dock_id, project=project, override_iface=override_iface) self.panel_stack.setMainPanel(self.main_panel) self.main_panel.setDockMode(True) + + +class DataPlotlyDockManager(): + """ + Manager to add multiple docks + """ + + def __init__(self, iface, dock_widgets): + self.iface = iface + self.dock_widgets = dock_widgets + self.state = None + self.geometry = None + + @staticmethod + def tr(message): + """ Translate function""" + return QCoreApplication.translate('DataPlotly', message) + + def addNewDockFromDlg(self): + """ Open a dlg and add dock""" + dlg = DataPlotlyNewDockDialog(self.dock_widgets) + if dlg.exec_(): + dock_title, dock_id = dlg.get_params() + self.addNewDock(dock_title, dock_id, False) + + def removeDockFromDlg(self): + """ Open a dlg to remove a dock""" + dlg = DataPlotlyRemoveDockDialog(self.dock_widgets) + if dlg.exec_(): + dock_id = dlg.get_param() + self.removeDock(dock_id) + + def addNewDock(self, dock_title='DataPlotly', dock_id='DataPlotly', # pylint: disable=too-many-arguments + hide=True, message_bar=None, project=None): + """ Add new dock """ + dock_title = safe_str_xml(dock_title) + dock_id = safe_str_xml(dock_id) + if dock_id in self.dock_widgets: + if dock_id == 'DataPlotly': + return self.dock_widgets[dock_id] + self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr( + f'DataPlotlyDock can not be added because {dock_id} is already present')) + return False + message_bar = message_bar or self.iface.messageBar() + dock = DataPlotlyDock( + dock_title=dock_title, message_bar=message_bar, dock_id=dock_id, project=project, override_iface=self.iface) + self.dock_widgets[dock_id] = dock + self.iface.addDockWidget(Qt.RightDockWidgetArea, dock) + if hide: + dock.hide() + return dock + + def removeDock(self, dock_id): + """ Remove dock with id """ + dock = self.dock_widgets.pop(dock_id, None) + if dock: + self.iface.removeDockWidget(dock) + # TODO remove dock_id in project file + + def removeDocks(self): + """ Remove all docks except the main one """ + dock_widgets = self.dock_widgets.copy() + for dock_id in dock_widgets.keys(): + if dock_id == 'DataPlotly': + continue + self.removeDock(dock_id) + + # self.dock_project_empty = True + + def addDocksFromProject(self, document: QDomDocument): + """ Add docks from project instance """ + root_node = document.elementsByTagName("qgis").item(0) + if root_node.isNull(): + return False + # loop to find matching dock + nodes = root_node.childNodes() + for i in range(nodes.length()): + tag_name = nodes.at(i).toElement().tagName() + if tag_name.startswith('DataPlotly_'): + _, dock_title, dock_id = tag_name.split('_') + self.addNewDock(dock_title=restore_safe_str_xml(dock_title), + dock_id=restore_safe_str_xml(dock_id), + hide=False, + message_bar=None, + project=document) + # FIXME : trigger the plot creation (not working) + # main_panel = self.getDock(tag_name).main_panel + # main_panel.create_plot() + if self.read_from_project(document): + self.iface.mainWindow().restoreGeometry(self.geometry) + self.iface.mainWindow().restoreState(self.state, version=999) + return True + + def getDock(self, dock_id: str) -> DataPlotlyDock: + """ Return the dock from the dock_id """ + dock = self.dock_widgets.get(dock_id) + if not dock: + self.iface.messageBar().pushWarning( + self.tr('Warning'), + self.tr(f'DataPlotlyDock {dock_id} can not be found')) + return dock + + # TODO: Refactor : this functions are almost the same in plot_settings.py + def write_xml(self, document: QDomDocument): + """ + Writes the docks position settings to an XML element + """ + mw = self.iface.mainWindow() + state = mw.saveState(version=999).toBase64() + geometry = mw.saveGeometry().toBase64() + + element = QgsXmlUtils.writeVariant({ + 'state': str(state, "utf-8"), + 'geometry': str(geometry, "utf-8") + }, document) + return element + + def read_xml(self, element: QDomElement) -> bool: + """ + Reads the docs state settings from an XML element + """ + res = QgsXmlUtils.readVariant(element) + if not isinstance(res, dict) or \ + 'geometry' not in res or \ + 'state' not in res: + return False + + self.state = restore(res['state']) + self.geometry = restore(res['geometry']) + return True + + def write_to_project(self, document: QDomDocument): + """ + Writes the settings to a project (represented by the given DOM document) + """ + elem = self.write_xml(document) + parent_elem = document.createElement('StateDataPlotly') + parent_elem.appendChild(elem) + root_node = document.elementsByTagName("qgis").item(0) + root_node.appendChild(parent_elem) + + def read_from_project(self, document: QDomDocument): + """ + Reads the settings from a project (represented by the given DOM document) + """ + root_node = document.elementsByTagName("qgis").item(0) + if root_node.isNull(): + return False + + node = root_node.toElement().firstChildElement('StateDataPlotly') + if node.isNull(): + return False + + elem = node.toElement() + return self.read_xml(elem.firstChildElement()) diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 1f687576..2540dcd7 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -76,7 +76,8 @@ from DataPlotly.core.plot_settings import PlotSettings from DataPlotly.gui.gui_utils import GuiUtils -WIDGET, _ = uic.loadUiType(GuiUtils.get_ui_file_path('dataplotly_dockwidget_base.ui')) +WIDGET, _ = uic.loadUiType( + GuiUtils.get_ui_file_path('dataplotly_dockwidget_base.ui')) class DataPlotlyPanelWidget(QgsPanelWidget, WIDGET): # pylint: disable=too-many-lines,too-many-instance-attributes,too-many-public-methods @@ -90,7 +91,8 @@ class DataPlotlyPanelWidget(QgsPanelWidget, WIDGET): # pylint: disable=too-many # emit signal when dialog is resized resizeWindow = pyqtSignal() - def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_bar: QgsMessageBar = None): # pylint: disable=too-many-statements + def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_bar: QgsMessageBar = None, # pylint: disable=too-many-statements,too-many-arguments + dock_title: str = None, dock_id: str = None, project: QDomDocument = None): """Constructor.""" super().__init__(parent) self.setupUi(self) @@ -101,6 +103,8 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b self.mode = mode self.message_bar = message_bar + self.dock_title = dock_title + self.dock_id = dock_id self.setPanelTitle(self.tr('Plot Properties')) @@ -115,7 +119,8 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b if self.iface is not None: self.listWidget.setIconSize(self.iface.iconSize(False)) - self.listWidget.setMaximumWidth(int(self.listWidget.iconSize().width() * 1.18)) + self.listWidget.setMaximumWidth( + int(self.listWidget.iconSize().width() * 1.18)) # connect signal to function to reload the plot view self.resizeWindow.connect(self.reloadPlotCanvas) @@ -130,9 +135,11 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b self.reload_btn.clicked.connect(self.reloadPlotCanvas2) self.configuration_menu = QMenu(self) - action_load_configuration = self.configuration_menu.addAction(self.tr("Load Configuration…")) + action_load_configuration = self.configuration_menu.addAction( + self.tr("Load Configuration…")) action_load_configuration.triggered.connect(self.load_configuration) - action_save_configuration = self.configuration_menu.addAction(self.tr("Save Configuration…")) + action_save_configuration = self.configuration_menu.addAction( + self.tr("Save Configuration…")) action_save_configuration.triggered.connect(self.save_configuration) self.configuration_btn.setMenu(self.configuration_menu) @@ -169,7 +176,8 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b type_classes = [clazz for _, clazz in PlotFactory.PLOT_TYPES.items()] type_classes.sort(key=lambda x: x.name().lower()) for clazz in type_classes: - self.plot_combo.addItem(clazz.icon(), clazz.name(), clazz.type_name()) + self.plot_combo.addItem( + clazz.icon(), clazz.name(), clazz.type_name()) # default to scatter plots self.set_plot_type('scatter') @@ -186,7 +194,8 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b self.plot_combo.currentIndexChanged.connect(self.refreshWidgets) self.plot_combo.currentIndexChanged.connect(self.helpPage) self.subcombo.currentIndexChanged.connect(self.refreshWidgets2) - self.marker_type_combo.currentIndexChanged.connect(self.refreshWidgets3) + self.marker_type_combo.currentIndexChanged.connect( + self.refreshWidgets3) # fill the layer combobox with vector layers self.layer_combo.setFilters(QgsMapLayerProxyModel.VectorLayer) @@ -222,12 +231,15 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b self.layoutw.setContentsMargins(0, 0, 0, 0) self.plot_qview.setLayout(self.layoutw) self.plot_view = QWebView() - self.plot_view.page().setNetworkAccessManager(QgsNetworkAccessManager.instance()) + self.plot_view.page().setNetworkAccessManager( + QgsNetworkAccessManager.instance()) self.plot_view.statusBarMessage.connect(self.getJSmessage) plot_view_settings = self.plot_view.settings() plot_view_settings.setAttribute(QWebSettings.WebGLEnabled, True) - plot_view_settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True) - plot_view_settings.setAttribute(QWebSettings.Accelerated2dCanvasEnabled, True) + plot_view_settings.setAttribute( + QWebSettings.DeveloperExtrasEnabled, True) + plot_view_settings.setAttribute( + QWebSettings.Accelerated2dCanvasEnabled, True) self.layoutw.addWidget(self.plot_view) # get the plot type from the combobox @@ -237,40 +249,69 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b # fill combo boxes when launching the UI self.selected_layer_changed(self.layer_combo.currentLayer()) - self.register_data_defined_button(self.feature_subset_defined_button, PlotSettings.PROPERTY_FILTER) - self.register_data_defined_button(self.size_defined_button, PlotSettings.PROPERTY_MARKER_SIZE) - self.size_defined_button.registerEnabledWidget(self.marker_size, natural=False) - self.register_data_defined_button(self.stroke_defined_button, PlotSettings.PROPERTY_STROKE_WIDTH) - self.stroke_defined_button.registerEnabledWidget(self.marker_width, natural=False) - self.register_data_defined_button(self.in_color_defined_button, PlotSettings.PROPERTY_COLOR) - self.in_color_defined_button.registerEnabledWidget(self.in_color_combo, natural=False) - self.in_color_defined_button.changed.connect(self.data_defined_color_updated) - self.register_data_defined_button(self.out_color_defined_button, PlotSettings.PROPERTY_STROKE_COLOR) - self.out_color_defined_button.registerEnabledWidget(self.out_color_combo, natural=False) - self.register_data_defined_button(self.plot_title_defined_button, PlotSettings.PROPERTY_TITLE) - self.plot_title_defined_button.registerEnabledWidget(self.plot_title_line, natural=False) - self.register_data_defined_button(self.legend_title_defined_button, PlotSettings.PROPERTY_LEGEND_TITLE) - self.legend_title_defined_button.registerEnabledWidget(self.legend_title, natural=False) - self.register_data_defined_button(self.x_axis_title_defined_button, PlotSettings.PROPERTY_X_TITLE) - self.x_axis_title_defined_button.registerEnabledWidget(self.x_axis_title, natural=False) - self.register_data_defined_button(self.y_axis_title_defined_button, PlotSettings.PROPERTY_Y_TITLE) - self.y_axis_title_defined_button.registerEnabledWidget(self.y_axis_title, natural=False) - self.register_data_defined_button(self.z_axis_title_defined_button, PlotSettings.PROPERTY_Z_TITLE) - self.z_axis_title_defined_button.registerEnabledWidget(self.z_axis_title, natural=False) - self.register_data_defined_button(self.x_axis_min_defined_button, PlotSettings.PROPERTY_X_MIN) - self.x_axis_min_defined_button.registerEnabledWidget(self.x_axis_min, natural=False) - self.register_data_defined_button(self.x_axis_max_defined_button, PlotSettings.PROPERTY_X_MAX) - self.x_axis_max_defined_button.registerEnabledWidget(self.x_axis_max, natural=False) - self.register_data_defined_button(self.y_axis_min_defined_button, PlotSettings.PROPERTY_Y_MIN) - self.y_axis_min_defined_button.registerEnabledWidget(self.y_axis_min, natural=False) - self.register_data_defined_button(self.y_axis_max_defined_button, PlotSettings.PROPERTY_Y_MAX) - self.y_axis_max_defined_button.registerEnabledWidget(self.y_axis_max, natural=False) + self.register_data_defined_button( + self.feature_subset_defined_button, PlotSettings.PROPERTY_FILTER) + self.register_data_defined_button( + self.size_defined_button, PlotSettings.PROPERTY_MARKER_SIZE) + self.size_defined_button.registerEnabledWidget( + self.marker_size, natural=False) + self.register_data_defined_button( + self.stroke_defined_button, PlotSettings.PROPERTY_STROKE_WIDTH) + self.stroke_defined_button.registerEnabledWidget( + self.marker_width, natural=False) + self.register_data_defined_button( + self.in_color_defined_button, PlotSettings.PROPERTY_COLOR) + self.in_color_defined_button.registerEnabledWidget( + self.in_color_combo, natural=False) + self.in_color_defined_button.changed.connect( + self.data_defined_color_updated) + self.register_data_defined_button( + self.out_color_defined_button, PlotSettings.PROPERTY_STROKE_COLOR) + self.out_color_defined_button.registerEnabledWidget( + self.out_color_combo, natural=False) + self.register_data_defined_button( + self.plot_title_defined_button, PlotSettings.PROPERTY_TITLE) + self.plot_title_defined_button.registerEnabledWidget( + self.plot_title_line, natural=False) + self.register_data_defined_button( + self.legend_title_defined_button, PlotSettings.PROPERTY_LEGEND_TITLE) + self.legend_title_defined_button.registerEnabledWidget( + self.legend_title, natural=False) + self.register_data_defined_button( + self.x_axis_title_defined_button, PlotSettings.PROPERTY_X_TITLE) + self.x_axis_title_defined_button.registerEnabledWidget( + self.x_axis_title, natural=False) + self.register_data_defined_button( + self.y_axis_title_defined_button, PlotSettings.PROPERTY_Y_TITLE) + self.y_axis_title_defined_button.registerEnabledWidget( + self.y_axis_title, natural=False) + self.register_data_defined_button( + self.z_axis_title_defined_button, PlotSettings.PROPERTY_Z_TITLE) + self.z_axis_title_defined_button.registerEnabledWidget( + self.z_axis_title, natural=False) + self.register_data_defined_button( + self.x_axis_min_defined_button, PlotSettings.PROPERTY_X_MIN) + self.x_axis_min_defined_button.registerEnabledWidget( + self.x_axis_min, natural=False) + self.register_data_defined_button( + self.x_axis_max_defined_button, PlotSettings.PROPERTY_X_MAX) + self.x_axis_max_defined_button.registerEnabledWidget( + self.x_axis_max, natural=False) + self.register_data_defined_button( + self.y_axis_min_defined_button, PlotSettings.PROPERTY_Y_MIN) + self.y_axis_min_defined_button.registerEnabledWidget( + self.y_axis_min, natural=False) + self.register_data_defined_button( + self.y_axis_max_defined_button, PlotSettings.PROPERTY_Y_MAX) + self.y_axis_max_defined_button.registerEnabledWidget( + self.y_axis_max, natural=False) # connect to refreshing function of listWidget and stackedWidgets self.listWidget.currentRowChanged.connect(self.updateStacked) # connect the plot changing to the color data defined buttons - self.plot_combo.currentIndexChanged.connect(self.data_defined_color_updated) + self.plot_combo.currentIndexChanged.connect( + self.data_defined_color_updated) # better default colors self.in_color_combo.setColor(QColor('#8EBAD9')) @@ -320,6 +361,12 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b QgsProject.instance().layerWillBeRemoved.connect(self.layer_will_be_removed) + # new dock instance from project + if project: + self.read_project(project) + # FIXME: creation plot is not working + # self.create_plot() + def updateStacked(self, row): """ according to the listWdiget row change the stackedWidget and @@ -342,7 +389,8 @@ def registerExpressionContextGenerator(self, generator: QgsExpressionContextGene self.x_combo.registerExpressionContextGenerator(generator) self.y_combo.registerExpressionContextGenerator(generator) self.z_combo.registerExpressionContextGenerator(generator) - self.additional_info_combo.registerExpressionContextGenerator(generator) + self.additional_info_combo.registerExpressionContextGenerator( + generator) buttons = self.findChildren(QgsPropertyOverrideButton) for button in buttons: @@ -352,7 +400,8 @@ def register_data_defined_button(self, button, property_key: int): """ Registers a new data defined button, linked to the given property key (see values in PlotSettings) """ - button.init(property_key, self.data_defined_properties, PlotSettings.DYNAMIC_PROPERTIES, None, False) + button.init(property_key, self.data_defined_properties, + PlotSettings.DYNAMIC_PROPERTIES, None, False) button.changed.connect(self._update_property) def _update_property(self): @@ -360,7 +409,8 @@ def _update_property(self): Triggered when a property override button value is changed """ button = self.sender() - self.data_defined_properties.setProperty(button.propertyKey(), button.toProperty()) + self.data_defined_properties.setProperty( + button.propertyKey(), button.toProperty()) def update_data_defined_button(self, button): """ @@ -371,7 +421,8 @@ def update_data_defined_button(self, button): return button.blockSignals(True) - button.setToProperty(self.data_defined_properties.property(button.propertyKey())) + button.setToProperty( + self.data_defined_properties.property(button.propertyKey())) button.blockSignals(False) def set_print_layout(self, print_layout): @@ -494,18 +545,22 @@ def getJSmessage(self, status): if dic['type'] == 'scatter': self.layer_combo.currentLayer().selectByIds([dic['fidd']]) elif dic["type"] == 'pie': - exp = """ "{}" = '{}' """.format(dic['field'], dic['label']) + exp = """ "{}" = '{}' """.format( + dic['field'], dic['label']) # set the iterator with the expression as filter in feature request request = QgsFeatureRequest().setFilterExpression(exp) it = self.layer_combo.currentLayer().getFeatures(request) - self.layer_combo.currentLayer().selectByIds([f.id() for f in it]) + self.layer_combo.currentLayer().selectByIds( + [f.id() for f in it]) elif dic["type"] == 'histogram': vmin = dic['id'] - dic['bin_step'] / 2 vmax = dic['id'] + dic['bin_step'] / 2 - exp = """ "{}" <= {} AND "{}" > {} """.format(dic['field'], vmax, dic['field'], vmin) + exp = """ "{}" <= {} AND "{}" > {} """.format( + dic['field'], vmax, dic['field'], vmin) request = QgsFeatureRequest().setFilterExpression(exp) it = self.layer_combo.currentLayer().getFeatures(request) - self.layer_combo.currentLayer().selectByIds([f.id() for f in it]) + self.layer_combo.currentLayer().selectByIds( + [f.id() for f in it]) elif dic["type"] == 'scatterternary': self.layer_combo.currentLayer().selectByIds([dic['fid']]) else: @@ -514,7 +569,8 @@ def getJSmessage(self, status): # set the iterator with the expression as filter in feature request request = QgsFeatureRequest().setFilterExpression(exp) it = self.layer_combo.currentLayer().getFeatures(request) - self.layer_combo.currentLayer().selectByIds([f.id() for f in it]) + self.layer_combo.currentLayer().selectByIds( + [f.id() for f in it]) # print(exp) except: # pylint: disable=bare-except # noqa: F401 pass @@ -529,7 +585,8 @@ def helpPage(self): self.help_view.load(QUrl('')) self.layouth.addWidget(self.help_view) - help_url = QUrl('https://dataplotly-docs.readthedocs.io/en/latest/{}.html'.format(self.ptype)) + help_url = QUrl( + 'https://dataplotly-docs.readthedocs.io/en/latest/{}.html'.format(self.ptype)) self.help_view.load(help_url) def resizeEvent(self, event): @@ -590,7 +647,8 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.outliers_combo.clear() self.outliers_combo.addItem(self.tr('No Outliers'), False) self.outliers_combo.addItem(self.tr('Standard Outliers'), 'outliers') - self.outliers_combo.addItem(self.tr('Suspected Outliers'), 'suspectedoutliers') + self.outliers_combo.addItem( + self.tr('Suspected Outliers'), 'suspectedoutliers') self.outliers_combo.addItem(self.tr('All Points'), 'all') # BoxPlot statistic types @@ -680,7 +738,8 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.hist_norm_combo.addItem(self.tr('Percents'), 'percent') self.hist_norm_combo.addItem(self.tr('Probability'), 'probability') self.hist_norm_combo.addItem(self.tr('Density'), 'density') - self.hist_norm_combo.addItem(self.tr('Prob Density'), 'probability density') + self.hist_norm_combo.addItem( + self.tr('Prob Density'), 'probability density') # Contour Plot rendering type self.contour_type = OrderedDict([ @@ -727,7 +786,8 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.x_label.setFixedWidth(100) self.orientation_label.setText(self.tr('Box orientation')) self.in_color_lab.setText(self.tr('Box color')) - self.register_data_defined_button(self.in_color_defined_button, PlotSettings.PROPERTY_COLOR) + self.register_data_defined_button( + self.in_color_defined_button, PlotSettings.PROPERTY_COLOR) elif self.ptype in ('scatter', 'ternary', 'bar', '2dhistogram', 'contour', 'polar'): self.x_label.setText(self.tr('X field')) @@ -738,7 +798,8 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch elif self.ptype == 'bar': self.orientation_label.setText(self.tr('Bar orientation')) self.in_color_lab.setText(self.tr('Bar color')) - self.register_data_defined_button(self.in_color_defined_button, PlotSettings.PROPERTY_COLOR) + self.register_data_defined_button( + self.in_color_defined_button, PlotSettings.PROPERTY_COLOR) elif self.ptype == 'pie': self.x_label.setText(self.tr('Grouping field')) @@ -748,7 +809,8 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.x_label.setFixedWidth(80) # Register button again with more specific help text self.in_color_defined_button.init( - PlotSettings.PROPERTY_COLOR, self.data_defined_properties.property(PlotSettings.PROPERTY_COLOR), + PlotSettings.PROPERTY_COLOR, self.data_defined_properties.property( + PlotSettings.PROPERTY_COLOR), QgsPropertyDefinition( 'color', QgsPropertyDefinition.DataType.DataTypeString, 'Color Array', "string [<b>r,g,b,a</b>] as int 0-255 or #<b>AARRGGBB</b> as hex or <b>color</b> as color's name, " @@ -760,7 +822,8 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch elif self.ptype == 'histogram': # Register button again with more specific help text self.in_color_defined_button.init( - PlotSettings.PROPERTY_COLOR, self.data_defined_properties.property(PlotSettings.PROPERTY_COLOR), + PlotSettings.PROPERTY_COLOR, self.data_defined_properties.property( + PlotSettings.PROPERTY_COLOR), QgsPropertyDefinition( 'color', QgsPropertyDefinition.DataType.DataTypeString, 'Color Array', "string [<b>r,g,b,a</b>] as int 0-255 or #<b>AARRGGBB</b> as hex or <b>color</b> as color's name, " @@ -1002,7 +1065,8 @@ def setLegend(self): elif self.ptype == 'histogram': self.legend_title.setText(self.x_combo.currentText()) else: - legend_title_string = ('{} - {}'.format(self.x_combo.currentText(), self.y_combo.currentText())) + legend_title_string = ( + '{} - {}'.format(self.x_combo.currentText(), self.y_combo.currentText())) self.legend_title.setText(legend_title_string) def get_settings(self) -> PlotSettings: # pylint: disable=R0915 @@ -1013,7 +1077,8 @@ def get_settings(self) -> PlotSettings: # pylint: disable=R0915 self.ptype = self.plot_combo.currentData() # if colorscale should be visible or not - color_scale_visible = self.color_scale_data_defined_in_check.isVisible() and self.color_scale_data_defined_in_check.isChecked() + color_scale_visible = self.color_scale_data_defined_in_check.isVisible( + ) and self.color_scale_data_defined_in_check.isChecked() # dictionary of all the plot properties plot_properties = {'custom': [self.x_combo.currentText()], @@ -1065,7 +1130,8 @@ def get_settings(self) -> PlotSettings: # pylint: disable=R0915 plot_properties[ 'color_scale_data_defined_in_invert_check'] = self.color_scale_data_defined_in_invert_check.isChecked() if self.ptype in self.widgetType[self.color_scale_data_defined_in]: - plot_properties['color_scale'] = self.color_scale_data_defined_in.currentData() + plot_properties['color_scale'] = self.color_scale_data_defined_in.currentData( + ) else: plot_properties['color_scale'] = self.color_scale_combo.currentData() @@ -1076,51 +1142,54 @@ def get_settings(self) -> PlotSettings: # pylint: disable=R0915 'legend_orientation': 'h' if self.orientation_legend_check.isChecked() else 'v', 'title': self.plot_title_line.text(), 'font_title_size': max( - self.font_title_style.currentFont().pixelSize(), - self.font_title_style.currentFont().pointSize()), - 'font_title_family': self.font_title_style.currentFont().family(), - 'font_title_color': self.font_title_color.color().name(), - 'font_xlabel_size': max( - self.font_xlabel_style.currentFont().pixelSize(), - self.font_xlabel_style.currentFont().pointSize()), - 'font_xlabel_family': self.font_xlabel_style.currentFont().family(), - 'font_xlabel_color': self.font_xlabel_color.color().name(), - 'font_xticks_size': max( - self.font_xticks_style.currentFont().pixelSize(), - self.font_xticks_style.currentFont().pointSize()), - 'font_xticks_family': self.font_xticks_style.currentFont().family(), - 'font_xticks_color': self.font_xticks_color.color().name(), - 'font_ylabel_size': max( - self.font_ylabel_style.currentFont().pixelSize(), - self.font_ylabel_style.currentFont().pointSize()), - 'font_ylabel_family': self.font_ylabel_style.currentFont().family(), - 'font_ylabel_color': self.font_ylabel_color.color().name(), - 'font_yticks_size': max( - self.font_yticks_style.currentFont().pixelSize(), - self.font_yticks_style.currentFont().pointSize()), - 'font_yticks_family': self.font_yticks_style.currentFont().family(), - 'font_yticks_color': self.font_yticks_color.color().name(), - 'x_title': self.x_axis_title.text(), - 'y_title': self.y_axis_title.text(), - 'z_title': self.z_axis_title.text(), - 'range_slider': {'visible': self.range_slider_combo.isChecked(), - 'borderwidth': 1}, - 'bar_mode': self.bar_mode_combo.currentData(), - 'x_type': self.x_axis_mode_combo.currentData(), - 'y_type': self.y_axis_mode_combo.currentData(), - 'x_inv': None if not self.invert_x_check.isChecked() else 'reversed', - 'y_inv': None if not self.invert_y_check.isChecked() else 'reversed', - 'x_min': self.x_axis_min.value() if self.x_axis_bounds_check.isChecked() else None, - 'x_max': self.x_axis_max.value() if self.x_axis_bounds_check.isChecked() else None, - 'y_min': self.y_axis_min.value() if self.y_axis_bounds_check.isChecked() else None, - 'y_max': self.y_axis_max.value() if self.y_axis_bounds_check.isChecked() else None, - 'bargaps': self.bar_gap.value(), - 'additional_info_expression': self.additional_info_combo.expression(), - 'bins_check': self.bins_check.isChecked(), - 'gridcolor': self.layout_grid_axis_color.color().name()} + self.font_title_style.currentFont().pixelSize(), + self.font_title_style.currentFont().pointSize()), + 'font_title_family': self.font_title_style.currentFont().family(), + 'font_title_color': self.font_title_color.color().name(), + 'font_xlabel_size': max( + self.font_xlabel_style.currentFont().pixelSize(), + self.font_xlabel_style.currentFont().pointSize()), + 'font_xlabel_family': self.font_xlabel_style.currentFont().family(), + 'font_xlabel_color': self.font_xlabel_color.color().name(), + 'font_xticks_size': max( + self.font_xticks_style.currentFont().pixelSize(), + self.font_xticks_style.currentFont().pointSize()), + 'font_xticks_family': self.font_xticks_style.currentFont().family(), + 'font_xticks_color': self.font_xticks_color.color().name(), + 'font_ylabel_size': max( + self.font_ylabel_style.currentFont().pixelSize(), + self.font_ylabel_style.currentFont().pointSize()), + 'font_ylabel_family': self.font_ylabel_style.currentFont().family(), + 'font_ylabel_color': self.font_ylabel_color.color().name(), + 'font_yticks_size': max( + self.font_yticks_style.currentFont().pixelSize(), + self.font_yticks_style.currentFont().pointSize()), + 'font_yticks_family': self.font_yticks_style.currentFont().family(), + 'font_yticks_color': self.font_yticks_color.color().name(), + 'x_title': self.x_axis_title.text(), + 'y_title': self.y_axis_title.text(), + 'z_title': self.z_axis_title.text(), + 'range_slider': {'visible': self.range_slider_combo.isChecked(), + 'borderwidth': 1}, + 'bar_mode': self.bar_mode_combo.currentData(), + 'x_type': self.x_axis_mode_combo.currentData(), + 'y_type': self.y_axis_mode_combo.currentData(), + 'x_inv': None if not self.invert_x_check.isChecked() else 'reversed', + 'y_inv': None if not self.invert_y_check.isChecked() else 'reversed', + 'x_min': self.x_axis_min.value() if self.x_axis_bounds_check.isChecked() else None, + 'x_max': self.x_axis_max.value() if self.x_axis_bounds_check.isChecked() else None, + 'y_min': self.y_axis_min.value() if self.y_axis_bounds_check.isChecked() else None, + 'y_max': self.y_axis_max.value() if self.y_axis_bounds_check.isChecked() else None, + 'bargaps': self.bar_gap.value(), + 'additional_info_expression': self.additional_info_combo.expression(), + 'bins_check': self.bins_check.isChecked(), + 'gridcolor': self.layout_grid_axis_color.color().name()} settings = PlotSettings(plot_type=self.ptype, properties=plot_properties, layout=layout_properties, - source_layer_id=self.layer_combo.currentLayer().id() if self.layer_combo.currentLayer() else None) + source_layer_id=self.layer_combo.currentLayer().id( + ) if self.layer_combo.currentLayer() else None, + dock_title=self.dock_title, + dock_id=self.dock_id) settings.data_defined_properties = self.data_defined_properties return settings @@ -1143,8 +1212,10 @@ def set_settings(self, settings: PlotSettings): # pylint: disable=too-many-stat # Set the plot properties self.set_layer_id(settings.source_layer_id) - self.selected_feature_check.setChecked(settings.properties.get('selected_features_only', False)) - self.visible_feature_check.setChecked(settings.properties.get('visible_features_only', False)) + self.selected_feature_check.setChecked( + settings.properties.get('selected_features_only', False)) + self.visible_feature_check.setChecked( + settings.properties.get('visible_features_only', False)) self.data_defined_properties = settings.data_defined_properties buttons = self.findChildren(QgsPropertyOverrideButton) @@ -1154,8 +1225,10 @@ def set_settings(self, settings: PlotSettings): # pylint: disable=too-many-stat # trigger methods depending on data defined button properties self.data_defined_color_updated() - self.filter_by_map_check.setChecked(settings.properties.get('layout_filter_by_map', False)) - self.filter_by_atlas_check.setChecked(settings.properties.get('layout_filter_by_atlas', False)) + self.filter_by_map_check.setChecked( + settings.properties.get('layout_filter_by_map', False)) + self.filter_by_atlas_check.setChecked( + settings.properties.get('layout_filter_by_atlas', False)) self.x_combo.setExpression(settings.properties.get('x_name', '')) self.y_combo.setExpression(settings.properties.get('y_name', '')) self.z_combo.setExpression(settings.properties.get('z_name', '')) @@ -1165,7 +1238,8 @@ def set_settings(self, settings: PlotSettings): # pylint: disable=too-many-stat self.color_scale_data_defined_in.setCurrentIndex( self.color_scale_data_defined_in.findData(settings.properties.get('color_scale', None))) - self.color_scale_data_defined_in_check.setChecked(settings.properties.get('color_scale_data_defined_in_check', False)) + self.color_scale_data_defined_in_check.setChecked( + settings.properties.get('color_scale_data_defined_in_check', False)) self.color_scale_data_defined_in_invert_check.setChecked( settings.properties.get('color_scale_data_defined_in_invert_check', False)) self.out_color_combo.setColor( @@ -1173,74 +1247,103 @@ def set_settings(self, settings: PlotSettings): # pylint: disable=too-many-stat self.marker_width.setValue(settings.properties.get('marker_width', 1)) self.marker_type_combo.setCurrentText( settings.properties.get('marker_type_combo', 'Points')) - self.point_combo.setCurrentText(settings.properties.get('point_combo', '')) + self.point_combo.setCurrentText( + settings.properties.get('point_combo', '')) self.line_combo.setCurrentText( settings.properties.get('line_combo', 'Solid Line')) self.contour_type_combo.setCurrentText( settings.properties.get('contour_type_combo', 'Fill')) - self.show_lines_check.setChecked(settings.properties.get('show_lines_check', False)) - self.color_scale_combo.setCurrentIndex(self.color_scale_combo.findData(settings.properties.get('color_scale', None))) + self.show_lines_check.setChecked( + settings.properties.get('show_lines_check', False)) + self.color_scale_combo.setCurrentIndex(self.color_scale_combo.findData( + settings.properties.get('color_scale', None))) self.opacity_widget.setOpacity(settings.properties.get('opacity', 1)) - self.orientation_legend_check.setChecked(settings.layout.get('legend_orientation') == 'h') - self.range_slider_combo.setChecked(settings.layout['range_slider']['visible']) + self.orientation_legend_check.setChecked( + settings.layout.get('legend_orientation') == 'h') + self.range_slider_combo.setChecked( + settings.layout['range_slider']['visible']) self.plot_title_line.setText( settings.layout.get('title', 'Plot Title')) self.legend_title.setText(settings.properties.get('name', '')) self.font_title_style.setCurrentFont( QFont(settings.layout.get('font_title_family', "Arial"), - settings.layout.get('font_title_size', 10))) + settings.layout.get('font_title_size', 10))) self.font_title_color.setColor( QColor(settings.layout.get('font_title_color', "#000000"))) self.font_xticks_style.setCurrentFont( QFont(settings.layout.get('font_xticks_family', "Arial"), - settings.layout.get('font_xticks_size', 10))) + settings.layout.get('font_xticks_size', 10))) self.font_xticks_color.setColor( QColor(settings.layout.get('font_xticks_color', "#000000"))) self.font_xlabel_style.setCurrentFont( QFont(settings.layout.get('font_xlabel_family', "Arial"), - settings.layout.get('font_xlabel_size', 10))) + settings.layout.get('font_xlabel_size', 10))) self.font_xlabel_color.setColor( QColor(settings.layout.get('font_xlabel_color', "#000000"))) self.font_yticks_style.setCurrentFont( QFont(settings.layout.get('font_yticks_family', "Arial"), - settings.layout.get('font_yticks_size', 10))) + settings.layout.get('font_yticks_size', 10))) self.font_yticks_color.setColor( QColor(settings.layout.get('font_yticks_color', "#000000"))) self.font_ylabel_style.setCurrentFont( QFont(settings.layout.get('font_ylabel_family', "Arial"), - settings.layout.get('font_ylabel_size', 10))) + settings.layout.get('font_ylabel_size', 10))) self.font_ylabel_color.setColor( QColor(settings.layout.get('font_ylabel_color', "#000000"))) self.x_axis_title.setText(settings.layout.get('x_title', '')) self.y_axis_title.setText(settings.layout.get('y_title', '')) self.z_axis_title.setText(settings.layout.get('z_title', '')) - self.info_combo.setCurrentIndex(self.info_combo.findData(settings.properties.get('hover_text', None))) - self.additional_info_combo.setExpression(settings.layout.get('additional_info_expression', '')) - self.hover_as_text_check.setChecked(settings.properties.get('hover_label_text') == '+text') + self.info_combo.setCurrentIndex(self.info_combo.findData( + settings.properties.get('hover_text', None))) + self.additional_info_combo.setExpression( + settings.layout.get('additional_info_expression', '')) + self.hover_as_text_check.setChecked( + settings.properties.get('hover_label_text') == '+text') self.combo_text_position.setCurrentIndex( self.combo_text_position.findData(settings.layout.get('hover_label_position', 'auto'))) - self.invert_x_check.setChecked(settings.layout.get('x_inv') == 'reversed') - self.x_axis_mode_combo.setCurrentIndex(self.x_axis_mode_combo.findData(settings.layout.get('x_type', None))) - self.invert_y_check.setChecked(settings.layout.get('y_inv') == 'reversed') - self.y_axis_mode_combo.setCurrentIndex(self.y_axis_mode_combo.findData(settings.layout.get('y_type', None))) - self.x_axis_bounds_check.setChecked(settings.layout.get('x_min', None) is not None) - self.x_axis_bounds_check.setCollapsed(settings.layout.get('x_min', None) is None) - self.x_axis_min.setValue(settings.layout.get('x_min') if settings.layout.get('x_min', None) is not None else 0.0) - self.x_axis_max.setValue(settings.layout.get('x_max') if settings.layout.get('x_max', None) is not None else 0.0) - self.y_axis_bounds_check.setChecked(settings.layout.get('y_min', None) is not None) - self.y_axis_bounds_check.setCollapsed(settings.layout.get('y_min', None) is None) - self.y_axis_min.setValue(settings.layout.get('y_min') if settings.layout.get('y_min', None) is not None else 0.0) - self.y_axis_max.setValue(settings.layout.get('y_max') if settings.layout.get('y_max', None) is not None else 0.0) - self.orientation_combo.setCurrentIndex(self.orientation_combo.findData(settings.properties.get('box_orientation', 'v'))) - self.bar_mode_combo.setCurrentIndex(self.bar_mode_combo.findData(settings.layout.get('bar_mode', None))) - self.hist_norm_combo.setCurrentIndex(self.hist_norm_combo.findData(settings.properties.get('normalization', None))) - self.box_statistic_combo.setCurrentIndex(self.box_statistic_combo.findData(settings.properties.get('box_stat', None))) - self.outliers_combo.setCurrentIndex(self.outliers_combo.findData(settings.properties.get('box_outliers', None))) - self.violinSideCombo.setCurrentIndex(self.violinSideCombo.findData(settings.properties.get('violin_side', None))) + self.invert_x_check.setChecked( + settings.layout.get('x_inv') == 'reversed') + self.x_axis_mode_combo.setCurrentIndex( + self.x_axis_mode_combo.findData(settings.layout.get('x_type', None))) + self.invert_y_check.setChecked( + settings.layout.get('y_inv') == 'reversed') + self.y_axis_mode_combo.setCurrentIndex( + self.y_axis_mode_combo.findData(settings.layout.get('y_type', None))) + self.x_axis_bounds_check.setChecked( + settings.layout.get('x_min', None) is not None) + self.x_axis_bounds_check.setCollapsed( + settings.layout.get('x_min', None) is None) + self.x_axis_min.setValue(settings.layout.get( + 'x_min') if settings.layout.get('x_min', None) is not None else 0.0) + self.x_axis_max.setValue(settings.layout.get( + 'x_max') if settings.layout.get('x_max', None) is not None else 0.0) + self.y_axis_bounds_check.setChecked( + settings.layout.get('y_min', None) is not None) + self.y_axis_bounds_check.setCollapsed( + settings.layout.get('y_min', None) is None) + self.y_axis_min.setValue(settings.layout.get( + 'y_min') if settings.layout.get('y_min', None) is not None else 0.0) + self.y_axis_max.setValue(settings.layout.get( + 'y_max') if settings.layout.get('y_max', None) is not None else 0.0) + self.orientation_combo.setCurrentIndex(self.orientation_combo.findData( + settings.properties.get('box_orientation', 'v'))) + self.bar_mode_combo.setCurrentIndex( + self.bar_mode_combo.findData(settings.layout.get('bar_mode', None))) + self.hist_norm_combo.setCurrentIndex(self.hist_norm_combo.findData( + settings.properties.get('normalization', None))) + self.box_statistic_combo.setCurrentIndex( + self.box_statistic_combo.findData(settings.properties.get('box_stat', None))) + self.outliers_combo.setCurrentIndex(self.outliers_combo.findData( + settings.properties.get('box_outliers', None))) + self.violinSideCombo.setCurrentIndex(self.violinSideCombo.findData( + settings.properties.get('violin_side', None))) self.violinBox.setChecked(settings.properties.get('violin_box', False)) - self.showMeanCheck.setChecked(settings.properties.get('show_mean_line', False)) - self.cumulative_hist_check.setChecked(settings.properties.get('cumulative', False)) - self.invert_hist_check.setChecked(settings.properties.get('invert_hist') == 'decreasing') + self.showMeanCheck.setChecked( + settings.properties.get('show_mean_line', False)) + self.cumulative_hist_check.setChecked( + settings.properties.get('cumulative', False)) + self.invert_hist_check.setChecked( + settings.properties.get('invert_hist') == 'decreasing') self.bins_check.setChecked(settings.layout.get('bins_check', False)) self.bins_value.setValue(settings.properties.get('bins', 0)) self.bar_gap.setValue(settings.layout.get('bargaps', 0)) @@ -1268,7 +1371,8 @@ def create_plot_factory(self) -> PlotFactory: # create default dictionary that contains all the plot and properties self.plot_factories[self.pid] = plot_factory - plot_factory.plot_built.connect(partial(self.refresh_plot, plot_factory)) + plot_factory.plot_built.connect( + partial(self.refresh_plot, plot_factory)) # just add 1 to the index self.idx += 1 @@ -1338,16 +1442,19 @@ def create_plot(self): # plot in single row and many columns if self.radio_rows.isChecked(): - self.plot_path = plot_factory.build_sub_plots('row', 1, gr, pl) + self.plot_path = 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('col', gr, 1, pl) + self.plot_path = plot_factory.build_sub_plots( + 'col', gr, 1, pl) except: # pylint: disable=bare-except # noqa: F401 if self.message_bar: self.message_bar.pushMessage( - self.tr("{} plot is not compatible for subplotting\n see ".format(self.ptype)), + self.tr( + "{} plot is not compatible for subplotting\n see ".format(self.ptype)), Qgis.MessageLevel(2), duration=5) return @@ -1361,7 +1468,7 @@ def UpdatePlot(self): and call the method to create the plot with the updated settings """ if self.mode == DataPlotlyPanelWidget.MODE_CANVAS: - plot_to_update = (sorted(self.plot_factories.keys())[-1]) + plot_to_update = sorted(self.plot_factories.keys())[-1] del self.plot_factories[plot_to_update] self.create_plot() @@ -1407,7 +1514,8 @@ def save_plot_as_image(self): Save the current plot view as a png image. The user can choose the path and the file name """ - plot_file, _ = QFileDialog.getSaveFileName(self, self.tr("Save Plot"), "", "*.png") + plot_file, _ = QFileDialog.getSaveFileName( + self, self.tr("Save Plot"), "", "*.png") if not plot_file: return @@ -1416,7 +1524,8 @@ def save_plot_as_image(self): frame = self.plot_view.page().mainFrame() self.plot_view.page().setViewportSize(frame.contentsSize()) # render image - image = QImage(self.plot_view.page().viewportSize(), QImage.Format_ARGB32) + image = QImage(self.plot_view.page().viewportSize(), + QImage.Format_ARGB32) painter = QPainter(image) frame.render(painter) painter.end() @@ -1424,7 +1533,8 @@ def save_plot_as_image(self): if self.message_bar: self.message_bar.pushSuccess(self.tr('DataPlotly'), self.tr('Plot saved to <a href="{}">{}</a>').format( - QUrl.fromLocalFile(plot_file).toString(), + QUrl.fromLocalFile( + plot_file).toString(), QDir.toNativeSeparators(plot_file))) def save_plot_as_html(self): @@ -1433,17 +1543,20 @@ def save_plot_as_html(self): where to save the already existing html file created by plotly """ - plot_file, _ = QFileDialog.getSaveFileName(self, self.tr("Save Plot"), "", "*.html") + plot_file, _ = QFileDialog.getSaveFileName( + self, self.tr("Save Plot"), "", "*.html") if not plot_file: return - plot_file = QgsFileUtils.ensureFileNameHasExtension(plot_file, ['html']) + plot_file = QgsFileUtils.ensureFileNameHasExtension(plot_file, [ + 'html']) copyfile(self.plot_path, plot_file) if self.message_bar: self.message_bar.pushSuccess(self.tr('DataPlotly'), self.tr('Saved plot to <a href="{}">{}</a>').format( - QUrl.fromLocalFile(plot_file).toString(), + QUrl.fromLocalFile( + plot_file).toString(), QDir.toNativeSeparators(plot_file))) def showPlotFromDic(self, plot_input_dic): @@ -1485,7 +1598,8 @@ def showPlotFromDic(self, plot_input_dic): # set some dialog widget from the input dictionary # plot type in the plot_combo combobox - self.plot_combo.setCurrentIndex(self.plot_combo.findData(plot_input_dic["plot_type"])) + self.plot_combo.setCurrentIndex( + self.plot_combo.findData(plot_input_dic["plot_type"])) try: self.layer_combo.setLayer(plot_input_dic["layer"]) @@ -1549,7 +1663,8 @@ def read_project(self, document: QDomDocument): if not self.read_from_project: return - settings = PlotSettings() + settings = PlotSettings( + dock_title=self.dock_title, dock_id=self.dock_id) if settings.read_from_project(document): # update the dock state to match the read settings self.set_settings(settings) @@ -1558,20 +1673,23 @@ def load_configuration(self): """ Loads configuration settings from a file """ - file, _ = QFileDialog.getOpenFileName(self, self.tr("Load Configuration"), "", "XML files (*.xml)") + file, _ = QFileDialog.getOpenFileName(self, self.tr( + "Load Configuration"), "", "XML files (*.xml)") if file: settings = PlotSettings() if settings.read_from_file(file): self.set_settings(settings) else: if self.message_bar: - self.message_bar.pushWarning(self.tr('DataPlotly'), self.tr('Could not read settings from file')) + self.message_bar.pushWarning(self.tr('DataPlotly'), self.tr( + 'Could not read settings from file')) def save_configuration(self): """ Saves configuration settings to a file """ - file, _ = QFileDialog.getSaveFileName(self, self.tr("Save Configuration"), "", "XML files (*.xml)") + file, _ = QFileDialog.getSaveFileName(self, self.tr( + "Save Configuration"), "", "XML files (*.xml)") if file: file = QgsFileUtils.ensureFileNameHasExtension(file, ['xml']) self.get_settings().write_to_file(file) diff --git a/DataPlotly/gui/remove_dock_dlg.py b/DataPlotly/gui/remove_dock_dlg.py new file mode 100644 index 00000000..fdb7f7e9 --- /dev/null +++ b/DataPlotly/gui/remove_dock_dlg.py @@ -0,0 +1,28 @@ +""" +Minimal dlg with combobox to remove DataPlotlyDialog +""" +from qgis.PyQt import uic + +from qgis.PyQt.QtWidgets import QDialog +from qgis.PyQt.QtCore import Qt + +from DataPlotly.gui.gui_utils import GuiUtils + + +WIDGET, _ = uic.loadUiType(GuiUtils.get_ui_file_path('remove_dock_dlg.ui')) + + +# pylint: disable=too-few-public-methods +class DataPlotlyRemoveDockDialog(QDialog, WIDGET): + """Dialog to remove new dock""" + def __init__(self, dock_widgets=None, parent=None): + super().__init__(parent) + self.setupUi(self) + dock_ids = [dock_id for dock_id in dock_widgets.keys() if dock_id != 'DataPlotly'] + self.DockIdsComboBox.addItems(dock_ids) + for i, dock_id in enumerate(dock_ids): + self.DockIdsComboBox.setItemData(i, dock_widgets[dock_id].title, Qt.ToolTipRole) + + def get_param(self): + """Return the dock_id to delete""" + return self.DockIdsComboBox.currentText() diff --git a/DataPlotly/test/qgis_interface.py b/DataPlotly/test/qgis_interface.py index a9b16fbc..57fd118d 100644 --- a/DataPlotly/test/qgis_interface.py +++ b/DataPlotly/test/qgis_interface.py @@ -35,6 +35,7 @@ # noinspection PyMethodMayBeStatic,PyPep8Naming +# pylint: disable=too-many-public-methods class QgisInterface(QObject): """Class to expose QGIS objects and functions to plugins. @@ -204,6 +205,17 @@ def addDockWidget(self, area, dock_widget: QDockWidget): """ pass # pylint: disable=unnecessary-pass + def removeDockWidget(self, dock_widget: QDockWidget): + """Remove a dock widget to the main window. + + :param area: Where in the ui the dock should be placed. + :type area: + + :param dock_widget: A dock widget to add to the UI. + :type dock_widget: QDockWidget + """ + pass # pylint: disable=unnecessary-pass + def legendInterface(self): """Get the legend.""" return self.canvas diff --git a/DataPlotly/test/test_dock_manager.py b/DataPlotly/test/test_dock_manager.py new file mode 100644 index 00000000..c8992711 --- /dev/null +++ b/DataPlotly/test/test_dock_manager.py @@ -0,0 +1,188 @@ +# coding=utf-8 +"""Plot factory test + +.. note:: This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +""" + +import os.path +import unittest + +from qgis.PyQt.QtCore import QByteArray, QFile, QIODevice +from qgis.PyQt.QtGui import QValidator +from qgis.PyQt.QtXml import QDomDocument + +from DataPlotly.core.core_utils import restore, restore_safe_str_xml, safe_str_xml +from DataPlotly.test.utilities import get_qgis_app +from DataPlotly.gui.dock import (DataPlotlyDock, DataPlotlyDockManager) +from DataPlotly.gui.add_new_dock_dlg import DataPlotlyNewDockIdValidator + +QGIS_APP, CANVAS, IFACE, PARENT = get_qgis_app() + + +def read_project(project_path): + """Retur a document from qgs file + + Args: + project_path (str): path to qgs file + + Returns: + QDocument: document + """ + xml_file = QFile(project_path) + if xml_file.open(QIODevice.ReadOnly): + xml_doc = QDomDocument() + xml_doc.setContent(xml_file) + xml_file.close() + return xml_doc + return None + + +class DataPlotlyDockManagerTest(unittest.TestCase): + """ + Test DataPlotlyDockManager + """ + + def setUp(self): + self.dock_widgets = {} + self.dock_manager = DataPlotlyDockManager( + iface=IFACE, dock_widgets=self.dock_widgets) + + def test_001_constructor(self): + """ + Test the constructor of DataPlotlyDockManager + """ + self.assertIs(self.dock_widgets, self.dock_manager.dock_widgets) + + def test_002_add_new_dock(self): + """ + Test addNewDock of DataPlotlyDockManager + """ + # checks DataPlotly main dock + self.assertNotIn('DataPlotly', self.dock_widgets) + dock_widget = self.dock_manager.addNewDock() + self.assertIsInstance(dock_widget, DataPlotlyDock) + self.assertIn('DataPlotly', self.dock_widgets) + self.assertIs(dock_widget, self.dock_widgets['DataPlotly']) + + # checks it's not possible to add a new dock with DataPlotly as dock_id + dock_widget2 = self.dock_manager.addNewDock(dock_title='NewDataPlotly', + dock_id='DataPlotly') + self.assertIs(dock_widget2, dock_widget) + + # checks we can not add new dock with same dock_id + dock_params = {'dock_title': 'DataPlotly2', 'dock_id': 'DataPlotly2'} + self.dock_manager.addNewDock(**dock_params) + self.assertIn('DataPlotly2', self.dock_widgets) + new_dock_widget = self.dock_manager.addNewDock( + dock_title='DataPlotly2b', dock_id='DataPlotly2') + self.assertFalse(new_dock_widget) + + def test_003_remove_dock(self): + """ + Test removeDock + """ + dock_id = 'dock_to_remove' + self.dock_manager.addNewDock(dock_id=dock_id) + self.assertIn(dock_id, self.dock_widgets) + self.dock_manager.removeDock(dock_id) + self.assertNotIn(dock_id, self.dock_widgets) + + def test_004_remove_docks(self): + """ + Test removeDocks + """ + docks = ['DataPlotly', 'DataPlotly2', 'DataPlotly3'] + for dock in docks: + self.dock_manager.addNewDock(dock_id=dock) + self.dock_manager.removeDocks() + # do not remove DataPlotly main dock + self.assertIn('DataPlotly', self.dock_widgets) + self.assertEqual(len(self.dock_widgets), 1) + + def test_005_get_dock(self): + """ + Test getDock + """ + docks = ['DataPlotly', 'DataPlotly2', 'DataPlotly3'] + for dock in docks: + self.dock_manager.addNewDock(dock_id=dock) + dock = self.dock_manager.getDock('DataPloty4_wrong_id') + self.assertIsNone(dock) + dock = self.dock_manager.getDock('DataPlotly3') + self.assertIsInstance(dock, DataPlotlyDock) + self.assertIs(dock, self.dock_widgets['DataPlotly3']) + + def test_006_read_project(self): + """ + Test read_project with or without StateDataPlotly + """ + # project with StateDataPlotly dom + project_path = os.path.join(os.path.dirname( + __file__), 'test_project_with_state.qgs') + document = read_project(project_path) + ok = self.dock_manager.read_from_project(document) + self.assertTrue(ok) + + # project without StateDataPlotly dom + project_path = os.path.join(os.path.dirname( + __file__), 'test_project_without_state.qgs') + document = read_project(project_path) + ko = self.dock_manager.read_from_project(document) + self.assertFalse(ko) + + def test_007_utils_xml_function(self): + """ + Test restore, restore_safe_str_xml, safe_str_xml + """ + test_string = "My test" + self.assertEqual(test_string, restore_safe_str_xml( + safe_str_xml(test_string))) + test_string = b'test' + str_b64 = str(QByteArray(test_string).toBase64(), 'utf-8') + self.assertEqual(test_string, restore(str_b64)) + + def test_008_add_docks_from_project(self): + """ + Test docks are added, custom project without StateDataPlotly node + """ + project_path = os.path.join(os.path.dirname( + __file__), 'test_project_without_state.qgs') + document = read_project(project_path) + self.dock_manager.addDocksFromProject(document) + # all docks except main DataPlotlyDock are created + dock_id = 'my-test' + dock_title = "My Test" + self.assertIn(dock_id, self.dock_widgets) + # . is replace by space My.Test -> My Test + self.assertEqual(self.dock_widgets[dock_id].title, dock_title) + + def test_009_add_new_dock_validator(self): + """ + Test DockIdValidator + """ + validator = DataPlotlyNewDockIdValidator( + dock_widgets=self.dock_widgets) + docks = ['DataPlotly', 'DataPlotly2', 'DataPlotly3'] + for dock in docks: + self.dock_manager.addNewDock(dock_id=dock) + + # Dockid is valid + state, _, _ = validator.validate('NewDockId', None) + self.assertEqual( + QValidator.Acceptable, + state + ) + # Dockid can not be empty / No underscore / Not already taken + for bad_dock_id in ['', 'with_underscore', 'DataPlotly2']: + state, _, _ = validator.validate(bad_dock_id, None) + self.assertEqual(QValidator.Intermediate, state) + + +if __name__ == "__main__": + suite = unittest.makeSuite(DataPlotlyDockManagerTest) + runner = unittest.TextTestRunner(verbosity=2) + runner.run(suite) diff --git a/DataPlotly/test/test_project_with_state.qgs b/DataPlotly/test/test_project_with_state.qgs new file mode 100644 index 00000000..14f31b26 --- /dev/null +++ b/DataPlotly/test/test_project_with_state.qgs @@ -0,0 +1,427 @@ +<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'> +<qgis version="3.18.3-Zürich" saveUserFull="jd" saveDateTime="2023-04-11T00:24:01" projectname="" saveUser="jd"> + <homePath path=""/> + <title></title> + <autotransaction active="0"/> + <evaluateDefaultValues active="0"/> + <trust active="0"/> + <projectCrs> + <spatialrefsys> + <wkt>GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]]</wkt> + <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4> + <srsid>3452</srsid> + <srid>4326</srid> + <authid>EPSG:4326</authid> + <description>WGS 84</description> + <projectionacronym>longlat</projectionacronym> + <ellipsoidacronym>EPSG:7030</ellipsoidacronym> + <geographicflag>true</geographicflag> + </spatialrefsys> + </projectCrs> + <layer-tree-group> + <customproperties/> + <custom-order enabled="0"/> + </layer-tree-group> + <snapping-settings type="1" maxScale="0" unit="1" minScale="0" intersection-snapping="0" self-snapping="0" mode="2" enabled="0" scaleDependencyMode="0" tolerance="12"> + <individual-layer-settings/> + </snapping-settings> + <relations/> + <polymorphicRelations/> + <mapcanvas annotationsVisible="1" name="theMapCanvas"> + <units>degrees</units> + <extent> + <xmin>-1</xmin> + <ymin>-1</ymin> + <xmax>1</xmax> + <ymax>1</ymax> + </extent> + <rotation>0</rotation> + <destinationsrs> + <spatialrefsys> + <wkt>GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]]</wkt> + <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4> + <srsid>3452</srsid> + <srid>4326</srid> + <authid>EPSG:4326</authid> + <description>WGS 84</description> + <projectionacronym>longlat</projectionacronym> + <ellipsoidacronym>EPSG:7030</ellipsoidacronym> + <geographicflag>true</geographicflag> + </spatialrefsys> + </destinationsrs> + <rendermaptile>0</rendermaptile> + <expressionContextScope/> + </mapcanvas> + <StateDataPlotly> + <Option type="Map"> + <Option type="QString" value="AdnQywADAAAAAABIAAAAGwAACf8AAAWfAAAEYwAAAEAAAAn/AAAFnwAAAAACAAAACgAAAABIAAAAQAAACf8AAAWf" name="geometry"/> + <Option type="QString" value="AAAA/wAAA+f9AAAABAAAAAAAAAG1AAAEuvwCAAAAD/sAAAB4AEQAYQB0AGEAUABsAG8AdABsAHkALQBNAG8AbgBlAHMAcwBhAGkAOQBhAGEANwAzADUAMwBiAC0AYgBhAGUAYwAtADQAZQAxADQALQBiAGQAZAAxAC0AYgAyAGQAMwAyADAAOQBhADgAOAAzAGYALQBEAG8AYwBrAQAAAIkAAAS6AAAAAAAAAAD7AAAAggBEAGEAdABhAFAAbABvAHQAbAB5AC0AZABlAHUAeABpAGUAbQBlAG4ARABvAGMAawA2ADgAMwBkADIANwAzAGEALQAzADAAOABhAC0ANAA4ADMAYwAtADkANQBkADcALQBlAGIAMQBmADQAOAA1AGEAMAAxAGQAOQAtAEQAbwBjAGsBAAAAiQAABLoAAAAAAAAAAPwAAACJAAACmAAAAAAA////+gAAAAABAAAAA/sAAAAMAEwAZQBnAGUAbgBkAQAAAAD/////AAAAAAAAAAD7AAAAFABMAGEAeQBlAHIATwByAGQAZQByAAAAAAD/////AAAApgD////7AAAADgBCAHIAbwB3AHMAZQByAAAAAAD/////AAAAOgD////7AAAAEABPAHYAZQByAHYAaQBlAHcAAAAB1wAAAMQAAAATAP////sAAAAiAEMAbwBvAHIAZABpAG4AYQB0AGUAQwBhAHAAdAB1AHIAZQAAAAF+AAAAoAAAAAAAAAAA+wAAAAgAVQBuAGQAbwAAAAHkAAAA3AAAAAAAAAAA+wAAABAAQgByAG8AdwBzAGUAcgAyAAAAAhMAAACtAAAAKAD////7AAAAHABHAFAAUwBJAG4AZgBvAHIAbQBhAHQAaQBvAG4AAAABuwAAAQUAAABXAP////sAAAAoAGQAdwBPAHAAZQBuAGwAYQB5AGUAcgBzAE8AdgBlAHIAdgBpAGUAdwAAAAFkAAABNwAAAAAAAAAA+wAAABwAdQBuAGQAbwAvAHIAZQBkAG8AIABkAG8AYwBrAAAAAAD/////AAAA7wD////7AAAALgBBAGQAdgBhAG4AYwBlAGQARABpAGcAaQB0AGkAegBpAG4AZwBUAG8AbwBsAHMAAAAAAP////8AAAClAAAB9PsAAAA0AFMAdABhAHQAaQBzAHQAYQBsAFMAdQBtAG0AYQByAHkARABvAGMAawBXAGkAZABnAGUAdAAAAAAA/////wAAAAAAAAAA+wAAACYAQgBvAG8AawBtAGEAcgBrAHMARABvAGMAawBXAGkAZABnAGUAdAAAAAAA/////wAAAHgA////+wAAAAwATABhAHkAZQByAHMBAAAAiQAABLoAAAB4AP////sAAAA4AFMAdABhAHQAaQBzAHQAaQBjAGEAbABTAHUAbQBtAGEAcgB5AEQAbwBjAGsAVwBpAGQAZwBlAHQAAAAAAP////8AAAC/AP///wAAAAEAAAI1AAAEuvwCAAAAEfsAAAAeAFMAZQB4AHQAYQBuAHQAZQBUAG8AbwBsAGIAbwB4AAAAAGcAAAI0AAAAAAAAAAD8AAAAiQAAAukAAACPAP////oAAAACAQAAAAP7AAAAegBEAGEAdABhAFAAbABvAHQAbAB5AC0AZgBxAGQAZgBxAHMAZABmAHEAMwAxADcAMQA2ADkANwAxAC0AYQBhADYAYQAtADQANgAzAGUALQBhADkANABjAC0AOQA4AGMAZgBiADMAOQAzAGEAOQAyADkALQBEAG8AYwBrAQAAAAD/////AAAAAAAAAAD7AAAAGABMAGEAeQBlAHIAUwB0AHkAbABpAG4AZwAAAAPWAAABKgAAASEA////+wAAACIAUAByAG8AYwBlAHMAcwBpAG4AZwBUAG8AbwBsAGIAbwB4AQAAAAD/////AAAARgD////7AAAAFABEAG8AYwBrAFcAaQBkAGcAZQB0AAAAAAD/////AAAAAAAAAAD7AAAAEABEAGUAdgBUAG8AbwBsAHMAAAAAAP////8AAABdAP////sAAAAaAFIAZQBzAHUAbAB0AHMAVgBpAGUAdwBlAHIAAAAAAP////8AAAEdAP////sAAAAmAEkAZABlAG4AdABpAGYAeQBSAGUAcwB1AGwAdABzAEQAbwBjAGsBAAADRAAAAf8AAAAAAAAAAPsAAAAkAHAAZwBfAG0AZQB0AGEAZABhAHQAYQBfAGcAZQBvAGkAZABlAQAAAhwAAAG/AAAAAAAAAAD7AAAANABEAGEAdABhAFAAbABvAHQAbAB5AC0ARABhAHQAYQBQAGwAbwB0AGwAeQAtAEQAbwBjAGsAAAAAiQAABLoAAABXAP////sAAAA0AEQAYQB0AGEAUABsAG8AdABsAHkALQBEAGEAdABhAFAAbABvAHQAbAB5AC0ARABvAGMAawAAAAKRAAACsgAAAAAAAAAA+wAAAHAARABhAHQAYQBQAGwAbwB0AGwAeQAtAFQAZQBzAHQAZQBjADcAMwA5ADcANgAxAC0AMgBkADEAMQAtADQAOABjADQALQBhADIAYgBlAC0AYwA2AGEANwA5AGIAMABkADEAOAA0ADgALQBEAG8AYwBrAQAAAIkAAAS6AAAAAAAAAAD7AAAAegBEAGEAdABhAFAAbABvAHQAbAB5AC0ATQBvAG4AIABlAHMAcwBhAGkAYwA0ADIAMABmAGYAOAA4AC0AMwA1AGEAOAAtADQAZgBmADMALQBiAGMANQBkAC0ANwA4ADcAZQAyAGQAMQAzADYAMgBkAGMALQBEAG8AYwBrAQAAAIkAAAS6AAAAAAAAAAD7AAAAegBEAGEAdABhAFAAbABvAHQAbAB5AC0ATQBvAG4AIABlAHMAcwBhAGkAOQBhAGEANwAzADUAMwBiAC0AYgBhAGUAYwAtADQAZQAxADQALQBiAGQAZAAxAC0AYgAyAGQAMwAyADAAOQBhADgAOAAzAGYALQBEAG8AYwBrAQAAAIkAAAS6AAAAAAAAAAD7AAAANABEAGEAdABhAFAAbABvAHQAbAB5AC0ARABhAHQAYQBQAGwAbwB0AGwAeQAtAEQAbwBjAGsBAAAAiQAABLoAAAAAAAAAAPsAAABwAEQAYQB0AGEAUABsAG8AdABsAHkALQB0AGUAcwB0AGUAZgBlADQANQA3ADMAYwAtAGQAOABhAGIALQA0ADkAMwA4AC0AOQBlAGUAMwAtADEAOAA5AGMAYgA3ADAAOAA5AGMAYwAxAC0ARABvAGMAawEAAAJ7AAACyAAAAAAAAAAA+wAAAHgARABhAHQAYQBQAGwAbwB0AGwAeQAtAGYAZABxAHMAZgBxAHMAZABjADAAOAA4ADUAMAAyADYALQAxAGIAZgAzAC0ANAA5ADYANAAtAGEAYQA3ADYALQBmADkANwBkADEAOQAxADkAZAA2ADkANgAtAEQAbwBjAGsBAAAE7AAAAFcAAAAAAAAAAPsAAAAgAHQAaABlAFQAaQBsAGUAUwBjAGEAbABlAEQAbwBjAGsAAAAAAP////8AAAB5AP////sAAAAuAEQAYQB0AGEAUABsAG8AdABsAHkALQBtAHkALQB0AGUAcwB0AC0ARABvAGMAawEAAAN4AAABywAAAFcA////AAAAAgAAAAAAAAAA/AEAAAAB+wAAACYAVABlAG0AcABvAHIAYQBsACAAQwBvAG4AdAByAG8AbABsAGUAcgAAAAAA/////wAAAEQA////AAAAAwAABZ0AAAM0/AEAAAAE+wAAABQATQBlAHMAcwBhAGcAZQBMAG8AZwAAAAFUAAADrAAAAH8A////+wAAACYAVQBzAGUAcgBJAG4AcAB1AHQARABvAGMAawBXAGkAZABnAGUAdAIAAAAAAAAAAAAAAMgAAABk+wAAABoAUAB5AHQAaABvAG4AQwBvAG4AcwBvAGwAZQAAAAAAAAAFnQAAAAAAAAAA+wAAABwAQQB0AHQAcgBpAGIAdQB0AGUAVABhAGIAbABlAAAAAecAAAaLAAAAAAAAAAAAAAXCAAAEugAAAAEAAAACAAAAAQAAAAL8AAAADQAAAAAAAAABAAAAGgBtAEwAYQB5AGUAcgBUAG8AbwBsAEIAYQByAgAAAML/////AAAAAAAAAAAAAAABAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAwAAABgAbQBGAGkAbABlAFQAbwBvAGwAQgBhAHIBAAAAAP////8AAAAAAAAAAAAAABwAbQBNAGEAcABOAGEAdgBUAG8AbwBsAEIAYQByAQAAANb/////AAAAAAAAAAAAAAAkAG0AQQB0AHQAcgBpAGIAdQB0AGUAcwBUAG8AbwBsAEIAYQByAQAAAvb/////AAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAgAAAAcAAAAyAG0ARABhAHQAYQBTAG8AdQByAGMAZQBNAGEAbgBhAGcAZQByAFQAbwBvAGwAQgBhAHIBAAAAAP////8AAAAAAAAAAAAAACAAbQBEAGkAZwBpAHQAaQB6AGUAVABvAG8AbABCAGEAcgEAAADk/////wAAAAAAAAAAAAAAGgBtAEwAYQBiAGUAbABUAG8AbwBsAEIAYQByAQAAAoz/////AAAAAAAAAAAAAAAgAG0ARABhAHQAYQBiAGEAcwBlAFQAbwBvAGwAQgBhAHIAAAACb/////8AAAAAAAAAAAAAABYAbQBXAGUAYgBUAG8AbwBsAEIAYQByAQAAA9P/////AAAAAAAAAAAAAAAcAG0AUABsAHUAZwBpAG4AVABvAG8AbABCAGEAcgEAAAQEAAABewAAAAAAAAAAAAAAHABtAFYAZQBjAHQAbwByAFQAbwBvAGwAQgBhAHIBAAAFfwAAAikAAAAAAAAAAAAAAAIAAAADAAAAMABtAEEAZAB2AGEAbgBjAGUAZABEAGkAZwBpAHQAaQB6AGUAVABvAG8AbABCAGEAcgAAAAAA/////wAAAAAAAAAAAAAAHABtAFIAYQBzAHQAZQByAFQAbwBvAGwAQgBhAHIAAAAAAAAAArAAAAAAAAAAAAAAACAAbQBTAG4AYQBwAHAAaQBuAGcAVABvAG8AbABCAGEAcgAAAAAA/////wAAAAAAAAAAAAAAAgAAAAUAAAAqAG0AUwBoAGEAcABlAEQAaQBnAGkAdABpAHoAZQBUAG8AbwBsAEIAYQByAAAAAAD/////AAAAAAAAAAD/////AQAAAAD/////AAAAAAAAAAAAAAAiAG0AUwBlAGwAZQBjAHQAaQBvAG4AVABvAG8AbABCAGEAcgEAAACp/////wAAAAAAAAAAAAAAGABtAEgAZQBsAHAAVABvAG8AbABCAGEAcgEAAAFhAAAEPAAAAAAAAAAAAAAAIABNAGEAagBpAGMAUAByAG8AcAByAGkAbwBQAGwAdQBnAQAABZ3/////AAAAAAAAAAA=" name="state"/> + </Option> + </StateDataPlotly> + <DataPlotly> + <Option type="Map"> + <Option type="Map" name="dynamic_properties"> + <Option type="QString" value="" name="name"/> + <Option name="properties"/> + <Option type="QString" value="collection" name="type"/> + </Option> + <Option type="Map" name="plot_layout"> + <Option type="QString" value="" name="additional_info_expression"/> + <Option type="QString" value="group" name="bar_mode"/> + <Option type="double" value="0" name="bargaps"/> + <Option type="bool" value="false" name="bins_check"/> + <Option type="QString" value="#000000" name="font_title_color"/> + <Option type="QString" value="Arial" name="font_title_family"/> + <Option type="int" value="10" name="font_title_size"/> + <Option type="QString" value="#000000" name="font_xlabel_color"/> + <Option type="QString" value="Arial" name="font_xlabel_family"/> + <Option type="int" value="10" name="font_xlabel_size"/> + <Option type="QString" value="#000000" name="font_xticks_color"/> + <Option type="QString" value="Arial" name="font_xticks_family"/> + <Option type="int" value="10" name="font_xticks_size"/> + <Option type="QString" value="#000000" name="font_ylabel_color"/> + <Option type="QString" value="Arial" name="font_ylabel_family"/> + <Option type="int" value="10" name="font_ylabel_size"/> + <Option type="QString" value="#000000" name="font_yticks_color"/> + <Option type="QString" value="Arial" name="font_yticks_family"/> + <Option type="int" value="10" name="font_yticks_size"/> + <Option type="QString" value="#bdbfc0" name="gridcolor"/> + <Option type="bool" value="true" name="legend"/> + <Option type="QString" value="v" name="legend_orientation"/> + <Option type="invalid" name="legend_title"/> + <Option type="Map" name="polar"> + <Option type="Map" name="angularaxis"> + <Option type="QString" value="clockwise" name="direction"/> + </Option> + </Option> + <Option type="Map" name="range_slider"> + <Option type="int" value="1" name="borderwidth"/> + <Option type="bool" value="false" name="visible"/> + </Option> + <Option type="QString" value="" name="title"/> + <Option type="invalid" name="x_inv"/> + <Option type="invalid" name="x_max"/> + <Option type="invalid" name="x_min"/> + <Option type="QString" value="" name="x_title"/> + <Option type="QString" value="linear" name="x_type"/> + <Option type="invalid" name="xaxis"/> + <Option type="invalid" name="y_inv"/> + <Option type="invalid" name="y_max"/> + <Option type="invalid" name="y_min"/> + <Option type="QString" value="" name="y_title"/> + <Option type="QString" value="linear" name="y_type"/> + <Option type="QString" value="" name="z_title"/> + </Option> + <Option type="Map" name="plot_properties"> + <Option type="invalid" name="additional_hover_text"/> + <Option type="int" value="10" name="bins"/> + <Option type="QString" value="v" name="box_orientation"/> + <Option type="bool" value="false" name="box_outliers"/> + <Option type="bool" value="false" name="box_stat"/> + <Option type="QString" value="Greys" name="color_scale"/> + <Option type="bool" value="false" name="color_scale_data_defined_in_check"/> + <Option type="bool" value="false" name="color_scale_data_defined_in_invert_check"/> + <Option type="QString" value="fill" name="cont_type"/> + <Option type="QString" value="Fill" name="contour_type_combo"/> + <Option type="bool" value="false" name="cumulative"/> + <Option type="List" name="custom"> + <Option type="QString" value=""/> + </Option> + <Option type="QString" value="auto" name="hover_label_position"/> + <Option type="invalid" name="hover_label_text"/> + <Option type="QString" value="all" name="hover_text"/> + <Option type="QString" value="#8ebad9" name="in_color"/> + <Option type="bool" value="false" name="invert_color_scale"/> + <Option type="QString" value="increasing" name="invert_hist"/> + <Option type="bool" value="false" name="layout_filter_by_atlas"/> + <Option type="bool" value="false" name="layout_filter_by_map"/> + <Option type="QString" value="Solid Line" name="line_combo"/> + <Option type="QString" value="solid" name="line_dash"/> + <Option type="QString" value="markers" name="marker"/> + <Option type="double" value="10" name="marker_size"/> + <Option type="int" value="0" name="marker_symbol"/> + <Option type="QString" value="Points" name="marker_type_combo"/> + <Option type="double" value="1" name="marker_width"/> + <Option type="QString" value="" name="name"/> + <Option type="QString" value="" name="normalization"/> + <Option type="double" value="1" name="opacity"/> + <Option type="QString" value="#1f77b4" name="out_color"/> + <Option type="QString" value="" name="point_combo"/> + <Option type="bool" value="false" name="selected_features_only"/> + <Option type="bool" value="false" name="show_colorscale_legend"/> + <Option type="bool" value="true" name="show_lines"/> + <Option type="bool" value="true" name="show_lines_check"/> + <Option type="bool" value="true" name="show_mean_line"/> + <Option type="bool" value="true" name="violin_box"/> + <Option type="QString" value="both" name="violin_side"/> + <Option type="bool" value="false" name="visible_features_only"/> + <Option type="QString" value="" name="x_name"/> + <Option type="QString" value="" name="y_name"/> + <Option type="QString" value="" name="z_name"/> + </Option> + <Option type="QString" value="scatter" name="plot_type"/> + <Option type="invalid" name="source_layer_id"/> + </Option> + </DataPlotly> + <projectModels/> + <legend updateDrawingOrder="true"/> + <mapViewDocks/> + <mapViewDocks3D/> + <DataPlotly_My.Test_my-test> + <Option type="Map"> + <Option type="Map" name="dynamic_properties"> + <Option type="QString" value="" name="name"/> + <Option name="properties"/> + <Option type="QString" value="collection" name="type"/> + </Option> + <Option type="Map" name="plot_layout"> + <Option type="QString" value="" name="additional_info_expression"/> + <Option type="QString" value="group" name="bar_mode"/> + <Option type="double" value="0" name="bargaps"/> + <Option type="bool" value="false" name="bins_check"/> + <Option type="QString" value="#000000" name="font_title_color"/> + <Option type="QString" value="Arial" name="font_title_family"/> + <Option type="int" value="10" name="font_title_size"/> + <Option type="QString" value="#000000" name="font_xlabel_color"/> + <Option type="QString" value="Arial" name="font_xlabel_family"/> + <Option type="int" value="10" name="font_xlabel_size"/> + <Option type="QString" value="#000000" name="font_xticks_color"/> + <Option type="QString" value="Arial" name="font_xticks_family"/> + <Option type="int" value="10" name="font_xticks_size"/> + <Option type="QString" value="#000000" name="font_ylabel_color"/> + <Option type="QString" value="Arial" name="font_ylabel_family"/> + <Option type="int" value="10" name="font_ylabel_size"/> + <Option type="QString" value="#000000" name="font_yticks_color"/> + <Option type="QString" value="Arial" name="font_yticks_family"/> + <Option type="int" value="10" name="font_yticks_size"/> + <Option type="QString" value="#bdbfc0" name="gridcolor"/> + <Option type="bool" value="true" name="legend"/> + <Option type="QString" value="v" name="legend_orientation"/> + <Option type="invalid" name="legend_title"/> + <Option type="Map" name="polar"> + <Option type="Map" name="angularaxis"> + <Option type="QString" value="clockwise" name="direction"/> + </Option> + </Option> + <Option type="Map" name="range_slider"> + <Option type="int" value="1" name="borderwidth"/> + <Option type="bool" value="false" name="visible"/> + </Option> + <Option type="QString" value="" name="title"/> + <Option type="invalid" name="x_inv"/> + <Option type="invalid" name="x_max"/> + <Option type="invalid" name="x_min"/> + <Option type="QString" value="" name="x_title"/> + <Option type="QString" value="linear" name="x_type"/> + <Option type="invalid" name="xaxis"/> + <Option type="invalid" name="y_inv"/> + <Option type="invalid" name="y_max"/> + <Option type="invalid" name="y_min"/> + <Option type="QString" value="" name="y_title"/> + <Option type="QString" value="linear" name="y_type"/> + <Option type="QString" value="" name="z_title"/> + </Option> + <Option type="Map" name="plot_properties"> + <Option type="invalid" name="additional_hover_text"/> + <Option type="int" value="10" name="bins"/> + <Option type="QString" value="v" name="box_orientation"/> + <Option type="bool" value="false" name="box_outliers"/> + <Option type="bool" value="false" name="box_stat"/> + <Option type="QString" value="Greys" name="color_scale"/> + <Option type="bool" value="false" name="color_scale_data_defined_in_check"/> + <Option type="bool" value="false" name="color_scale_data_defined_in_invert_check"/> + <Option type="QString" value="fill" name="cont_type"/> + <Option type="QString" value="Fill" name="contour_type_combo"/> + <Option type="bool" value="false" name="cumulative"/> + <Option type="List" name="custom"> + <Option type="QString" value=""/> + </Option> + <Option type="QString" value="auto" name="hover_label_position"/> + <Option type="invalid" name="hover_label_text"/> + <Option type="QString" value="all" name="hover_text"/> + <Option type="QString" value="#8ebad9" name="in_color"/> + <Option type="bool" value="false" name="invert_color_scale"/> + <Option type="QString" value="increasing" name="invert_hist"/> + <Option type="bool" value="false" name="layout_filter_by_atlas"/> + <Option type="bool" value="false" name="layout_filter_by_map"/> + <Option type="QString" value="Solid Line" name="line_combo"/> + <Option type="QString" value="solid" name="line_dash"/> + <Option type="QString" value="markers" name="marker"/> + <Option type="double" value="10" name="marker_size"/> + <Option type="int" value="0" name="marker_symbol"/> + <Option type="QString" value="Points" name="marker_type_combo"/> + <Option type="double" value="1" name="marker_width"/> + <Option type="QString" value="" name="name"/> + <Option type="QString" value="" name="normalization"/> + <Option type="double" value="1" name="opacity"/> + <Option type="QString" value="#1f77b4" name="out_color"/> + <Option type="QString" value="" name="point_combo"/> + <Option type="bool" value="false" name="selected_features_only"/> + <Option type="bool" value="false" name="show_colorscale_legend"/> + <Option type="bool" value="true" name="show_lines"/> + <Option type="bool" value="true" name="show_lines_check"/> + <Option type="bool" value="true" name="show_mean_line"/> + <Option type="bool" value="true" name="violin_box"/> + <Option type="QString" value="both" name="violin_side"/> + <Option type="bool" value="false" name="visible_features_only"/> + <Option type="QString" value="" name="x_name"/> + <Option type="QString" value="" name="y_name"/> + <Option type="QString" value="" name="z_name"/> + </Option> + <Option type="QString" value="scatter" name="plot_type"/> + <Option type="invalid" name="source_layer_id"/> + </Option> + </DataPlotly_My.Test_my-test> + <main-annotation-layer type="annotation" refreshOnNotifyEnabled="0" refreshOnNotifyMessage="" autoRefreshTime="0" autoRefreshEnabled="0"> + <id>Annotations_b98336a3_09d4_43e4_add7_9a292a832484</id> + <datasource></datasource> + <keywordList> + <value></value> + </keywordList> + <layername>Annotations</layername> + <srs> + <spatialrefsys> + <wkt></wkt> + <proj4></proj4> + <srsid>0</srsid> + <srid>0</srid> + <authid></authid> + <description></description> + <projectionacronym></projectionacronym> + <ellipsoidacronym></ellipsoidacronym> + <geographicflag>false</geographicflag> + </spatialrefsys> + </srs> + <resourceMetadata> + <identifier></identifier> + <parentidentifier></parentidentifier> + <language></language> + <type></type> + <title></title> + <abstract></abstract> + <links/> + <fees></fees> + <encoding></encoding> + <crs> + <spatialrefsys> + <wkt></wkt> + <proj4></proj4> + <srsid>0</srsid> + <srid>0</srid> + <authid></authid> + <description></description> + <projectionacronym></projectionacronym> + <ellipsoidacronym></ellipsoidacronym> + <geographicflag>false</geographicflag> + </spatialrefsys> + </crs> + <extent/> + </resourceMetadata> + <items/> + <layerOpacity>1</layerOpacity> + <blendMode>0</blendMode> + </main-annotation-layer> + <projectlayers/> + <layerorder/> + <properties> + <Digitizing> + <AvoidIntersectionsMode type="int">0</AvoidIntersectionsMode> + </Digitizing> + <Gui> + <CanvasColorBluePart type="int">255</CanvasColorBluePart> + <CanvasColorGreenPart type="int">255</CanvasColorGreenPart> + <CanvasColorRedPart type="int">255</CanvasColorRedPart> + <SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart> + <SelectionColorBluePart type="int">0</SelectionColorBluePart> + <SelectionColorGreenPart type="int">255</SelectionColorGreenPart> + <SelectionColorRedPart type="int">255</SelectionColorRedPart> + </Gui> + <Legend> + <filterByMap type="bool">false</filterByMap> + </Legend> + <Measure> + <Ellipsoid type="QString">EPSG:7030</Ellipsoid> + </Measure> + <Measurement> + <AreaUnits type="QString">m2</AreaUnits> + <DistanceUnits type="QString">meters</DistanceUnits> + </Measurement> + <PAL> + <CandidatesLinePerCM type="double">5</CandidatesLinePerCM> + <CandidatesPolygonPerCM type="double">2.5</CandidatesPolygonPerCM> + <DrawRectOnly type="bool">false</DrawRectOnly> + <DrawUnplaced type="bool">false</DrawUnplaced> + <PlacementEngineVersion type="int">1</PlacementEngineVersion> + <SearchMethod type="int">0</SearchMethod> + <ShowingAllLabels type="bool">false</ShowingAllLabels> + <ShowingCandidates type="bool">false</ShowingCandidates> + <ShowingPartialsLabels type="bool">true</ShowingPartialsLabels> + <TextFormat type="int">0</TextFormat> + <UnplacedColor type="QString">255,0,0,255</UnplacedColor> + </PAL> + <Paths> + <Absolute type="bool">false</Absolute> + </Paths> + <PositionPrecision> + <Automatic type="bool">true</Automatic> + <DecimalPlaces type="int">2</DecimalPlaces> + </PositionPrecision> + <SpatialRefSys> + <ProjectionsEnabled type="int">1</ProjectionsEnabled> + </SpatialRefSys> + </properties> + <dataDefinedServerProperties> + <Option type="Map"> + <Option type="QString" value="" name="name"/> + <Option name="properties"/> + <Option type="QString" value="collection" name="type"/> + </Option> + </dataDefinedServerProperties> + <visibility-presets/> + <transformContext/> + <projectMetadata> + <identifier></identifier> + <parentidentifier></parentidentifier> + <language></language> + <type></type> + <title></title> + <abstract></abstract> + <links/> + <author>jd</author> + <creation>2023-04-11T00:22:50</creation> + </projectMetadata> + <Annotations/> + <Layouts/> + <Bookmarks/> + <ProjectViewSettings UseProjectScales="0"> + <Scales/> + <DefaultViewExtent ymax="1" ymin="-1" xmin="-3.5" xmax="3.5"> + <spatialrefsys> + <wkt>GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]]</wkt> + <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4> + <srsid>3452</srsid> + <srid>4326</srid> + <authid>EPSG:4326</authid> + <description>WGS 84</description> + <projectionacronym>longlat</projectionacronym> + <ellipsoidacronym>EPSG:7030</ellipsoidacronym> + <geographicflag>true</geographicflag> + </spatialrefsys> + </DefaultViewExtent> + </ProjectViewSettings> + <ProjectTimeSettings frameRate="1" cumulativeTemporalRange="0" timeStep="1" timeStepUnit="h"/> + <ProjectDisplaySettings> + <BearingFormat id="bearing"> + <Option type="Map"> + <Option type="QChar" value="" name="decimal_separator"/> + <Option type="int" value="6" name="decimals"/> + <Option type="int" value="0" name="direction_format"/> + <Option type="int" value="0" name="rounding_type"/> + <Option type="bool" value="false" name="show_plus"/> + <Option type="bool" value="true" name="show_thousand_separator"/> + <Option type="bool" value="false" name="show_trailing_zeros"/> + <Option type="QChar" value="" name="thousand_separator"/> + </Option> + </BearingFormat> + </ProjectDisplaySettings> +</qgis> diff --git a/DataPlotly/test/test_project_without_state.qgs b/DataPlotly/test/test_project_without_state.qgs new file mode 100644 index 00000000..4afc1c9f --- /dev/null +++ b/DataPlotly/test/test_project_without_state.qgs @@ -0,0 +1,421 @@ +<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'> +<qgis version="3.18.3-Zürich" saveUserFull="jd" saveDateTime="2023-04-11T00:24:01" projectname="" saveUser="jd"> + <homePath path=""/> + <title></title> + <autotransaction active="0"/> + <evaluateDefaultValues active="0"/> + <trust active="0"/> + <projectCrs> + <spatialrefsys> + <wkt>GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]]</wkt> + <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4> + <srsid>3452</srsid> + <srid>4326</srid> + <authid>EPSG:4326</authid> + <description>WGS 84</description> + <projectionacronym>longlat</projectionacronym> + <ellipsoidacronym>EPSG:7030</ellipsoidacronym> + <geographicflag>true</geographicflag> + </spatialrefsys> + </projectCrs> + <layer-tree-group> + <customproperties/> + <custom-order enabled="0"/> + </layer-tree-group> + <snapping-settings type="1" maxScale="0" unit="1" minScale="0" intersection-snapping="0" self-snapping="0" mode="2" enabled="0" scaleDependencyMode="0" tolerance="12"> + <individual-layer-settings/> + </snapping-settings> + <relations/> + <polymorphicRelations/> + <mapcanvas annotationsVisible="1" name="theMapCanvas"> + <units>degrees</units> + <extent> + <xmin>-1</xmin> + <ymin>-1</ymin> + <xmax>1</xmax> + <ymax>1</ymax> + </extent> + <rotation>0</rotation> + <destinationsrs> + <spatialrefsys> + <wkt>GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]]</wkt> + <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4> + <srsid>3452</srsid> + <srid>4326</srid> + <authid>EPSG:4326</authid> + <description>WGS 84</description> + <projectionacronym>longlat</projectionacronym> + <ellipsoidacronym>EPSG:7030</ellipsoidacronym> + <geographicflag>true</geographicflag> + </spatialrefsys> + </destinationsrs> + <rendermaptile>0</rendermaptile> + <expressionContextScope/> + </mapcanvas> + <DataPlotly> + <Option type="Map"> + <Option type="Map" name="dynamic_properties"> + <Option type="QString" value="" name="name"/> + <Option name="properties"/> + <Option type="QString" value="collection" name="type"/> + </Option> + <Option type="Map" name="plot_layout"> + <Option type="QString" value="" name="additional_info_expression"/> + <Option type="QString" value="group" name="bar_mode"/> + <Option type="double" value="0" name="bargaps"/> + <Option type="bool" value="false" name="bins_check"/> + <Option type="QString" value="#000000" name="font_title_color"/> + <Option type="QString" value="Arial" name="font_title_family"/> + <Option type="int" value="10" name="font_title_size"/> + <Option type="QString" value="#000000" name="font_xlabel_color"/> + <Option type="QString" value="Arial" name="font_xlabel_family"/> + <Option type="int" value="10" name="font_xlabel_size"/> + <Option type="QString" value="#000000" name="font_xticks_color"/> + <Option type="QString" value="Arial" name="font_xticks_family"/> + <Option type="int" value="10" name="font_xticks_size"/> + <Option type="QString" value="#000000" name="font_ylabel_color"/> + <Option type="QString" value="Arial" name="font_ylabel_family"/> + <Option type="int" value="10" name="font_ylabel_size"/> + <Option type="QString" value="#000000" name="font_yticks_color"/> + <Option type="QString" value="Arial" name="font_yticks_family"/> + <Option type="int" value="10" name="font_yticks_size"/> + <Option type="QString" value="#bdbfc0" name="gridcolor"/> + <Option type="bool" value="true" name="legend"/> + <Option type="QString" value="v" name="legend_orientation"/> + <Option type="invalid" name="legend_title"/> + <Option type="Map" name="polar"> + <Option type="Map" name="angularaxis"> + <Option type="QString" value="clockwise" name="direction"/> + </Option> + </Option> + <Option type="Map" name="range_slider"> + <Option type="int" value="1" name="borderwidth"/> + <Option type="bool" value="false" name="visible"/> + </Option> + <Option type="QString" value="" name="title"/> + <Option type="invalid" name="x_inv"/> + <Option type="invalid" name="x_max"/> + <Option type="invalid" name="x_min"/> + <Option type="QString" value="" name="x_title"/> + <Option type="QString" value="linear" name="x_type"/> + <Option type="invalid" name="xaxis"/> + <Option type="invalid" name="y_inv"/> + <Option type="invalid" name="y_max"/> + <Option type="invalid" name="y_min"/> + <Option type="QString" value="" name="y_title"/> + <Option type="QString" value="linear" name="y_type"/> + <Option type="QString" value="" name="z_title"/> + </Option> + <Option type="Map" name="plot_properties"> + <Option type="invalid" name="additional_hover_text"/> + <Option type="int" value="10" name="bins"/> + <Option type="QString" value="v" name="box_orientation"/> + <Option type="bool" value="false" name="box_outliers"/> + <Option type="bool" value="false" name="box_stat"/> + <Option type="QString" value="Greys" name="color_scale"/> + <Option type="bool" value="false" name="color_scale_data_defined_in_check"/> + <Option type="bool" value="false" name="color_scale_data_defined_in_invert_check"/> + <Option type="QString" value="fill" name="cont_type"/> + <Option type="QString" value="Fill" name="contour_type_combo"/> + <Option type="bool" value="false" name="cumulative"/> + <Option type="List" name="custom"> + <Option type="QString" value=""/> + </Option> + <Option type="QString" value="auto" name="hover_label_position"/> + <Option type="invalid" name="hover_label_text"/> + <Option type="QString" value="all" name="hover_text"/> + <Option type="QString" value="#8ebad9" name="in_color"/> + <Option type="bool" value="false" name="invert_color_scale"/> + <Option type="QString" value="increasing" name="invert_hist"/> + <Option type="bool" value="false" name="layout_filter_by_atlas"/> + <Option type="bool" value="false" name="layout_filter_by_map"/> + <Option type="QString" value="Solid Line" name="line_combo"/> + <Option type="QString" value="solid" name="line_dash"/> + <Option type="QString" value="markers" name="marker"/> + <Option type="double" value="10" name="marker_size"/> + <Option type="int" value="0" name="marker_symbol"/> + <Option type="QString" value="Points" name="marker_type_combo"/> + <Option type="double" value="1" name="marker_width"/> + <Option type="QString" value="" name="name"/> + <Option type="QString" value="" name="normalization"/> + <Option type="double" value="1" name="opacity"/> + <Option type="QString" value="#1f77b4" name="out_color"/> + <Option type="QString" value="" name="point_combo"/> + <Option type="bool" value="false" name="selected_features_only"/> + <Option type="bool" value="false" name="show_colorscale_legend"/> + <Option type="bool" value="true" name="show_lines"/> + <Option type="bool" value="true" name="show_lines_check"/> + <Option type="bool" value="true" name="show_mean_line"/> + <Option type="bool" value="true" name="violin_box"/> + <Option type="QString" value="both" name="violin_side"/> + <Option type="bool" value="false" name="visible_features_only"/> + <Option type="QString" value="" name="x_name"/> + <Option type="QString" value="" name="y_name"/> + <Option type="QString" value="" name="z_name"/> + </Option> + <Option type="QString" value="scatter" name="plot_type"/> + <Option type="invalid" name="source_layer_id"/> + </Option> + </DataPlotly> + <projectModels/> + <legend updateDrawingOrder="true"/> + <mapViewDocks/> + <mapViewDocks3D/> + <DataPlotly_My.Test_my-test> + <Option type="Map"> + <Option type="Map" name="dynamic_properties"> + <Option type="QString" value="" name="name"/> + <Option name="properties"/> + <Option type="QString" value="collection" name="type"/> + </Option> + <Option type="Map" name="plot_layout"> + <Option type="QString" value="" name="additional_info_expression"/> + <Option type="QString" value="group" name="bar_mode"/> + <Option type="double" value="0" name="bargaps"/> + <Option type="bool" value="false" name="bins_check"/> + <Option type="QString" value="#000000" name="font_title_color"/> + <Option type="QString" value="Arial" name="font_title_family"/> + <Option type="int" value="10" name="font_title_size"/> + <Option type="QString" value="#000000" name="font_xlabel_color"/> + <Option type="QString" value="Arial" name="font_xlabel_family"/> + <Option type="int" value="10" name="font_xlabel_size"/> + <Option type="QString" value="#000000" name="font_xticks_color"/> + <Option type="QString" value="Arial" name="font_xticks_family"/> + <Option type="int" value="10" name="font_xticks_size"/> + <Option type="QString" value="#000000" name="font_ylabel_color"/> + <Option type="QString" value="Arial" name="font_ylabel_family"/> + <Option type="int" value="10" name="font_ylabel_size"/> + <Option type="QString" value="#000000" name="font_yticks_color"/> + <Option type="QString" value="Arial" name="font_yticks_family"/> + <Option type="int" value="10" name="font_yticks_size"/> + <Option type="QString" value="#bdbfc0" name="gridcolor"/> + <Option type="bool" value="true" name="legend"/> + <Option type="QString" value="v" name="legend_orientation"/> + <Option type="invalid" name="legend_title"/> + <Option type="Map" name="polar"> + <Option type="Map" name="angularaxis"> + <Option type="QString" value="clockwise" name="direction"/> + </Option> + </Option> + <Option type="Map" name="range_slider"> + <Option type="int" value="1" name="borderwidth"/> + <Option type="bool" value="false" name="visible"/> + </Option> + <Option type="QString" value="" name="title"/> + <Option type="invalid" name="x_inv"/> + <Option type="invalid" name="x_max"/> + <Option type="invalid" name="x_min"/> + <Option type="QString" value="" name="x_title"/> + <Option type="QString" value="linear" name="x_type"/> + <Option type="invalid" name="xaxis"/> + <Option type="invalid" name="y_inv"/> + <Option type="invalid" name="y_max"/> + <Option type="invalid" name="y_min"/> + <Option type="QString" value="" name="y_title"/> + <Option type="QString" value="linear" name="y_type"/> + <Option type="QString" value="" name="z_title"/> + </Option> + <Option type="Map" name="plot_properties"> + <Option type="invalid" name="additional_hover_text"/> + <Option type="int" value="10" name="bins"/> + <Option type="QString" value="v" name="box_orientation"/> + <Option type="bool" value="false" name="box_outliers"/> + <Option type="bool" value="false" name="box_stat"/> + <Option type="QString" value="Greys" name="color_scale"/> + <Option type="bool" value="false" name="color_scale_data_defined_in_check"/> + <Option type="bool" value="false" name="color_scale_data_defined_in_invert_check"/> + <Option type="QString" value="fill" name="cont_type"/> + <Option type="QString" value="Fill" name="contour_type_combo"/> + <Option type="bool" value="false" name="cumulative"/> + <Option type="List" name="custom"> + <Option type="QString" value=""/> + </Option> + <Option type="QString" value="auto" name="hover_label_position"/> + <Option type="invalid" name="hover_label_text"/> + <Option type="QString" value="all" name="hover_text"/> + <Option type="QString" value="#8ebad9" name="in_color"/> + <Option type="bool" value="false" name="invert_color_scale"/> + <Option type="QString" value="increasing" name="invert_hist"/> + <Option type="bool" value="false" name="layout_filter_by_atlas"/> + <Option type="bool" value="false" name="layout_filter_by_map"/> + <Option type="QString" value="Solid Line" name="line_combo"/> + <Option type="QString" value="solid" name="line_dash"/> + <Option type="QString" value="markers" name="marker"/> + <Option type="double" value="10" name="marker_size"/> + <Option type="int" value="0" name="marker_symbol"/> + <Option type="QString" value="Points" name="marker_type_combo"/> + <Option type="double" value="1" name="marker_width"/> + <Option type="QString" value="" name="name"/> + <Option type="QString" value="" name="normalization"/> + <Option type="double" value="1" name="opacity"/> + <Option type="QString" value="#1f77b4" name="out_color"/> + <Option type="QString" value="" name="point_combo"/> + <Option type="bool" value="false" name="selected_features_only"/> + <Option type="bool" value="false" name="show_colorscale_legend"/> + <Option type="bool" value="true" name="show_lines"/> + <Option type="bool" value="true" name="show_lines_check"/> + <Option type="bool" value="true" name="show_mean_line"/> + <Option type="bool" value="true" name="violin_box"/> + <Option type="QString" value="both" name="violin_side"/> + <Option type="bool" value="false" name="visible_features_only"/> + <Option type="QString" value="" name="x_name"/> + <Option type="QString" value="" name="y_name"/> + <Option type="QString" value="" name="z_name"/> + </Option> + <Option type="QString" value="scatter" name="plot_type"/> + <Option type="invalid" name="source_layer_id"/> + </Option> + </DataPlotly_My.Test_my-test> + <main-annotation-layer type="annotation" refreshOnNotifyEnabled="0" refreshOnNotifyMessage="" autoRefreshTime="0" autoRefreshEnabled="0"> + <id>Annotations_b98336a3_09d4_43e4_add7_9a292a832484</id> + <datasource></datasource> + <keywordList> + <value></value> + </keywordList> + <layername>Annotations</layername> + <srs> + <spatialrefsys> + <wkt></wkt> + <proj4></proj4> + <srsid>0</srsid> + <srid>0</srid> + <authid></authid> + <description></description> + <projectionacronym></projectionacronym> + <ellipsoidacronym></ellipsoidacronym> + <geographicflag>false</geographicflag> + </spatialrefsys> + </srs> + <resourceMetadata> + <identifier></identifier> + <parentidentifier></parentidentifier> + <language></language> + <type></type> + <title></title> + <abstract></abstract> + <links/> + <fees></fees> + <encoding></encoding> + <crs> + <spatialrefsys> + <wkt></wkt> + <proj4></proj4> + <srsid>0</srsid> + <srid>0</srid> + <authid></authid> + <description></description> + <projectionacronym></projectionacronym> + <ellipsoidacronym></ellipsoidacronym> + <geographicflag>false</geographicflag> + </spatialrefsys> + </crs> + <extent/> + </resourceMetadata> + <items/> + <layerOpacity>1</layerOpacity> + <blendMode>0</blendMode> + </main-annotation-layer> + <projectlayers/> + <layerorder/> + <properties> + <Digitizing> + <AvoidIntersectionsMode type="int">0</AvoidIntersectionsMode> + </Digitizing> + <Gui> + <CanvasColorBluePart type="int">255</CanvasColorBluePart> + <CanvasColorGreenPart type="int">255</CanvasColorGreenPart> + <CanvasColorRedPart type="int">255</CanvasColorRedPart> + <SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart> + <SelectionColorBluePart type="int">0</SelectionColorBluePart> + <SelectionColorGreenPart type="int">255</SelectionColorGreenPart> + <SelectionColorRedPart type="int">255</SelectionColorRedPart> + </Gui> + <Legend> + <filterByMap type="bool">false</filterByMap> + </Legend> + <Measure> + <Ellipsoid type="QString">EPSG:7030</Ellipsoid> + </Measure> + <Measurement> + <AreaUnits type="QString">m2</AreaUnits> + <DistanceUnits type="QString">meters</DistanceUnits> + </Measurement> + <PAL> + <CandidatesLinePerCM type="double">5</CandidatesLinePerCM> + <CandidatesPolygonPerCM type="double">2.5</CandidatesPolygonPerCM> + <DrawRectOnly type="bool">false</DrawRectOnly> + <DrawUnplaced type="bool">false</DrawUnplaced> + <PlacementEngineVersion type="int">1</PlacementEngineVersion> + <SearchMethod type="int">0</SearchMethod> + <ShowingAllLabels type="bool">false</ShowingAllLabels> + <ShowingCandidates type="bool">false</ShowingCandidates> + <ShowingPartialsLabels type="bool">true</ShowingPartialsLabels> + <TextFormat type="int">0</TextFormat> + <UnplacedColor type="QString">255,0,0,255</UnplacedColor> + </PAL> + <Paths> + <Absolute type="bool">false</Absolute> + </Paths> + <PositionPrecision> + <Automatic type="bool">true</Automatic> + <DecimalPlaces type="int">2</DecimalPlaces> + </PositionPrecision> + <SpatialRefSys> + <ProjectionsEnabled type="int">1</ProjectionsEnabled> + </SpatialRefSys> + </properties> + <dataDefinedServerProperties> + <Option type="Map"> + <Option type="QString" value="" name="name"/> + <Option name="properties"/> + <Option type="QString" value="collection" name="type"/> + </Option> + </dataDefinedServerProperties> + <visibility-presets/> + <transformContext/> + <projectMetadata> + <identifier></identifier> + <parentidentifier></parentidentifier> + <language></language> + <type></type> + <title></title> + <abstract></abstract> + <links/> + <author>jd</author> + <creation>2023-04-11T00:22:50</creation> + </projectMetadata> + <Annotations/> + <Layouts/> + <Bookmarks/> + <ProjectViewSettings UseProjectScales="0"> + <Scales/> + <DefaultViewExtent ymax="1" ymin="-1" xmin="-3.5" xmax="3.5"> + <spatialrefsys> + <wkt>GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]]</wkt> + <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4> + <srsid>3452</srsid> + <srid>4326</srid> + <authid>EPSG:4326</authid> + <description>WGS 84</description> + <projectionacronym>longlat</projectionacronym> + <ellipsoidacronym>EPSG:7030</ellipsoidacronym> + <geographicflag>true</geographicflag> + </spatialrefsys> + </DefaultViewExtent> + </ProjectViewSettings> + <ProjectTimeSettings frameRate="1" cumulativeTemporalRange="0" timeStep="1" timeStepUnit="h"/> + <ProjectDisplaySettings> + <BearingFormat id="bearing"> + <Option type="Map"> + <Option type="QChar" value="" name="decimal_separator"/> + <Option type="int" value="6" name="decimals"/> + <Option type="int" value="0" name="direction_format"/> + <Option type="int" value="0" name="rounding_type"/> + <Option type="bool" value="false" name="show_plus"/> + <Option type="bool" value="true" name="show_thousand_separator"/> + <Option type="bool" value="false" name="show_trailing_zeros"/> + <Option type="QChar" value="" name="thousand_separator"/> + </Option> + </BearingFormat> + </ProjectDisplaySettings> +</qgis> diff --git a/DataPlotly/ui/add_dock_dlg.ui b/DataPlotly/ui/add_dock_dlg.ui new file mode 100644 index 00000000..f6d3c4cc --- /dev/null +++ b/DataPlotly/ui/add_dock_dlg.ui @@ -0,0 +1,192 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DialogAddNewDock</class> + <widget class="QDialog" name="DialogAddNewDock"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>586</width> + <height>187</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>586</width> + <height>0</height> + </size> + </property> + <property name="windowTitle"> + <string>DataPlotly</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Add a new dock</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="DockTitleLabel"> + <property name="text"> + <string>Dock Title</string> + </property> + </widget> + </item> + <item> + <widget class="QgsFilterLineEdit" name="DockTitleLineEdit"> + <property name="qgisRelation" stdset="0"> + <string notr="true"/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QgsCollapsibleGroupBox" name="mCustomizeGroupBox"> + <property name="styleSheet"> + <string notr="true">QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; margin-left: 20px; margin-right: 10px; left: 0px; top: 2px;}QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; margin-left: 20px; margin-right: 5px; left: 0px; top: 1px;} QgsCollapsibleGroupBoxBasic { border: none; }</string> + </property> + <property name="title"> + <string>Customize Dock Id</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="collapsed"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="DockIdLabel"> + <property name="toolTip"> + <string>Dock id must be unique</string> + </property> + <property name="text"> + <string>Dock Id</string> + </property> + </widget> + </item> + <item> + <widget class="QgsFilterLineEdit" name="DockIdLineEdit"> + <property name="qgisRelation" stdset="0"> + <string notr="true"/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QLabel" name="DockIdInformationLabel"> + <property name="font"> + <font> + <italic>true</italic> + </font> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="styleSheet"> + <string notr="true">*{ margin-right:5px;}</string> + </property> + <property name="text"> + <string>Dock id error information</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="indent"> + <number>0</number> + </property> + <property name="textInteractionFlags"> + <set>Qt::NoTextInteraction</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>QgsCollapsibleGroupBox</class> + <extends>QGroupBox</extends> + <header>qgscollapsiblegroupbox.h</header> + <container>1</container> + </customwidget> + <customwidget> + <class>QgsFilterLineEdit</class> + <extends>QLineEdit</extends> + <header>qgsfilterlineedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DialogAddNewDock</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>227</x> + <y>250</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>186</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>DialogAddNewDock</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>295</x> + <y>250</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>186</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/DataPlotly/ui/remove_dock_dlg.ui b/DataPlotly/ui/remove_dock_dlg.ui new file mode 100644 index 00000000..1211f334 --- /dev/null +++ b/DataPlotly/ui/remove_dock_dlg.ui @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DialogAddNewDock</class> + <widget class="QDialog" name="DialogAddNewDock"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>586</width> + <height>187</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>586</width> + <height>0</height> + </size> + </property> + <property name="windowTitle"> + <string>DataPlotly</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Remove a dock</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="DockIdLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Dock Id</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="DockIdsComboBox"> + <property name="toolTip"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DialogAddNewDock</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>227</x> + <y>250</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>186</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>DialogAddNewDock</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>295</x> + <y>250</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>186</y> + </hint> + </hints> + </connection> + </connections> +</ui> From 380686f5c3be819ab414c07494c28bbfad769c00 Mon Sep 17 00:00:00 2001 From: jdlom <jdaniel.lomenede@gmail.com> Date: Thu, 13 Apr 2023 17:55:30 +0200 Subject: [PATCH 39/57] Auto create clear plot (#318) * feat : call create_plot when project is readed * feat: clear plot view when project is cleared * style: pylint --- DataPlotly/gui/plot_settings_widget.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 2540dcd7..eb221ebf 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -116,6 +116,7 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b # listen out for project save/restore, and update our state accordingly QgsProject.instance().writeProject.connect(self.write_project) QgsProject.instance().readProject.connect(self.read_project) + QgsProject.instance().cleared.connect(self.clearPlotView) if self.iface is not None: self.listWidget.setIconSize(self.iface.iconSize(False)) @@ -364,8 +365,6 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b # new dock instance from project if project: self.read_project(project) - # FIXME: creation plot is not working - # self.create_plot() def updateStacked(self, row): """ @@ -1668,6 +1667,7 @@ def read_project(self, document: QDomDocument): if settings.read_from_project(document): # update the dock state to match the read settings self.set_settings(settings) + self.create_plot() def load_configuration(self): """ From cb8883f94387670f1fe0bba76765b24c1a5f661b Mon Sep 17 00:00:00 2001 From: jdlom <jdaniel.lomenede@gmail.com> Date: Mon, 17 Apr 2023 11:17:50 +0200 Subject: [PATCH 40/57] feat: add hole option to pie chart (#317) * feat: add hole option to pie chart * style: pylint * fix: limit pie_hole to 0.95 --- DataPlotly/core/plot_settings.py | 3 +- DataPlotly/core/plot_types/pie.py | 1 + DataPlotly/gui/plot_settings_widget.py | 9 +- DataPlotly/ui/dataplotly_dockwidget_base.ui | 397 +++++++++++--------- 4 files changed, 221 insertions(+), 189 deletions(-) diff --git a/DataPlotly/core/plot_settings.py b/DataPlotly/core/plot_settings.py index 32dbfa07..803384a8 100644 --- a/DataPlotly/core/plot_settings.py +++ b/DataPlotly/core/plot_settings.py @@ -130,7 +130,8 @@ def __init__(self, plot_type: str = 'scatter', properties: dict = None, layout: 'violin_box': False, 'show_mean_line': False, 'layout_filter_by_map': False, - 'layout_filter_by_atlas': False + 'layout_filter_by_atlas': False, + 'pie_hole': 0 } # layout nested dictionary diff --git a/DataPlotly/core/plot_types/pie.py b/DataPlotly/core/plot_types/pie.py index b45df2a1..229b62dc 100644 --- a/DataPlotly/core/plot_types/pie.py +++ b/DataPlotly/core/plot_types/pie.py @@ -40,6 +40,7 @@ def create_trace(settings): 'colors': settings.data_defined_colors if settings.data_defined_colors else [settings.properties['in_color']] }, name=settings.properties['custom'][0], + hole=settings.properties['pie_hole'] )] @staticmethod diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index eb221ebf..51540d0c 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -172,6 +172,9 @@ def __init__(self, mode=MODE_CANVAS, parent=None, override_iface=None, message_b self.marker_width.setSingleStep(0.2) self.marker_width.setClearValue(0, self.tr('None')) + # pie_hole + self.pie_hole.setClearValue(0, self.tr('None')) + # Populate PlotTypes combobox # we sort available types by translated name type_classes = [clazz for _, clazz in PlotFactory.PLOT_TYPES.items()] @@ -983,6 +986,8 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch self.violinSideLabel: ['violin'], self.violinSideCombo: ['violin'], self.violinBox: ['violin'], + self.pie_hole_label : ['pie'], + self.pie_hole : ['pie'], } # enable the widget according to the plot type @@ -1121,7 +1126,8 @@ def get_settings(self) -> PlotSettings: # pylint: disable=R0915 'contour_type_combo': self.contour_type_combo.currentText(), 'show_lines_check': self.show_lines_check.isChecked(), 'layout_filter_by_map': self.filter_by_map_check.isChecked(), - 'layout_filter_by_atlas': self.filter_by_atlas_check.isChecked() + 'layout_filter_by_atlas': self.filter_by_atlas_check.isChecked(), + 'pie_hole' : self.pie_hole.value() } if self.in_color_defined_button.isActive(): @@ -1349,6 +1355,7 @@ def set_settings(self, settings: PlotSettings): # pylint: disable=too-many-stat self.show_legend_check.setChecked(settings.layout.get('legend', True)) self.layout_grid_axis_color.setColor( QColor(settings.layout.get('gridcolor') or '#bdbfc0')) + self.pie_hole.setValue(settings.properties.get('pie_hole', 0)) def create_plot_factory(self) -> PlotFactory: """ diff --git a/DataPlotly/ui/dataplotly_dockwidget_base.ui b/DataPlotly/ui/dataplotly_dockwidget_base.ui index 91ac9eba..2cfd3f03 100644 --- a/DataPlotly/ui/dataplotly_dockwidget_base.ui +++ b/DataPlotly/ui/dataplotly_dockwidget_base.ui @@ -489,86 +489,93 @@ QListWidget::item::selected { <string>Properties</string> </property> <layout class="QGridLayout" name="gridLayout_22"> - <item row="8" column="1" colspan="5"> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QComboBox" name="contour_type_combo"/> + <item row="14" column="1" colspan="5"> + <widget class="QComboBox" name="combo_text_position"/> </item> - <item> - <widget class="QCheckBox" name="show_lines_check"> + <item row="1" column="5"> + <widget class="QgsPropertyOverrideButton" name="size_defined_button"> <property name="text"> - <string>Show lines</string> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QgsColorButton" name="in_color_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="21" column="0"> + <widget class="QCheckBox" name="violinBox"> + <property name="toolTip"> + <string>If checked, box plots will be overlaid on top of violin plots</string> + </property> + <property name="text"> + <string>Include box plots</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> - </layout> - </item> - <item row="6" column="1" colspan="5"> - <widget class="QComboBox" name="point_combo"/> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="in_color_lab"> + <item row="19" column="0"> + <widget class="QLabel" name="violinSideLabel"> <property name="text"> - <string>Marker color</string> + <string>Violin side</string> </property> </widget> </item> - <item row="10" column="1" colspan="5"> - <widget class="QComboBox" name="color_scale_combo"/> - </item> - <item row="16" column="0"> - <widget class="QLabel" name="hist_norm_label"> + <item row="0" column="5"> + <widget class="QgsPropertyOverrideButton" name="legend_title_defined_button"> <property name="text"> - <string>Normalization</string> + <string>...</string> </property> </widget> </item> - <item row="4" column="5"> - <widget class="QgsPropertyOverrideButton" name="stroke_defined_button"> + <item row="1" column="3"> + <widget class="QLabel" name="marker_size_lab"> <property name="text"> - <string>...</string> + <string>Marker size</string> </property> </widget> </item> - <item row="4" column="2"> - <widget class="QgsPropertyOverrideButton" name="out_color_defined_button"> + <item row="7" column="0"> + <widget class="QLabel" name="line_lab"> <property name="text"> - <string>...</string> + <string>Line type</string> </property> </widget> </item> - <item row="15" column="1" colspan="5"> - <widget class="QComboBox" name="orientation_combo"/> - </item> - <item row="16" column="1" colspan="5"> - <widget class="QComboBox" name="hist_norm_combo"/> + <item row="17" column="1" colspan="5"> + <widget class="QComboBox" name="box_statistic_combo"/> </item> - <item row="22" column="0" colspan="6"> - <layout class="QHBoxLayout" name="horiz_layout_histogram"> - <item> - <widget class="QCheckBox" name="invert_hist_check"> - <property name="enabled"> - <bool>true</bool> - </property> + <item row="1" column="0"> + <widget class="QLabel" name="in_color_lab"> <property name="text"> - <string>Invert histogram direction</string> + <string>Marker color</string> </property> </widget> </item> - <item> - <widget class="QCheckBox" name="cumulative_hist_check"> - <property name="enabled"> - <bool>true</bool> + <item row="2" column="0"> + <widget class="QLabel" name="color_scale_data_defined_in_label"> + <property name="text"> + <string>Color scale</string> </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QgsPropertyOverrideButton" name="in_color_defined_button"> <property name="text"> - <string>Cumulative histogram</string> + <string>...</string> </property> </widget> </item> - </layout> + <item row="5" column="1" colspan="5"> + <widget class="QComboBox" name="marker_type_combo"/> </item> <item row="6" column="0"> <widget class="QLabel" name="point_lab"> @@ -577,54 +584,44 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="4" column="1"> - <widget class="QgsColorButton" name="out_color_combo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QLabel" name="line_lab"> + <item row="22" column="0"> + <widget class="QCheckBox" name="showMeanCheck"> <property name="text"> - <string>Line type</string> + <string>Show mean line</string> + </property> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> - <item row="20" column="0"> - <widget class="QCheckBox" name="violinBox"> - <property name="toolTip"> - <string>If checked, box plots will be overlaid on top of violin plots</string> - </property> + <item row="2" column="1" colspan="5"> + <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0,0"> + <item> + <widget class="QComboBox" name="color_scale_data_defined_in"/> + </item> + <item> + <widget class="QCheckBox" name="color_scale_data_defined_in_check"> <property name="text"> - <string>Include box plots</string> + <string>Visible</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> - <item row="4" column="3"> - <widget class="QLabel" name="marker_width_lab"> + <item> + <widget class="QCheckBox" name="color_scale_data_defined_in_invert_check"> <property name="text"> - <string>Stroke width</string> + <string>Invert color</string> </property> </widget> </item> - <item row="19" column="0"> - <widget class="QLabel" name="violinSideLabel"> - <property name="text"> - <string>Violin side</string> - </property> - </widget> + </layout> </item> - <item row="17" column="0"> - <widget class="QLabel" name="box_statistic_label"> + <item row="18" column="0"> + <widget class="QLabel" name="outliers_label"> <property name="text"> - <string>Show statistics</string> + <string>Outliers</string> </property> </widget> </item> @@ -635,10 +632,17 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="11" column="0"> - <widget class="QLabel" name="alpha_lab"> + <item row="24" column="0"> + <widget class="QCheckBox" name="bins_check"> <property name="text"> - <string>Opacity</string> + <string>Manual bin size</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="legend_label"> + <property name="text"> + <string>Legend title</string> </property> </widget> </item> @@ -649,72 +653,96 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="1" column="3"> - <widget class="QLabel" name="marker_size_lab"> + <item row="15" column="1" colspan="5"> + <widget class="QComboBox" name="orientation_combo"/> + </item> + <item row="8" column="0"> + <widget class="QLabel" name="contour_type_label"> <property name="text"> - <string>Marker size</string> + <string>Contour type</string> </property> </widget> </item> - <item row="23" column="1" colspan="5"> - <widget class="QgsSpinBox" name="bins_value"> - <property name="enabled"> - <bool>false</bool> + <item row="4" column="4"> + <widget class="QgsDoubleSpinBox" name="marker_width"/> + </item> + <item row="12" column="0"> + <widget class="QLabel" name="info_label"> + <property name="text"> + <string>Hover tooltip</string> </property> - <property name="maximum"> - <number>1000</number> + </widget> + </item> + <item row="8" column="1" colspan="5"> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QComboBox" name="contour_type_combo"/> + </item> + <item> + <widget class="QCheckBox" name="show_lines_check"> + <property name="text"> + <string>Show lines</string> </property> - <property name="value"> - <number>10</number> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> - <item row="2" column="0"> - <widget class="QLabel" name="color_scale_data_defined_in_label"> + </layout> + </item> + <item row="23" column="0" colspan="6"> + <layout class="QHBoxLayout" name="horiz_layout_histogram"> + <item> + <widget class="QCheckBox" name="invert_hist_check"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="text"> - <string>Color scale</string> + <string>Invert histogram direction</string> </property> </widget> </item> - <item row="1" column="5"> - <widget class="QgsPropertyOverrideButton" name="size_defined_button"> + <item> + <widget class="QCheckBox" name="cumulative_hist_check"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="text"> - <string>...</string> + <string>Cumulative histogram</string> </property> </widget> </item> - <item row="8" column="0"> - <widget class="QLabel" name="contour_type_label"> + </layout> + </item> + <item row="4" column="5"> + <widget class="QgsPropertyOverrideButton" name="stroke_defined_button"> <property name="text"> - <string>Contour type</string> + <string>...</string> </property> </widget> </item> - <item row="1" column="2"> - <widget class="QgsPropertyOverrideButton" name="in_color_defined_button"> + <item row="1" column="4"> + <widget class="QgsDoubleSpinBox" name="marker_size"/> + </item> + <item row="4" column="2"> + <widget class="QgsPropertyOverrideButton" name="out_color_defined_button"> <property name="text"> <string>...</string> </property> </widget> </item> - <item row="4" column="4"> - <widget class="QgsDoubleSpinBox" name="marker_width"/> - </item> - <item row="12" column="0"> - <widget class="QLabel" name="info_label"> + <item row="11" column="0"> + <widget class="QLabel" name="alpha_lab"> <property name="text"> - <string>Hover tooltip</string> + <string>Opacity</string> </property> </widget> </item> - <item row="7" column="1" colspan="5"> - <widget class="QComboBox" name="line_combo"/> - </item> - <item row="18" column="1" colspan="5"> - <widget class="QComboBox" name="outliers_combo"/> + <item row="6" column="1" colspan="5"> + <widget class="QComboBox" name="point_combo"/> </item> - <item row="1" column="1"> - <widget class="QgsColorButton" name="in_color_combo"> + <item row="4" column="1"> + <widget class="QgsColorButton" name="out_color_combo"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -723,121 +751,116 @@ QListWidget::item::selected { </property> </widget> </item> - <item row="4" column="0"> - <widget class="QLabel" name="out_color_lab"> - <property name="text"> - <string>Stroke color</string> - </property> - </widget> - </item> - <item row="14" column="1" colspan="5"> - <widget class="QComboBox" name="combo_text_position"/> + <item row="16" column="1" colspan="5"> + <widget class="QComboBox" name="hist_norm_combo"/> </item> - <item row="21" column="0"> - <widget class="QCheckBox" name="showMeanCheck"> - <property name="text"> - <string>Show mean line</string> + <item row="24" column="1" colspan="5"> + <widget class="QgsSpinBox" name="bins_value"> + <property name="enabled"> + <bool>false</bool> </property> - <property name="checked"> - <bool>true</bool> + <property name="maximum"> + <number>1000</number> + </property> + <property name="value"> + <number>10</number> </property> </widget> </item> - <item row="14" column="0"> - <widget class="QLabel" name="label_text_position"> + <item row="7" column="1" colspan="5"> + <widget class="QComboBox" name="line_combo"/> + </item> + <item row="0" column="1" colspan="4"> + <widget class="QLineEdit" name="legend_title"/> + </item> + <item row="10" column="1" colspan="5"> + <widget class="QComboBox" name="color_scale_combo"/> + </item> + <item row="15" column="0"> + <widget class="QLabel" name="orientation_label"> <property name="text"> - <string>Label text position</string> + <string>Bar orientation</string> </property> </widget> </item> - <item row="13" column="0"> - <widget class="QCheckBox" name="hover_as_text_check"> + <item row="19" column="1" colspan="5"> + <widget class="QComboBox" name="violinSideCombo"/> + </item> + <item row="16" column="0"> + <widget class="QLabel" name="hist_norm_label"> <property name="text"> - <string>Hover label as text</string> + <string>Normalization</string> </property> </widget> </item> - <item row="1" column="4"> - <widget class="QgsDoubleSpinBox" name="marker_size"/> - </item> - <item row="2" column="1" colspan="5"> - <layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0,0"> - <item> - <widget class="QComboBox" name="color_scale_data_defined_in"/> - </item> - <item> - <widget class="QCheckBox" name="color_scale_data_defined_in_check"> + <item row="4" column="3"> + <widget class="QLabel" name="marker_width_lab"> <property name="text"> - <string>Visible</string> - </property> - <property name="checked"> - <bool>true</bool> + <string>Stroke width</string> </property> </widget> </item> - <item> - <widget class="QCheckBox" name="color_scale_data_defined_in_invert_check"> + <item row="17" column="0"> + <widget class="QLabel" name="box_statistic_label"> <property name="text"> - <string>Invert color</string> + <string>Show statistics</string> </property> </widget> </item> - </layout> + <item row="18" column="1" colspan="5"> + <widget class="QComboBox" name="outliers_combo"/> </item> - <item row="15" column="0"> - <widget class="QLabel" name="orientation_label"> + <item row="14" column="0"> + <widget class="QLabel" name="label_text_position"> <property name="text"> - <string>Bar orientation</string> + <string>Label text position</string> </property> </widget> </item> - <item row="18" column="0"> - <widget class="QLabel" name="outliers_label"> + <item row="5" column="0"> + <widget class="QLabel" name="marker_type_lab"> <property name="text"> - <string>Outliers</string> + <string>Marker type</string> </property> </widget> </item> - <item row="17" column="1" colspan="5"> - <widget class="QComboBox" name="box_statistic_combo"/> - </item> - <item row="19" column="1" colspan="5"> - <widget class="QComboBox" name="violinSideCombo"/> + <item row="12" column="1" colspan="5"> + <widget class="QComboBox" name="info_combo"/> </item> - <item row="23" column="0"> - <widget class="QCheckBox" name="bins_check"> + <item row="4" column="0"> + <widget class="QLabel" name="out_color_lab"> <property name="text"> - <string>Manual bin size</string> + <string>Stroke color</string> </property> </widget> </item> - <item row="12" column="1" colspan="5"> - <widget class="QComboBox" name="info_combo"/> - </item> - <item row="5" column="1" colspan="5"> - <widget class="QComboBox" name="marker_type_combo"/> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="marker_type_lab"> + <item row="13" column="0"> + <widget class="QCheckBox" name="hover_as_text_check"> <property name="text"> - <string>Marker type</string> + <string>Hover label as text</string> </property> </widget> </item> - <item row="0" column="0"> - <widget class="QLabel" name="legend_label"> + <item row="20" column="0"> + <widget class="QLabel" name="pie_hole_label"> <property name="text"> - <string>Legend title</string> + <string>Pie hole</string> </property> </widget> </item> - <item row="0" column="1" colspan="4"> - <widget class="QLineEdit" name="legend_title"/> - </item> - <item row="0" column="5"> - <widget class="QgsPropertyOverrideButton" name="legend_title_defined_button"> - <property name="text"> - <string>...</string> + <item row="20" column="1"> + <widget class="QgsDoubleSpinBox" name="pie_hole"> + <property name="maximum"> + <double>0.950000000000000</double> + </property> + <property name="singleStep"> + <double>0.050000000000000</double> + </property> + <property name="value"> + <double>0.000000000000000</double> + </property> + <property name="clearValue"> + <bool>false</bool> </property> </widget> </item> From 3d0a3bba94deea978e6bb6e70857037629029063 Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Mon, 17 Apr 2023 11:35:36 +0200 Subject: [PATCH 41/57] update changelog for version 4.0.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c3ed68e..557901fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## 4.0.0 - 2023-04-17 + +- multiple plot docks thanks to @jdlom +- add a pie hole parameter to have donuts like charts thanks to @jdlom + ## 3.9.2 - 2022-08-30 - test added for Processing From 121f43d042e8321381efe867e2d4bf366f61363b Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Mon, 17 Apr 2023 11:35:53 +0200 Subject: [PATCH 42/57] try to fix qt5 installation trouble in workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 895d524e..457cef28 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: - name: Install Qt lrelease run: | sudo apt-get update - sudo apt-get install qt5-default qttools5-dev-tools + sudo apt-get install qtbase5-dev qt5-qmake qttools5-dev-tools - name: Install Python requirements run: pip install qgis-plugin-ci From aa4bf7649a4828870c21ebc73a1cc7487e769177 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@gmail.com> Date: Fri, 12 May 2023 13:56:51 +0200 Subject: [PATCH 43/57] Fix bar width (#321) * set the initial value to Auto, clearValue to Auto and tooltip * tweak the bar width value to pass to plotly * add changelog info * bump new release and minimum QGIS version * no more 3.22 in docker --- .github/workflows/test_plugin.yaml | 2 +- CHANGELOG.md | 5 +++++ DataPlotly/core/plot_types/bar_plot.py | 11 ++++++++++- DataPlotly/gui/plot_settings_widget.py | 4 +++- DataPlotly/metadata.txt | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test_plugin.yaml b/.github/workflows/test_plugin.yaml index a0b341ad..d55e80f7 100644 --- a/.github/workflows/test_plugin.yaml +++ b/.github/workflows/test_plugin.yaml @@ -27,7 +27,7 @@ jobs: strategy: matrix: - docker_tags: [release-3_22, release-3_28, latest] + docker_tags: [release-3_28, latest] steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 557901fa..ffae5399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## 4.0.1 2023-05-12 + +- tweak the bar width values, usefull with time series +- minimum QGIS version to 3.28 LTR + ## 4.0.0 - 2023-04-17 - multiple plot docks thanks to @jdlom diff --git a/DataPlotly/core/plot_types/bar_plot.py b/DataPlotly/core/plot_types/bar_plot.py index 1a5a94ad..864453d7 100644 --- a/DataPlotly/core/plot_types/bar_plot.py +++ b/DataPlotly/core/plot_types/bar_plot.py @@ -42,6 +42,15 @@ def create_trace(settings): x = settings.x y = settings.y + # tweak the width value + if settings.data_defined_marker_sizes: + width = settings.data_defined_marker_sizes + # set to None if 0.0 or Auto, useful especially for date/datetime data + elif settings.properties['marker_size'] == 0.0: + width = None + else: + width = settings.properties['marker_size'] + return [graph_objs.Bar( x=x, y=y, @@ -62,7 +71,7 @@ def create_trace(settings): 'color': settings.data_defined_stroke_colors if settings.data_defined_stroke_colors else settings.properties['out_color'], 'width': settings.data_defined_stroke_widths if settings.data_defined_stroke_widths else settings.properties['marker_width']} }, - width=settings.data_defined_marker_sizes if settings.data_defined_marker_sizes else settings.properties['marker_size'], + width=width, opacity=settings.properties['opacity'] )] diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 51540d0c..50f4607e 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -836,7 +836,9 @@ def refreshWidgets(self): # pylint: disable=too-many-statements,too-many-branch # change the label and the spin box value when the bar plot is chosen if self.ptype == 'bar': self.marker_size_lab.setText(self.tr('Bar width')) - self.marker_size.setValue(0.5) + self.marker_size.setValue(0.0) + self.marker_size.setClearValue(0.0, self.tr('Auto')) + self.marker_size.setToolTip(self.tr('Set to Auto to automatically resize the bar width')) # change the label and the spin box value when the scatter plot is chosen if self.ptype == 'scatter': diff --git a/DataPlotly/metadata.txt b/DataPlotly/metadata.txt index 78a50f13..646ae0fd 100644 --- a/DataPlotly/metadata.txt +++ b/DataPlotly/metadata.txt @@ -1,6 +1,6 @@ [general] name=Data Plotly -qgisMinimumVersion=3.4 +qgisMinimumVersion=3.28 qgisMaximumVersion=3.98 description=D3 Plots for QGIS author=Matteo Ghetta (Faunalia) From 1258d3814d855d455cee026c30dd21fdcfdb935a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <etienne.trimaille@gmail.com> Date: Mon, 15 May 2023 12:15:08 +0200 Subject: [PATCH 44/57] Python cleanup, raise to 3.7 minimum due to QGIS 3.28 (#323) * Python cleanup, raise to 3.7 minimum due to QGIS 3.28 * Do not use fstring when the string is translated * Update DataPlotly/gui/plot_settings_widget.py --- DataPlotly/__init__.py | 1 - DataPlotly/core/core_utils.py | 1 - DataPlotly/core/plot_expressions.py | 1 - DataPlotly/core/plot_factory.py | 1 - DataPlotly/core/plot_settings.py | 1 - DataPlotly/core/plot_types/__init__.py | 1 - DataPlotly/core/plot_types/bar_plot.py | 1 - DataPlotly/core/plot_types/box.py | 1 - DataPlotly/core/plot_types/contour.py | 1 - DataPlotly/core/plot_types/histogram.py | 1 - DataPlotly/core/plot_types/histogram2d.py | 1 - DataPlotly/core/plot_types/pie.py | 1 - DataPlotly/core/plot_types/plot_type.py | 1 - DataPlotly/core/plot_types/polar.py | 1 - DataPlotly/core/plot_types/scatter.py | 1 - DataPlotly/core/plot_types/ternary.py | 1 - DataPlotly/core/plot_types/violin.py | 1 - DataPlotly/data_plotly.py | 3 +-- DataPlotly/gui/dock.py | 1 - DataPlotly/gui/gui_utils.py | 1 - DataPlotly/gui/layout_item_gui.py | 1 - DataPlotly/gui/plot_settings_widget.py | 16 +++++++--------- DataPlotly/layouts/plot_layout_item.py | 5 ++--- DataPlotly/processing/dataplotly_provider.py | 1 - DataPlotly/processing/dataplotly_scatterplot.py | 1 - DataPlotly/test/qgis_interface.py | 1 - DataPlotly/test/test_data_plotly_dialog.py | 3 +-- DataPlotly/test/test_dock_manager.py | 3 +-- DataPlotly/test/test_guiutils.py | 3 +-- DataPlotly/test/test_init.py | 3 +-- DataPlotly/test/test_plot_factory.py | 3 +-- DataPlotly/test/test_plot_settings.py | 3 +-- DataPlotly/test/test_processing.py | 2 +- DataPlotly/test/test_qgis_environment.py | 1 - DataPlotly/test/test_resources.py | 3 +-- DataPlotly/test/utilities.py | 3 +-- DataPlotly/test_suite.py | 5 ++--- 37 files changed, 21 insertions(+), 58 deletions(-) diff --git a/DataPlotly/__init__.py b/DataPlotly/__init__.py index da566a30..59ecd5f0 100644 --- a/DataPlotly/__init__.py +++ b/DataPlotly/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ /*************************************************************************** DataPlotly diff --git a/DataPlotly/core/core_utils.py b/DataPlotly/core/core_utils.py index 76e5f067..371b1afd 100644 --- a/DataPlotly/core/core_utils.py +++ b/DataPlotly/core/core_utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """COre Utilities .. note:: This program is free software; you can redistribute it and/or modify diff --git a/DataPlotly/core/plot_expressions.py b/DataPlotly/core/plot_expressions.py index 336ea78c..dff797f1 100644 --- a/DataPlotly/core/plot_expressions.py +++ b/DataPlotly/core/plot_expressions.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ /*************************************************************************** DataPlotly diff --git a/DataPlotly/core/plot_factory.py b/DataPlotly/core/plot_factory.py index f1ddbc7e..6a970b66 100644 --- a/DataPlotly/core/plot_factory.py +++ b/DataPlotly/core/plot_factory.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Plot creation diff --git a/DataPlotly/core/plot_settings.py b/DataPlotly/core/plot_settings.py index 803384a8..1f45e0d0 100644 --- a/DataPlotly/core/plot_settings.py +++ b/DataPlotly/core/plot_settings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Encapsulates settings for a plot .. note:: This program is free software; you can redistribute it and/or modify diff --git a/DataPlotly/core/plot_types/__init__.py b/DataPlotly/core/plot_types/__init__.py index 52e9b350..3f033e43 100644 --- a/DataPlotly/core/plot_types/__init__.py +++ b/DataPlotly/core/plot_types/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Available plot types diff --git a/DataPlotly/core/plot_types/bar_plot.py b/DataPlotly/core/plot_types/bar_plot.py index 864453d7..ae2bcbc7 100644 --- a/DataPlotly/core/plot_types/bar_plot.py +++ b/DataPlotly/core/plot_types/bar_plot.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Bar plot diff --git a/DataPlotly/core/plot_types/box.py b/DataPlotly/core/plot_types/box.py index 1613fecb..0f9f38be 100644 --- a/DataPlotly/core/plot_types/box.py +++ b/DataPlotly/core/plot_types/box.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Box plot diff --git a/DataPlotly/core/plot_types/contour.py b/DataPlotly/core/plot_types/contour.py index 4487d655..71e9e538 100644 --- a/DataPlotly/core/plot_types/contour.py +++ b/DataPlotly/core/plot_types/contour.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Contour chart factory diff --git a/DataPlotly/core/plot_types/histogram.py b/DataPlotly/core/plot_types/histogram.py index 1d68eb30..71980410 100644 --- a/DataPlotly/core/plot_types/histogram.py +++ b/DataPlotly/core/plot_types/histogram.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Histogram factory diff --git a/DataPlotly/core/plot_types/histogram2d.py b/DataPlotly/core/plot_types/histogram2d.py index 57d5201d..6d157e69 100644 --- a/DataPlotly/core/plot_types/histogram2d.py +++ b/DataPlotly/core/plot_types/histogram2d.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ 2D histogram factory diff --git a/DataPlotly/core/plot_types/pie.py b/DataPlotly/core/plot_types/pie.py index 229b62dc..884776a9 100644 --- a/DataPlotly/core/plot_types/pie.py +++ b/DataPlotly/core/plot_types/pie.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Pie chart factory diff --git a/DataPlotly/core/plot_types/plot_type.py b/DataPlotly/core/plot_types/plot_type.py index 19fe91ed..4e0bc1f3 100644 --- a/DataPlotly/core/plot_types/plot_type.py +++ b/DataPlotly/core/plot_types/plot_type.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Base class for plot type subclasses diff --git a/DataPlotly/core/plot_types/polar.py b/DataPlotly/core/plot_types/polar.py index ff4ffe24..963e1ec9 100644 --- a/DataPlotly/core/plot_types/polar.py +++ b/DataPlotly/core/plot_types/polar.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Polar chart factory diff --git a/DataPlotly/core/plot_types/scatter.py b/DataPlotly/core/plot_types/scatter.py index cc72f606..b6034d11 100644 --- a/DataPlotly/core/plot_types/scatter.py +++ b/DataPlotly/core/plot_types/scatter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Base class for trace factories diff --git a/DataPlotly/core/plot_types/ternary.py b/DataPlotly/core/plot_types/ternary.py index eefe77d4..bb31f5f5 100644 --- a/DataPlotly/core/plot_types/ternary.py +++ b/DataPlotly/core/plot_types/ternary.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Ternary plot factory diff --git a/DataPlotly/core/plot_types/violin.py b/DataPlotly/core/plot_types/violin.py index b0bd4a2a..232e4333 100644 --- a/DataPlotly/core/plot_types/violin.py +++ b/DataPlotly/core/plot_types/violin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Violin chart factory diff --git a/DataPlotly/data_plotly.py b/DataPlotly/data_plotly.py index 2aeeb3d8..709a4342 100644 --- a/DataPlotly/data_plotly.py +++ b/DataPlotly/data_plotly.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ /*************************************************************************** DataPlotly @@ -71,7 +70,7 @@ def __init__(self, iface): locale_path = os.path.join( self.plugin_dir, 'i18n', - 'application_{}.qm'.format(locale)) + f'application_{locale}.qm') if os.path.exists(locale_path): self.translator = QTranslator() diff --git a/DataPlotly/gui/dock.py b/DataPlotly/gui/dock.py index b37959ab..f6d73384 100644 --- a/DataPlotly/gui/dock.py +++ b/DataPlotly/gui/dock.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Dock widget .. note:: This program is free software; you can redistribute it and/or modify diff --git a/DataPlotly/gui/gui_utils.py b/DataPlotly/gui/gui_utils.py index bb86ddd2..af3ede3a 100644 --- a/DataPlotly/gui/gui_utils.py +++ b/DataPlotly/gui/gui_utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """GUI Utilities .. note:: This program is free software; you can redistribute it and/or modify diff --git a/DataPlotly/gui/layout_item_gui.py b/DataPlotly/gui/layout_item_gui.py index 814f12dd..929db89d 100644 --- a/DataPlotly/gui/layout_item_gui.py +++ b/DataPlotly/gui/layout_item_gui.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Plot Layout Gui Handling .. note:: This program is free software; you can redistribute it and/or modify diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 50f4607e..4a13f5ee 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ /*************************************************************************** DataPlotlyDialog @@ -588,7 +587,7 @@ def helpPage(self): self.help_view.load(QUrl('')) self.layouth.addWidget(self.help_view) help_url = QUrl( - 'https://dataplotly-docs.readthedocs.io/en/latest/{}.html'.format(self.ptype)) + f'https://dataplotly-docs.readthedocs.io/en/latest/{self.ptype}.html') self.help_view.load(help_url) def resizeEvent(self, event): @@ -596,7 +595,7 @@ def resizeEvent(self, event): reimplemented event to detect the dialog resizing """ self.resizeWindow.emit() - return super(DataPlotlyPanelWidget, self).resizeEvent(event) # pylint:disable=super-with-arguments + return super().resizeEvent(event) # pylint:disable=super-with-arguments def reloadPlotCanvas(self): """ @@ -1072,7 +1071,7 @@ def setLegend(self): self.legend_title.setText(self.x_combo.currentText()) else: legend_title_string = ( - '{} - {}'.format(self.x_combo.currentText(), self.y_combo.currentText())) + f'{self.x_combo.currentText()} - {self.y_combo.currentText()}') self.legend_title.setText(legend_title_string) def get_settings(self) -> PlotSettings: # pylint: disable=R0915 @@ -1374,7 +1373,7 @@ def create_plot_factory(self) -> PlotFactory: plot_factory = PlotFactory(settings, visible_region=visible_region) # unique name for each plot trace (name is idx_plot, e.g. 1_scatter) - self.pid = ('{}_{}'.format(str(self.idx), settings.plot_type)) + self.pid = f'{self.idx}_{settings.plot_type}' # create default dictionary that contains all the plot and properties self.plot_factories[self.pid] = plot_factory @@ -1461,12 +1460,11 @@ def create_plot(self): except: # pylint: disable=bare-except # noqa: F401 if self.message_bar: self.message_bar.pushMessage( - self.tr( - "{} plot is not compatible for subplotting\n see ".format(self.ptype)), + self.tr("{} plot is not compatible for subplotting\n see ").format(self.ptype), Qgis.MessageLevel(2), duration=5) return - # connect to simple function that reloads the view + # connect to a simple function that reloads the view self.refreshPlotView() def UpdatePlot(self): @@ -1494,7 +1492,7 @@ def refreshPlotView(self): self.layoutw.addWidget(self.plot_view) self.raw_plot_text.clear() - with open(self.plot_path, 'r', encoding="utf8") as myfile: + with open(self.plot_path, encoding="utf8") as myfile: plot_text = myfile.read() self.raw_plot_text.setPlainText(plot_text) diff --git a/DataPlotly/layouts/plot_layout_item.py b/DataPlotly/layouts/plot_layout_item.py index 1e19cc21..24922f47 100644 --- a/DataPlotly/layouts/plot_layout_item.py +++ b/DataPlotly/layouts/plot_layout_item.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Plot Layout Item .. note:: This program is free software; you can redistribute it and/or modify @@ -43,7 +42,7 @@ def __init__(self, parent=None): super().__init__(parent) def javaScriptConsoleMessage(self, message, lineNumber, source): - QgsMessageLog.logMessage('{}:{} {}'.format(source, lineNumber, message), 'DataPlotly') + QgsMessageLog.logMessage(f'{source}:{lineNumber} {message}', 'DataPlotly') class PlotLayoutItem(QgsLayoutItem): @@ -196,7 +195,7 @@ def create_plot(self): pl.append(factory.trace[0]) plot_path = plot_factory.build_figures(self.plot_settings[0].plot_type, pl, config=config) - with open(plot_path, 'r') as myfile: + with open(plot_path) as myfile: return myfile.read() def get_polygon_filter(self, index=0): diff --git a/DataPlotly/processing/dataplotly_provider.py b/DataPlotly/processing/dataplotly_provider.py index 44d921d1..25a0ea58 100644 --- a/DataPlotly/processing/dataplotly_provider.py +++ b/DataPlotly/processing/dataplotly_provider.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ /*************************************************************************** DataPlotly diff --git a/DataPlotly/processing/dataplotly_scatterplot.py b/DataPlotly/processing/dataplotly_scatterplot.py index 094984c1..d13230bc 100644 --- a/DataPlotly/processing/dataplotly_scatterplot.py +++ b/DataPlotly/processing/dataplotly_scatterplot.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ /*************************************************************************** DataPlotly diff --git a/DataPlotly/test/qgis_interface.py b/DataPlotly/test/qgis_interface.py index 57fd118d..08e106bb 100644 --- a/DataPlotly/test/qgis_interface.py +++ b/DataPlotly/test/qgis_interface.py @@ -1,4 +1,3 @@ -# coding=utf-8 """QGIS plugin implementation. .. note:: This program is free software; you can redistribute it and/or modify diff --git a/DataPlotly/test/test_data_plotly_dialog.py b/DataPlotly/test/test_data_plotly_dialog.py index 39201b0e..db655b55 100644 --- a/DataPlotly/test/test_data_plotly_dialog.py +++ b/DataPlotly/test/test_data_plotly_dialog.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Dialog test. .. note:: This program is free software; you can redistribute it and/or modify @@ -603,6 +602,6 @@ def test_duplicate_chart_in_layout(self): # pylint: disable=too-many-statements if __name__ == "__main__": - suite = unittest.makeSuite(DataPlotlyDialogTest) + suite = unittest.defaultTestLoader.loadTestsFromTestCase(DataPlotlyDialogTest) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite) diff --git a/DataPlotly/test/test_dock_manager.py b/DataPlotly/test/test_dock_manager.py index c8992711..f83cec41 100644 --- a/DataPlotly/test/test_dock_manager.py +++ b/DataPlotly/test/test_dock_manager.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Plot factory test .. note:: This program is free software; you can redistribute it and/or modify @@ -183,6 +182,6 @@ def test_009_add_new_dock_validator(self): if __name__ == "__main__": - suite = unittest.makeSuite(DataPlotlyDockManagerTest) + suite = unittest.defaultTestLoader.loadTestsFromTestCase(DataPlotlyDockManagerTest) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite) diff --git a/DataPlotly/test/test_guiutils.py b/DataPlotly/test/test_guiutils.py index 50539649..8b647331 100644 --- a/DataPlotly/test/test_guiutils.py +++ b/DataPlotly/test/test_guiutils.py @@ -1,4 +1,3 @@ -# coding=utf-8 """GUI Utils Test. .. note:: This program is free software; you can redistribute it and/or modify @@ -44,6 +43,6 @@ def testGetIconSvg(self): if __name__ == "__main__": - suite = unittest.makeSuite(GuiUtilsTest) + suite = unittest.defaultTestLoader.loadTestsFromTestCase(GuiUtilsTest) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite) diff --git a/DataPlotly/test/test_init.py b/DataPlotly/test/test_init.py index cbe30d2a..b74d5b4c 100644 --- a/DataPlotly/test/test_init.py +++ b/DataPlotly/test/test_init.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests QGIS plugin init.""" __author__ = 'Tim Sutton <tim@linfiniti.com>' @@ -55,7 +54,7 @@ def test_read_init(self): metadata.extend(parser.items('general')) for expectation in required_metadata: - message = ('Cannot find metadata "%s" in metadata source (%s).' % ( + message = ('Cannot find metadata "{}" in metadata source ({}).'.format( expectation, file_path)) self.assertIn(expectation, dict(metadata), message) diff --git a/DataPlotly/test/test_plot_factory.py b/DataPlotly/test/test_plot_factory.py index 3e676249..bc82bc29 100644 --- a/DataPlotly/test/test_plot_factory.py +++ b/DataPlotly/test/test_plot_factory.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Plot factory test .. note:: This program is free software; you can redistribute it and/or modify @@ -726,6 +725,6 @@ def createExpressionContext(self) -> QgsExpressionContext: # pylint: disable=mi if __name__ == "__main__": - suite = unittest.makeSuite(DataPlotlyFactory) + suite = unittest.defaultTestLoader.loadTestsFromTestCase(DataPlotlyFactory) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite) diff --git a/DataPlotly/test/test_plot_settings.py b/DataPlotly/test/test_plot_settings.py index 1ec20bc5..d479af1d 100644 --- a/DataPlotly/test/test_plot_settings.py +++ b/DataPlotly/test/test_plot_settings.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Plot settings test .. note:: This program is free software; you can redistribute it and/or modify @@ -346,6 +345,6 @@ def test_read_write_file(self): if __name__ == "__main__": - suite = unittest.makeSuite(DataPlotlySettings) + suite = unittest.defaultTestLoader.loadTestsFromTestCase(DataPlotlySettings) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite) diff --git a/DataPlotly/test/test_processing.py b/DataPlotly/test/test_processing.py index 2b1ff435..3e722b6f 100644 --- a/DataPlotly/test/test_processing.py +++ b/DataPlotly/test/test_processing.py @@ -54,7 +54,7 @@ def test_scatterplot_figure(self): result = processing.run("DataPlotly:dataplotly_scatterplot", plot_param) - with open(result['OUTPUT_JSON_FILE'], 'r', encoding='utf8') as f: + with open(result['OUTPUT_JSON_FILE'], encoding='utf8') as f: result_dict = json.load(f) self.assertListEqual( diff --git a/DataPlotly/test/test_qgis_environment.py b/DataPlotly/test/test_qgis_environment.py index 342953c2..1e750728 100644 --- a/DataPlotly/test/test_qgis_environment.py +++ b/DataPlotly/test/test_qgis_environment.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Tests for QGIS functionality. .. note:: This program is free software; you can redistribute it and/or modify diff --git a/DataPlotly/test/test_resources.py b/DataPlotly/test/test_resources.py index abc7053f..b311bcba 100644 --- a/DataPlotly/test/test_resources.py +++ b/DataPlotly/test/test_resources.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Resources test. .. note:: This program is free software; you can redistribute it and/or modify @@ -36,6 +35,6 @@ def test_icon_png(self): if __name__ == "__main__": - suite = unittest.makeSuite(DataPlotlyResourcesTest) + suite = unittest.defaultTestLoader.loadTestsFromTestCase(DataPlotlyResourcesTest) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite) diff --git a/DataPlotly/test/utilities.py b/DataPlotly/test/utilities.py index a67b368f..0e00598b 100644 --- a/DataPlotly/test/utilities.py +++ b/DataPlotly/test/utilities.py @@ -1,4 +1,3 @@ -# coding=utf-8 """Common functionality used by regression tests.""" import sys @@ -68,7 +67,7 @@ def debug_log_message(message, tag, level): :param level: log message level (severity) :return: """ - print('{}({}): {}'.format(tag, level, message)) + print(f'{tag}({level}): {message}') QgsApplication.instance().messageLog().messageReceived.connect( debug_log_message) diff --git a/DataPlotly/test_suite.py b/DataPlotly/test_suite.py index 28b1722e..48f2e0d7 100644 --- a/DataPlotly/test_suite.py +++ b/DataPlotly/test_suite.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ Test Suite. @@ -38,7 +37,7 @@ def _run_tests(test_suite, package_name, with_coverage=False): """Core function to test a test suite.""" count = test_suite.countTestCases() print('########') - print('%s tests has been discovered in %s' % (count, package_name)) + print('{} tests has been discovered in {}'.format(count, package_name)) print('Python GDAL : %s' % gdal.VersionInfo('VERSION_NUM')) print('########') if with_coverage: @@ -57,7 +56,7 @@ def _run_tests(test_suite, package_name, with_coverage=False): cov.report(file=report) # Produce HTML reports in the `htmlcov` folder and open index.html # cov.html_report() - with open(report.name, 'r', encoding='utf8') as fin: + with open(report.name, encoding='utf8') as fin: print(fin.read()) From 5129f4ab45fe7c27cb018d84660c63b7bb6e32b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <etienne.trimaille@gmail.com> Date: Mon, 15 May 2023 14:02:34 +0200 Subject: [PATCH 45/57] Python - Remove some unused code now that QGIS 3.28 is the minimum (#322) --- DataPlotly/data_plotly.py | 16 +++++++--------- setup.cfg | 4 ++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/DataPlotly/data_plotly.py b/DataPlotly/data_plotly.py index 709a4342..7ee0384e 100644 --- a/DataPlotly/data_plotly.py +++ b/DataPlotly/data_plotly.py @@ -25,7 +25,7 @@ from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, QUrl from qgis.PyQt.QtGui import QDesktopServices, QIcon from qgis.PyQt.QtWidgets import QAction, QMenu, QToolButton -from qgis.core import Qgis, QgsApplication, QgsExpression, QgsProject +from qgis.core import QgsApplication, QgsExpression, QgsProject from qgis.gui import QgsGui # Import the code for the dialog @@ -170,11 +170,10 @@ def initGui(self): QgsGui.layoutItemGuiRegistry().addLayoutItemGuiMetadata(self.plot_item_gui_metadata) # Open the online help - if Qgis.QGIS_VERSION_INT >= 31000: - self.help_action = QAction( - icon, 'DataPlotly', self.iface.mainWindow()) - self.iface.pluginHelpMenu().addAction(self.help_action) - self.help_action.triggered.connect(self.open_help) + self.help_action = QAction( + icon, 'DataPlotly', self.iface.mainWindow()) + self.iface.pluginHelpMenu().addAction(self.help_action) + self.help_action.triggered.connect(self.open_help) # register the function QgsExpression.registerFunction(get_symbol_colors) @@ -259,9 +258,8 @@ def unload(self): self.toolButton.deleteLater() self.toolButton = None - if Qgis.QGIS_VERSION_INT >= 31000 and self.help_action: - self.iface.pluginHelpMenu().removeAction(self.help_action) - self.help_action = None + self.iface.pluginHelpMenu().removeAction(self.help_action) + self.help_action = None # Remove processing provider QgsApplication.processingRegistry().removeProvider(self.provider) diff --git a/setup.cfg b/setup.cfg index 05301948..f47753f4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,3 +6,7 @@ transifex_organization = dataplotly transifex_project = dataplotly-ui transifex_resource = application transifex_coordinator = ghtmtt + +[flake8] +exclude = + .venv/, From 68f303c1e7c395c48632b0dec56fb3caa46a159a Mon Sep 17 00:00:00 2001 From: jdlom <jdaniel.lomenede@gmail.com> Date: Fri, 23 Jun 2023 16:45:32 +0200 Subject: [PATCH 46/57] fix : #324 key error pie_hole (#326) --- DataPlotly/core/plot_types/pie.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataPlotly/core/plot_types/pie.py b/DataPlotly/core/plot_types/pie.py index 884776a9..6e62df65 100644 --- a/DataPlotly/core/plot_types/pie.py +++ b/DataPlotly/core/plot_types/pie.py @@ -39,7 +39,7 @@ def create_trace(settings): 'colors': settings.data_defined_colors if settings.data_defined_colors else [settings.properties['in_color']] }, name=settings.properties['custom'][0], - hole=settings.properties['pie_hole'] + hole=settings.get('pie_hole', 0) )] @staticmethod From c3f4e4e35d52123fb564ba6109bc3030a7e612a5 Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Sat, 24 Jun 2023 10:44:54 +0200 Subject: [PATCH 47/57] prepare changelog for 4.0.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffae5399..1de44125 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 4.0.2 2023-06-24 + +- fix bug with old projects thanks to @jdlom + ## 4.0.1 2023-05-12 - tweak the bar width values, usefull with time series From 7b5d55277d610876dae3aaa74b8130722f64f0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <etienne.trimaille@gmail.com> Date: Mon, 26 Jun 2023 10:20:07 +0200 Subject: [PATCH 48/57] Fix parsing changelog (#327) --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1de44125..89fee81e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,13 @@ ## Unreleased -## 4.0.2 2023-06-24 +## 4.0.2 - 2023-06-24 - fix bug with old projects thanks to @jdlom -## 4.0.1 2023-05-12 +## 4.0.1 - 2023-05-12 -- tweak the bar width values, usefull with time series +- tweak the bar width values, useful with time series - minimum QGIS version to 3.28 LTR ## 4.0.0 - 2023-04-17 From 95d3cde8de44033dd0bef8babc8699df964f324e Mon Sep 17 00:00:00 2001 From: Etienne Trimaille <gustrimaille@yahoo.fr> Date: Mon, 26 Jun 2023 10:24:51 +0200 Subject: [PATCH 49/57] Docs - Add some badges in the readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 56305319..84de01cc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # DataPlotly +[](https://plugins.qgis.org/plugins/DataPlotly/) [](https://github.com/ghtmtt/DataPlotly/actions/workflows/test_plugin.yaml) +[](https://github.com/ghtmtt/DataPlotly/actions/workflows/transifex.yml) The DataPlotly plugin allows creation of -like interactive plots directly within QGIS, thanks to the  From db35c51b6db37cbfb16b050feda25f6f0ae08401 Mon Sep 17 00:00:00 2001 From: jdlom <jdaniel.lomenede@gmail.com> Date: Tue, 27 Jun 2023 15:23:52 +0200 Subject: [PATCH 50/57] fix: really fix this time #324 (#329) --- DataPlotly/core/plot_types/pie.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataPlotly/core/plot_types/pie.py b/DataPlotly/core/plot_types/pie.py index 6e62df65..88a04f74 100644 --- a/DataPlotly/core/plot_types/pie.py +++ b/DataPlotly/core/plot_types/pie.py @@ -39,7 +39,7 @@ def create_trace(settings): 'colors': settings.data_defined_colors if settings.data_defined_colors else [settings.properties['in_color']] }, name=settings.properties['custom'][0], - hole=settings.get('pie_hole', 0) + hole=settings.properties.get('pie_hole', 0) )] @staticmethod From b6b0fe7d143f963af140dfb44ac564f8d214a254 Mon Sep 17 00:00:00 2001 From: ghtmtt <matteo.ghetta@gmail.com> Date: Tue, 27 Jun 2023 16:23:08 +0200 Subject: [PATCH 51/57] prepare changelog for 4.0.3 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89fee81e..d6acd4c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 4.0.3 - 2023-06-27 + +- fix bug with old projects (second part) thanks to @jdlom + ## 4.0.2 - 2023-06-24 - fix bug with old projects thanks to @jdlom From e14209bb5e5eb19d15577cc7947466da624f435f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <etienne.trimaille@gmail.com> Date: Tue, 4 Jul 2023 15:21:57 +0200 Subject: [PATCH 52/57] Fix loading of the plugin without pandas installed (#332) --- CHANGELOG.md | 2 ++ DataPlotly/processing/dataplotly_provider.py | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6acd4c8..b20f46ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Fix loading of the plugin when the Pandas library is not found, contribution from @Gustry + ## 4.0.3 - 2023-06-27 - fix bug with old projects (second part) thanks to @jdlom diff --git a/DataPlotly/processing/dataplotly_provider.py b/DataPlotly/processing/dataplotly_provider.py index 25a0ea58..d64c30de 100644 --- a/DataPlotly/processing/dataplotly_provider.py +++ b/DataPlotly/processing/dataplotly_provider.py @@ -19,9 +19,18 @@ * * ***************************************************************************/ """ -from qgis.core import QgsProcessingProvider +from qgis.core import Qgis, QgsMessageLog, QgsProcessingProvider from DataPlotly.gui.gui_utils import GuiUtils -from DataPlotly.processing.dataplotly_scatterplot import DataPlotlyProcessingScatterPlot + +try: + # 🐼 + from DataPlotly.processing.dataplotly_scatterplot import DataPlotlyProcessingScatterPlot + WITH_PANDAS = True +except ImportError: + WITH_PANDAS = False + QgsMessageLog.logMessage( + "Pandas has not been found. The processing algorithm will not be loaded. " + "Please install qgis-full or qgis standalone", "DataPlotly", Qgis.Warning) class DataPlotlyProvider(QgsProcessingProvider): @@ -76,4 +85,5 @@ def loadAlgorithms(self): even if the list does not change, since the self.algs list is cleared before calling this method. """ - self.addAlgorithm(DataPlotlyProcessingScatterPlot()) + if WITH_PANDAS: + self.addAlgorithm(DataPlotlyProcessingScatterPlot()) From 2c9a21576f72e65e6105801ae43949613fcbd331 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@faunalia.it> Date: Wed, 15 Nov 2023 15:37:54 +0100 Subject: [PATCH 53/57] prepare changelog for 4.1.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b20f46ca..21458341 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 4.1.0 - 2023-11-15 - Fix loading of the plugin when the Pandas library is not found, contribution from @Gustry From 7ab2553e6a69bd30c3b2fc16c0cf49abed5bfbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <etienne.trimaille@gmail.com> Date: Wed, 21 Feb 2024 08:19:59 +0100 Subject: [PATCH 54/57] Do not add docks if self.iface is not defined when using qgis_process (#345) --- CHANGELOG.md | 4 ++++ DataPlotly/gui/dock.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21458341..f7a9759c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- Fix loading of the plugin when used with `qgis_process`, contribution from @Gustry + ## 4.1.0 - 2023-11-15 - Fix loading of the plugin when the Pandas library is not found, contribution from @Gustry diff --git a/DataPlotly/gui/dock.py b/DataPlotly/gui/dock.py index f6d73384..4c43cc49 100644 --- a/DataPlotly/gui/dock.py +++ b/DataPlotly/gui/dock.py @@ -127,7 +127,7 @@ def addDocksFromProject(self, document: QDomDocument): # FIXME : trigger the plot creation (not working) # main_panel = self.getDock(tag_name).main_panel # main_panel.create_plot() - if self.read_from_project(document): + if self.iface and self.read_from_project(document): self.iface.mainWindow().restoreGeometry(self.geometry) self.iface.mainWindow().restoreState(self.state, version=999) return True From 4319fbcdd045127e4a4e08206f7498b14f478c4a Mon Sep 17 00:00:00 2001 From: Nyall Dawson <nyall.dawson@gmail.com> Date: Thu, 24 Oct 2024 22:31:28 +1000 Subject: [PATCH 55/57] Deepcopy settings when creating factories (#356) * Deepcopy settings when creating factories Otherwise things get murky when we re-use the same settings objects with multiple factories, as the factory plot generation logic modifies settings (eg by recording the list of found feature ids) Fixes incomplete plots when used with atlas * Simpler fix --- DataPlotly/core/plot_factory.py | 8 +++++--- DataPlotly/core/plot_settings.py | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/DataPlotly/core/plot_factory.py b/DataPlotly/core/plot_factory.py index 6a970b66..759d2d34 100644 --- a/DataPlotly/core/plot_factory.py +++ b/DataPlotly/core/plot_factory.py @@ -7,11 +7,13 @@ (at your option) any later version. """ + import tempfile import os import re import plotly import plotly.graph_objs as go +from copy import deepcopy from plotly import subplots from qgis.core import ( @@ -95,9 +97,9 @@ def __init__(self, settings: PlotSettings = None, context_generator: QgsExpressi visible_region: QgsReferencedRectangle = None, polygon_filter: FilterRegion = None): super().__init__() if settings is None: - settings = PlotSettings('scatter') - - self.settings = settings + self.settings = PlotSettings('scatter') + else: + self.settings = deepcopy(settings) self.context_generator = context_generator self.raw_plot = None self.plot_path = None diff --git a/DataPlotly/core/plot_settings.py b/DataPlotly/core/plot_settings.py index 1f45e0d0..420ccee7 100644 --- a/DataPlotly/core/plot_settings.py +++ b/DataPlotly/core/plot_settings.py @@ -6,10 +6,15 @@ (at your option) any later version. """ +from copy import deepcopy from qgis.PyQt.QtCore import QFile, QIODevice from qgis.PyQt.QtXml import QDomDocument, QDomElement from qgis.core import QgsXmlUtils, QgsPropertyCollection, QgsPropertyDefinition +def _pc_deepcopy(self, memo): + return QgsPropertyCollection(self) + +QgsPropertyCollection.__deepcopy__ = _pc_deepcopy class PlotSettings: # pylint: disable=too-many-instance-attributes """ From e6b8d9d95d5f231fcaccd8b76e900fd173c0b331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Trimaille?= <etienne.trimaille@gmail.com> Date: Thu, 24 Oct 2024 14:39:02 +0200 Subject: [PATCH 56/57] Update metadata.txt about homePage (#354) --- DataPlotly/metadata.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataPlotly/metadata.txt b/DataPlotly/metadata.txt index 646ae0fd..248171a5 100644 --- a/DataPlotly/metadata.txt +++ b/DataPlotly/metadata.txt @@ -8,6 +8,7 @@ email=matteo.ghetta@gmail.com about=Draw D3 plots in QGIS +homepage=https://github.com/ghtmtt/DataPlotly/blob/master/README.md tracker=https://github.com/ghtmtt/DataPlotly/issues repository=https://github.com/ghtmtt/DataPlotly # End of mandatory metadata @@ -25,7 +26,6 @@ dateTime= # Tags are comma separated with spaces allowed tags=python, d3, plots, vector, graphs, datavis, dataviz, dataplotly -homepage=https://github.com/ghtmtt/DataPlotly category=Plugins icon=icon.png # experimental flag From b3e7b76b0b7a972671a5b892ca46acf5f4195ca3 Mon Sep 17 00:00:00 2001 From: Matteo Ghetta <matteo.ghetta@faunalia.it> Date: Thu, 24 Oct 2024 14:48:13 +0200 Subject: [PATCH 57/57] more complete gitignore file --- .gitignore | 156 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 145 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 61f853b1..c99b104d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,154 @@ -# Python -*.pyc -.venv -venv +# Byte-compiled / optimized / DLL files __pycache__/ +*.py[cod] +*$py.class +*.pyc -# IDE -.idea/* +# C extensions +*.so -.backuputils.py +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST -# QGIS-Plugin-CI -DataPlotly.*.zip -DataPlotly/i18n/ +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ .coverage -.noseids +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# Vscode +.vscode/ + +# Windows thumbs +Thumbs.db + +# zip files +*.zip + +# IDE +.idea/* # Vscode .vscode/*