echarts containLabel do not work on the horizontal axis label

ltqd579y  于 2022-11-13  发布在  Echarts
关注(0)|答案(4)|浏览(248)

Version

4.5.0

Steps to reproduce

var dd =  new Date();
var oneDay = 3600 * 24 * 1000 * 1000;
var data = [];
for (var i = 0; i < 20; i  ) {
    data.push([
        dd, i % 3 ? 10 : 20
    ]);
    dd  = oneDay;
}

var option = {
    backgroundColor: '#fff',
    toolbox: {
        feature: {
            brush: {}
        }
    },
    grid: {
        containLabel: true,
        right: 5
    },
    xAxis: {
        type: 'time',
        axisLabel: {
            formatter: function (value) {
                return echarts.format.formatTime('yyyy-MM-dd', value);
            }
        }
    },
    yAxis: {},
    series: {
        type: 'line',
        data: data
    }
};

What is expected?

Do not cut the right label.

What is actually happening?

The right most label is cut.

ni65a41a

ni65a41a1#

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 you have posted enough image to demo your request. 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 dev@echarts.apache.org . Please attach the issue link if it's a technical questions.

If you are interested in the project, you may also subscribe our mail list .

Have a nice day! 🍵

sxissh06

sxissh063#

still actual. My main version is 4.9, but also checked in examples sandbox of v5x - same.
It seems like for X axis it calculates bottom space, and for Y left one. So when X labels go out of X axis dimension - not included in calculation.

import { graphic } from 'echarts/lib/export';
import { estimateLabelUnionRect, makeLabelFormatter } from 'echarts/lib/coord/axisHelper';

rotateTextRect(textRect, rotate) {
    const rotateRadians = rotate * Math.PI / 180;
    const boundingBox = textRect.plain();
    const beforeWidth = boundingBox.width;
    const beforeHeight = boundingBox.height;
    const afterWidth = beforeWidth * Math.cos(rotateRadians) + beforeHeight * Math.sin(rotateRadians);
    const afterHeight = beforeWidth * Math.sin(rotateRadians) + beforeHeight * Math.cos(rotateRadians);

    return new graphic.BoundingRect(boundingBox.x, boundingBox.y, afterWidth, afterHeight);
}

function reFit(chart, ret = false) {
    const model = chart.getModel();
    const x = model.getComponent('xAxis');
    const y = model.getComponent('yAxis');
    if(x === undefined){
        return;
    }
    const xAxis = x.axis;
    const yAxis = y.axis;
    const gridModel = model.getComponent('grid');

    if(!gridModel || (!gridModel.option.containLabel && !ret)){
        return;
    }

    const yLabelUnionRect = estimateLabelUnionRect(yAxis);
    const yWidth = yLabelUnionRect ? yLabelUnionRect.width : 0;

    const axisLabelModel = xAxis.getLabelModel();
    const labelFormatter = makeLabelFormatter(xAxis);

    const xAxisTickes = x.axis.getTicksCoords();
    const xAxisRealTickes = x.axis.scale.getTicks();
    const firstRealTick = xAxisRealTickes[x.option.inverse ? xAxisRealTickes.length - 1 : 0];
    const firstTick = xAxisTickes.find(t => t.tickValue === firstRealTick);
    const label = labelFormatter(firstTick.tickValue);
    const unrotatedSingleRect = axisLabelModel.getTextRect(label);
    const singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0);
    const needToFit = singleRect.width - firstTick.coord;
    const ySpace = Math.max(needToFit - yWidth, yWidth);
    if(ret){
        return ySpace;
    }
    chart.setOption({
        grid: {
            left: ySpace
        }
    })
}

This is my adhoc solution.

相关问题