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引发重绘导致悬浮文字不显示

相关推荐
Book_熬夜!14 小时前
Python基础(六)——PyEcharts数据可视化初级版
开发语言·python·信息可视化·echarts·数据可视化
范特西是只猫2 天前
echarts 自定义标注样式&自定义tooltip弹窗样式
前端·javascript·echarts
范特西是只猫2 天前
echarts map地图动态下钻,自定义标注,自定义tooltip弹窗【完整demo版本】
前端·javascript·echarts
人工智能的苟富贵2 天前
微信小程序中实现类似于 ECharts 的图表渲染及优化
微信小程序·小程序·echarts
GHUIJS3 天前
【Echarts】vue3打开echarts的正确方式
前端·vue.js·echarts·数据可视化
Peanuts.3 天前
VUE使用echarts编写甘特图(组件)
开发语言·javascript·echarts
GHUIJS6 天前
【Echarts】使用多横坐标轴展示近十五天天气预报
javascript·echarts
暖锋丫6 天前
echarts实现湖南省地图并且定时轮询
前端·javascript·echarts
时光匆匆岁月荏苒,转眼我们已不是当年7 天前
【前端echarts】echarts双饼图与easyui列表联动
前端·echarts·easyui
SnowMan19938 天前
高级 ECharts 技巧:自定义图表主题与样式
信息可视化·数据分析·echarts