echarts
echarts copied to clipboard
Prevent overlapping elements
Version
5.2.0
Reproduction link
https://codepen.io/ataft/pen/dyWxpyG
Steps to reproduce
There are many open issues where various elements are overlapping with each other. Axis names overlap with axis labels, the legend and grid overlap, axis labels are cut, timeline overlaps with axis, etc. This makes it very difficult to manually set grid top/bottom/left/right, axis nameGap, legend location, top/bottom/left/right for non-grid series (e.g. pie), and separate non-series top/bottom/left/right settings (e.g. parallel).
Here are some of the open issues that highlight the problem:
Axis names overlap with axis labels https://github.com/apache/echarts/issues/9265 https://github.com/apache/echarts/issues/14996
Legend and Grid overlap https://github.com/apache/echarts/issues/14252 https://github.com/apache/echarts/issues/14724
Axis Labels cut off https://github.com/apache/echarts/issues/15562
Label overlap in scatterplot https://github.com/apache/echarts/issues/15509
What is expected?
Elements are sized appropriately based on positions
What is actually happening?
Elements overlap
Hi! We've received your issue and please be patient to get responded. 🎉 The average response time is expected to be within one day for weekdays.
In the meanwhile, please make sure that it contains a minimum reproducible demo and necessary images to illustrate. Otherwise, our committers will ask you to do so.
A minimum reproducible demo should contain as little data and components as possible but can still illustrate your problem. This is the best way for us to reproduce it and solve the problem faster.
You may also check out the API and chart option to get the answer.
If you don't get helped for a long time (over a week) or have an urgent question to ask, you may also send an email to [email protected]. Please attach the issue link if it's a technical question.
If you are interested in the project, you may also subscribe to our mailing list.
Have a nice day! 🍵
scatter data label
<div id="container" style="width: 640px; height: 400px"></div>
option = {
tooltip: {
trigger: 'item',
borderWidth: 0
},
legend: { show: true, bottom: 0, itemHeight: 8, itemWidth: 8 },
grid: { left: 16, right: 32, top: 32, bottom: 32, containLabel: true },
yAxis: {
type: 'value',
axisLine: { show: true, onZero: false },
splitLine: { show: false },
axisTick: { show: true }
},
xAxis: {
type: 'value',
axisLine: { onZero: false },
splitLine: { show: false },
axisTick: { show: true }
},
series: [
{
type: 'scatter',
name: '2021-06-15',
symbolSize: 8,
data: [
{
value: [0.41, 0.49],
name: '林业'
},
{
value: [0.97, 0.96],
name: '农产品加工'
},
{
value: [0.66, 0.69],
name: '农业综合'
},
{
value: [0.39, 0.55],
name: '饲料'
},
{
value: [0.31, 0.18],
name: '渔业'
},
{
value: [0.67, 0.69],
name: '种植业'
},
{
value: [0.92, 0.96],
name: '畜禽养殖'
},
{
value: [0.33, 0.44],
name: '动物保健'
}
],
label: {
position: 'right',
show: true,
formatter: params => params.name
},
labelLayout: { hideOverlap: true, dy: 10 }
}
]
};
codepen: https://codepen.io/eeeqxxtg/pen/WNOxbEm
It's a very general topic that we keep working on for years. Currently, https://github.com/apache/echarts/pull/15510 is working on the label auto layout on the charts like scatter. And components overlap is in our plan, we are still finding out a solution that is good enough for echarts.
What is expected? Elements are sized appropriately based on positions
We shouldn't expect this to happen all the times.
In my case, even when there is enough space there is overlapping. See below
When there is enough space, they should be autopositioned like HTML elements in html page. (when you add two span tags in html they will appear next to each other, when you add two paragraph tags they appear one below other, block and inline).
Hi guys! Diving deep into legend & grid overlapping issue got this finally working.
This approach is not much tested and should have a lot of pitfalls. The solution I found is based on linear relationship of legend and Grid area (I found it some confusing).
Works for legend at the bottom of grid. Not tested for other layouts. Here awesomeID
is a legend id.
const legendY = echartsInstance._componentsMap["_ec_awesomeID_legend.plain"].group.y;
const gridHeight = echartsInstance._coordSysMgr._coordinateSystems[0]._rect.height;
const gridY = echartsInstance._coordSysMgr._coordinateSystems[0]._rect.y;
const gridVerticalOffset = gridHeight - gridY - (legendY - SOMECONSTANTVALUE);
setOption({
grid: {
bottom: gridVerticalOffset
}
});
Don't know why, but SOMECONSTANTVALUE = 80
works great for me with any chart width and any level of legend overlapping.
In my case I want the legend at the top to not overflow the grid.
The solution from @Houstoten didn't work for me as accessing anything from the _componentsMap
was always returning undefined.
I was able to come up with this hack:
const found = echartsInstance._componentsViews.find((entry) => entry.type === 'legend.plain');
const legendHeight = found._backgroundEl.shape.height;
if (legendHeight) {
echartsInstance.setOption({
grid: {
top: legendHeight + 20,
},
});
}
@Ovilia I saw some of your comments in other related issues about you having internal discussing on how to solve this. Are there any updates on this ?
Perhaps this could be resolved by implementing something similar to flexbox. Right now unfortunately, my legends are always overlapping my x-axis labels at certain breakpoints and I can't do anything about it. Would appreciate solutions!
I'm not sure how to make it automatically avoid overlapping because all components (grid, legend, title, and etc.) use absoulute positions (left, right, top, bottom, width, height) and we cannot just move some components to elsewhere if overlap happens.
@Ovilia That makes perfect sense 👍 Is there an example of how we can access the main (legend, grid) elements position and size via the echarts instance so we can resolve the overlap on our side ? I could only find that information by accessing private properties which isn't reliable.
If you set these positions like grid.left/right/top/bottom/width/height
, you can keep a reference to your option and get that value. Or, you can use chart.getOptions()
to get the merged options with default values and get the values actually being used.
This open PR that offers new nameLocation properties ('outsideStart', 'outsideMiddle', 'outsideEnd') would help with some of the screenshots above. It seems like it's very close to being ready to merge, but the author hasn't responded recently, I could potentially address the remaining comments and open a new PR?
Any updates on this issue? It's really annoying
I'm not sure how to make it automatically avoid overlapping because all components (grid, legend, title, and etc.) use absoulute positions (left, right, top, bottom, width, height) and we cannot just move some components to elsewhere if overlap happens.
The indirect approach of competitors to avoid overlapping data labels, for reference(https://github.com/apache/echarts/issues/18780).