最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用echart實(shí)現(xiàn)柱狀圖里的水波效果示例代碼

 更新時(shí)間:2026年05月23日 09:46:16   作者:前端靈派派  
這篇文章主要介紹了使用echart實(shí)現(xiàn)柱狀圖里水波效果的相關(guān)資料,主要通過(guò)renderItem函數(shù)方法,返回每個(gè)數(shù)據(jù)項(xiàng)對(duì)應(yīng)的圖形元素,包括一個(gè)矩形和一個(gè)波浪路徑,需要的朋友可以參考下

一、項(xiàng)目介紹

最近做項(xiàng)目,甲方要求在柱狀圖里加上水波圖的效果,真是太有趣了,太有創(chuàng)意啦。馬上動(dòng)手實(shí)現(xiàn)。

思路

echart提供了一個(gè)renderItem方法,可以幫助我們自定義每個(gè)series的配置。我們分析柱狀圖跟水波圖,就是由一個(gè)矩形跟一個(gè)波浪路徑組成,因此我們可以返回一個(gè)圖形數(shù)組來(lái)表現(xiàn)當(dāng)前項(xiàng)。

二、了解renderItem

renderItem 函數(shù)是自定義系列的核心,它負(fù)責(zé)將數(shù)據(jù)項(xiàng)(dataItem)轉(zhuǎn)換為可視化的圖形元素。ECharts 會(huì)為 series.data 中的每個(gè)數(shù)據(jù)項(xiàng)調(diào)用一次 renderItem 函數(shù)。主要優(yōu)勢(shì)在于:

  1. 可以自由繪制各種圖形元素
  2. ECharts 會(huì)自動(dòng)管理圖形的創(chuàng)建、刪除、動(dòng)畫(huà)等細(xì)節(jié)
  3. 可以與其他組件(如 dataZoom、visualMap)無(wú)縫聯(lián)動(dòng)

參數(shù)

renderItem 函數(shù)接收兩個(gè)參數(shù):paramsapi

//params 包含當(dāng)前數(shù)據(jù)信息和坐標(biāo)系信息:
{
    context: {},       // 可供開(kāi)發(fā)者暫存東西的對(duì)象
    seriesId: string,  // 本系列 ID
    seriesName: string, // 本系列名稱(chēng)
    seriesIndex: number, // 本系列索引
    dataIndex: number,  // 數(shù)據(jù)項(xiàng)在原始數(shù)據(jù)中的索引
    dataIndexInside: number, // 數(shù)據(jù)項(xiàng)在當(dāng)前可見(jiàn)數(shù)據(jù)窗口中的索引
    dataInsideLength: number, // 當(dāng)前可見(jiàn)數(shù)據(jù)長(zhǎng)度
    coordSys: {        // 坐標(biāo)系信息,類(lèi)型不同結(jié)構(gòu)也不同
        type: 'cartesian2d' | 'polar' | 'geo' | 'calendar' | 'singleAxis',
        // 不同坐標(biāo)系下的具體屬性...
    }
}

api 參數(shù)提供了一系列方法:

  • api.value(index) - 獲取數(shù)據(jù)項(xiàng)中指定維度的值
  • api.coord(valueArray) - 將數(shù)據(jù)值轉(zhuǎn)換為坐標(biāo)系上的點(diǎn)
  • api.size(valueArray) - 獲取坐標(biāo)系上一段數(shù)值范圍對(duì)應(yīng)的像素長(zhǎng)度
  • api.style(styleOverrides) - 獲取或覆蓋默認(rèn)樣式

返回值

renderItem 函數(shù)需要返回一個(gè)圖形元素定義對(duì)象

{
    type: string,       // 圖形類(lèi)型,如'rect','circle','sector','polygon'等
    shape: object,      // 圖形形狀定義
    style: object,      // 圖形樣式
    extra: object,      // 額外信息,可在事件處理器中訪(fǎng)問(wèn)
    children: array,    // 子圖形(當(dāng)type為'group'時(shí))
    // 其他可選屬性...
}

三、實(shí)現(xiàn)

首先要實(shí)現(xiàn)基本配置,柱子的高度為數(shù)據(jù)的總數(shù),水波的位置為已處理數(shù)據(jù),提示窗展示名稱(chēng)、已處理、未處理、總數(shù)等數(shù)據(jù)。

// 數(shù)據(jù)配置 - 包含已處理和未處理的數(shù)據(jù)
const chartData = [
  { name: "車(chē)輛只進(jìn)不出", processed: 60, unprocessed: 62, total: 122 },
  { name: "預(yù)警模型2", processed: 72, unprocessed: 82, total: 154 },
  { name: "預(yù)警模型3", processed: 71, unprocessed: 91, total: 162 }
];
// 創(chuàng)建水波柱狀圖配置
const createOption = () => {
  return {
    backgroundColor: 'transparent', //echart背景為透明
    animation: false,
    tooltip: { //提示窗配置
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      },
      formatter: function(params) {
        const data = chartData[params[0].dataIndex];
        return `${params[0].name}
已處理: ${data.processed}
未處理: ${data.unprocessed}
總計(jì):${data.total}`;
      }
    },
    grid: { //圖表位置占比配置,盡量居中
      left: '3%',
      right: '4%',
      bottom: '12%',
      top:'5%',
      containLabel: true
    },
    xAxis: {  //配置x軸
      type: 'category',
      data: chartData.map(item => item.name),
      axisLabel: {
        color: '#fff',
        fontSize: 12
      },
      axisLine: {
        lineStyle: {
          color: '#fff'
        }
      }
    },
    yAxis: { //配置y軸
      type: 'value',
      axisLabel: {
        color: '#fff',
        fontSize: 12,
      },
      axisLine: {
        lineStyle: {
          color: '#fff'
        }
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(255, 255, 255, 0.1)'
        }
      }
    },
    series:series //配置數(shù)據(jù)項(xiàng)
  };
};

自定義數(shù)據(jù)項(xiàng),通過(guò)rederItem方法返回一個(gè)矩形跟一個(gè)波浪路徑

// 水波動(dòng)畫(huà)時(shí)間
let animationTime = 0;
let series = [
{
    name: '水波柱狀圖',
    type: 'custom',
    renderItem: (params, api) => {
      const categoryIndex = api.value(0); //當(dāng)前項(xiàng)索引
      const totalValue = api.value(1); //當(dāng)前項(xiàng)的值
      const processedValue = chartData[categoryIndex].processed; //已完成的值
      const start = api.coord([api.value(0), 0]); //開(kāi)始的坐標(biāo)位置,返回[x,y]坐標(biāo)
      const end = api.coord([api.value(0), totalValue]); //結(jié)束的坐位位置
      const height = end[1] - start[1]; //高度
      const width = 40; //寬度
      const rectShape = {  //定義矩形的形狀
        x: start[0] - width / 2, 
        y: start[1],
        width: width,
        height: height
      };
      // 計(jì)算水波位置 - 基于已處理數(shù)量占總數(shù)的比例
      const waterLevel = processedValue / totalValue;
      const wavePath = createWavePath(rectShape, waterLevel, animationTime);
      return { //返回值
        type: 'group',
        children: [
          {
            type: 'rect',  //矩形
            shape: rectShape,
            style: {
              fill: {
                  type: 'linear',
                  x: 0,
                  y: 0,
                  x2: 0,
                  y2: 1,
                  colorStops: [
                    { offset: 0, color: 'rgba(24, 144, 255, 0.8)' },
                    { offset: 0.5, color: 'rgba(64, 169, 255, 0.6)' },
                    { offset: 1, color: 'rgba(9, 109, 217, 0.4)' }
                  ]
                },
              stroke: 'rgba(24, 144, 255, 0.3)',
              lineWidth: 1
            }
          },
          {
            type: 'path',  //水波路徑
            shape: {
              pathData: wavePath
            },
            style: {
              fill: {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [
                  { offset: 0, color: 'rgba(24, 144, 255, 0.8)' },
                  { offset: 0.5, color: 'rgba(64, 169, 255, 0.6)' },
                  { offset: 0.5, color: 'rgba(64, 169, 255, 0.6)' },
                  { offset: 1, color: 'rgba(9, 109, 217, 0.4)' }
                ]
              }
            },
            z: 10
          }
        ]
      };
    },
    data: chartData.map(item => item.total),
    z: 10
  }
]

實(shí)現(xiàn)水波的方法,生成一個(gè)svg的路徑。SVG 路徑字符串是描述矢量圖形的重要方式,下面我將詳細(xì)介紹如何生成 SVG 路徑字符串

基本 SVG 路徑命令

命令含義示例
M移動(dòng)到 (MoveTo)M 10,20
L直線(xiàn)到 (LineTo)L 30,40
C三次貝塞爾曲線(xiàn) (Cubic Bezier)C x1,y1 x2,y2 x,y
Q二次貝塞爾曲線(xiàn) (Quadratic Bezier)Q x1,y1 x,y
Z閉合路徑 (ClosePath)Z
// 創(chuàng)建水波路徑
const createWavePath = (rect, waterLevel, time) => {
  const { x, y, width, height } = rect;
  const waterHeight = height * waterLevel; //水波的高度=柱子高度*百分比
  const waterY = y + height - waterHeight; //水波的y軸位置
  
  const waveLength = width;
  const waveHeight = 3;
  const frequency = 1;
  
  // 從底部開(kāi)始繪制路徑
  let path = `M ${x} ${y + height}`;
  
  // 繪制左側(cè)邊線(xiàn)到水波位置
  path += ` L ${x} ${waterY}`;
  
  // 繪制水波頂部
  for (let i = 0; i <= width; i += 2) {
    const waveX = x + i;
    // 使用正弦函數(shù)計(jì)算Y坐標(biāo)
    const waveY = waterY + Math.sin((i / waveLength) * Math.PI * frequency + time) * waveHeight;
    path += ` L ${waveX} ${waveY}`;
  }
  
  // 繪制右側(cè)邊線(xiàn)回到底部
  path += ` L ${x + width} ${y + height}`;
  
  // 閉合路徑
  path += ` Z`;
  
  return path;
};

創(chuàng)建echart圖標(biāo),并實(shí)現(xiàn)水波的動(dòng)畫(huà)效果

// 創(chuàng)建圖表
const createChart = () => {
  const container = chartRef.value;
  chartInstance = echarts.init(container);
  
  chartInstance.setOption(createOption());
  
  // 啟動(dòng)水波動(dòng)畫(huà)
  const animate = () => {
    animationTime += 0.1;
    if (chartInstance) {
      chartInstance.setOption({series:series});
    }
    
    requestAnimationFrame(animate);
  };
  
  animate();
};

onMounted(() => {
  createChart();
});

onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
});

最終效果:

總結(jié) 

到此這篇關(guān)于使用echart實(shí)現(xiàn)柱狀圖里水波效果的文章就介紹到這了,更多相關(guān)echart柱狀圖水波效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

保定市| 增城市| 广南县| 阿拉善左旗| 临江市| 张掖市| 芦山县| 黔西县| 中方县| 金寨县| 巨野县| 乐陵市| 周至县| 锡林郭勒盟| 黔南| 房产| 阜阳市| 静安区| 高阳县| 东台市| 沈丘县| 大姚县| 静安区| 安泽县| 南木林县| 屯门区| 乌拉特前旗| 南宁市| 玉林市| 多伦县| 灵山县| 开鲁县| 武城县| 临西县| 石狮市| 万州区| 汉源县| 堆龙德庆县| 洪江市| 尼勒克县| 民丰县|