Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions DataPlotly/core/plot_expressions.py
Original file line number Diff line number Diff line change
@@ -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.
<h4>Syntax</h4>
<p>
get_categories_colors(categorization_field)
</p>
<h4>Arguments</h4>
<p><strong>categorization_field</strong>: the name of the field used in the categorization</p>
<h4>Example</h4>
<p>
get_categories_colors("CONTINENT") -> '#da1ddd'
</p>
"""

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
8 changes: 4 additions & 4 deletions DataPlotly/core/plot_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
11 changes: 10 additions & 1 deletion DataPlotly/data_plotly.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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."""
Expand Down Expand Up @@ -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)
Expand All @@ -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. """
Expand Down
15 changes: 12 additions & 3 deletions DataPlotly/gui/plot_settings_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange, I can't do code suggestion ...

exp = QgsExpression.createFieldEqualityExpression(dic['field'], dic['id'])
self.layer_combo.currentLayer().selectByExpression(exp)

This function createFieldEqualityExpression will manage if dic['id'] is integer or string for instance instance. I'm don't know what is the value

It's possible to make a selection straight from a expression string

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmmm.. ok then we can stick with this patch. What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you want to stick to the current patch ?

You can make your code easier :
L484, L486 and L495 by using selectByExpression instead of selectByIds and having to create a loop.
getFeatures is not very efficient, even if you use a QgsFeatureRequest if you don't specify just the fields you need (ID in your example). You can read the blogpost https://nyalldawson.net/2016/10/speeding-up-your-pyqgis-scripts/

# 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
Expand Down