桑基图优化
This commit is contained in:
parent
a121765433
commit
719ff5de46
23
README.md
23
README.md
@ -1,18 +1,25 @@
|
|||||||
|
|
||||||
|
## 铸龙-用户行为分析系统
|
||||||
技术栈主要用: Vue + golang
|
|
||||||
|
|
||||||
欢迎大家提出自己的issue。
|
|
||||||
|
|
||||||
铸龙-用户事件分析系统
|
|
||||||
-----------
|
-----------
|
||||||
> 铸龙-用户事件分析系统 是一款用来进行分析用户行为事件的BI软件,功能如下
|
> 铸龙-用户行为分析系统 是一款用于分析用户行为事件的BI软件,功能如下
|
||||||
* 事件分析
|
* 事件分析
|
||||||
* 漏斗分析
|
* 漏斗分析
|
||||||
* 留存分析
|
* 留存分析
|
||||||
* 智能路径分析
|
* 智能路径分析
|
||||||
* 报表,面板管理
|
* 报表,面板管理
|
||||||
|
|
||||||
|
> 技术栈主要用
|
||||||
|
* 前端:vue+elementui+antdv
|
||||||
|
* 后端:go
|
||||||
|
|
||||||
|
> 所需中间件
|
||||||
|
* mysql
|
||||||
|
* redis
|
||||||
|
* kafka
|
||||||
|
* clickhouse
|
||||||
|
|
||||||
|
欢迎大家提出自己的issue。
|
||||||
|
|
||||||
## 相关
|
## 相关
|
||||||
[下载地址]( https://gitee.com/cynthia520/xwl_bi/releases/v1.0.0 )
|
[下载地址]( https://gitee.com/cynthia520/xwl_bi/releases/v1.0.0 )
|
||||||
[文档地址]( https://www.yuque.com/jianghurenchenggolang/oehqme/hen7qy )
|
[文档地址]( https://www.yuque.com/jianghurenchenggolang/oehqme/hen7qy )
|
||||||
|
@ -1,176 +1,213 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :id="className" :class="className" :style="{height:height,width:width}" />
|
<div :class="className" :id="className" :style="{height:height,width:width}"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import echarts from 'echarts'
|
// import echarts from 'echarts'
|
||||||
// require('echarts/theme/macarons') // echarts theme
|
//require('echarts/theme/macarons') // echarts theme
|
||||||
import resize from './mixins/resize'
|
import resize from './mixins/resize'
|
||||||
import { setNotopt } from './mixins/utils'
|
import {setNotopt} from './mixins/utils'
|
||||||
export default {
|
|
||||||
mixins: [resize],
|
|
||||||
props: {
|
|
||||||
className: {
|
|
||||||
type: String,
|
|
||||||
default: 'chart'
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: String,
|
|
||||||
default: '100%'
|
|
||||||
},
|
|
||||||
height: {
|
|
||||||
type: String,
|
|
||||||
default: '400px'
|
|
||||||
},
|
|
||||||
autoResize: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
chartData: {
|
|
||||||
type: Array,
|
|
||||||
default: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
chart: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
|
|
||||||
},
|
export default {
|
||||||
mounted() {
|
mixins: [resize],
|
||||||
this.initChart()
|
props: {
|
||||||
},
|
className: {
|
||||||
beforeDestroy() {
|
type: String,
|
||||||
if (!this.chart) {
|
default: 'chart'
|
||||||
return
|
},
|
||||||
}
|
width: {
|
||||||
this.chart.dispose()
|
type: String,
|
||||||
this.chart = null
|
default: '100%'
|
||||||
},
|
},
|
||||||
methods: {
|
height: {
|
||||||
initChart() {
|
type: String,
|
||||||
this.chart = echarts.init(document.getElementById(this.className))
|
default: '400px'
|
||||||
|
},
|
||||||
this.setOptions()
|
autoResize: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
chartData: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setOptions() {
|
data() {
|
||||||
if (this.chartData.length == 0) {
|
return {
|
||||||
setNotopt(this.chart)
|
chart: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {},
|
||||||
|
mounted() {
|
||||||
|
this.initChart()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (!this.chart) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.chart.dispose()
|
||||||
const eventArr = []
|
this.chart = null
|
||||||
const targetArr = []
|
|
||||||
const eventSet = new Map()
|
|
||||||
for (const k in this.chartData) {
|
|
||||||
const traceCharts = this.chartData[k]
|
|
||||||
|
|
||||||
eventSet.set(traceCharts['event'][0], 1)
|
|
||||||
eventSet.set(traceCharts['event'][1], 1)
|
|
||||||
|
|
||||||
targetArr.push({
|
|
||||||
source: traceCharts['event'][0],
|
|
||||||
target: traceCharts['event'][1],
|
|
||||||
value: traceCharts['sum_user_count']
|
|
||||||
})
|
|
||||||
}
|
|
||||||
eventSet.forEach((v, k, tmp) => {
|
|
||||||
const obj = {
|
|
||||||
name: k
|
|
||||||
}
|
|
||||||
eventArr.push(obj)
|
|
||||||
})
|
|
||||||
|
|
||||||
const option = {
|
|
||||||
toolbox: {
|
|
||||||
feature: {
|
|
||||||
saveAsImage: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
triggerOn: 'mousemove'
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
type: 'sankey',
|
|
||||||
emphasis: {
|
|
||||||
focus: 'adjacency'
|
|
||||||
},
|
|
||||||
nodeAlign: 'left',
|
|
||||||
data: eventArr,
|
|
||||||
links: targetArr,
|
|
||||||
lineStyle: {
|
|
||||||
color: 'source',
|
|
||||||
curveness: 0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
this.chart.setOption(
|
|
||||||
option
|
|
||||||
)
|
|
||||||
} catch (e) {
|
|
||||||
this.setOptions2()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
setOptions2() {
|
methods: {
|
||||||
const eventArr = []
|
initChart() {
|
||||||
const targetArr = []
|
this.chart = echarts.init(document.getElementById(this.className))
|
||||||
const eventSet = new Map()
|
|
||||||
for (const k in this.chartData) {
|
|
||||||
const traceCharts = this.chartData[k]
|
|
||||||
|
|
||||||
eventSet.set(traceCharts['event'][0] + ' ', 1)
|
this.setOptions()
|
||||||
eventSet.set(traceCharts['event'][1] + ' ', 1)
|
|
||||||
|
|
||||||
targetArr.push({
|
},
|
||||||
source: traceCharts['event'][0] + ' ',
|
getColor1() {//固定红色值
|
||||||
target: traceCharts['event'][1] + ' ',
|
var re = "#";
|
||||||
value: traceCharts['sum_user_count']
|
var col = this.color();
|
||||||
})
|
re += col + "FF";
|
||||||
}
|
return re
|
||||||
eventSet.forEach((v, k, tmp) => {
|
},
|
||||||
const obj = {
|
getColor2() {//固定蓝色值
|
||||||
name: k
|
var re = "#FF";
|
||||||
}
|
var col = this.color();
|
||||||
eventArr.push(obj)
|
re += col;
|
||||||
})
|
return re
|
||||||
|
},
|
||||||
|
|
||||||
const option = {
|
color() {
|
||||||
toolbox: {
|
var re = "";
|
||||||
feature: {
|
for (var loopNum = 0; loopNum < 2; loopNum++) {
|
||||||
saveAsImage: {}
|
var temp = Math.floor(256 * Math.random());
|
||||||
|
if (temp < 130 && loopNum == 0) {
|
||||||
|
temp = 130;
|
||||||
}
|
}
|
||||||
},
|
if (temp > 200 && loopNum == 1) {
|
||||||
tooltip: {
|
temp = 200;
|
||||||
trigger: 'item',
|
}
|
||||||
triggerOn: 'mousemove'
|
temp = temp.toString(16);//将数值转换成16进制
|
||||||
},
|
if (temp.length !== 2) {
|
||||||
series: [
|
temp = "0" + temp
|
||||||
{
|
}
|
||||||
type: 'sankey',
|
re += temp//对颜色进行拼接
|
||||||
emphasis: {
|
}
|
||||||
focus: 'adjacency'
|
return re;
|
||||||
},
|
},
|
||||||
nodeAlign: 'left',
|
|
||||||
data: eventArr,
|
setOptions() {
|
||||||
links: targetArr,
|
if (this.chartData.length == 0) {
|
||||||
lineStyle: {
|
setNotopt(this.chart)
|
||||||
color: 'source',
|
return
|
||||||
curveness: 0.5
|
}
|
||||||
|
|
||||||
|
let eventArr = []
|
||||||
|
let targetArr = []
|
||||||
|
let eventSet = new Map()
|
||||||
|
for (let k in this.chartData) {
|
||||||
|
let traceCharts = this.chartData[k]
|
||||||
|
|
||||||
|
eventSet.set(traceCharts['event'][0], 1)
|
||||||
|
eventSet.set(traceCharts['event'][1], 1)
|
||||||
|
|
||||||
|
targetArr.push({
|
||||||
|
source: traceCharts['event'][0],
|
||||||
|
target: traceCharts['event'][1],
|
||||||
|
value: traceCharts['sum_user_count'],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
eventSet.forEach((v, k, tmp) => {
|
||||||
|
let color = ""
|
||||||
|
var random = Math.random();
|
||||||
|
if(random <0.618){//分配红色和蓝色出现的比例
|
||||||
|
color = this.getColor1()
|
||||||
|
}else{
|
||||||
|
color = this.getColor2()
|
||||||
|
}
|
||||||
|
let obj = {
|
||||||
|
name: k,
|
||||||
|
itemStyle: {
|
||||||
|
color: color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
eventArr.push(obj)
|
||||||
|
})
|
||||||
|
|
||||||
|
let levelsArr = []
|
||||||
|
|
||||||
|
for (let i in eventArr) {
|
||||||
|
levelsArr.push({
|
||||||
|
depth: i,
|
||||||
|
itemStyle: {
|
||||||
|
color: eventArr[i].itemStyle.color
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: 'source',
|
||||||
|
opacity: 0.4
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
triggerOn: 'mousemove'
|
||||||
|
},
|
||||||
|
backgroundColor: '#FFFFFF',
|
||||||
|
series: {
|
||||||
|
type: 'sankey',
|
||||||
|
layout: 'none',
|
||||||
|
top: 50,
|
||||||
|
left: '3%',
|
||||||
|
right: '12%',
|
||||||
|
nodeGap: 14,
|
||||||
|
layoutIterations: 0, // 自动优化列表,尽量减少线的交叉,为0就是按照数据排列
|
||||||
|
data: eventArr, // 节点
|
||||||
|
links: targetArr, // 节点之间的连线
|
||||||
|
|
||||||
|
focusNodeAdjacency: 'allEdges', // 鼠标划上时高亮的节点和连线,allEdges表示鼠标划到节点上点亮节点上的连线及连线对应的节点
|
||||||
|
levels: [{
|
||||||
|
depth: 0,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#F27E7E'
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: 'source',
|
||||||
|
opacity: 0.4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
depth: 1,
|
||||||
|
lineStyle: {
|
||||||
|
color: 'source',
|
||||||
|
opacity: 0.4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
depth: 2,
|
||||||
|
lineStyle: {
|
||||||
|
color: 'source',
|
||||||
|
opacity: 0.4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
depth: 3,
|
||||||
|
label: {
|
||||||
|
fontSize: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
label: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#666'
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
borderWidth: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.chart.setOption(
|
||||||
|
option
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chart.setOption(
|
|
||||||
option
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user