Ecahrts.toolbox 图标自定义

echars.toolbox 除了各个内置的工具按钮外,还可以自定义工具按钮,每个工具按钮都可以通过icon自定义展示图标,同时配置iconStyle设置图标样式。

icon 选项

  • 可以通过 'image://url' 设置为图片,其中 URL 为图片的链接,或者 dataURI

    • URL 为图片链接例如:
    rust 复制代码
    'image://http://example.website/a/b.png'
    • URL 为 dataURI 例如:
    rust 复制代码
    'image://data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'
  • 可以通过 'path://' 将图标设置为任意的矢量路径。这种方式相比于使用图片的方式,不用担心因为缩放而产生锯齿或模糊,而且可以设置为任意颜色。路径图形会自适应调整为合适的大小。路径的格式参见 SVG PathData。可以从 Adobe Illustrator 等工具编辑导出。

rust 复制代码
'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z'

缺点:只能设置线性图标-无背景

iconStyle 选项

配置过的都知道,只能配置线性图标颜色或者阴影(基本少用),无法添加背景色,只能设置简单的线性图标按钮样式。

如果我们的设计稿是实现这样的图标,那该如何处理?

思路

  1. 通过你所掌握的任意绘图工具,获得对应图标的 image://[url]image://[dataURI] 链接,通过 icon 选项配置得到自定义图标

通过 image:// 格式指定的自定义图标,会有尺寸缩放问题,所以需要稍微调整实际尺寸。

例子通过 svg + btoa 获取一个dataURI:

arduino 复制代码
const customIconSVG = `<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><rect x="0" y="0" width="30" height="30" rx="5" fill="#F7F7F7" /><polyline points="10 13 15 18 20 13" fill="black" /><line x1="15" y1="13" x2="15" y2="5" stroke="black" stroke-width="2" stroke-linecap="round" /><line x1="6" y1="23" x2="24" y2="23" stroke="black" stroke-width="2" stroke-linecap="round" /></svg>`

const iconDataURI = 'data:image/svg+xml;base64,' + btoa(customIconSVG);
// data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIgdmlld0JveD0iMCAwIDMwIDMwIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMzAiIGhlaWdodD0iMzAiIHJ4PSI1IiBmaWxsPSIjRjdGN0Y3IiAvPjxwb2x5bGluZSBwb2ludHM9IjEwIDEzIDE1IDE4IDIwIDEzIiBmaWxsPSJibGFjayIgLz48bGluZSB4MT0iMTUiIHkxPSIxMyIgeDI9IjE1IiB5Mj0iNSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIC8+PGxpbmUgeDE9IjYiIHkxPSIyMyIgeDI9IjI0IiB5Mj0iMjMiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiAvPjwvc3ZnPg==
  1. 定义每个图标的普通状态icon和悬浮状态icon
js 复制代码
// 定义每个图标的普通状态和鼠标悬浮状态的路径
const iconInfo = {
    save: {
        normal: 'image://data:image/png;base64,XXXXX', // 保存图标的普通状态路径
        hover: 'image://data:image/png;base64,YYYYY' // 保存图标的鼠标悬浮状态路径
    },
    dataZoom: {
        normal: 'image://data:image/png;base64,AAAAA', // 数据区域缩放图标的普通状态路径
        hover: 'image://data:image/png;base64,BBBBB' // 数据区域缩放图标的鼠标悬浮状态路径
    },
    // 其他图标的普通状态和鼠标悬浮状态路径 // ...
};
  1. 声明echart实例
js 复制代码
const option = {
    // ...
    toolbox: {
        feature: {
            saveAsImage: {
                icon: iconInfo.save.normal, // 保存图标的普通状态路径
            },
            dataZoom: {
                icon: iconInfo.dataZoom.normal, // 数据区域缩放图标的普通状态路径
            }
            // 其他图标的配置
        },
        // ...
   }
   // ...
};
  1. 最后通过echart实例监听鼠标 mousemove 事件,通过 echartInstance.containPixel api判断鼠标位置,如果是toolbox对应图标,则进行图标替换:
js 复制代码
myChart.getZr().on('mousemove', function (params) {
    var pointInPixel = [params.offsetX, params.offsetY];
    for (var key in iconInfo) {
        if (myChart.containPixel('toolbox', pointInPixel, {icon: key})) {
            // 根据图标名称切换图标显示
            myChart.dispatchAction({
                type: 'updateAxisPointer',
                axisPointer: {
                    toolboxIcon: iconInfo[key].hover // 切换为鼠标悬浮状态的图标
                }
            });
        } else {
            // 鼠标不在该图标区域内,恢复普通状态的图标
            myChart.dispatchAction({
                type: 'updateAxisPointer',
                axisPointer: {
                    toolboxIcon: iconInfo[key].normal // 恢复为普通状态的图标
                }
            });
        }
   }
});

最终实现

js 复制代码
var customIconSVG = `<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><rect x="0" y="0" width="30" height="30" rx="5" fill="#F7F7F7" /><polyline points="10 13 15 18 20 13" fill="black" /><line x1="15" y1="13" x2="15" y2="5" stroke="black" stroke-width="2" stroke-linecap="round" /><line x1="6" y1="23" x2="24" y2="23" stroke="black" stroke-width="2" stroke-linecap="round" /></svg>`;


var customIconHoverSVG = `<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><rect x="0" y="0" width="30" height="30" rx="5" fill="#3D97D0" /><polyline points="10 13 15 18 20 13" fill="white" /><line x1="15" y1="13" x2="15" y2="5" stroke="white" stroke-width="2" stroke-linecap="round" /><line x1="6" y1="23" x2="24" y2="23" stroke="white" stroke-width="2" stroke-linecap="round" /></svg>`;

// 自定义图标
var iconInfo = {
    saveAsImage: {
        normal: 'image://data:image/svg+xml;base64,' + btoa(customIconSVG), // 保存图标的普通状态路径
        hover: 'image://data:image/svg+xml;base64,' + btoa(customIconHoverSVG), // 保存图标的鼠标悬浮状态路径
    }
};

// 配置项
option = {
   // ...
  toolbox: {
    feature: {
      saveAsImage: {
        title: 'Save as image', // 基于title值进行判断
        icon: iconInfo.saveAsImage.normal
      }
    }
  },
   // ...
};

// 事件监听
// 不同版本echarts实现方式有差异
myChart.getZr().on('mousemove', function (params) {
    var pointInPixel = [params.offsetX, params.offsetY];
    if (params.topTarget && params.topTarget.__title === 'Save as image') { // 基于title值进行判断
        // 鼠标悬浮在保存图标区域内,切换图标显示
        option.toolbox.feature.saveAsImage.icon = iconInfo.saveAsImage.hover; // 切换为鼠标悬浮状态的图标
        myChart.setOption(option);
    } else {
        // 鼠标不在保存图标区域内,恢复普通状态的图标
        option.toolbox.feature.saveAsImage.icon = iconInfo.saveAsImage.normal; // 恢复为普通状态的图标
        myChart.setOption(option);
    }
});

normal:

hover:

注:不同版本ecahrts监听鼠标移动到toolbox有差异

注:setOption引发重绘导致悬浮文字不显示

相关推荐
不修×蝙蝠6 小时前
ECharts折线图背景渐变设置
echarts·基础·背景·颜色渐变
AIoT科技物语2 天前
免费,基于React + ECharts 国产开源 IoT 物联网 Web 可视化数据大屏
前端·物联网·react.js·开源·echarts
橙某人2 天前
📊基于Vue对Echarts5进行基础封装-按需引入
前端·vue.js·echarts
摇头的金丝猴2 天前
uniapp vue3 使用echarts-gl 绘画3d图表
前端·uni-app·echarts
暴富的im3 天前
Vue中使用echarts生成地图步骤详解
javascript·vue.js·echarts
麦麦大数据3 天前
vue+django+neo4j航班智能问答知识图谱可视化系统
django·vue·echarts·neo4j·智能问答·ltp·航班
莫问alicia4 天前
echarts 实现3D饼状图 加 label标签显示
前端·3d·echarts·swift
左&耳7 天前
echarts-for-react和echarts连用实现地图下钻,上钻以及图层
react.js·echarts
一行注释8 天前
echarts属性之title
前端·javascript·echarts
偷光9 天前
React 中使用 Echarts
前端·react.js·echarts