diff --git a/DataPlotly/core/plot_expressions.py b/DataPlotly/core/plot_expressions.py new file mode 100644 index 00000000..55d7e133 --- /dev/null +++ b/DataPlotly/core/plot_expressions.py @@ -0,0 +1,53 @@ +# -*- 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, iface + +@qgsfunction(args='auto', group='DataPlotly') +def get_categories_colors(field, feature, parent): + """ + 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. +

Syntax

+

+ get_categories_colors(categorization_field) +

+

Arguments

+

categorization_field: the name of the field used in the categorization

+

Example

+

+ get_categories_colors("CONTINENT") -> '#da1ddd' +

+ """ + + layer = iface.activeLayer() + renderer = layer.renderer() + + if layer.renderer().type() == "categorizedSymbol": + for category in renderer.categories(): + if field == category.value(): + category_color = category.symbol().color().name() + break + + return category_color \ No newline at end of file diff --git a/DataPlotly/core/plot_factory.py b/DataPlotly/core/plot_factory.py index 0c7e7735..59be929d 100644 --- a/DataPlotly/core/plot_factory.py +++ b/DataPlotly/core/plot_factory.py @@ -485,13 +485,11 @@ def js_callback(_): dds["type"] = data.points[0].data.type featureIds = []; - featureIdsTernary = []; data.points.forEach(function(pt){ - featureIds.push(parseInt(pt.id)) - featureIdsTernary.push(parseInt(pt.pointNumber)) + featureIds.push(pt.x) dds["id"] = featureIds - dds["tid"] = featureIdsTernary + dds["field"] = pt.data.customdata[0] }) //console.log(dds) window.status = JSON.stringify(dds) @@ -511,6 +509,8 @@ def js_callback(_): if(data.points[i].data.type == 'scatter'){ dd["uid"] = data.points[i].data.uid dd["type"] = data.points[i].data.type + dd["field"] = data.points[i].data.customdata[0] + dd["id"] = data.points[i].x data.points.forEach(function(pt){ dd["fid"] = pt.id diff --git a/DataPlotly/data_plotly.py b/DataPlotly/data_plotly.py index 97e0e523..ea7c94a0 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_categories_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_categories_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_categories_colors') + @staticmethod def open_help(): """ Open the online help. """ diff --git a/DataPlotly/gui/plot_settings_widget.py b/DataPlotly/gui/plot_settings_widget.py index 7d5780cf..b11095f4 100644 --- a/DataPlotly/gui/plot_settings_widget.py +++ b/DataPlotly/gui/plot_settings_widget.py @@ -475,15 +475,24 @@ def getJSmessage(self, status): # if a selection event is performed if dic['mode'] == 'selection': + exp = """ {} IN {} """.format(dic['field'], dic['id']) + exp = exp.replace('[', '(').replace(']', ')') + # set the iterator with the expression as filter in feature request + request = QgsFeatureRequest().setFilterExpression(exp) + it = self.layer_combo.currentLayer().getFeatures(request) if dic['type'] == 'scatter': - self.layer_combo.currentLayer().selectByIds(dic['id']) + self.layer_combo.currentLayer().selectByIds([f.id() for f in it]) else: - self.layer_combo.currentLayer().selectByIds(dic['tid']) + self.layer_combo.currentLayer().selectByIds([f.id() for f in it]) # if a clicking event is performed depending on the plot type elif dic["mode"] == 'clicking': if dic['type'] == 'scatter': - self.layer_combo.currentLayer().selectByIds([dic['fidd']]) + exp = """ {} = '{}' """.format(dic['field'], dic['id']) + # 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]) elif dic["type"] == 'pie': exp = """ "{}" = '{}' """.format(dic['field'], dic['label']) # set the iterator with the expression as filter in feature request