New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] create_ramp() expression function #4632
Conversation
@nyalldawson , review appreciated. |
Here's a practical example that can be achieved with this new function: graduate a polygon fill based on a numerical field against the field's maximum value: |
Looks good to me! My only thought - having a single function for both creation of the ramp AND retrieving a color from it is going to be inefficient for large number of calculations. If the functions were instead split into two separate functions then the ramp creation function would be considered static and compiled once (thanks for @m-kuhn's recent optimisations), meaning only one ramp creation instead of 1000s... |
@nyalldawson , yeah , I thought of that too, but initially I was not warm to the idea of introducing a new type of returned value in the expression engine (ie, a "ramp" value/object). |
I understand that. However - there's also a good benefit of having ramps as a datatype. At the moment if you use the color property assistant and set a property to get its value from a custom ramp, there's no way to map this across to an expression function. We need some way to store custom ramps in expression functions to allow this. So this change would also benefit that use case... |
@nyalldawson , OK, following your request, I've updated this PR to allow for creation of ramps within the expression engine. The create_ramp() function creates a ramp, which can be used by the pre-existing ramp_color(). The latter was updated to take as its first parameter a ramp object in addition to a saved ramp name string. The create_ramp() has two parameters: a required map() parameter, and an optional discrete boolean. This allows us to re-create all variants of the QgsGradientColorRamp ramp type. For e.g.:
This practical example shows how a user can retrieve a color for a expression-created ramp: The above would return '128,0,0,255'. |
const QgsColorRamp *mRamp = QgsStyle::defaultStyle()->colorRampRef( rampName ); | ||
if ( ! mRamp ) | ||
QgsGradientColorRamp expRamp; | ||
const QgsColorRamp *mRamp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be just ramp, not mRamp
if ( ! mRamp ) | ||
{ | ||
parent->setEvalErrorString( QObject::tr( "\"%1\" is not a valid color ramp" ).arg( rampName ) ); | ||
return QColor( 0, 0, 0 ).name(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is odd - i think it should return QVariant() instead
tests/src/core/testqgsexpression.cpp
Outdated
@@ -1010,6 +1010,8 @@ class TestQgsExpression: public QObject | |||
|
|||
// Color functions | |||
QTest::newRow( "ramp color" ) << "ramp_color('Spectral',0.3)" << false << QVariant( "254,190,116,255" ); | |||
QTest::newRow( "create ramp color, two colors" ) << "ramp_color(create_ramp(map('0,0,0','255,0,0')),0.33)" << false << QVariant( "84,0,0,255" ); | |||
QTest::newRow( "create ramp color, three colors" ) << "ramp_color(create_ramp(map('0,0,0','0,255,0','0,0,255','255,0,0')),0.5)" << false << QVariant( "0,127,128,255" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need some tests here for bad parameters - e.g. 0 stops, 1 stop, non-map values
Looks good! Just some minor suggestions. Also - should we explicitly say that this is a gradient ramp creator, in case we want to allow random/etc ramp creation functions in future? |
@nyalldawson , as in updating the function name or adding a note in the documentation? |
I think just documentation |
5e9d9ac
to
f7e78ee
Compare
@nyalldawson , your comments were all addressed. Thanks |
{ | ||
"name": "create_ramp", | ||
"type": "function", | ||
"description": "Returns a gradient ramp from a an map of color strings and steps.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a an map
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oups, used to be an array -- thanks for spotting this.
|
||
// If we get here then we can't convert so we just error and return invalid. | ||
if ( report_error ) | ||
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1' to QgsGradientColorRamp" ).arg( value.toString() ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would the end user understand what QgsGradientColorRamp is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DelazJ , trying to stick to what was established elsewhere (see getGeometry(), getFeature()).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should be fixed too - we shouldn't expose the class names to users. By the way - QgsExpression::formatPreviewString will need to be updated to show ramps too.
@DelazJ , QgsGradientColorRamp renamed to "gradient ramp". @nyalldawson , QgsExpression::formatPreviewString updated, thanks for pointing this out. |
Description
This PR adds a useful expression function to create color ramps from scratch. It can be quite useful when a project in shared among many users as it does not rely on the presence of a saved ramp (let alone having that ramp having the same colors).
It's also simply useful to be able to quickly create ramps within expressions 馃槃
Checklist
fixes #11111
in the commit message next to the description[FEATURE]
in the commit message[needs-docs]
in the commit message and containt sufficient information in the commit message to be documentedscripts/prepare-commit.sh
script before each commit