brush选中上下拖动

描述:当前是关于Echarts图表中的 示例。
 
            function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj; // 如果是原始值或函数,直接返回
    }

    let clone;
    if (Array.isArray(obj)) {
        clone = []; // 如果是数组,创建一个空数组
        for (let i = 0; i < obj.length; i++) {
            clone[i] = deepClone(obj[i]); // 递归深拷贝数组的每个元素
        }
    } else {
        clone = {}; // 如果是对象,创建一个空对象
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                clone[key] = deepClone(obj[key]); // 递归深拷贝对象的每个属性
            }
        }
    }
    return clone; // 返回深拷贝后的对象或数组
}
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: [100, 200, 300, 400, 500].map((v) => v * 1.2)
    }
]


const lineStyle = {
    type: 'scatter',
    smooth: true,
    coordinateSystem: 'cartesian2d'
}
let batchSelected = [];
const computedSeries = (Data, dif = 0) => {
    let selected = batchSelected;
    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, dif = 0) => {
    if (dif == 0) return;
    let selected = batchSelected;
    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;
            }
        })
    })
}
let onmousedownY = 0;
let oldDif = 0;
const seriesDataToGraphic = (series) => {
    let dom = document.getElementById('container');
    let myChart = echarts.getInstanceByDom(dom);
    let graphic = [];
    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,
                        onmousedown: echarts.util.curry((e) => {
                            onmousedownY = e.offsetY;
                            // myChart.dispatchAction({
                            //     type: 'restore'
                            // })

                            myChart.dispatchAction({
                                type: 'takeGlobalCursor',
                                key: null,
                            })
                            myChart.dispatchAction({
                                type: 'brush',
                                areas: []
                            })
                        }),
                        ondrag: echarts.util.curry((dataI, e) => {
                            let onmousedownYToValue = myChart.convertFromPixel({ seriesIndex: sindex }, [dataI, onmousedownY])[1];
                            let ondragYToValue = myChart.convertFromPixel({ seriesIndex: sindex }, [dataI, e.offsetY])[1];
                            let dif = onmousedownYToValue - ondragYToValue;

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

const setSelectTitle = (selected) => {
    let dom = document.getElementById('container');
    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'
                    }
                }
            }

        }
    })
}



let dom = document.getElementById('container');
let myChart = echarts.init(dom);
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 = deepClone(params.batch[0]);
    let selected = batch.selected;
    batchSelected = selected;
    let seriesData = computedSeries(data);
    let graphics = seriesDataToGraphic(seriesData);
    myChart.setOption({
        series: seriesData,
        graphic: graphics
    })
    setSelectTitle(batchSelected);
})

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