// 对于次数等统计不允许出现小数的情况,
// 折线图的处理是
// props.count_list.push(0, 0, 0, 0, 0, 5)

// 柱形图的处理是 原始数据最大值小于 5 数轴设置 max 5
// if (Math.max(...props.map(e => e.num)) <= 5) {
// option.yAxis[0].max = 5
// }

const colorStartArray = [
'#3c89ff',
'#ffa900',
'#70bb68',
'#02cbc7',
'#ff6289',
'#9d56df',
'#585ae1',
'#02cbc7',
'#3c89ff',
'#ffa900',
'#70bb68',
'#02cbc7',
'#ff6289',
'#9d56df',
'#585ae1'
];

const colorBarArray = [
'#3049b0',
'#0085e8',
'#01d6e6',
'#dcd44b',
'#de9209'
];

const colorCardArray = [
'#1639a4',
'#027da6',
'#1c929e',
'#0266bb',
'#91841a',
'#9a660e',
'#9b4e35'
];

const colorEndArray = [
'rgba(60, 137, 255, 0.5)',
'rgba(255, 169, 0, 0.5)',
'rgba(112, 187, 104, 0.5)',
'rgba(2, 203, 199, 0.5)',
'rgba(255, 98, 137, 0.5)',
'rgba(157, 86, 223, 0.5)',
'rgba(88, 90, 225, 0.5)',
'rgba(2, 203, 199, 0.3)',
'rgba(60, 137, 255, 0.5)',
'rgba(255, 169, 0, 0.5)',
'rgba(112, 187, 104, 0.5)',
'rgba(2, 203, 199, 0.5)',
'rgba(255, 98, 137, 0.5)',
'rgba(157, 86, 223, 0.5)',
'rgba(88, 90, 225, 0.5)'
];

const getLinear = (index, type) => {
index %= colorStartArray.length
if (type === 1) {

// 适用于纵向柱状图
return new echarts.graphic.LinearGradient(
  0, 0, 1, 1, [
    {offset: 1, color: colorStartArray[index]},
    {offset: 0, color: colorEndArray[index]}
  ]
)

} else if (type === 2) {

// 适用于横向柱状图
return new echarts.graphic.LinearGradient(
  0, 0, 1, 1, [
    {offset: 0, color: colorStartArray[index]},
    {offset: 1, color: colorEndArray[index]}
  ]
)

}
// 扇形图
return new echarts.graphic.LinearGradient(

0, 0, 0, 1, [
  {offset: 0, color: colorStartArray[index]},
  {offset: 1, color: colorEndArray[index]}
]

)
}

const getLinearByParams = (params) => {
return new echarts.graphic.LinearGradient(

0, 0, 0, 1, [
  {offset: params[0], color: params[1]},
  {offset: params[2], color: params[3]}
]

)
}

const getTitle = (label) => {
return {

show: false,
text: label,
x: 'left',
y: 'top',
textStyle: {
  fontSize: 16,
  color: '#ffffff'
}

}
}

const matchMedia = () => {
/*

  • 用于判断屏幕大小的函数,便于给 chart 添加变量

*/
let media = "";
if (window.matchMedia('(min-height:800px) and (max-height:900px)').matches) {

media = 'middle';

} else if (window.matchMedia('(max-height:800px)').matches) {

media = 'min';

} else {

media = 'max';

}
return media;
}

const filterNum = (val) => {
/*

  • 用于格式化纵坐标

*/
if ( val !== 0 && (!val || isNaN(val)) ) {

return val;

}
let num = Number(val);
if (Math.abs(num) > 100000000) {

return (num / 100000000).toFixed(0) + '亿';

} else if (Math.abs(num) > 10000) {

return (num / 10000).toFixed(0) + '万';

} else {

return num;

}
return num
}

const pieOption = (props, chartTitle) => {
return {

tooltip: {
  trigger: 'item',
  formatter: (val) => {
    return `<div class="tooltip_person_wrap">${val.data.code}: ${val.value} (${val.percent}%)</div>`
  },
  extraCssText: 'border: 1px solid #319aff; z-index: 333; box-sizing: border-box;'
},
title: getTitle(chartTitle),
grid: {
  left: '15%',
  top: '10%',
  height: '74%',
  width: '70%',
  containLabel: true
},
series: [{
  name: '',
  type: 'pie',
  radius: ['30%', '60%'],
  center: ['50%', '55%'],
  minAngle: 15,
  roseType: false,
  color: [
    '#ff6a83',
    '#ffd188',
    '#3988ff',
    '#0f5ed6',
    '#003da9',
    '#04dfff',
    '#00dcda',
    '#018b89'
  ],
  label: {
    normal: {
      color: '#3988ff'
    }
  },
  data: props.map((e, i) => {
    e.labelLine = {
      normal: {
        lineStyle: {
          color: colorStartArray[i]
        }
      }
    };
    e.label = {
      normal: {
        color: colorStartArray[i % 15]
      }
    };
    e.itemStyle = {
      normal: {
        color: getLinear(i)
      }
    };
    e.code = e.name;
    const str = e.name.toString();
    if (str.length > 9) {
      e.name = e.name.toString().slice(0, 9) + '...';
    } else {
      e.name = e.name;
    }
    e.value = e.account;
    return e;
  })
}]

}
}

const barOption = (props, chartTitle, barColors) => {
const toStringSize = matchMedia() == 'max' ? 6 : 4;
const option = {

title: getTitle(chartTitle),
grid: {
  right: '8%',
  left: '8%',
  top: '5%',
  bottom: '20%'
},
tooltip: {
  trigger: 'axis',
  extraCssText: 'padding: 4px 8px; border: 1px solid #319aff; z-index: 333; box-sizing: border-box;',
  axisPointer: {
    type: 'shadow'
  },
  formatter: (val) => {
    return val[0].data.name +
      '<br /><span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' +
      val[0].color.colorStops[0].color + '"></span>' +
      val[0].data.value
  }
},
xAxis: [{
  type: 'category',
  data: props.map((e, i) => {
    const str = e.riskName.toString();
    if (str.length > toStringSize) {
      return e.riskName.toString().slice(0, toStringSize) + '...';
    }
    return e.riskName;
  }),
  axisLabel: {
    interval: 0,
    show: true,
    rotate: 320,
    fontSize: 10,
    textStyle: {
      color: '#e8e8e8'
    }
  },
  axisTick: {
    show: false
  },
  splitLine: {
    lineStyle: {
      show: false,
      color: '#e8e8e8',
      width: 1
    }
  },
  axisLine: {
    lineStyle: {
      show: false,
      color: '#e8e8e8',
      width: 1
    }
  }
}],
yAxis: [{
  type: 'value',
  axisLabel: {
    interval: 0,
    show: true,
    textStyle: {
      color: '#e8e8e8'
    },
    formatter: (val) => {
      return filterNum(val);
    }
  },
  axisTick: {
    show: false
  },
  axisLine: {
    show: true,
    lineStyle: {
      color: '#e8e8e8',
      width: 1
    }
  },
  splitLine: {
    show: false,
    lineStyle: {
      color: '#e8e8e8',
      width: 1
    }
  }
}],
series: [{
  name: '漏洞数',
  type: 'bar',
  barWidth: '3',
  silent: true,
  data: props.map((e, i) => {
    e.name = e.riskName
    e.value = e.count
    e.itemStyle = {
      normal: {
        color: getLinearByParams([0.1, barColors[0], 1, barColors[1]])
      }
    }
    return e
  })
}]

}
if (Math.max(...props.map((e) => e.num)) <= 5) {

option.yAxis[0].max = 5

}
return option
}

const composeOption = (props, chartTitle, barColors) => {
const seriesArr = [];
const isEllipsis = matchMedia() == 'min';
if (props && props.maliceTypeArr && props.maliceTypeArr.length) {

props.maliceTypeArr.map( (o, i) => {
  const temp = {
    name: o.name,
    type: 'bar',
    stack: '总量',
    barWidth: '3px',
    label: {
      normal: {
        show: false,
        position: 'insideRight'
      }
    },
    itemStyle: {
      normal: {
        color: colorBarArray[i % 5]
      }
    },
    data: o.data
  }
  seriesArr.push(temp);
})

}
return {

title: getTitle(chartTitle),
tooltip: {
  trigger: 'axis',
  axisPointer: { // 坐标轴指示器,坐标轴触发有效
    type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
  }
},
legend: {
  show: false,
  data: props.maliceNameArr
},
grid: {
  top: '2%',
  left: '3%',
  right: 25,
  bottom: '3%',
  containLabel: true
},
xAxis: {
  type: 'value',
  // 坐标轴的分割段数,需要注意的是这个分割段数只是个预估值,最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整。
  splitNumber: 3,
  axisLabel: {
    interval: 0,
    show: true,
    textStyle: {
      color: '#e8e8e8'
    },
    formatter: (val) => {
      return filterNum(val);
    }
  },
  axisTick: {
    show: false
  },
  axisLine: {
    show: true,
    lineStyle: {
      color: '#e8e8e8',
      width: 1
    }
  },
  splitLine: {
    show: false,
    lineStyle: {
      color: '#e8e8e8',
      width: 1
    }
  }
},
yAxis: {
  type: 'category',
  zlevel: 1,
  axisTick: {
    show: false
  },
  axisLine: {
    show: true,
    lineStyle: {
      color: '#d7dae9',
      width: 1
    }
  },
  splitLine: {
    show: false
  },
  data: props.locationNameArr.map((e, i) => {
    const str = e.toString();
    if (isEllipsis && str.length > 3) {
      return e.toString().slice(0, 3) + '...';
    }
    return e;
  }),
},
series: seriesArr

};
}

const waterOption = (numParam, chartTitle) => {
const option = {

title: getTitle(chartTitle),
series: [{
  type: 'liquidFill',
  data: [{
    value: numParam / 100,
    itemStyle: {
      normal: {
        color: getLinearByParams([0.1, '#00dbda', 1, '#00b5d6'])
      }
    }
  }],
  label: {
    normal: {
      formatter(param) {
        return numParam + '分'
      },
      textStyle: {
        color: '#fff',
        insideColor: '#000',
        fontSize: 40
      }
    }
  },
  backgroundStyle: {
    color: '#e8e8e8' // 球状的背景颜色
  },
  outline: {
    show: true, // 是否显示轮廓 布尔值
    borderDistance: 0, // 外部轮廓与图表的距离 数字
    itemStyle: {
      borderColor: '#00dbda', // 边框的颜色
      borderWidth: 1, // 边框的宽度
      // shadowBlur: 5 , // 外部轮廓的阴影范围 一旦设置了内外都有阴影
      shadowColor: '#fff' // 外部轮廓的阴影颜色
    }
  },
  radius: '70%', // 水波图的半径
  center: ['50%', '55%']
}]

};
return option
}

const trendOption = (props, chartTitle) => {
// 全局的 统计趋势配置 ECHARTS
if (props.trend_series[props.trend_active].series_type !== 'rate') {

props.trend_series[props.trend_active].series_datalist.push(0, 0, 0, 0, 5)

}
const option = {

title: getTitle(chartTitle),
grid: {
  right: '7%',
  left: '8%',
  top: '20%',
  bottom: '12%'
},
tooltip: {
  trigger: 'axis',
  extraCssText: 'padding: 4px 8px; text-align: left; z-index: 333; box-sizing: border-box; border: 1px solid ' + colorStartArray[props.trend_active] + ';',
  formatter: (prop) => {
    if (props.trend_series[props.trend_active].series_type === 'rate') {
      return `${prop[0].axisValue}
                        <br/>
                        <span 
                          style="
                            display: inline-block;
                            margin-right: 5px;
                            border-radius: 10px;
                            width: 9px;
                            height: 9px;
                            background-color: ${colorStartArray[props.trend_active]};">
                        </span>
                        检测APP数量: ${Number(prop[0].value * 100).toFixed(2)} %`
    }
    return `${prop[0].axisValue}
                        <br/>
                        <span 
                          style="
                            display: inline-block;
                            margin-right: 5px;
                            border-radius: 10px;
                            width: 9px;
                            height: 9px;
                            background-color: ${colorStartArray[props.trend_active]};">
                        </span>
                        检测APP数量:  ${prop[0].value}`
  },
  axisPointer: {
    lineStyle: {
      color: colorStartArray[props.trend_active]
    }
  }
},
xAxis: {
  type: 'category',
  boundaryGap: false,
  data: props.trend_series[props.trend_active].series_coord_list,
  axisLabel: {
    // interval: 0,
    show: true,
    margin: 14,
    textStyle: {
      color: '#5a5a5a'
    }
  },
  axisTick: {
    show: true
  },
  splitLine: {
    lineStyle: {
      show: false,
      color: '#5a5a5a',
      width: 1
    }
  },
  axisLine: {
    lineStyle: {
      show: false,
      color: '#5a5a5a',
      width: 1
    }
  }
},
yAxis: {
  type: 'value',
  axisLabel: {
    interval: 0,
    margin: 10,
    show: true,
    textStyle: {
      color: '#5a5a5a'
    },
    formatter: (val) => {
      let res = null;
      if (props.trend_series[props.trend_active].series_type === 'rate') {
        res = (val * 100).toFixed(2) + '%'
      } else {
        res = val
      }
      return res
    }
  },
  axisTick: {
    show: false
  },
  axisLine: {
    show: true,
    lineStyle: {
      color: '#5a5a5a',
      width: 1
    }
  },
  splitLine: {
    lineStyle: {
      show: false,
      color: '#bcbcbc',
      width: 1
    }
  }
},
// trend_series: [
//   {
//     series_title: '安全事件数',
//     series_type: 'number',
//     series_index: 0,
//     series_url: '',
//     series_params: {},
//     series_coord_list: [],
//     series_datalist: [],
//   }
// ],
series: [{
  name: props.trend_series[props.trend_active].series_title,
  type: 'line',
  showSymbol: false,
  silent: true,
  itemStyle: {
    normal: {
      color: colorStartArray[props.trend_active]
    },
    emphasis: {
      color: colorStartArray[props.trend_active]
    }
  },
  // lineStyle: {
  //   normal: {
  //     type: 'dashed'
  //   }
  // },
  cursor: 'pointer',
  areaStyle: {
    normal: {
      color: getLinear(props.trend_active)
    }
  },
  data: props.trend_series[props.trend_active].series_datalist
}]

}
return option
}

const roseOption = (params, chartTitle) => {
const angleArr = [];
const valueData = [];
if ( params && params.length ) {

params.map( (o) => {
  angleArr.push( o.privacyName ? o.privacyName : '未知数据' );
})
params.map( (o) => {
  valueData.push(o.count);
})

}
return {

title: getTitle(chartTitle),
tooltip: {
  trigger: 'axis',
  extraCssText: 'padding: 4px 8px; text-align: left; z-index: 333; box-sizing: border-box; border: 1px solid #f0f0f0;',
  formatter: (prop) => {
    return `<span 
              style="
                display: inline-block;
                margin-right: 5px;
                border-radius: 10px;
                width: 9px;
                height: 9px;">
            </span>
            ${prop[0].name}:  ${prop[0].value}`
  }
},
angleAxis: {
  type: 'category',
  data: angleArr,
  z: 10,
  axisLabel: {
    show: true,
    color: '#f0f0f0',
    fontSize: 10,
    formatter: (e) => {
      const str = e.toString();
      if (str.length > 5) {
        e = e.toString().slice(0, 5) + '...';
      } else {
        e = e;
      }
      return e;
    }
  },
  axisTick: {
    show: false,
    lineStyle: {
      show: false,
      color: '#00baff'
    }
  },
  axisLine: {
    show: false,
    lineStyle: {
      show: true,
      color: '#00baff'
    }
  }
},
radiusAxis: {
  minInterval: 1,
  splitNumber: 3,
  splitLine: {
    show: true,
    lineStyle: {
      show: false,
      color: '#00baff'
    }
  },
  axisLine: {
    show: false,
    lineStyle: {
      show: false,
      color: '#00baff'
    }
  },
  axisLabel: {
    show: true,
    color: '#00baff',
    fontSize: 10,
    formatter: (val) => {
      return filterNum(val);
    }
  },
  axisTick: {
    show: false,
    lineStyle: {
      show: false,
      color: '#00baff'
    }
  }
},
polar: {
},
series: [{
  type: 'bar',
  data: valueData,
  barMaxWidth: '50px',
  coordinateSystem: 'polar',
  name: 'A',
  stack: 'a',
  itemStyle: {
    color: 'rgba(0,186,255,0.5)'
  }
}],
legend: {
  show: false,
  data: ['A', 'B', 'C']
}

};
}

const sankeyOption = (params, chartTitle) => {
const option = {

color: colorStartArray,
title: getTitle(chartTitle),
grid: {
  right: '8%',
  left: '8%',
  top: '100'
},
tooltip: {
  trigger: 'item',
  triggerOn: 'mousemove'
},
series: [{
  type: 'sankey',
  data: params.nodes,
  links: params.links,
  focusNodeAdjacency: 'allEdges',
  label: {
    normal: {
      color: '#3988ff'
    }
  },
  itemStyle: {
    normal: {
      borderWidth: 0
    }
  },
  lineStyle: {
    normal: {
      color: 'source',
      curveness: 0.5
    }
  }
}]

};
return option
}

const treeOption = (params, chartTitle) => {
const option = {

color: colorCardArray,
title: getTitle(chartTitle),
grid: {
  right: '8%',
  left: '8%',
  top: '100',
  bottom: '0%'
},
tooltip: {
  trigger: 'item',
  triggerOn: 'mousemove'
},
series: [{
  type: 'treemap',
  breadcrumb: {
    show: false
  },
  data: params.map( (e) => {
    e.name = e.countryName ? e.countryName : '未知国家';
    e.value = e.count;
    return e;
  })
}]

};
return option
}

const emptyOption = (chartTitle) => {
const option = {

title: {
  subtext: '暂无数据',
  text: chartTitle,
  x: 'center',
  y: 'center',
  subtextStyle: {
    color: '#3988ff',
    fontWeight: 'lighter',
    fontSize: 13
  },
  textStyle: {
    color: '#ffffff',
    fontWeight: 'bold',
    fontSize: 16
  }
},
series: [{
  type: 'pie',
  radius: ['58%', '72%'],
  silent: true,
  label: {
    normal: {
      show: false
    }
  },
  data: [{
    value: 1,
    itemStyle: {
      normal: {
        color: '#bcbccf',
        shadowBlur: 2,
        shadowColor: '#bcbccf'
      }
    }
  }],
  animation: false
}, {
    type: 'pie',
    radius: ['58%', '72%'],
    silent: true,
    label: {
      normal: {
        show: false
      }
    },
    data: [{
      value: 1,
      itemStyle: {
        normal: {
          color: '#bcbccf',
          shadowBlur: 20,
          shadowColor: '#bcbccf'
        }
      }
    }],
    animation: false
  }, {
    name: 'main',
    type: 'pie',
    radius: ['72%', '78%'],
    label: {
      normal: {
        show: false
      }
    },
    data: [{
      value: 0.67,
      itemStyle: {
        normal: {
          color: '#3988ff',
          shadowBlur: 10,
          shadowColor: '#3988ff'
        }
      }
    }, {
      value: 0.5,
      itemStyle: {
        normal: {
          color: 'transparent'
        }
      }
    }],
    animationEasingUpdate: 'cubicInOut',
    animationDurationUpdate: 500
  }
]

};
return option
}

export {
roseOption,
treeOption,
composeOption,
waterOption,
trendOption,
barOption,
pieOption,
sankeyOption,
emptyOption
}


亲爱的阿乾
885 声望22 粉丝

此时无能为力,此心随波逐流