如何在 Apache Echarts 中将图例项沿 x 轴居中?

问题描述 投票:0回答:1

我想将Echarts中的不同图例项居中对齐,而不是默认的左对齐。这可能吗?我在文档中找不到执行此操作的方法。

enter image description here

我正在使用堆叠水平栏的默认代码,您可以在此处找到

echarts apache-echarts
1个回答
0
投票

没有可以设置使图例项目居中的选项,这样 你想要的。项目按函数

boxLayout
排列, 布局.ts#L57 当当前行放不下某个项目时,将其添加到下一行 在
x = 0
,请参阅 layout.ts#L87

图表呈现后,可以重新排列图例项 图例(以及每个图表之后

resize
)但这是一个黑客解决方案 访问图表的未记录的内部结构可能 在库的未来版本中进行更改,恕不另行通知:

myChart.setOption(option);
centerLegendItems(myChart);

window.addEventListener('resize', ()=>{
    myChart.resize(); 
    centerLegendItems(myChart)
});

function centerLegendItems(chart){
    const legendView = Object.values(chart._componentsMap).find(view => view.type === 'legend.plain');
    const maxWidth = legendView.group.getBoundingRect().width;
    const legendItems = legendView.group._children.find(group => group._children.length > 0)._children;
    const nItems = legendItems.length;

    const positions = legendItems.map(group => ({x: group.x, y: group.y, width: group.getBoundingRect().width}));
    const lines = [];
    let line = [positions[0]];
    lines.push(line);
    for(let i = 1; i < nItems; i++){
        const position = positions[i];
        if(Math.abs(position.y - line[0].y) < 2){
            line.push(position);
        }
        else{
            line = [position];
            lines.push(line);
        }
    }
    const deltaX = [];
    for(const line of lines){
        const lastItem = line[line.length-1];
        const lineWidth = lastItem.x + lastItem.width;
        const deltaLine = (maxWidth - lineWidth) / 2;
        deltaX.push(...Array(line.length).fill(deltaLine));
    }
    for(let i = 0; i < nItems; i++){
        legendItems[i].x += deltaX[i];
    }
}

在带有示例图表的片段中:

const myChart = echarts.init(document.getElementById('main'));

const option = {
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow'
        }
    },
    legend: {
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    xAxis: {
        type: 'value'
    },
    yAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    series: [
        {
            name: 'Direct',
            type: 'bar',
            stack: 'total',
            label: {
                show: true
            },
            emphasis: {
                focus: 'series'
            },
            data: [320, 302, 301, 334, 390, 330, 320]
        },
        {
            name: 'Mail Ad',
            type: 'bar',
            stack: 'total',
            label: {
                show: true
            },
            emphasis: {
                focus: 'series'
            },
            data: [120, 132, 101, 134, 90, 230, 210]
        },
        {
            name: 'Affiliate Ad',
            type: 'bar',
            stack: 'total',
            label: {
                show: true
            },
            emphasis: {
                focus: 'series'
            },
            data: [220, 182, 191, 234, 290, 330, 310]
        },
        {
            name: 'Video Ad',
            type: 'bar',
            stack: 'total',
            label: {
                show: true
            },
            emphasis: {
                focus: 'series'
            },
            data: [150, 212, 201, 154, 190, 330, 410]
        },
        {
            name: 'Search Engine',
            type: 'bar',
            stack: 'total',
            label: {
                show: true
            },
            emphasis: {
                focus: 'series'
            },
            data: [820, 832, 901, 934, 1290, 1330, 1320]
        }
    ]
};

myChart.setOption(option);
centerLegendItems(myChart);

window.addEventListener('resize', ()=>{myChart.resize(); centerLegendItems(myChart)});

function centerLegendItems(chart){
    const legendView = Object.values(chart._componentsMap).find(view => view.type === 'legend.plain');
    const maxWidth = legendView.group.getBoundingRect().width;
    const legendItems = legendView.group._children.find(group => group._children.length > 0)._children;
    const nItems = legendItems.length;

    const positions = legendItems.map(group => ({x: group.x, y: group.y, width: group.getBoundingRect().width}));
    const lines = [];
    let line = [positions[0]];
    lines.push(line);
    for(let i = 1; i < nItems; i++){
        const position = positions[i];
        if(Math.abs(position.y - line[0].y) < 2){
            line.push(position);
        }
        else{
            line = [position];
            lines.push(line);
        }
    }
    const deltaX = [];
    for(const line of lines){
        const lastItem = line[line.length-1];
        const lineWidth = lastItem.x + lastItem.width;
        const deltaLine = (maxWidth - lineWidth) / 2;
        deltaX.push(...Array(line.length).fill(deltaLine));
    }
    for(let i = 0; i < nItems; i++){
        legendItems[i].x += deltaX[i];
    }
}
<div id='main' style='height: 300px'></div>
<script src="https://fastly.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.