mirror of
https://github.com/PanJiaChen/vue-element-admin.git
synced 2025-08-07 18:25:45 +08:00
Add support to Area chart and Waterfall chart (#946)
This commit is contained in:
parent
b8b80b9b41
commit
65d5ff19af
183
src/components/ADempiere/Dashboard/charts/AreaChart.vue
Normal file
183
src/components/ADempiere/Dashboard/charts/AreaChart.vue
Normal file
@ -0,0 +1,183 @@
|
||||
<!--
|
||||
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
|
||||
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
|
||||
Contributor(s): Yamel Senih ysenih@erpya.com www.erpya.com
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https:www.gnu.org/licenses/>.
|
||||
-->
|
||||
<template>
|
||||
<div :class="className" :style="{height:height,width:width}" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from './mixins/resize'
|
||||
import { getMetrics } from '@/api/ADempiere/dashboard/chart'
|
||||
|
||||
const animationDuration = 2800
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '350px'
|
||||
},
|
||||
autoResize: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
metadata: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
deep: true,
|
||||
handler(val) {
|
||||
this.setOptions(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.unsubscribe = this.subscribeChanges()
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.unsubscribe()
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
subscribeChanges() {
|
||||
return this.$store.subscribe((mutation, state) => {
|
||||
if (mutation.type === 'notifyDashboardRefresh') {
|
||||
this.initChart()
|
||||
}
|
||||
})
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(this.$el, 'macarons')
|
||||
getMetrics({
|
||||
id: this.metadata.id
|
||||
})
|
||||
.then(metrics => {
|
||||
this.loadChartMetrics(metrics)
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn(`Error getting Metrics: ${error.message}. Code: ${error.code}.`)
|
||||
})
|
||||
},
|
||||
loadChartMetrics(metrics) {
|
||||
let xAxisValues = []
|
||||
let seriesToShow = []
|
||||
let legendToShow = []
|
||||
if (!this.isEmptyValue(metrics.series)) {
|
||||
if (metrics.series.length > 0) {
|
||||
metrics.series.forEach(serie => {
|
||||
xAxisValues = xAxisValues.concat(serie.data_set.map(set => set.name))
|
||||
})
|
||||
}
|
||||
seriesToShow = metrics.series.map(serie => {
|
||||
return {
|
||||
name: serie.name,
|
||||
stack: 'vistors',
|
||||
data: serie.data_set.map(set => set.value),
|
||||
animationDuration,
|
||||
smooth: true,
|
||||
large: true,
|
||||
type: 'line',
|
||||
animationEasing: 'quadraticOut',
|
||||
lineStyle: {
|
||||
width: 2
|
||||
},
|
||||
areaStyle: {}
|
||||
}
|
||||
})
|
||||
legendToShow = metrics.series.map(serie => serie.name)
|
||||
}
|
||||
this.chart.setOption({
|
||||
xAxis: {
|
||||
data: xAxisValues,
|
||||
boundaryGap: false,
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
silent: false,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
splitArea: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
// y: 'bottom',
|
||||
feature: {
|
||||
magicType: {
|
||||
type: ['stack', 'tiled']
|
||||
},
|
||||
dataView: {},
|
||||
saveAsImage: {
|
||||
pixelRatio: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: 10,
|
||||
right: 10,
|
||||
bottom: 20,
|
||||
top: 30,
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
},
|
||||
padding: [5, 10]
|
||||
},
|
||||
yAxis: {
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: legendToShow
|
||||
},
|
||||
series: seriesToShow
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -113,6 +113,18 @@ export default {
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
// y: 'bottom',
|
||||
feature: {
|
||||
magicType: {
|
||||
type: ['stack', 'tiled']
|
||||
},
|
||||
dataView: {},
|
||||
saveAsImage: {
|
||||
pixelRatio: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
top: 10,
|
||||
left: '2%',
|
||||
|
@ -118,12 +118,8 @@ export default {
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
animationEasing: 'quadraticOut',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
lineStyle: {
|
||||
width: 2
|
||||
}
|
||||
}
|
||||
lineStyle: {
|
||||
width: 2
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -137,6 +133,18 @@ export default {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
// y: 'bottom',
|
||||
feature: {
|
||||
magicType: {
|
||||
type: ['stack', 'tiled']
|
||||
},
|
||||
dataView: {},
|
||||
saveAsImage: {
|
||||
pixelRatio: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: 10,
|
||||
right: 10,
|
||||
|
@ -119,6 +119,18 @@ export default {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||
},
|
||||
toolbox: {
|
||||
// y: 'bottom',
|
||||
feature: {
|
||||
magicType: {
|
||||
type: ['stack', 'tiled']
|
||||
},
|
||||
dataView: {},
|
||||
saveAsImage: {
|
||||
pixelRatio: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
left: 'center',
|
||||
bottom: '10',
|
||||
|
@ -117,6 +117,18 @@ export default {
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
// y: 'bottom',
|
||||
feature: {
|
||||
magicType: {
|
||||
type: ['stack', 'tiled']
|
||||
},
|
||||
dataView: {},
|
||||
saveAsImage: {
|
||||
pixelRatio: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
radar: {
|
||||
radius: '66%',
|
||||
center: ['50%', '42%'],
|
||||
@ -142,13 +154,11 @@ export default {
|
||||
type: 'radar',
|
||||
symbolSize: 0,
|
||||
areaStyle: {
|
||||
normal: {
|
||||
shadowBlur: 13,
|
||||
shadowColor: 'rgba(0,0,0,.2)',
|
||||
shadowOffsetX: 0,
|
||||
shadowOffsetY: 10,
|
||||
opacity: 1
|
||||
}
|
||||
shadowBlur: 13,
|
||||
shadowColor: 'rgba(0,0,0,.2)',
|
||||
shadowOffsetX: 0,
|
||||
shadowOffsetY: 10,
|
||||
opacity: 1
|
||||
},
|
||||
data: seriesToShow,
|
||||
animationDuration: animationDuration
|
||||
|
155
src/components/ADempiere/Dashboard/charts/WaterfallChart.vue
Normal file
155
src/components/ADempiere/Dashboard/charts/WaterfallChart.vue
Normal file
@ -0,0 +1,155 @@
|
||||
<!--
|
||||
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
|
||||
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
|
||||
Contributor(s): Yamel Senih ysenih@erpya.com www.erpya.com
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https:www.gnu.org/licenses/>.
|
||||
-->
|
||||
<template>
|
||||
<div :class="className" :style="{height:height,width:width}" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from './mixins/resize'
|
||||
import { getMetrics } from '@/api/ADempiere/dashboard/chart'
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '300px'
|
||||
},
|
||||
metadata: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.unsubscribe = this.subscribeChanges()
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.unsubscribe()
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
subscribeChanges() {
|
||||
return this.$store.subscribe((mutation, state) => {
|
||||
if (mutation.type === 'notifyDashboardRefresh') {
|
||||
this.initChart()
|
||||
}
|
||||
})
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(this.$el, 'macarons')
|
||||
getMetrics({
|
||||
id: this.metadata.id
|
||||
})
|
||||
.then(metrics => {
|
||||
this.loadChartMetrics(metrics)
|
||||
})
|
||||
.catch(error => {
|
||||
console.warn(`Error getting Metrics: ${error.message}. Code: ${error.code}.`)
|
||||
})
|
||||
},
|
||||
loadChartMetrics(metrics) {
|
||||
let xAxisValues = []
|
||||
let seriesToShow = []
|
||||
let legendToShow = []
|
||||
if (!this.isEmptyValue(metrics.series)) {
|
||||
if (metrics.series.length > 0) {
|
||||
metrics.series.forEach(serie => {
|
||||
xAxisValues = xAxisValues.concat(serie.data_set.map(set => set.name))
|
||||
})
|
||||
}
|
||||
seriesToShow = metrics.series.map(serie => {
|
||||
return {
|
||||
name: serie.name,
|
||||
type: 'bar',
|
||||
data: serie.data_set.map(set => set.value),
|
||||
animationDelay: function(idx) {
|
||||
return idx * 10
|
||||
}
|
||||
}
|
||||
})
|
||||
legendToShow = metrics.series.map(serie => serie.name)
|
||||
}
|
||||
this.chart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
toolbox: {
|
||||
// y: 'bottom',
|
||||
feature: {
|
||||
magicType: {
|
||||
type: ['stack', 'tiled']
|
||||
},
|
||||
dataView: {},
|
||||
saveAsImage: {
|
||||
pixelRatio: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
xAxis: [{
|
||||
data: xAxisValues,
|
||||
type: 'category',
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
}],
|
||||
yAxis: {
|
||||
},
|
||||
legend: {
|
||||
data: legendToShow
|
||||
},
|
||||
series: seriesToShow,
|
||||
animationEasing: 'elasticOut',
|
||||
animationDelayUpdate: function(idx) {
|
||||
return idx * 5
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -87,7 +87,7 @@ export default {
|
||||
break
|
||||
// Area Chart
|
||||
case 'AC':
|
||||
dashboard = () => import('@/components/ADempiere/Dashboard/charts/RaddarChart')
|
||||
dashboard = () => import('@/components/ADempiere/Dashboard/charts/AreaChart')
|
||||
break
|
||||
// Line Chart
|
||||
case 'LC':
|
||||
@ -103,7 +103,7 @@ export default {
|
||||
break
|
||||
// Waterfall Chart
|
||||
case 'WC':
|
||||
dashboard = () => import('@/components/ADempiere/Dashboard/charts/RaddarChart')
|
||||
dashboard = () => import('@/components/ADempiere/Dashboard/charts/WaterfallChart')
|
||||
break
|
||||
default:
|
||||
dashboard = () => import('@/components/ADempiere/Dashboard/charts/LineChart')
|
||||
|
Loading…
x
Reference in New Issue
Block a user