vue 页面
<template>
<div class="echarts">
<div ref="dom" class="charts chart-bar" style="width:100%;height:100%;"></div>
</div>
</template>
<script>
import echarts from 'echarts'
import tdTheme from './theme.json'
import {
on,
off
} from '@/libs/tools'
echarts.registerTheme('tdTheme', tdTheme)
export default {
name: 'sunburst',
props: {
value: {
type: Array,
default () {
return [{
name: '',
itemStyle: {
normal: {
color: '#FF7853'
}
},
children: [{
name: '小说',
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#fff'
},
children: [{
name: '5☆',
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#fff'
},
children: [{
name: '疼',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}, {
name: '慈悲',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}, {
name: '楼下的房客',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}]
}, {
name: '4☆',
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#fff'
},
children: [{
name: '虚无的十字架',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}, {
name: '无声告白',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}, {
name: '童年的终结',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}]
}, {
name: '3☆',
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#fff'
},
children: [{
name: '疯癫老人日记',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}]
}]
}, {
name: '其他',
itemStyle: {
color: '#FFAE57'
},
children: [{
name: '5☆',
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#fff'
},
children: [{
name: '纳博科夫短篇小说全集',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}]
}, {
name: '4☆',
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#fff'
},
children: [{
name: '安魂曲',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}, {
name: '人生拼图版',
value: 1,
itemStyle: {
color: '#28b44b'
},
label: {
fontSize: 10,
color: '#28b44b'
}
}]
}, {
name: '3☆',
itemStyle: {
color: '#FFAE57'
},
label: {
fontSize: 10,
color: '#fff'
},
children: [{
name: '比起爱你,我更需要你',
value: 1,
itemStyle: {
color: '#FFAE57',
// borderWidth: 3
}
,
label: {
fontSize: 10,
color: '#FFAE57'
}
}]
}]
}]
}];
}
}
},
data() {
return {
dom: null,
legend: [],
bgColor: '#fff',
colors: ['#FFAE57', '#FF7853', '#EA5151', '#CC3F57', '#9A2555'],
itemStyle: {
}
}
},
watch: {
yData() {
this.setEcharts();
}
},
methods: {
resize() {
this.dom.resize()
},
setEcharts() {
this.legend = this.value.legendData;
var that = this;
this.$nextTick(() => {
var option = {
backgroundColor: this.bgColor,
color: this.colors,
series: [{
type: 'sunburst',
center: ['50%', '48%'],
data: this.value,
sort: function(a, b) {
if (a.depth === 1) {
return b.getValue() - a.getValue();
} else {
return a.dataIndex - b.dataIndex;
}
},
label: {
rotate: 'radial',
color: this.bgColor
},
itemStyle: {
borderColor: this.bgColor,
borderWidth: 2
},
levels: [{},
{
r0: 0,
r: 10,
label: {
rotate: 0
}
}, {
r0: 10,
r: 105
}, {
r0: 115,
r: 140,
itemStyle: {
shadowBlur: 2,
shadowColor: that.colors[2],
color: 'transparent'
},
label: {
rotate: 'tangential',
fontSize: 10,
color: that.colors[0]
}
}, {
r0: 140,
r: 145,
itemStyle: {
shadowBlur: 80,
shadowColor: that.colors[0]
},
label: {
position: 'outside',
// textShadowBlur: 5,
// textShadowColor: '#333',
},
downplay: {
label: {
opacity: 0.5
}
}
}
]
}]
};
this.dom = echarts.init(this.$refs.dom, 'tdTheme')
// 双击事件
this.dom.on('dblclick', (param) => {
console.log(param)
})
this.dom.setOption(option)
//单击后执行操作
this.dom.on('click', (param) => {
this.$emit("click", param);
});
on(window, 'resize', this.resize)
})
}
},
mounted() {
this.itemStyle = {
star5: {
color: this.colors[0]
},
star4: {
color: this.colors[1]
},
star3: {
color: this.colors[2]
},
star2: {
color: this.colors[3]
},
star1: {
color: this.colors[4]
}
};
// var that = this;
// for (var j = 0; j < this.value.length; ++j) {
// var level1 = this.value[j].children;
// for (var i = 0; i < level1.length; ++i) {
// var block = level1[i].children;
// var bookScore = [];
// var bookScoreId;
// for (var star = 0; star < block.length; ++star) {
// var style = (function(name) {
// switch (name) {
// case '5☆':
// bookScoreId = 0;
// return that.itemStyle.star5;
// case '4☆':
// bookScoreId = 1;
// return that.itemStyle.star4;
// case '3☆':
// bookScoreId = 2;
// return that.itemStyle.star3;
// case '2☆':
// bookScoreId = 3;
// return that.itemStyle.star2;
// case '1☆':
// bookScoreId = 4;
// return that.itemStyle.star1;
// }
// })(block[star].name);
//
// block[star].label = {
// color: style.color,
// downplay: {
// opacity: 0.5
// }
// };
//
// if (block[star].children) {
// style = {
// opacity: 1,
// color: style.color
// };
// block[star].children.forEach(function(book) {
// book.value = 1;
// book.itemStyle = style;
//
// book.label = {
// color: style.color
// };
//
// var value = 1;
// if (bookScoreId === 0 || bookScoreId === 3) {
// value = 5;
// }
//
// if (bookScore[bookScoreId]) {
// bookScore[bookScoreId].value += value;
// } else {
// bookScore[bookScoreId] = {
// color: that.colors[bookScoreId],
// value: value
// };
// }
// });
// }
// }
//
// level1[i].itemStyle = {
// color: that.value[j].itemStyle.color
// };
// }
// }
this.setEcharts();
},
beforeDestroy() {
off(window, 'resize', this.resize)
}
}
</script>
<style>
.echarts {
width: 100%;
margin-top: 10px;
height: calc(100vh - 190px);
}
</style>
theme.json
{
"color": [
"#2d8cf0",
"#19be6b",
"#ff9900",
"#E46CBB",
"#9A66E4",
"#ed3f14"
],
"backgroundColor": "rgba(0,0,0,0)",
"textStyle": {},
"title": {
"textStyle": {
"color": "#516b91"
},
"subtextStyle": {
"color": "#93b7e3"
}
},
"line": {
"itemStyle": {
"normal": {
"borderWidth": "2"
}
},
"lineStyle": {
"normal": {
"width": "2"
}
},
"symbolSize": "6",
"symbol": "emptyCircle",
"smooth": true
},
"radar": {
"itemStyle": {
"normal": {
"borderWidth": "2"
}
},
"lineStyle": {
"normal": {
"width": "2"
}
},
"symbolSize": "6",
"symbol": "emptyCircle",
"smooth": true
},
"bar": {
"itemStyle": {
"normal": {
"barBorderWidth": 0,
"barBorderColor": "#ccc"
},
"emphasis": {
"barBorderWidth": 0,
"barBorderColor": "#ccc"
}
}
},
"pie": {
"itemStyle": {
"normal": {
"borderWidth": 0,
"borderColor": "#ccc"
},
"emphasis": {
"borderWidth": 0,
"borderColor": "#ccc"
}
}
},
"scatter": {
"itemStyle": {
"normal": {
"borderWidth": 0,
"borderColor": "#ccc"
},
"emphasis": {
"borderWidth": 0,
"borderColor": "#ccc"
}
}
},
"boxplot": {
"itemStyle": {
"normal": {
"borderWidth": 0,
"borderColor": "#ccc"
},
"emphasis": {
"borderWidth": 0,
"borderColor": "#ccc"
}
}
},
"parallel": {
"itemStyle": {
"normal": {
"borderWidth": 0,
"borderColor": "#ccc"
},
"emphasis": {
"borderWidth": 0,
"borderColor": "#ccc"
}
}
},
"sankey": {
"itemStyle": {
"normal": {
"borderWidth": 0,
"borderColor": "#ccc"
},
"emphasis": {
"borderWidth": 0,
"borderColor": "#ccc"
}
}
},
"funnel": {
"itemStyle": {
"normal": {
"borderWidth": 0,
"borderColor": "#ccc"
},
"emphasis": {
"borderWidth": 0,
"borderColor": "#ccc"
}
}
},
"gauge": {
"itemStyle": {
"normal": {
"borderWidth": 0,
"borderColor": "#ccc"
},
"emphasis": {
"borderWidth": 0,
"borderColor": "#ccc"
}
}
},
"candlestick": {
"itemStyle": {
"normal": {
"color": "#edafda",
"color0": "transparent",
"borderColor": "#d680bc",
"borderColor0": "#8fd3e8",
"borderWidth": "2"
}
}
},
"graph": {
"itemStyle": {
"normal": {
"borderWidth": 0,
"borderColor": "#ccc"
}
},
"lineStyle": {
"normal": {
"width": 1,
"color": "#aaa"
}
},
"symbolSize": "6",
"symbol": "emptyCircle",
"smooth": true,
"color": [
"#2d8cf0",
"#19be6b",
"#f5ae4a",
"#9189d5",
"#56cae2",
"#cbb0e3"
],
"label": {
"normal": {
"textStyle": {
"color": "#eee"
}
}
}
},
"map": {
"itemStyle": {
"normal": {
"areaColor": "#f3f3f3",
"borderColor": "#516b91",
"borderWidth": 0.5
},
"emphasis": {
"areaColor": "rgba(165,231,240,1)",
"borderColor": "#516b91",
"borderWidth": 1
}
},
"label": {
"normal": {
"textStyle": {
"color": "#000"
}
},
"emphasis": {
"textStyle": {
"color": "rgb(81,107,145)"
}
}
}
},
"geo": {
"itemStyle": {
"normal": {
"areaColor": "#f3f3f3",
"borderColor": "#516b91",
"borderWidth": 0.5
},
"emphasis": {
"areaColor": "rgba(165,231,240,1)",
"borderColor": "#516b91",
"borderWidth": 1
}
},
"label": {
"normal": {
"textStyle": {
"color": "#000"
}
},
"emphasis": {
"textStyle": {
"color": "rgb(81,107,145)"
}
}
}
},
"categoryAxis": {
"axisLine": {
"show": true,
"lineStyle": {
"color": "#cccccc"
}
},
"axisTick": {
"show": false,
"lineStyle": {
"color": "#333"
}
},
"axisLabel": {
"show": true,
"textStyle": {
"color": "#999999"
}
},
"splitLine": {
"show": true,
"lineStyle": {
"color": [
"#eeeeee"
]
}
},
"splitArea": {
"show": false,
"areaStyle": {
"color": [
"rgba(250,250,250,0.05)",
"rgba(200,200,200,0.02)"
]
}
}
},
"valueAxis": {
"axisLine": {
"show": true,
"lineStyle": {
"color": "#cccccc"
}
},
"axisTick": {
"show": false,
"lineStyle": {
"color": "#333"
}
},
"axisLabel": {
"show": true,
"textStyle": {
"color": "#999999"
}
},
"splitLine": {
"show": true,
"lineStyle": {
"color": [
"#eeeeee"
]
}
},
"splitArea": {
"show": false,
"areaStyle": {
"color": [
"rgba(250,250,250,0.05)",
"rgba(200,200,200,0.02)"
]
}
}
},
"logAxis": {
"axisLine": {
"show": true,
"lineStyle": {
"color": "#cccccc"
}
},
"axisTick": {
"show": false,
"lineStyle": {
"color": "#333"
}
},
"axisLabel": {
"show": true,
"textStyle": {
"color": "#999999"
}
},
"splitLine": {
"show": true,
"lineStyle": {
"color": [
"#eeeeee"
]
}
},
"splitArea": {
"show": false,
"areaStyle": {
"color": [
"rgba(250,250,250,0.05)",
"rgba(200,200,200,0.02)"
]
}
}
},
"timeAxis": {
"axisLine": {
"show": true,
"lineStyle": {
"color": "#cccccc"
}
},
"axisTick": {
"show": false,
"lineStyle": {
"color": "#333"
}
},
"axisLabel": {
"show": true,
"textStyle": {
"color": "#999999"
}
},
"splitLine": {
"show": true,
"lineStyle": {
"color": [
"#eeeeee"
]
}
},
"splitArea": {
"show": false,
"areaStyle": {
"color": [
"rgba(250,250,250,0.05)",
"rgba(200,200,200,0.02)"
]
}
}
},
"toolbox": {
"iconStyle": {
"normal": {
"borderColor": "#999"
},
"emphasis": {
"borderColor": "#666"
}
}
},
"legend": {
"textStyle": {
"color": "#999999"
}
},
"tooltip": {
"axisPointer": {
"lineStyle": {
"color": "#ccc",
"width": 1
},
"crossStyle": {
"color": "#ccc",
"width": 1
}
}
},
"timeline": {
"lineStyle": {
"color": "#8fd3e8",
"width": 1
},
"itemStyle": {
"normal": {
"color": "#8fd3e8",
"borderWidth": 1
},
"emphasis": {
"color": "#8fd3e8"
}
},
"controlStyle": {
"normal": {
"color": "#8fd3e8",
"borderColor": "#8fd3e8",
"borderWidth": 0.5
},
"emphasis": {
"color": "#8fd3e8",
"borderColor": "#8fd3e8",
"borderWidth": 0.5
}
},
"checkpointStyle": {
"color": "#8fd3e8",
"borderColor": "rgba(138,124,168,0.37)"
},
"label": {
"normal": {
"textStyle": {
"color": "#8fd3e8"
}
},
"emphasis": {
"textStyle": {
"color": "#8fd3e8"
}
}
}
},
"visualMap": {
"color": [
"#516b91",
"#59c4e6",
"#a5e7f0"
]
},
"dataZoom": {
"backgroundColor": "rgba(0,0,0,0)",
"dataBackgroundColor": "rgba(255,255,255,0.3)",
"fillerColor": "rgba(167,183,204,0.4)",
"handleColor": "#a7b7cc",
"handleSize": "100%",
"textStyle": {
"color": "#333"
}
},
"markPoint": {
"label": {
"normal": {
"textStyle": {
"color": "#eee"
}
},
"emphasis": {
"textStyle": {
"color": "#eee"
}
}
}
}
}
tools.js
export const forEach = (arr, fn) => {
if (!arr.length || !fn) return
let i = -1
let len = arr.length
while (++i < len) {
let item = arr[i]
fn(item, i, arr)
}
}
/**
* @param {Array} arr1
* @param {Array} arr2
* @description 得到两个数组的交集, 两个数组的元素为数值或字符串
*/
export const getIntersection = (arr1, arr2) => {
let len = Math.min(arr1.length, arr2.length)
let i = -1
let res = []
while (++i < len) {
const item = arr2[i]
if (arr1.indexOf(item) > -1) res.push(item)
}
return res
}
/**
* @param {Array} arr1
* @param {Array} arr2
* @description 得到两个数组的并集, 两个数组的元素为数值或字符串
*/
export const getUnion = (arr1, arr2) => {
return Array.from(new Set([...arr1, ...arr2]))
}
/**
* @param {Array} target 目标数组
* @param {Array} arr 需要查询的数组
* @description 判断要查询的数组是否至少有一个元素包含在目标数组中
*/
export const hasOneOf = (targetarr, arr) => {
return targetarr.some(_ => arr.indexOf(_) > -1)
}
/**
* @param {String|Number} value 要验证的字符串或数值
* @param {*} validList 用来验证的列表
*/
export function oneOf (value, validList) {
for (let i = 0; i < validList.length; i++) {
if (value === validList[i]) {
return true
}
}
return false
}
/**
* @param {Number} timeStamp 判断时间戳格式是否是毫秒
* @returns {Boolean}
*/
const isMillisecond = timeStamp => {
const timeStr = String(timeStamp)
return timeStr.length > 10
}
/**
* @param {Number} timeStamp 传入的时间戳
* @param {Number} currentTime 当前时间时间戳
* @returns {Boolean} 传入的时间戳是否早于当前时间戳
*/
const isEarly = (timeStamp, currentTime) => {
return timeStamp < currentTime
}
/**
* @param {Number} num 数值
* @returns {String} 处理后的字符串
* @description 如果传入的数值小于10,即位数只有1位,则在前面补充0
*/
const getHandledValue = num => {
return num < 10 ? '0' + num : num
}
/**
* @param {Number} timeStamp 传入的时间戳
* @param {Number} startType 要返回的时间字符串的格式类型,传入'year'则返回年开头的完整时间
*/
const getDate = (timeStamp, startType) => {
const d = new Date(timeStamp * 1000)
const year = d.getFullYear()
const month = getHandledValue(d.getMonth() + 1)
const date = getHandledValue(d.getDate())
const hours = getHandledValue(d.getHours())
const minutes = getHandledValue(d.getMinutes())
const second = getHandledValue(d.getSeconds())
let resStr = ''
if (startType === 'year') resStr = year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + second
else resStr = month + '-' + date + ' ' + hours + ':' + minutes
return resStr
}
/**
* @param {String|Number} timeStamp 时间戳
* @returns {String} 相对时间字符串
*/
export const getRelativeTime = timeStamp => {
// 判断当前传入的时间戳是秒格式还是毫秒
const IS_MILLISECOND = isMillisecond(timeStamp)
// 如果是毫秒格式则转为秒格式
if (IS_MILLISECOND) Math.floor(timeStamp /= 1000)
// 传入的时间戳可以是数值或字符串类型,这里统一转为数值类型
timeStamp = Number(timeStamp)
// 获取当前时间时间戳
const currentTime = Math.floor(Date.parse(new Date()) / 1000)
// 判断传入时间戳是否早于当前时间戳
const IS_EARLY = isEarly(timeStamp, currentTime)
// 获取两个时间戳差值
let diff = currentTime - timeStamp
// 如果IS_EARLY为false则差值取反
if (!IS_EARLY) diff = -diff
let resStr = ''
const dirStr = IS_EARLY ? '前' : '后'
// 少于等于59秒
if (diff <= 59) resStr = diff + '秒' + dirStr
// 多于59秒,少于等于59分钟59秒
else if (diff > 59 && diff <= 3599) resStr = Math.floor(diff / 60) + '分钟' + dirStr
// 多于59分钟59秒,少于等于23小时59分钟59秒
else if (diff > 3599 && diff <= 86399) resStr = Math.floor(diff / 3600) + '小时' + dirStr
// 多于23小时59分钟59秒,少于等于29天59分钟59秒
else if (diff > 86399 && diff <= 2623859) resStr = Math.floor(diff / 86400) + '天' + dirStr
// 多于29天59分钟59秒,少于364天23小时59分钟59秒,且传入的时间戳早于当前
else if (diff > 2623859 && diff <= 31567859 && IS_EARLY) resStr = getDate(timeStamp)
else resStr = getDate(timeStamp, 'year')
return resStr
}
/**
* @returns {String} 当前浏览器名称
*/
export const getExplorer = () => {
const ua = window.navigator.userAgent
const isExplorer = (exp) => {
return ua.indexOf(exp) > -1
}
if (isExplorer('MSIE')) return 'IE'
else if (isExplorer('Firefox')) return 'Firefox'
else if (isExplorer('Chrome')) return 'Chrome'
else if (isExplorer('Opera')) return 'Opera'
else if (isExplorer('Safari')) return 'Safari'
}
/**
* @description 绑定事件 on(element, event, handler)
*/
export const on = (function () {
if (document.addEventListener) {
return function (element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false)
}
}
} else {
return function (element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler)
}
}
}
})()
/**
* @description 解绑事件 off(element, event, handler)
*/
export const off = (function () {
if (document.removeEventListener) {
return function (element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false)
}
}
} else {
return function (element, event, handler) {
if (element && event) {
element.detachEvent('on' + event, handler)
}
}
}
})()
/**
* 判断一个对象是否存在key,如果传入第二个参数key,则是判断这个obj对象是否存在key这个属性
* 如果没有传入key这个参数,则判断obj对象是否有键值对
*/
export const hasKey = (obj, key) => {
if (key) return key in obj
else {
let keysArr = Object.keys(obj)
return keysArr.length
}
}
/**
* @param {*} obj1 对象
* @param {*} obj2 对象
* @description 判断两个对象是否相等,这两个对象的值只能是数字或字符串
*/
export const objEqual = (obj1, obj2) => {
const keysArr1 = Object.keys(obj1)
const keysArr2 = Object.keys(obj2)
if (keysArr1.length !== keysArr2.length) return false
else if (keysArr1.length === 0 && keysArr2.length === 0) return true
/* eslint-disable-next-line */
else return !keysArr1.some(key => obj1[key] != obj2[key])
}