Open jbadilla opened 6 years ago
sorry, I don't quite understand what you mean, can you show me the ECharts option and the effect picture you want.
Certainly! I have included the option in the original post.
Explanation: I would like for the x-axis and y-axis names to be set based on the 'rotate' value of the axisLabel property inside xAxis and yAxis.
Justification: This is because sometimes the yAxis or xAxis labels overlaps with the yAxis or xAxis name. This is visually unpleasant, and it should be a standard feature that it automatically sets xAxis.nameGap and yAxis.nameGap so that it is not being overlapped by the axis labels.
How it should look:
Do you mean that you want to rotate the axis name or where do you want to place it? Sorry I didn't quite follow.
Here is how echarts behaves by default:
Here's how it should behave:
This has to be done by setting the xAxis.nameGap property to something reasonable
Currenly containLabel
only considered axis labels, but not consider axis name.
@jbadilla
This axis lable is visually unpleasant because the default nameGap
is 0
.
Another issue #9286 gave a related situation that the axis name might overflow the rendering area.
To make the layout wisely, I think two enhancements can be taken into accout (and the two enhancement might be independent with each other in implementation):
Keep the current behaviors of nameLocation
and nameGap
, and add a new option nameLocationAdjust
(or some likely name), which enable axis name to be auto adjusted to avoid interfering with axis labels and overflow the viewport, following the strategy below:
Procedure X:
Layout axis name by the given nameLoation
and nameGap
, and then adjust it to avoid interfering with axis labels. Finally the relative location of axis name with axis line get. Detailedly, in this case, nameGap
is not the gap with axis line any more, but actually is the gap with the bounding rect of both axis line and axis labels.
Procedure X will be executed twices if containLabel
is set, the same as current implementation:
Procedure Y:
Ajust the axis name to avoid overflowing the viewport (if it makes the axis name interfere with axis labels again, leave them there). Notice the overflow also need to be taken into account when nameLocation
is start
or end
, like #9286 issued, which enables that when two cartesian exists axes align with each other without dynamic axis names overflow.
Procedure Y is only be executed in the "cartesian rendering stage", after Procedure X executed.
containLabel
Currently containLabel
has considdered axis label (and rotation). We should make it take into account the located axis name also, whatever the (A) is implemented or not.
But the logic looks not neat, a little complecated :(
What do you think @pissang
Currently, is there any workaround?
The workaround was offered in @100pah 's answer.
That being said, the 'nameGap' property is – in my opinion – flawed, because the property should not really exist. Rather, the 'nameGap' should be calculated internally, taking into account the length of the 'xAxis.axisLabels' and 'yAxis.axisLabels', as well as the 'rotate' property, which says how much labels should be rotated.
Any ideas?
@jbadilla Thanks for answers, but how can I get yAxis.axisLabels
? Is there any api?
Hi @sunzy0212 ! Sorry I hadn't answered in a while; I've been neglecting this issue in my code, and have implemented a messy (albeit temporarily) solution so I could move on.
You should already have access to your categorical labels outside of echarts (e.g. in the data you use to build the chart). alternatively, you can use the echartsInstance
object getOption
function: https://ecomfe.github.io/echarts-doc/public/en/api.html#echartsInstance.getOption
Like @100pah says, the problem is not only the axis labels but also the viewport.
I will spend some time on this today
@100pah @pissang any news? do you expect to push a fix for this anytime soon?
I have the same problem, most of the problems can be solved by calculating nameGap externally, but when yAxis is the category axis, and the categories are very large, echarts will perform display optimization according to interval: 'auto'
, but we have no way to get which labels will eventually be displayed, which can cause problems with our final nameGap calculations.
I have the same problem, most of the problems can be solved by calculating nameGap externally, but when yAxis is the category axis, and the categories are very large, echarts will perform display optimization according to
interval: 'auto'
, but we have no way to get which labels will eventually be displayed, which can cause problems with our final nameGap calculations.
After reviewing the source code related to the axis, I finally found the way to get the viewLabels in the instance of echarts!
Hello I just came across this problem in a project I am working on and was wondering the progress for a solution to the nameGap issue?
Is there any fix/workaround for this issue? In my case if nameGap set with static value it overlap once yAxis data reaches to 4 digit. and yAxis name overlap over ticks
@AbhaysinghBhosale
https://github.com/apache/incubator-echarts/issues/9265#issuecomment-536500226
use the axis.getViewLabel
and calculate these labels's dom width, then you get a nameGap...
After 3 years, this problem is still relevant. Is there still hope that it will be fixed?
Either nameGap is set too high and the text disappears to the left, or it is set too low and overlaps with the numbers on the Y-axis.
Would be great if you could fix this.
Seems like proposed pull request will fix it. Any ideas if it will be merged at some point?
@pissang has this been fixed in the any version of Chart.js
Changed calculated label gap to be passed from top #16825
There is a PR #16825 under review.
Any news?
在echarts实例setOption后调用下述方法可暂时解决此问题
/**
* 修复Y轴名称间隔问题(Y轴名称与Y轴刻度标签重叠问题)
* @param {EChartsType} chartInstance
*/
export function fixYAxisNameGap(chartInstance) {
const globalModel = chartInstance._api.getModel()
const yAxisList = globalModel.option.yAxis
const ctx = document.createElement('canvas').getContext('2d')
const nameGapList = []
// 兼容多Y轴
yAxisList.forEach(({ nameTextStyle, axisLabel }, index) => {
const fontSize = nameTextStyle?.fontSize ?? 12
const fontFamily = nameTextStyle?.fontFamily ?? 'sans-serif'
ctx.save()
ctx.font = `${fontSize}px ${fontFamily}`
const yAxis = globalModel.getComponent('yAxis', index)?.axis
// 计算刻度标签文字最大宽度
const labelMaxWidth = Math.max(...yAxis.getViewLabels().map(item => ctx.measureText(item.formattedLabel).width))
const axisLabelMargin = axisLabel?.margin ?? 8
nameGapList.push(labelMaxWidth + axisLabelMargin + 5)
ctx.restore()
})
chartInstance.setOption({
yAxis: nameGapList.map(nameGap => ({ nameGap }))
})
}
Is above PR will resolve this issue? If yes when can we expect it’s going to live?
xAxis.nameGap and yAxis.nameGap should be set automatically given grid.containLabel; this would provide the user with an easy way to display his/her axis name in a way that it doesn't visually interfere with the axis labels
One-line summary [问题简述]
Version & Environment [版本及环境]
Expected behaviour [期望结果]
When containLabel is selected, and a name for the xAxis or the yAxis has been specified, these should always fit on the graph's rendering, taking into account the 'rotate' property of the axis labels.
ECharts option [ECharts配置项]
if:
then:
Other comments [其他信息]