ECharts散点图实现鼠标点击散点删除

1,278 阅读3分钟

前言

最近用 ECharts 绘制散点图的时候,有个需求就是能够通过交互来删除散点图中的某些点。在这个删除的过程中,需要弹出框提示,然后再点击按钮选择是否删除,接着就能够更新视图,达到想要的交互效果。

下面是具体的实现。

实现

HTML 和 CSS

整体 HTML 代码:

<body>
    <main>
        <!-- 绘图容器 -->
        <div class="chart"></div>
        
        <!-- 弹出框的结构 -->
        <div id="tooltip">
            <span>您确定要删除这个点吗?</span>
            <div>
                <button class="btn">Yes</button>
                <button class="btn">No</button>
            </div>
        </div>
    </main>
</body>

CSS 代码:

main {
    position: relative;
    margin: 0 auto;
}
.chart {
    width: 500px;
    height: 500px;
}
/* 提示工具 */
#tooltip {
    display: none;
    width: 200px;
    height: 45px;
    background-color: gray;
    color: #000;
    border-radius: 6px;
    padding: 5px 0;
    text-align: center;
    /* 因为弹出框要随鼠标移动,所以这里使用绝对定位 */
    position: absolute;
    z-index: 1;
}
/* 为了好看,可以添加一个箭头,也可以选择不加,我这里选择在右侧添加箭头 */
#tooltip::after {
    content: "";
    position: absolute;
    
    border-width: 5px;
    border-style: solid;
    /* 1. 在工具提示的右侧添加箭头 */
    top: 50%;
    left: 100%;
    margin-top: -5px;
    border-color: transparent transparent transparent gray;
    
    /* 2. 在工具提示的左侧添加箭头 */
    /*
    top: 50%;
    right: 100%;
    margin-top: -5px;
    border-color: transparent gray transparent transparent;
    */
    
    /* 3. 在工具提示的下方添加箭头 */
    /*
    top: 100%;
    left: 50%;
    margin-left: -5px;
    border-color: gray transparent transparent transparent;
    */

    /* 4. 在工具提示的上方添加箭头 */
    /* 
    bottom: 100%;
    left: 50%;
    margin-left: -5px;
    border-color: transparent transparent gray transparent; 
    */
}
#tooltip div {
    text-align: right;
    margin: 0 15px;
}
#tooltip div button {
    width: 40px;
    height: 22px;
}

JS

接下来就是核心代码了,用来控制弹出框随着鼠标移动显示,这里通过鼠标点击事件来控制弹出框。下面就拿 ECharts 官网上的基础散点图例子来测试了。

let myChart = echarts.init(document.querySelector(".chart"));
let tooltip = document.getElementById("tooltip");
let btns = [...document.getElementsByClassName("btn")];
let delData = [];  // 用来保存将要删除的数据
function drawChart(chartName) {
    let data = [
        [10.0, 8.04, "1"],
        [8.07, 6.95, "2"],
        [13.0, 7.58, "3"],
        [9.05, 8.81, "4"],
        [11.0, 8.33, "5"],
        [14.0, 7.66, "6"],
        [9.15, 7.2, "7"],
        [11.5, 7.2, "8"],
        [3.03, 4.23, "9"],
        [12.2, 7.83, "10"],
        [2.02, 4.47, "11"],
        [1.05, 3.33, "12"],
        [4.05, 4.96, "13"],
        [6.03, 7.24, "14"],
        [7.08, 5.82, "15"],
        [5.02, 5.68, "16"],
    ];
    // 删除点
    if (delData.length > 0) {
        for (let i = 0; i < delData.length; i++) {
            for (let j = 0; j < data.length; j++) {
                if (delData[i][2] === data[j][2]) {
                    data.splice(j, 1);
                }
            }
        }
    }
    let option = {
        tooltip: {},
        xAxis: {},
        yAxis: {},
        series: [
            {
                symbolSize: 20,
                data: data,
                type: "scatter",
            },
        ],
    };

    myChart.setOption(option);
}
drawChart(myChart);  // 绘制散点图
// 用户点击散点的交互
myChart.on("click", function (params) {
    // console.log(params);
    let e = params.event.event;
    // 自定义设置弹出框的位置
    tooltip.style.left = e.offsetX - 220 + "px";
    tooltip.style.top = e.offsetY - 30 + "px";
    tooltip.style.display = "block";
    // 为提示框中 Yes/No 按钮绑定点击事件
    btns.forEach((btn) => {
        btn.onclick = (e) => {
            // console.log(e);
            let str = e.target.innerHTML;
            tooltip.style.display = "none";
            if (str === "Yes") {
                delData.push(params.value);
                // 更新散点图
                drawChart(myChart);
            }
        };
    });
});

关于clientX/clientY、pageX/pageY 、screenX/screenY、offsetX/offsetY 的区别

跟鼠标位置有关的属性有:clientX/clientY、pageX/pageY、screenX/screenY、offsetX/offsetY等。它们的区别是:

  • clientX/clientY: 鼠标位置 距离当前浏览器可视区域左上角的 x/y 坐标,它会随着滚动条而变动。
  • pageX/pageY: 鼠标位置 距离当前浏览器内容区域左上角的 x/y 坐标,它不会随着滚动条而变动。
  • screenX/screenY: 鼠标位置 距离电脑屏幕左上角的 x/y 坐标。
  • offsetX/offsetY: 鼠标位置 相对于带有定位的父盒子的 x/y 坐标。

image.png

效果展示

最后,用户通过点击散点图中的散点可以实现弹出框显示,然后通过点击按钮完成是否删除散点。

删除前

image.png

删除后

image.png

可以看到已经大致能够实现刚开始的需求了😀。

结束

上面代码是我实践过了的,没什么问题后才放上来的,如果有哪里还有问题,可以评论交流哈!

如果文章哪里表述有问题,欢迎大家评论指正。如果觉得不错,就点个👍吧!谢谢大家了!!!