-
Notifications
You must be signed in to change notification settings - Fork 19.6k
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: legend visual still with decal when user set 'legend.itemStyle.decal' to 'none' #16922
Conversation
Thanks for your contribution! |
src/model/mixin/itemStyle.ts
Outdated
@@ -35,7 +35,8 @@ export const ITEM_STYLE_KEY_MAP = [ | |||
['lineDashOffset', 'borderDashOffset'], | |||
['lineCap', 'borderCap'], | |||
['lineJoin', 'borderJoin'], | |||
['miterLimit', 'borderMiterLimit'] | |||
['miterLimit', 'borderMiterLimit'], | |||
['decal'] |
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 underlying method maps the itemStyle
in echarts to the style object in zrender.
But decal
in echarts is different with decal
in zrender. In echarts it's an object that describe how the decal looks like. But in zrender it's a image that rendered as pattern on top of the element. So we didn't include decal
here directly. Instead the decal property is created in
Line 44 in 4a52199
style.decal = createOrUpdatePatternFromDecal(decal, api); |
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.
Thank you for pointing it out. I agree I should use it to deal with interface decal
. But the problem is that I cannot find other function than
echarts/src/component/legend/LegendView.ts
Line 565 in 4a52199
const itemStyle = legendItemModel.getItemStyle(); |
to pick up attributes in
legend.itemStyle
.Since
getItemStyle()
will only pick the attributes in the list of ITEM_STYLE_KEY_MAP, the only other way I think is to directly visit the decal attribute level by level, which I think is not elegant enough. And it could be risky if we call a structure like legendItemModel.ecModel.option.legend[0].itemStyle.decal
, because if any structure in between does not exist or has changed, it could result in unstability. Is there any good one to pick the attribute decal
without adding it to the list of ITEM_STYLE_KEY_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.
Using Model#get
or Model#getShallow
is the best way to access the property in the option. getItemStyle
is also using Model#getShallow
at the bottom.
const val = model.getShallow(propName, ignoreParent); |
These two method works like optional chaining operator. Some examples:
// Get the itemStyle object in series.
seriesModel.get('itemStyle')
// Get itemStyle.color value in series. Similar to seriesModel.option?.itemStyle?.color
seriesModel.get(['itemStyle', 'color'])
The difference between Model#get
and Model#getShallow
is Model#get
will also consider cascading. If we didn't find itemStyle.color
in the data level, it will keep finding in the series level and global option level.
The difference between Model#get
and Model#getShallow
is Model#get
supports using array to get deep properties in object.
There is another method Model#getModel
will wrap a new model after getting the value:
const itemStyleModel = seriesModel.getModel('itemStyle');
// itemStyleModel is now in the itemStyle scope
const color = itemStyleModel.get('color');
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.
Thank you for your detailed explanation! My appreciate for your patience.
Now I use getShallow
to get decal
and use createOrUpdatePatternFromDecal
to deal with it. But one last thing is to get api
for createOrUpdatePatternFromDecal
, which I found to be at legendItemModel.ecModel.scheduler.api
. Is there a better way to access it?
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.
api
will be given in the render
method
echarts/src/component/legend/LegendView.ts
Line 100 in 72f4c41
render( |
You can pass it down to other methods if the method needs it.
BTW: I was wrong about Model#get
and Model#getShallow
. Just updated in the previous comment. get(path, false)
in your commited code is the way to ignore option cascading.
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.
Just updated the code. I think I used getShallow
in code and as I track the dataflow, it traces back to parent model if option is not found. So I think it works well in the code.
Congratulations! Your PR has been merged. Thanks for your contribution! 👍 |
Brief Information
This pull request is in the type of:
What does this PR do?
Fix the problem that the legend patterns are still with decals when user sets 'legend.itemStyle.decal' to 'none'.
Fixed issues
Details
Before: What was the problem?
As is described in #16909 (comment),
legend.itemStyle.decal
is directly overwritten by series itemStyle without checking if it's set to 'none' by user.After: How is it fixed in this PR?
By adding the 'decal' into the ITEM_STYLE_KEY_MAP, Echarts now can correctly read the value of
legend.itemstyle.decal
set by users.By checking whether user sets
legend.itemstyle.decal
tonone
, we decide whetherdecal
should be overwritten by series itemStyle.Misc
Related test cases or examples to use the new APIs
N.A.
Others
Merging options
Other information