fix: legend visual still with decal when user set 'legend.itemStyle.decal' to 'none'#16922
Conversation
|
Thanks for your contribution! |
| ['lineJoin', 'borderJoin'], | ||
| ['miterLimit', 'borderMiterLimit'] | ||
| ['miterLimit', 'borderMiterLimit'], | ||
| ['decal'] |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
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.
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.
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.
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.
api will be given in the render method
echarts/src/component/legend/LegendView.ts
Line 100 in 72f4c41
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.
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.decalis 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.decalset by users.By checking whether user sets
legend.itemstyle.decaltonone, we decide whetherdecalshould be overwritten by series itemStyle.Misc
Related test cases or examples to use the new APIs
N.A.
Others
Merging options
Other information