apache / echarts

Apache ECharts is a powerful, interactive charting and data visualization library for browser
https://echarts.apache.org
Apache License 2.0
60.69k stars 19.62k forks source link

如何在一条线段上,根据类别的不同,使用不用的颜色渲染线条的不同部分?目前官网示例,只有根据y轴的值范围来确定颜色的示例 #20469

Closed LK007CX closed 2 weeks ago

LK007CX commented 3 weeks ago

Version

4.9.0

Link to Minimal Reproduction

https://echarts.apache.org/examples/zh/editor.html?c=line-sections

Steps to Reproduce

这是我的代码的最小demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ECharts Example</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.3/echarts.min.js"></script>
    <style>
        #main {
            width: 600px;
            height: 400px;
        }
    </style>
</head>
<body>
<div id="main"></div>
<script>
    const myChart = echarts.init(document.getElementById('main'));

    option = {
        title: {
            text: 'Distribution of Electricity',
            subtext: 'Fake Data'
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'cross'
            }
        },
        toolbox: {
            show: true,
            feature: {
                saveAsImage: {}
            }
        },
        xAxis: {
            type: 'category',
            boundaryGap: false,
            // prettier-ignore
            data: ['00:00', '01:15', '02:30', '03:45'  ]
        },
        yAxis: {
            type: 'value',
            axisLabel: {
                formatter: '{value} W'
            },
            axisPointer: {
                snap: true
            }
        },
        visualMap: {
            show: false,
            dimension: 1,
            categories: ['1', '2', '3', '4'],
            inRange: {
                color: ['red', 'blue', 'yellow', 'black']
            },
            outOfRange: {
                color: 'green'
            }
        },
        series: [
            {
                name: 'Electricity',
                type: 'line',
                smooth: true,
                // prettier-ignore
                data: [[100, "1"],
                    [200, "2"],
                    [300, "3"],
                    [400, "4"]]
            }
        ]
    };

    myChart.setOption(option);
</script>
</body>
</html>

Current Behavior

目前这段代码,报错信息为: echarts.min.js:45 Uncaught TypeError: Cannot read properties of undefined (reading 'coord') at gS (echarts.min.js:45:338543) at e.render (echarts.min.js:45:341108) at t.progress (echarts.min.js:45:166893) at t._doProgress (echarts.min.js:45:135412) at t.perform (echarts.min.js:45:134984) at echarts.min.js:45:216047 at e. (echarts.min.js:45:116287) at Array.forEach () at E (echarts.min.js:35:5071) at e.eachSeries (echarts.min.js:45:116207)

Expected Behavior

我想根据不同的类别(类别1,类别2...),去设置当前线条,不同区域的颜色,比如类别1对应红色,如何修复这段代码?

Environment

- OS: win10
- Browser: chrome
- Framework: js echarts

Any additional comments?

No response

echarts-bot[bot] commented 3 weeks ago

@LK007CX It seems you are not using English, I've helped translate the content automatically. To make your issue understood by more people and get helped, we'd like to suggest using English next time. 🤗

TRANSLATED
**TITLE** How do I render different parts of a line on a line, depending on the category, with different colors? At present, there is only an example of determining the color according to the value range of the y-axis
Ovilia commented 3 weeks ago

类别是 y 值还是什么?理论上只有点(itemStyle)有数据,线段(lineStyle)对应两个数据,很难说对应什么

Jefy-Wang commented 2 weeks ago

https://jsfiddle.net/q5hvkL9n/3/

image

这样满足诉求吗

LK007CX commented 2 weeks ago

这样貌似不行。 我假设的是,每个y轴的数据,包含2个字段,数值和类别,我需要根据类别的不同(类别1、类别2、类别3、类别4)去判断线条的颜色,而不是看数值的取值范围。

helgasoft commented 2 weeks ago

line segment coloring by data categories - Demo see also #19270 and #17138

LK007CX commented 2 weeks ago

谢谢你们的帮助,这是我最后需要的东西

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <title>ECharts Example</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.3/echarts.min.js"></script>
    <style>
        #main {
            width: 600px;
            height: 400px;
        }
    </style>
</head>
<body>
<div id="main"></div>
<script>
    // ref page
    // https://echarts.apache.org/zh/tutorial.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B3%BB%E5%88%97
    const myChart = echarts.init(document.getElementById('main'));

    /**
     * renderItem函数
     */
    function myRender(params, api) {
        // 获取当前数据点的索引
        let currentIndex = params.dataIndexInside;

        // 当前点的坐标
        // 这里使用 api.coord(...) 将数值在当前坐标系中转换成为屏幕上的点的像素值。
        let startPoint = api.coord([api.value(0, currentIndex), api.value(1, currentIndex)]);

        // 获取下一个数据点的坐标(确保不越界)
        let nextIndex = currentIndex + 1;
        let endPoint = nextIndex < data.length ? api.coord([api.value(0, nextIndex), api.value(1, nextIndex)]) : startPoint;

        // 获取颜色(根据类型选择红色或绿色)
        let color = api.value(2, currentIndex) === "高风险" ? "red" : "green";

        const child1 = {
            type: "line",
            shape: {
                x1: startPoint[0],
                y1: startPoint[1],
                x2: endPoint[0],
                y2: startPoint[1]
            },
            style: {stroke: color, lineWidth: 2}
        }

        const child2 = {
            type: "line",
            shape: {
                x1: endPoint[0],
                y1: startPoint[1],
                x2: endPoint[0],
                y2: endPoint[1]
            },
            style: {stroke: 'green', lineWidth: 2}
        }

        // 如果不是最后一个点,则返回一个 group 包含两个子元素
        if (nextIndex < data.length - 1) {
            // 创建一个 group 来包含多个元素
            // 返回整个 group 对象
            return {
                type: "group",  // 指定为 group 类型
                children: [
                    // 绘制第一个水平线段
                    child1,
                    // 绘制第二个垂直线段
                    child2
                ]
            };
        } else {
            // 绘制第一个水平线段
            return child1
        }
    }

    const data = [
        ['00:00', 100, "高风险"],
        ['01:15', 200, "一般风险"],
        ['02:30', 300, "高风险"],
        ['03:45', 400, "一般风险"]
    ];

    const option = {
        title: {
            text: 'Distribution of Electricity',
            subtext: 'Fake Data'
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'cross'
            }
        },
        toolbox: {
            show: true,
            feature: {
                saveAsImage: {}
            }
        },
        xAxis: {
            type: 'category',
        },
        yAxis: {
            type: 'value',
            axisLabel: {
                formatter: '{value} pcs'
            },
            axisPointer: {
                snap: true
            }
        },
        series: [
            {
                name: 'Electricity',
                type: 'custom',
                renderItem: myRender,
                data: data
            }
        ]
    };

    myChart.setOption(option);

</script>
</body>
</html>