feat: commit、issue图表修改
This commit is contained in:
parent
f9345c3e35
commit
a17d9d07a2
72
frontend/src/components/CustomChart.vue
Normal file
72
frontend/src/components/CustomChart.vue
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart ref="customChart" :option="option" autoresize />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { use } from 'echarts/core'
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers'
|
||||||
|
import { LineChart, BarChart } from 'echarts/charts'
|
||||||
|
import { GridComponent, LegendComponent, TooltipComponent, DataZoomComponent } from 'echarts/components'
|
||||||
|
import VChart from 'vue-echarts'
|
||||||
|
use([CanvasRenderer, LineChart, LegendComponent, GridComponent, TooltipComponent, BarChart, DataZoomComponent])
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CustomChart',
|
||||||
|
props: {
|
||||||
|
customOption: { type: Object, default: () => {} }
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
VChart,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
option() {
|
||||||
|
if (this.customOption) {
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
textStyle: {
|
||||||
|
align: 'left'
|
||||||
|
},
|
||||||
|
...this.customOption?.tooltip
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: this.customOption.series.map(ser => ser.name) || [],
|
||||||
|
...this.customOption?.legend
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
axisLabel: {
|
||||||
|
showMaxLabel: true,
|
||||||
|
showMinLabel: true
|
||||||
|
},
|
||||||
|
boundaryGap: false,
|
||||||
|
...this.customOption?.xAxis
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
...this.customOption?.yAxis
|
||||||
|
},
|
||||||
|
dataZoom: [{
|
||||||
|
type: 'slider',
|
||||||
|
startValue: 0,
|
||||||
|
endValue: 3,
|
||||||
|
show: this.customOption?.xAxis?.data?.length > 4
|
||||||
|
}],
|
||||||
|
series: this.customOption.series || [],
|
||||||
|
}
|
||||||
|
return option
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
// 手动销毁实例
|
||||||
|
if (this.$refs.customChart && this.$refs.customChart.dispose) {
|
||||||
|
this.$refs.customChart.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
@ -1,58 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-chart ref="lineChart" :option="option" autoresize />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { use } from 'echarts/core'
|
|
||||||
import { CanvasRenderer } from 'echarts/renderers'
|
|
||||||
import { LineChart } from 'echarts/charts'
|
|
||||||
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
|
|
||||||
import VChart from 'vue-echarts'
|
|
||||||
use([CanvasRenderer, LineChart, LegendComponent, GridComponent, TooltipComponent])
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'LineChart',
|
|
||||||
props: {
|
|
||||||
data: { type: Object, default: () => {} }
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
VChart,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
option() {
|
|
||||||
const option = {
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
data: this.data.series.map(ser => ser.name) || []
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
boundaryGap: false,
|
|
||||||
data: this.data.xData || [],
|
|
||||||
axisLabel: {
|
|
||||||
showMaxLabel: true,
|
|
||||||
showMinLabel: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
minInterval: 1
|
|
||||||
},
|
|
||||||
series: this.data.series || []
|
|
||||||
}
|
|
||||||
return option
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeUnmount() {
|
|
||||||
// 手动销毁实例
|
|
||||||
if (this.$refs.lineChart && this.$refs.lineChart.dispose) {
|
|
||||||
this.$refs.lineChart.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
</style>
|
|
||||||
@ -217,5 +217,8 @@ export default {
|
|||||||
'Upload attachment': 'Upload attachment',
|
'Upload attachment': 'Upload attachment',
|
||||||
"Didn't get the email? Check junk folder or": "Didn't get the email? Check junk folder or ",
|
"Didn't get the email? Check junk folder or": "Didn't get the email? Check junk folder or ",
|
||||||
'send again': 'send again',
|
'send again': 'send again',
|
||||||
'No content yet': 'No content yet'
|
'No content yet': 'No content yet',
|
||||||
|
'open': 'open',
|
||||||
|
'resolved': 'resolved',
|
||||||
|
'unresolved': 'unresolved'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -225,5 +225,8 @@ export default {
|
|||||||
CLOSED: '已关闭',
|
CLOSED: '已关闭',
|
||||||
REJECTED: '已拒绝',
|
REJECTED: '已拒绝',
|
||||||
APPLYING: '申请中',
|
APPLYING: '申请中',
|
||||||
ACCEPTING: '接受中'
|
ACCEPTING: '接受中',
|
||||||
|
'open': '未解决',
|
||||||
|
'resolved': '已解决',
|
||||||
|
'unresolved': '未解决总计'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -445,7 +445,7 @@
|
|||||||
{{ $t('TO BE IMPLEMENTED.') }}
|
{{ $t('TO BE IMPLEMENTED.') }}
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="chart-container">
|
<div class="chart-container">
|
||||||
<line-chart :data="getCodeChartData(project.project.code)" />
|
<custom-chart :customOption="getCodeChartOption(project.project.code)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -493,7 +493,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="chart-container">
|
<div class="chart-container">
|
||||||
<line-chart :data="getIssueChartData(project.project.issue)" />
|
<custom-chart :customOption="getIssueChartOption(project.project.issue)" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="project-invite-collaborator-containter">
|
<!-- <div class="project-invite-collaborator-containter">
|
||||||
<button
|
<button
|
||||||
@ -615,11 +615,11 @@ import {
|
|||||||
convertIntoToMilestoneStatus,
|
convertIntoToMilestoneStatus,
|
||||||
convertIntoToProjectIssueStatus
|
convertIntoToProjectIssueStatus
|
||||||
} from '@/types/index'
|
} from '@/types/index'
|
||||||
import LineChart from '@/components/LineChart.vue'
|
import CustomChart from '@/components/CustomChart.vue'
|
||||||
import EmptyContent from '@/components/EmptyContent.vue'
|
import EmptyContent from '@/components/EmptyContent.vue'
|
||||||
export default {
|
export default {
|
||||||
name: 'Workspace',
|
name: 'Workspace',
|
||||||
components: { LineChart, EmptyContent },
|
components: { CustomChart, EmptyContent },
|
||||||
props: {},
|
props: {},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
@ -989,20 +989,27 @@ export default {
|
|||||||
this.websocketOnClose
|
this.websocketOnClose
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
getCodeChartData(code) {
|
getCodeChartOption(code) {
|
||||||
const { weekly_commits } = code
|
const { weekly_commits } = code
|
||||||
if (weekly_commits) {
|
if (weekly_commits) {
|
||||||
// 把数据按日期排序
|
// 把数据按日期排序
|
||||||
const sortData = Object.entries(weekly_commits).sort((a, b) => new Date(a[0]) - new Date(b[0]));
|
const sortData = Object.entries(weekly_commits).sort((a, b) => new Date(a[0]) - new Date(b[0]))
|
||||||
|
const xData = sortData.map(data => data[0])
|
||||||
return {
|
return {
|
||||||
xData: sortData.map(data => data[0]),
|
xAxis: {
|
||||||
|
data: xData
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
minInterval: 1
|
||||||
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
data: sortData.map(data => data[1]),
|
data: sortData.map(data => data[1]),
|
||||||
type: 'line',
|
type: 'line',
|
||||||
name: 'commits',
|
name: this.$t('Commits'),
|
||||||
areaStyle: { color: 'rgba(63,73,255,0.1)' },
|
lineStyle: {
|
||||||
smooth: true,
|
color: 'rgb(23,72,248)'
|
||||||
|
},
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
connectNulls: true
|
connectNulls: true
|
||||||
}
|
}
|
||||||
@ -1011,32 +1018,48 @@ export default {
|
|||||||
}
|
}
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
getIssueChartData(issue) {
|
getIssueChartOption(issue) {
|
||||||
const { weekly_open_issues, weekly_resolved_issues } = issue
|
const { weekly_open_issues, weekly_resolved_issues } = issue
|
||||||
if (weekly_open_issues && weekly_resolved_issues) {
|
if (weekly_open_issues && weekly_resolved_issues) {
|
||||||
// 把数据按日期排序
|
// 把数据按日期排序
|
||||||
const sortOpenData = Object.entries(weekly_open_issues).sort((a, b) => new Date(a[0]) - new Date(b[0]));
|
const sortOpenData = Object.entries(weekly_open_issues).sort((a, b) => new Date(a[0]) - new Date(b[0]))
|
||||||
const sortResolvedData = Object.entries(weekly_resolved_issues).sort((a, b) => new Date(a[0]) - new Date(b[0]));
|
const sortResolvedData = Object.entries(weekly_resolved_issues).sort((a, b) => new Date(a[0]) - new Date(b[0]))
|
||||||
|
const openSerData = sortOpenData.map(data => data[1])
|
||||||
|
const resolvedSerData = sortResolvedData.map(data => data[1])
|
||||||
|
const unresolvedSerData = openSerData.map((data, index) => data - resolvedSerData[index]).reduce((acc, cur, index) => {
|
||||||
|
acc.push(index === 0 ? cur : cur + acc[index - 1]);
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
const xData = sortOpenData.map(data => data[0])
|
||||||
return {
|
return {
|
||||||
xData: sortOpenData.map(data => data[0]),
|
xAxis: {
|
||||||
|
data: xData
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
minInterval: 1
|
||||||
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
data: sortOpenData.map(data => data[1]),
|
data: openSerData,
|
||||||
name: 'open',
|
name: this.$t('open'),
|
||||||
type: 'line',
|
type: 'line',
|
||||||
stack: 'issue',
|
|
||||||
areaStyle: { color: 'rgba(63,73,255,0.1)' },
|
|
||||||
smooth: true,
|
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
connectNulls: true
|
connectNulls: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: sortResolvedData.map(data => data[1]),
|
data: resolvedSerData,
|
||||||
name: 'resolved',
|
name: this.$t('resolved'),
|
||||||
type: 'line',
|
type: 'line',
|
||||||
stack: 'issue',
|
symbol: 'none',
|
||||||
areaStyle: { color: 'rgba(63,73,255,0.2)' },
|
connectNulls: true
|
||||||
smooth: true,
|
},
|
||||||
|
{
|
||||||
|
data: unresolvedSerData,
|
||||||
|
name: this.$t('unresolved'),
|
||||||
|
type: 'line',
|
||||||
|
lineStyle: {
|
||||||
|
type: 'dashed'
|
||||||
|
},
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
connectNulls: true
|
connectNulls: true
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user