首页 > 其他分享 >echarts折线图实现矩形圈中的点可拖拽,圈外的点不可拖拽

echarts折线图实现矩形圈中的点可拖拽,圈外的点不可拖拽

时间:2024-07-09 17:57:03浏览次数:16  
标签:map myChart echarts item let 圈中 seriesIndex data 拖拽

原生HTML + JavaScript版本

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>曲线形式的统计图示例</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.9.0-rc.1/echarts.min.js"></script>
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.2.1/echarts.min.js"></script> -->
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #ecDiv {
            width: 1400px;
            height: 600px;
            box-shadow: 0px 0px 10px #ccc;
            margin: 10px auto;
        }
    </style>
</head>

<body>
    <div id="ecDiv"></div>
</body>

<script type="text/javascript">
    let color = ['#0071db', '#ff4868']
    let xdata = ['2024-1-1', '2024-1-2', '2024-1-3', '2024-1-4', '2024-1-5']
    const data = [
        {
            name: 'line1',
            data: [100, 200, 300, 400, 500]
        },
        {
            name: 'line2',
            data: [200, 200, 200, 200, 200]
        }
    ]


    const lineStyle = {
        type: 'scatter',
        smooth: true,
        coordinateSystem: 'cartesian2d'
    }

    const computedSeries = (Data, selected, dif = 0) => {
        let items = [];
        Data.map((item, key) => {
            let point = {
                name: item.name,
                data: item.data.map((val, i) => {
                    let dataValue = {
                        value: val,
                        symbolSize: 1,
                    }
                    return dataValue
                }),
                ...lineStyle
            }
            items.push(point);
        })
        selected.map((item) => {
            let seriesIndex = item.seriesIndex;
            let findItem = items.find((v, k) => {
                if (item.seriesIndex === k) {
                    return v;
                }
            });
            findItem && findItem.data.map((val, key) => {
                if (item.dataIndex.includes(key)) {
                    val['symbolSize'] = 10;
                    val['value'] = val.value + dif;
                }
            })
        })

        let lines = items.map((v, k) => {
            let itemData = v.data.map((v) => v.value);
            return {
                z: 1,
                type: 'line',
                name: v.name,
                data: itemData
            }
        })
        items.push(...lines)
        return items;
    }

    const echartDataSetData = (Data, selected, dif = 0) => {
        if (dif == 0) return;
        selected.map((item) => {
            let seriesIndex = item.seriesIndex;
            let Dataitem = Data[seriesIndex];
            Dataitem && Dataitem.data.map((val, key) => {
                if (item.dataIndex.includes(key)) {
                    Dataitem.data[key] = val + dif;
                }
            })
        })
    }
    const seriesDataToGraphic = (series, batchSelected) => {
        let dom = document.getElementById('ecDiv');
        let myChart = echarts.getInstanceByDom(dom);
        let graphic = [];
        let onm ousedownY = 0;
        let oldDif = 0;
        series.map((item, sindex) => {
            if (item.type === 'scatter') {
                item.data.map((dt, tk) => {
                    //! 等于10 标识选中
                    if (dt.symbolSize && dt.symbolSize === 10) {
                        let dataIndex = tk;
                        let position = myChart.convertToPixel({ seriesIndex: sindex }, [dataIndex, dt.value]);
                        let graphicItem = {
                            type: 'circle',
                            position: position,
                            shape: {
                                r: 5
                            },
                            invisible: true,
                            draggable: true,
                            onm ousedown: echarts.util.curry((e) => {
                                onm ousedownY = e.offsetY;
                                myChart.dispatchAction({
                                    type: 'restore'
                                })
                            }),
                            ondrag: echarts.util.curry((dataI, e) => {
                                let onm ousedownYToValue = myChart.convertFromPixel({ seriesIndex: sindex }, [dataI, onm ousedownY])[1];
                                let ondragYToValue = myChart.convertFromPixel({ seriesIndex: sindex }, [dataI, e.offsetY])[1];
                                let dif = onm ousedownYToValue - ondragYToValue;

                                let seriesData = computedSeries(data, batchSelected, -dif);
                                let graphics = seriesDataToGraphic(seriesData, batchSelected);
                                myChart.setOption({
                                    series: seriesData,
                                    graphic: graphics
                                })
                                oldDif = dif;
                            }, dataIndex),
                            ondragend: echarts.util.curry(() => {
                                echartDataSetData(data, batchSelected, -oldDif);
                                setSelectTitle(batchSelected)
                            }, dataIndex),
                            z: 100,
                        }
                        graphic.push(graphicItem);
                    }
                })
            };
        })
        return graphic;
    }

    const setSelectTitle = (selected) => {
        let dom = document.getElementById('ecDiv');
        let myChart = echarts.getInstanceByDom(dom);
        let title = ''
        selected.map((item) => {
            if (!item.dataIndex.length) {
                return;
            }
            let seriesName = item.seriesName;
            let dataIndexList = item.dataIndex.map((i) => {
                return `{x|${xdata[i]}数值:${data[item.seriesIndex].data[i]}}\n`
            })
            let line = `{name|${seriesName}}${dataIndexList}`;
            title += '\n' + line;
        })
        myChart.setOption({
            title: {
                text: '已选中:\n' + title,
                right: 20,
                top: 40,
                textStyle: {
                    rich: {
                        name: {
                            color: '#333'
                        },
                        x: {
                            color: 'red'
                        }
                    }
                }

            }
        })
    }


    const initEchart = () => {
        let dom = document.getElementById('ecDiv');
        let myChart = echarts.init(dom);
        let dataIndexs = [];
        let seriesIndexs = [];
        let series = computedSeries(data, []);
        let option = {
            color,
            xAxis: [
                {
                    type: 'category',
                    data: xdata
                }
            ],
            yAxis: [
                {
                    type: 'value'
                }
            ],
            grid: {
                width: "80%",
                containLabel: true,
                left: 30,
                top: 50,
                right: 30,
                bottom: 20
            },
            legend: {
                show: true,
                data: data.map((v) => v.name)
            },
            brush: {
                xAxisIndex: 'all',
                throttleType: 'debounce',
                transformable: false,
                removeOnClick: true,
                brushMode:'single',
                throttleDelay:0,
                brushStyle: {
                    borderWidth: 1,
                    color: 'rgba(120,140,180,0.1)',
                    borderColor: 'rgba(120,140,180,0.1)'
                },
                inBrush: {
                    symbolSize: 10
                },
                outOfBrush: {
                    colorAlpha: 1,
                    opacity: 1
                },
            },
            animation: false,
            series
        }
        myChart.setOption(option);
        myChart.on('brushselected', (params) => {
            if (!params.batch[0].areas.length) {
                return;
            };
            let batch = params.batch[0];
            let seriesData = computedSeries(data, batch.selected);
            let graphics = seriesDataToGraphic(seriesData, batch.selected);
            myChart.setOption({
                series: seriesData,
                graphic: graphics
            })
            setSelectTitle(batch.selected);

            // 不加这个有毛病,echartsbug; 首先选择两个线的点拖拽,取消选择后在选择上次的其中一个拖动会选择两个点
            window.onmouseup = () => {
                myChart.dispatchAction({
                    type: 'restore'
                })
            }
        })

        // ! 点击取消 取消选中节点
        myChart.on('brush', (params) => {
            if (params?.command === 'clear') {
                let seriesData = computedSeries(data, []);
                let graphics = seriesDataToGraphic(seriesData, []);
                myChart.setOption({
                    series: seriesData,
                    graphic: graphics
                })
                setSelectTitle([]);
            }
        })
    }

    initEchart();
</script>

</html>

标签:map,myChart,echarts,item,let,圈中,seriesIndex,data,拖拽
From: https://blog.csdn.net/ni15534789894/article/details/140267180

相关文章

  • echarts折线图加一条目标值线
    文章目录一、echarts折线图加一条目标值线?二、使用步骤1.代码如下:2.示例图片总结一、echarts折线图加一条目标值线?在ECharts中添加一条目标值线(即一个固定值的水平线),可以使用markLine组件,以下是一个简单的例子,展示了如何在ECharts折线图中添加一条目标值线。......
  • 【饼图交通方式】用ECharts的graphic配置打造个性化
    利用ECharts的graphic配置打造个性化图表内容概要ECharts是一款强大的数据可视化工具,它提供了丰富的配置选项来定制图表。本文将重点介绍graphic配置的使用,展示如何通过在饼图中添加个性化的图形元素,例如中心图像,来增强图表的视觉效果。效果预览适用人群数据可视化工......
  • Echarts:渲染成Canvas还是SVG,该如何抉择?
    ECharts从初始一直使用Canvas绘制图表。而EChartsv4.0发布了SVG渲染器,从而提供了一种新的选择。在初始化图表实例时,只需设置renderer参数为'canvas'或'svg'即可指定渲染器,比较方便。贝格前端工场带领大家看下如何选择。一、Canvas和SVG的区分Canvas和SVG都是......
  • 前端画图引擎ZRender,echarts的渲染器,你知道吗?
    Zrender是一个轻量级的Canvas和SVG渲染库,它提供了一个高性能的图形绘制和交互的解决方案,用于在Web页面上创建丰富的数据可视化和交互式图形。可能大部分小伙伴不知道这个类库,本文给大家科普一下。一、Zrender是谁?该项目由EFE团队开发而来,项目托管在GitHub上。Zrender基于HT......
  • 提升ECharts图例可读性的实用技巧
    在使用echarts进行数据可视化时,图例(legend)是帮助用户理解图表中各个系列所代表含义的重要组件。然而,在实现过程中,我们可能会遇到一些常见问题,本文将分享一些关于echarts图例分页的注意事项和解决方案。1.图例中出现多余的undefined数据在使用echarts的legend组件时,如果未正确......
  • echarts 折线图拼接
    效果图: <scriptsetuplang="ts">import*asechartsfrom'echarts';import{ref,watch,nextTick,computed}from'vue';import{useRouteParams}from'@/hooks/useRouteParams';import{queryIncreaseTrend......
  • 获取Echarts的geoJson文件(省市/区县)
    1.获取市的级别直接使用阿里云提供的工具直接获取: https://datav.aliyun.com/portal/school/atlas/area_selector#&lat=32.62087018318113&lng=118.43261718749999&zoom=4和 https://map.easyv.cloud/和 https://geojson.hxkj.vip/  2.获取县和区的细到街道的geoJson,需......
  • React+TS前台项目实战(二十六)-- 高性能可配置Echarts图表组件封装
    文章目录前言CommonChart组件1.功能分析2.代码+详细注释3.使用到的全局hook代码4.使用方式5.效果展示总结前言Echarts图表在项目中经常用到,然而,重复编写初始化,更新,以及清除实例等动作对于开发人员来说是一种浪费时间和精力。因此,在这篇文章中,将封装一个“高......
  • echarts中Label标签与数据项颜色设置为同一种颜色
    echarts5中默认标签颜色不会跟数据项颜色保持一致,而是全都是黑色。想要实现label颜色和它的数据项颜色一致,需要手动继承颜色,设置label{color:'inherit'}即可解决label标签颜色与数据项颜色一致。  https://echarts.apache.org/examples/zh/editor.html?c=pie-simple注意:......
  • 邮件显示统计图表echarts-java+phantomjs实现
    邮件显示统计图表echarts-java+phantomjs实现项目背景是产品业务上的订阅推送,纯java后端实现,通过邮件将统计报表发送给用户。这里会涉及一些关键点:首先是统计图表的生成,我们采用常见的echarts,简单易用,支持图表类型丰富美观;java后端实现可使用echarts-java来实现图表的生成......