|
@@ -0,0 +1,356 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="statstics-wrapper">
|
|
|
|
+ <div
|
|
|
|
+ ref="headerWrapper"
|
|
|
|
+ class="statstics-header"
|
|
|
|
+ >
|
|
|
|
+ <StatisticsHeader
|
|
|
|
+ :title="`${chartsTitle}量统计`"
|
|
|
|
+ @getFormData="getFormData"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="statstics-content">
|
|
|
|
+ <div
|
|
|
|
+ id="chart"
|
|
|
|
+ class="flight-statistics-chart"
|
|
|
|
+ :style="{ height: chartHeight }"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import StatisticsHeader from './statisticsHeader.vue'
|
|
|
|
+import { Query } from '@/api/dataIntegration'
|
|
|
|
+import { mapGetters } from 'vuex'
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ name: 'CommonStatisticsCharts',
|
|
|
|
+ components: { StatisticsHeader },
|
|
|
|
+ props: {
|
|
|
|
+ chartsTitle: {
|
|
|
|
+ type: String,
|
|
|
|
+ required: true
|
|
|
|
+ },
|
|
|
|
+ querySettings: {
|
|
|
|
+ type: Object,
|
|
|
|
+ required: true
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ myChart: null,
|
|
|
|
+ debounceTime: 300,
|
|
|
|
+ chartHeight: '70vh',
|
|
|
|
+ options: {
|
|
|
|
+ backgroundColor: '#fff',
|
|
|
|
+ tooltip: {
|
|
|
|
+ trigger: 'axis',
|
|
|
|
+ axisPointer: {
|
|
|
|
+ type: 'cross',
|
|
|
|
+ crossStyle: {
|
|
|
|
+ color: '#999'
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ legend: {
|
|
|
|
+ top: '5%',
|
|
|
|
+ right: '5%',
|
|
|
|
+ icon: 'rect',
|
|
|
|
+ height: 14,
|
|
|
|
+ itemWidth: 14,
|
|
|
|
+ itemHeight: 14,
|
|
|
|
+ itemGap: 30,
|
|
|
|
+ data: [
|
|
|
|
+ `${this.chartsTitle}数量`,
|
|
|
|
+ // `${this.chartsTitle}量同比`,
|
|
|
|
+ `${this.chartsTitle}量环比`
|
|
|
|
+ ],
|
|
|
|
+ textStyle: {
|
|
|
|
+ fontFamily: 'Helvetica, "Microsoft YaHei"',
|
|
|
|
+ color: '#101116'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ grid: {
|
|
|
|
+ top: '15%',
|
|
|
|
+ left: '5%',
|
|
|
|
+ right: '5%',
|
|
|
|
+ bottom: '5%'
|
|
|
|
+ },
|
|
|
|
+ xAxis: {
|
|
|
|
+ data: [],
|
|
|
|
+ axisLine: {
|
|
|
|
+ show: true,
|
|
|
|
+ lineStyle: {
|
|
|
|
+ color: '#000000'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ axisTick: {
|
|
|
|
+ show: false // 隐藏X轴刻度
|
|
|
|
+ },
|
|
|
|
+ axisLabel: {
|
|
|
|
+ fontFamily: 'Helvetica, "Microsoft YaHei"',
|
|
|
|
+ color: '#101116'
|
|
|
|
+ },
|
|
|
|
+ axisPointer: {
|
|
|
|
+ type: 'shadow'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ yAxis: [
|
|
|
|
+ {
|
|
|
|
+ min: 0,
|
|
|
|
+ max: 60000,
|
|
|
|
+ splitLine: {
|
|
|
|
+ lineStyle: {
|
|
|
|
+ type: 'dashed',
|
|
|
|
+ color: '#B0B3C3',
|
|
|
|
+ opacity: 0.5
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ axisPointer: {
|
|
|
|
+ label: {
|
|
|
|
+ formatter: ({ value }) => value.toFixed()
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ axisLabel: {
|
|
|
|
+ fontFamily: 'Helvetica, "Microsoft YaHei"',
|
|
|
|
+ color: '#101116'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ min: -0.3,
|
|
|
|
+ max: 0.5,
|
|
|
|
+ axisLabel: {
|
|
|
|
+ formatter: value => (value * 100).toFixed(2) + '%',
|
|
|
|
+ fontFamily: 'Helvetica, "Microsoft YaHei"',
|
|
|
|
+ color: '#101116'
|
|
|
|
+ },
|
|
|
|
+ axisPointer: {
|
|
|
|
+ label: {
|
|
|
|
+ formatter: ({ value }) => (value * 100).toFixed(2) + '%'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ splitLine: {
|
|
|
|
+ show: false
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ ],
|
|
|
|
+ series: [
|
|
|
|
+ {
|
|
|
|
+ name: `${this.chartsTitle}数量`,
|
|
|
|
+ type: 'bar',
|
|
|
|
+ z: 2,
|
|
|
|
+ itemStyle: {
|
|
|
|
+ color: '#6682B5'
|
|
|
|
+ },
|
|
|
|
+ barWidth: 40,
|
|
|
|
+ label: {
|
|
|
|
+ show: true,
|
|
|
|
+ position: 'top'
|
|
|
|
+ },
|
|
|
|
+ data: []
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ name: `${this.chartsTitle}量同比`,
|
|
|
|
+ type: 'line',
|
|
|
|
+ z: 4,
|
|
|
|
+ yAxisIndex: 1,
|
|
|
|
+ symbol: 'circle',
|
|
|
|
+ itemStyle: {
|
|
|
|
+ color: '#F2B849',
|
|
|
|
+ borderColor: '#ffffff',
|
|
|
|
+ borderWidth: 4
|
|
|
|
+ },
|
|
|
|
+ lineStyle: {
|
|
|
|
+ width: 4,
|
|
|
|
+ color: '#F2B849'
|
|
|
|
+ },
|
|
|
|
+ symbolSize: 32,
|
|
|
|
+ tooltip: {
|
|
|
|
+ valueFormatter: value => (value * 100).toFixed(2) + '%'
|
|
|
|
+ },
|
|
|
|
+ data: []
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ name: `${this.chartsTitle}量环比`,
|
|
|
|
+ type: 'line',
|
|
|
|
+ z: 3,
|
|
|
|
+ yAxisIndex: 1,
|
|
|
|
+ symbol: 'circle',
|
|
|
|
+ itemStyle: {
|
|
|
|
+ color: '#E33D3D',
|
|
|
|
+ borderColor: '#ffffff',
|
|
|
|
+ borderWidth: 4
|
|
|
|
+ },
|
|
|
|
+ lineStyle: {
|
|
|
|
+ width: 4,
|
|
|
|
+ color: '#E33D3D'
|
|
|
|
+ },
|
|
|
|
+ symbolSize: 32,
|
|
|
|
+ tooltip: {
|
|
|
|
+ valueFormatter: value => (value * 100).toFixed(2) + '%'
|
|
|
|
+ },
|
|
|
|
+ data: []
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ ...mapGetters(['sidebar'])
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ // 监听数据变化 重绘图形
|
|
|
|
+ options: {
|
|
|
|
+ handler(obj) {
|
|
|
|
+ this.myChart.setOption(obj)
|
|
|
|
+ },
|
|
|
|
+ deep: true
|
|
|
|
+ },
|
|
|
|
+ 'sidebar.expand'() {
|
|
|
|
+ this.resizeHandler()
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ mounted() {
|
|
|
|
+ this.setChartHeight()
|
|
|
|
+ this.myChart = this.$echarts.init(document.getElementById('chart'))
|
|
|
|
+ this.myChart.setOption(this.options)
|
|
|
|
+ // 监听页面缩放
|
|
|
|
+ window.addEventListener('resize', this.setChartHeight)
|
|
|
|
+ window.addEventListener('resize', this._.debounce(this.resizeHandler, this.debounceTime))
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.resizeHandler()
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ beforeDestroy() {
|
|
|
|
+ // 销毁实例和移除监听
|
|
|
|
+ window.removeEventListener('resize', this.setChartHeight)
|
|
|
|
+ if (this.myChart) {
|
|
|
|
+ this.myChart.dispose()
|
|
|
|
+ window.removeEventListener('resize', this.resizeHandler)
|
|
|
|
+ this.myChart = null
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ getFormData(data) {
|
|
|
|
+ this.getData(data)
|
|
|
|
+ },
|
|
|
|
+ async getData(data) {
|
|
|
|
+ let id
|
|
|
|
+ let params = []
|
|
|
|
+ if (data.range === '') {
|
|
|
|
+ this.$message.warning('请先选择统计范围')
|
|
|
|
+ return
|
|
|
|
+ } else if (data.range === '航线' && !data.airline) {
|
|
|
|
+ this.$message.warning('请先选择航线')
|
|
|
|
+ return
|
|
|
|
+ } else if (data.range === '航站' && !data.airport) {
|
|
|
|
+ this.$message.warning('请先选择航站')
|
|
|
|
+ return
|
|
|
|
+ } else if (data.range === '基地分公司' && !data.company) {
|
|
|
|
+ this.$message.warning('请先选择基地分公司')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if (data.inOrOut === '') {
|
|
|
|
+ this.$message.warning('请先选择进离港')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if (data.interval === '') {
|
|
|
|
+ this.$message.warning('请先选择统计时间维度')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if (data.dateTime === '') {
|
|
|
|
+ this.$message.warning('请先选择统计时间范围')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if (data.range === '基地分公司') {
|
|
|
|
+ // id = DATACONTENT_ID.byAreaId
|
|
|
|
+ id = this.querySettings.byAreaId
|
|
|
|
+ params = [data.interval, data.company, data.inOrOut, data.dateTime[0], data.dateTime[1]]
|
|
|
|
+ } else if (data.range !== '基地分公司' && data.range !== '') {
|
|
|
|
+ // id = DATACONTENT_ID.byOtherId
|
|
|
|
+ id = this.querySettings.byOtherId
|
|
|
|
+ params = [data.interval, data.range, data.inOrOut, data.dateTime[0], data.dateTime[1]]
|
|
|
|
+ if (data.airline === '' && data.airport === '' && data.terminal === '') {
|
|
|
|
+ params.splice(2, 0, '全部')
|
|
|
|
+ }
|
|
|
|
+ if (data.airline !== '') {
|
|
|
|
+ params.splice(2, 0, data.airline)
|
|
|
|
+ }
|
|
|
|
+ if (data.airport !== '') {
|
|
|
|
+ params.splice(2, 0, data.airport)
|
|
|
|
+ }
|
|
|
|
+ if (data.terminal !== '') {
|
|
|
|
+ params.splice(2, 0, data.terminal)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ const {
|
|
|
|
+ code,
|
|
|
|
+ returnData: { listValues },
|
|
|
|
+ message
|
|
|
|
+ } = await Query({
|
|
|
|
+ id: id,
|
|
|
|
+ dataContent: params
|
|
|
|
+ })
|
|
|
|
+ if (Number(code) === 0) {
|
|
|
|
+ const xAxisData = []
|
|
|
|
+ const yAxisData = [0]
|
|
|
|
+ const seriesData = []
|
|
|
|
+ for (let i = 0; i < listValues.length; i++) {
|
|
|
|
+ xAxisData.push(listValues[i].A)
|
|
|
|
+ seriesData.push(listValues[i][this.querySettings.seriesKey])
|
|
|
|
+ if (i > 0) {
|
|
|
|
+ if (listValues[i - 1][this.querySettings.seriesKey] > 0) {
|
|
|
|
+ yAxisData.push(
|
|
|
|
+ (listValues[i][this.querySettings.seriesKey] -
|
|
|
|
+ listValues[i - 1][this.querySettings.seriesKey]) /
|
|
|
|
+ listValues[i - 1][this.querySettings.seriesKey]
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ yAxisData.push(0)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ let max = Math.max(...seriesData)
|
|
|
|
+ max = Math.ceil(max / 10) * 10
|
|
|
|
+ this.options.yAxis[0].max = max
|
|
|
|
+ this.options.xAxis.data = xAxisData
|
|
|
|
+ this.options.series[0].data = seriesData
|
|
|
|
+ this.options.series[2].data = yAxisData
|
|
|
|
+ this.options.yAxis[1].min = (Math.min(...yAxisData) - 0.1).toFixed(2)
|
|
|
|
+ this.options.yAxis[1].max = (Math.max(...yAxisData) + 0.1).toFixed(2)
|
|
|
|
+ this.resizeHandler()
|
|
|
|
+ } else {
|
|
|
|
+ this.$message.error(message)
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log('出错了', error)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ setChartHeight() {
|
|
|
|
+ const topBarHeight = 80
|
|
|
|
+ const headerBlankHeight = 24
|
|
|
|
+ const tabsWrapperHeight = 62
|
|
|
|
+ const headerHeight = this.$refs['headerWrapper'].offsetHeight
|
|
|
|
+ const footerBlankHeight = 24
|
|
|
|
+ this.chartHeight = `calc(100vh - ${
|
|
|
|
+ topBarHeight + headerBlankHeight + tabsWrapperHeight + headerHeight + footerBlankHeight
|
|
|
|
+ }px)`
|
|
|
|
+ },
|
|
|
|
+ resizeHandler() {
|
|
|
|
+ if (this.myChart) {
|
|
|
|
+ this.myChart.resize()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.statstics-wrapper {
|
|
|
|
+ .flight-statistics-chart {
|
|
|
|
+ width: 100%;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|