亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

基于Echarts實(shí)現(xiàn)繪制立體柱狀圖的示例代碼

瀏覽:45日期:2022-06-02 08:49:04
目錄
  • 前言
  • 實(shí)現(xiàn)方法
    • 先寫(xiě)一個(gè)常規(guī)的柱狀圖
    • echarts的配置選項(xiàng)
  • 效果圖

    前言

    大家好,我是梁木由。之前在做大屏可視化項(xiàng)目時(shí),UI設(shè)計(jì)了一個(gè)立體形狀的柱狀圖,根據(jù)之前做的一些圖表的項(xiàng)目沒(méi)有能復(fù)用的,沒(méi)有做過(guò)這種立體形狀的圖表,打開(kāi)echarts也沒(méi)看到有相關(guān)的demo,看下如何實(shí)現(xiàn)

    實(shí)現(xiàn)方法

    先寫(xiě)一個(gè)常規(guī)的柱狀圖

    在這個(gè)基礎(chǔ)上進(jìn)行改進(jìn)

    <div id="main"></div>?#main{  width: 500px;  height: 350px;}?var chartDom = document.getElementById("main");var myChart = echarts.init(chartDom);var option;?option = {  xAxis: {    axisTick: {      show: false    },    nameTextStyle: {      color: "#fff"    },    data: ["春節(jié)", "元宵節(jié)", "端午節(jié)", "中秋節(jié)"]  },  legend: {    data: ["春節(jié)", "元宵節(jié)", "端午節(jié)", "中秋節(jié)"],    right: "25",    top: "18",    icon: "rect",    itemHeight: 10,    itemWidth: 10,    textStyle: {      color: "#000"    }  },  yAxis: {    type: "value",    axisLabel: {      color: "#000"    },    splitLine: {      show: true,      lineStyle: {type: "dashed",color: ["#ccc"]      }    }  },  series: [    {      data: [{ name: "春節(jié)", value: 24 },{ name: "端午節(jié)", value: 44 },{ name: "中秋節(jié)", value: 32 },{ name: "春節(jié)", value: 50 }      ],      barWidth: 30,      type: "bar"    }  ]};??option && myChart.setOption(option);

    echarts的配置選項(xiàng)

    首先呢我們看下echarts的配置選項(xiàng)

    那我們看所有的type 沒(méi)有立體柱狀圖的類(lèi)型,但是呢我們看最后一項(xiàng)type: custom,什么意思呢,自定義系列,那就是說(shuō)我們可以選擇custom 類(lèi)型來(lái)實(shí)現(xiàn)立體柱狀圖

    renderItem

    type為custom可以自定義系列圖形元素渲染。

    根據(jù)查看配置項(xiàng),發(fā)現(xiàn)有一個(gè)renderItem函數(shù),custom 系列需要開(kāi)發(fā)者自己提供圖形渲染的邏輯。這個(gè)渲染邏輯一般命名為 renderItem

    看下renderItem函數(shù)的介紹

    renderItem 函數(shù)提供了兩個(gè)參數(shù):

    params:包含了當(dāng)前數(shù)據(jù)信息和坐標(biāo)系的信息。

    {    context: // {Object} 一個(gè)可供開(kāi)發(fā)者暫存東西的對(duì)象。生命周期只為:當(dāng)前次的渲染。    seriesId: // {string} 本系列 id。    seriesName: // {string} 本系列 name。    seriesIndex: // {number} 本系列 index。    dataIndex: // {number} 數(shù)據(jù)項(xiàng)的 index。    dataIndexInside: // {number} 數(shù)據(jù)項(xiàng)在當(dāng)前坐標(biāo)系中可見(jiàn)的數(shù)據(jù)的 index(即 dataZoom 當(dāng)前窗口中的數(shù)據(jù)的 index)。    dataInsideLength: // {number} 當(dāng)前坐標(biāo)系中可見(jiàn)的數(shù)據(jù)長(zhǎng)度(即 dataZoom 當(dāng)前窗口中的數(shù)據(jù)數(shù)量)。    actionType: // {string} 觸發(fā)此次重繪的 action 的 type。    coordSys: // 不同的坐標(biāo)系中,coordSys 里的信息不一樣,含有如下這些可能:    coordSys: {type: "cartesian2d",x: // {number} grid rect 的 xy: // {number} grid rect 的 ywidth: // {number} grid rect 的 widthheight: // {number} grid rect 的 height    },    coordSys: {type: "calendar",x: // {number} calendar rect 的 xy: // {number} calendar rect 的 ywidth: // {number} calendar rect 的 widthheight: // {number} calendar rect 的 heightcellWidth: // {number} calendar cellWidthcellHeight: // {number} calendar cellHeightrangeInfo: {    start: // calendar 日期開(kāi)端    end: // calendar 日期結(jié)尾    weeks: // calendar 周數(shù)    dayCount: // calendar 日數(shù)}    },    coordSys: {type: "geo",x: // {number} geo rect 的 xy: // {number} geo rect 的 ywidth: // {number} geo rect 的 widthheight: // {number} geo rect 的 heightzoom: // {number} 縮放的比率。如果沒(méi)有縮放,則值為 1。例如 0.5 表示縮小了一半。    },    coordSys: {type: "polar",cx: // {number} polar 的中心坐標(biāo)cy: // {number} polar 的中心坐標(biāo)r: // {number} polar 的外半徑r0: // {number} polar 的內(nèi)半徑    },    coordSys: {type: "singleAxis",x: // {number} singleAxis rect 的 xy: // {number} singleAxis rect 的 ywidth: // {number} singleAxis rect 的 widthheight: // {number} singleAxis rect 的 height    }}

    其中,關(guān)于 dataIndexdataIndexInside 的區(qū)別:

    • dataIndex 指的 dataItem 在原始數(shù)據(jù)中的 index。
    • dataIndexInside 指的是 dataItem 在當(dāng)前數(shù)據(jù)窗口中的 index。

    [renderItem.arguments.api] 中使用的參數(shù)都是 dataIndexInside 而非 dataIndex,因?yàn)閺?dataIndex 轉(zhuǎn)換成 dataIndexInside 需要時(shí)間開(kāi)銷(xiāo)。

    api:是一些開(kāi)發(fā)者可調(diào)用的方法集合。

    所有屬性

    {[value], [coord] , [size] , [style] , [styleEmphasis] , [visual] , [barLayout] , [currentSeriesIndices] , [font], [getWidth] , [getHeight], [getZr], [getDevicePixelRatio]}

    我們使用renderItem來(lái)自定義元素會(huì)使用到renderItem.api的三個(gè)方法,先來(lái)介紹下這三個(gè)方法

    • [api.value(...)],意思是取出 dataItem 中的數(shù)值。例如 api.value(0) 表示取出當(dāng)前 dataItem 中第一個(gè)維度的數(shù)值。
    • [api.coord(...)],意思是進(jìn)行坐標(biāo)轉(zhuǎn)換計(jì)算。例如 var point = api.coord([api.value(0), api.value(1)]) 表示 dataItem 中的數(shù)值轉(zhuǎn)換成坐標(biāo)系上的點(diǎn)。
    • [api.size(...)] ,表示得到坐標(biāo)系上一段數(shù)值范圍對(duì)應(yīng)的長(zhǎng)度。

    看下代碼實(shí)現(xiàn)

    series:  getSeriesData()?function getSeriesData() {  const data = [];  seriesData.forEach((item, index) => {    data.push(      {type: "custom",name: item.label,renderItem: function (params, api) {  return getRenderItem(params, api);},data: item.value,      }    )  })  return data}?function getRenderItem(params, api) {  // params.seriesIndex表示本系列 index  const index = params.seriesIndex;  // api.coord() 坐標(biāo)轉(zhuǎn)換計(jì)算  // api.value() 取出當(dāng)前項(xiàng)中的數(shù)值  let location = api.coord([api.value(0) + index, api.value(1)]);  // api.size() 坐標(biāo)系數(shù)值范圍對(duì)應(yīng)的長(zhǎng)度  var extent = api.size([0, api.value(1)]);  return {    type: "rect",    shape: {      x: location[0] - 20 / 2,      y: location[1],      width: 20,      height: extent[1]    },    style: api.style()  };}

    來(lái)看下我們的實(shí)現(xiàn)效果

    柱狀圖效果出來(lái)了,那來(lái)看下怎么將柱狀圖改為立體圖

    return_group

    我看到renderItem可以返回一個(gè)return_group類(lèi)型,來(lái)看看這個(gè)類(lèi)型的介紹

    • group 是唯一的可以有子節(jié)點(diǎn)的容器。
    • group 可以用來(lái)整體定位一組圖形元素。

    那就是說(shuō)我們可以將設(shè)定一組圖形元素然后組合到一起形成立體柱狀圖

    那么問(wèn)題又來(lái)了怎么設(shè)定一組圖形元素呢?

    graphic

    這個(gè)呢是關(guān)于圖形相關(guān)的方法,再來(lái)了解兩個(gè)API

    graphic.extendShape

    創(chuàng)建一個(gè)新的圖形元素

    graphic.registerShape

    注冊(cè)一個(gè)開(kāi)發(fā)者定義的圖形元素

    創(chuàng)建圖形元素

    那我們先來(lái)創(chuàng)建一個(gè)新的圖形元素

    const leftRect = echarts.graphic.extendShape({    shape: {      x: 0,      y: 0,      width: 19, //柱狀圖寬      zWidth: 8, //陰影折角寬      zHeight: 4, //陰影折角高    },    buildPath: function (ctx, shape) {      const api = shape.api;      const xAxisPoint = api.coord([shape.xValue, 0]);      const p0 = [shape.x - shape.width / 2, shape.y - shape.zHeight];      const p1 = [shape.x - shape.width / 2, shape.y - shape.zHeight];      const p2 = [xAxisPoint[0] - shape.width / 2, xAxisPoint[1]];      const p3 = [xAxisPoint[0] + shape.width / 2, xAxisPoint[1]];      const p4 = [shape.x + shape.width / 2, shape.y];?      ctx.moveTo(p0[0], p0[1]);       ctx.lineTo(p1[0], p1[1]);      ctx.lineTo(p2[0], p2[1]);      ctx.lineTo(p3[0], p3[1]);      ctx.lineTo(p4[0], p4[1]);      ctx.lineTo(p0[0], p0[1]);      ctx.closePath();    },  });??const rightRect = echarts.graphic.extendShape({    shape: {      x: 0,      y: 0,      width: 18,      zWidth: 15,      zHeight: 8,    },    buildPath: function (ctx, shape) {      const api = shape.api;      const xAxisPoint = api.coord([shape.xValue, 0]);      const p1 = [shape.x - shape.width / 2, shape.y - shape.zHeight / 2];      const p3 = [xAxisPoint[0] + shape.width / 2, xAxisPoint[1]];      const p4 = [shape.x + shape.width / 2, shape.y];      const p5 = [xAxisPoint[0] + shape.width / 2 + shape.zWidth, xAxisPoint[1]];      const p6 = [shape.x + shape.width / 2 + shape.zWidth, shape.y - shape.zHeight / 2];      const p7 = [shape.x - shape.width / 2 + shape.zWidth, shape.y - shape.zHeight];      ctx.moveTo(p4[0], p4[1]);       ctx.lineTo(p3[0], p3[1]);      ctx.lineTo(p5[0], p5[1]);      ctx.lineTo(p6[0], p6[1]);      ctx.lineTo(p4[0], p4[1]);?      ctx.moveTo(p4[0], p4[1]);      ctx.lineTo(p6[0], p6[1]);      ctx.lineTo(p7[0], p7[1]);      ctx.lineTo(p1[0], p1[1]);      ctx.lineTo(p4[0], p4[1]);      ctx.closePath();    },  });

    注冊(cè)圖形元素

    echarts.graphic.registerShape("leftRect", leftRect);echarts.graphic.registerShape("rightRect", rightRect);

    再來(lái)修改一下return_group

    function getRenderItem(params, api) {  const index = params.seriesIndex;  let location = api.coord([api.value(0) + index, api.value(1)]);  var extent = api.size([0, api.value(1)]);  return {    type: "group",    children: [      {type: "leftRect",shape: {  api,  xValue: api.value(0) + index,  yValue: api.value(1),  x: location[0],  y: location[1]},style: api.style()      },      {type: "rightRect",shape: {  api,  xValue: api.value(0) + index,  yValue: api.value(1),  x: location[0],  y: location[1]},style: api.style()      }    ]  };}

    再來(lái)看下效果

    可以看到立體形狀的柱狀圖已經(jīng)實(shí)現(xiàn)了,那還有個(gè)缺點(diǎn)就是顏色需要再按照設(shè)計(jì)圖來(lái)改改

    const colors = [    [      { offset: 0, color: "rgba(26, 132, 191, 1)" },      { offset: 1, color: "rgba(52, 163, 224, 0.08)" },    ],    [      { offset: 0, color: "rgba(137, 163, 164, 1)" },      { offset: 1, color: "rgba(137, 163, 164, 0.08)" },    ],    [      { offset: 0, color: "rgba(44, 166, 166, 1)" },      { offset: 1, color: "rgba(44, 166, 166, 0.08)" },    ],    [      { offset: 0, color: "rgba(34, 66, 186, 1)" },      { offset: 1, color: "rgba(34, 66, 186, 0.08)" },    ],  ];?//在getSeriesData添加itemStyleitemStyle: {       color: () => {      return new echarts.graphic.LinearGradient(0, 0, 0, 1, colors[index]);       },},

    效果圖

    以上就是基于Echarts實(shí)現(xiàn)繪制立體柱狀圖的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Echarts繪制立體柱狀圖的資料請(qǐng)關(guān)注其它相關(guān)文章!

    標(biāo)簽: JavaScript
    主站蜘蛛池模板: 国产欧美日韩精品第一区 | 久久九九精品一区二区 | 毛片线看免费观看 | 麻豆视频观看 | 欧美综合精品 | 最新国产在线观看 | 色片在线免费观看 | 国产免费a级片 | 国产农村乱色xxxx | 亚洲日b | 手机在线观看视频你懂的 | 国产免费影院 | 日本成熟老妇乱 | 千百橹最新亚洲地址在线播放 | 国产在线欧美精品 | 日本特黄特色aaa大片免费欧 | 日韩综合图区 | 国产换爱交换乱理伦片 | 欧美久久久久欧美一区 | 伊人久久精品午夜 | 免费国产最新进精品视频 | 中文字幕在线播放 | 青青操国产视频 | 亚洲欧洲日韩国产 | 欧美一区二区三区精品 | 99re8免费视频精品全部 | 国产精品一区二区三区高清在线 | 中文国产成人精品久久无广告 | 成人在线观看免费爱爱 | 丝袜美腿秘书ol在线播放 | 国产亚洲精品美女久久久 | 一级片一级片一级片一级片 | 亚洲男女免费视频 | 国产亚洲免费观看 | 亚洲欧美经典 | 国产一级做a爰片久久毛片 国产一级做a爰片久久毛片99 | 88国产精品视频一区二区三区 | 国产久热香蕉在线观看 | 一本伊人 | 亚洲精品黄色 | 91国在线啪精品一区 |