echarts

echarts饼图legend百分比计算时四舍五入有误差的解决方案

   // 传入参数(数组数据,数组下标,精度),底下有例子调用
    var getPercentValue = function (valueList, idx, precision) {
        // 判断是否为空
        if (!valueList[idx]) {
            return 0;
        }
        // 求和
        var sum = valueList.reduce(function (acc, val) {
            return acc + (isNaN(val) ? 0 : val);
        }, 0)
        if (sum === 0) {
            return 0;
        }
        // 10的2次幂是100,用于计算精度。
        var digits = Math.pow(10, precision);
        // 扩大比例100,
        var votesPerQuota = valueList.map(function (val) {
            return (isNaN(val) ? 0 : val) / sum * digits * 100;
        })
        // 总数,扩大比例意味的总数要扩大
        var targetSeats = digits * 100;
        // 再向下取值,组成数组
        var seats = votesPerQuota.map(function (votes) {
            return Math.floor(votes);
        })
        // 再新计算合计,用于判断与总数量是否相同,相同则占比会100%
        var currentSum = seats.reduce(function (acc, val) {
            return acc + val;
        }, 0)
        // 余数部分的数组:原先数组减去向下取值的数组,得到余数部分的数组
        var remainder = votesPerQuota.map(function (votes, idx) {
            return votes - seats[idx];
        })
        // 给最大最大的余额加1,凑个占比100%;
        while (currentSum < targetSeats) {
            //  找到下一个最大的余额,给其加1
            var max = Number.NEGATIVE_INFINITY;
            var maxId = null;
            for (var i = 0, len = remainder.length; i < len; ++i) {
                if (remainder[i] > max) {
                    max = remainder[i];
                    maxId = i;
                }
            }
            // 对最大项余额加1
            ++seats[maxId];
            // 已经增加最大余数加1,则下次判断就可以不需要再判断这个余额数。
            remainder[maxId] = 0;
            // 总的也要加1,为了判断是否总数是否相同,跳出循环。
            ++currentSum;
        }
        // 这时候的seats就会总数占比会100%
        return seats[idx] / digits
    }
  //调用
  getPercentValue(arr,0,2)

echarts迁徙地图

<template>
  <div id="moveMapChart" style=" 100%; height: 500px"></div>
</template>

<script>
import resize from "@/util/resize"
import * as echarts from "echarts"
import "./china.js"
export default {
  name:"moveMapChart",
  mixins:[resize],
  data() {
    return {
      data:[],
      charts:null,
      timeFn:null,
      geoCoordMap:{},
      cityName:""
    };
  },
  props:{
    comJson:{
      type:Object,
      default:function(){
        return {linaData:[],cityList:[],geoCoord:{},config:{}}
      }
    }
  },
  watch:{
    comJson:{
      handler:function(){
        this.whatfuck()
      },
      deep:true
    }
  },
  computed: {},
  created(){
    this.getStore();
  },
  mounted(){
    this.whatfuck()
  },
  methods: {
    let that = this
    if(that.charts){
      that.charts.dispose()
    }
    that.charts=that.$echarts.init(document.getElementById("moveMapChart"))
    let cityList = that.comJson.cityList.length === 0?[that.cityName]:this.comJson.cityList
    let text = that.comJson.config.text||""
    that.geoCoordMap = that.comJson.geoCoord
    let convertData = function(data){
      let res = []
      for (let i = 0; i < data.length; i++) {
        let dataItem = data[i]
        let fromCoord = that.geoCoordMap[dataItem[0].name]
        let toCoord = that.geoCoordMap[dataItem[1].name]
        if(fromCoord && toCoord){
          res.push({
            coords:[fromCoord,toCoord],
            info:[dataItem[0].name,dataItem[1].name,dataItem[0].value]
          })
        }
      }
      return res
    }
    let series = [
      {
        type:"effectScatter",
        name:"qianXi",
        rippleEffect:{
          brushType:"fill"
        },
        coordinateSystem:"geo",
        symbolSize:10,
        label:{
          show:true,
          position:"right",
          formatter:"{b}"
        },
        itemStyle:{
          color:"#00ffff"
        },
        data:cityList.map(function(item){
          return {name:item,value:that.geoCoordMap[item]}
        }),
        zlevel:2
      }
    ]
    [["qianXi",that.conJson.lineData]].forEach(function(item,i){
      series.push(
        {
          type:"lines",
          name:item[0],
          zlevel:2,
          effect:{
            show:true,
            constantSpeed:20,
            symbol:"triangle",
            symbolSize:6,
            trailLength:0
          },
          lineStyle:{
            color:"#0ff",
            1.5,
            opacity:0.4,
            curveness:0.2
          },
          label:{
            show:true
          },
          data:convertData(item[1])
        }
      )
    })
    let mapBoxOption={
      backgroundColor:"#0c1a3c",
      title:{
        text:text,
        textStyle:{
          color:"#fff"
        },
        left:"center",
        top:26
      },
      tooltip:{
        show:true
      },
      geo:{
        map:"china",
        roam:true,
        aspectScale:0.75,
        zoom:1,
        label:{
          show:false,
          textStyle:{
            color:"#00a0c9"
          }
        },
        itemStyle:{
          areaColor:"#0f1f48",
          borderColor:"#3598dc"
        },
        emphasis:{
          label:{
            show:false,
            textStyle:{
              color:"#00a0c9"
            }
          },
          itemStyle:{
            borderWidth:0,
            borderColor:"#0066ba",
            areaColor:"#0f1f48",
            shadowColor:"rgba(0,0,0,0.5)"
          }
        },
        left:"16%",
        top:"12%",
        tooltip:{
          show:true,
          formatter:function(par){
            if(par.componentType==="series"){
              if(par.data.info){
                return (par.data.info[0]+"->"+par.data.info[1]+":"+par.data.info[2])
              }
            }
          }else{
            return ""
          }
        }
      },
      series:series
    }
    that.charts.setOption(mapBoxOption)
    that.charts.resize()
  },
  getStore(){
    this.cityName = JSON.parse(window.localStorage.getItem("store")).user.userInfo.organizationName
  }
};
</script>
<style></style>

echarts热力图

<template>
  <div :id="id" style=" 100%; height: 100%"></div>
</template>
<script>
import resize from "@/util/resize";
export default {
  mixins: [resize],
  name: "heatMap",
  props: {
    id: {
      type: String,
      default: "heatMap",
    },
    comJSON: {
      type: Object,
      default: function () {
        return { data: {}, config: {} };
      },
    },
  },
  data() {
    return {
      charts: null,
    };
  },
  watch: {
    comJSON: {
      handler: function () {
        this.drawLineChart();
      },
      deep: true,
    },
  },
  mounted() {
    this.drawLineChart();
  },
  methods: {
    drawLineChart() {
      //set data and config
      let titleName = this.comJSON.data.title ? this.comJSON.data.title : "";
      let min = this.comJSON.config.min ? this.comJSON.config.min : 0;
      let max = this.comJSON.config.max ? this.comJSON.config.max : 100;
      let xName =
        this.comJSON.data.xArray && this.comJSON.data.xArray.length
          ? this.comJSON.data.xArray
          : [];
      let yName =
        this.comJSON.data.yArray && this.comJSON.data.yArray.length
          ? this.comJSON.data.yArray
          : [];
      let chartData =
        this.comJSON.data.chartData && this.comJSON.data.chartData.length
          ? this.comJSON.data.chartData
          : [];
      chartData = chartData.map(function (item) {
        return [item[0], item[1], item[2] || "-"];
      });

      let series = [];
      let option = {
        title: {
          text: titleName,
          top: "4%",
          left: "center",
        },
        tooltip: {
          position: "top",
        },
        grid: {
          height: "auto",
          top: "16%",
        },
        xAxis: {
          type: "category",
          data: xName,
          axisLine: {
            show: false,
          },
          axisTick: {
            show: false,
          },
          splitArea: {
            show: true,
          },
        },
        yAxis: {
          type: "category",
          name: "单位:面积",
          data: yName,
          axisLine: {
            show: false,
          },
          axisTick: {
            show: false,
          },
          splitArea: {
            show: true,
          },
        },
        visualMap: {
          min: min,
          max: max,
          inRange: {
            color: ["#8fdffd", "#8ec8fe", "#59adfc", "#2e99fd", "#3082fe"],
          },
          calculable: true,
          inverse: true,
          top: "10%",
          left: "center",
          orient: "horizontal",
          type: "piecewise",
        },
        series: [
          {
            type: "heatmap",
            data: chartData,
            label: {
              show: true,
            },
            itemStyle: {
              borderWidth: "2",
              borderColor: "#fff",
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowColor: "rgba(0,0,0,0.5)",
              },
            },
          },
        ],
      };
      if (this.charts) {
        this.charts.dispose();
      }
      this.charts = this.$echarts.init(document.getElementById(this.id));
      this.charts.setOption(option, true);
      this.charts.resize();
    },
  },
};
</script>
<style lang="scss" scoped></style>

原文地址:https://www.cnblogs.com/chyshy/p/13212691.html