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'
               }
            }
         }

      }
   })
}


const initEchart = () => {
   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([]);
      }
   })
}

initEchart();