Browse Source

[Feature][UI Next] Add task state statistics chart. (#7765)

3.0.0/version-upgrade
songjianet 3 years ago committed by GitHub
parent
commit
7e378ea672
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      dolphinscheduler-ui-next/src/components/chart/index.ts
  2. 20
      dolphinscheduler-ui-next/src/components/chart/modules/Pie.tsx
  3. 21
      dolphinscheduler-ui-next/src/views/home/index.module.scss
  4. 18
      dolphinscheduler-ui-next/src/views/home/index.tsx
  5. 21
      dolphinscheduler-ui-next/src/views/home/state-card.tsx
  6. 16
      dolphinscheduler-ui-next/src/views/home/types.ts
  7. 4
      dolphinscheduler-ui-next/src/views/home/use-process-definition.ts
  8. 17
      dolphinscheduler-ui-next/src/views/home/use-task-state.ts

19
dolphinscheduler-ui-next/src/components/chart/index.ts

@ -15,7 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { getCurrentInstance, onMounted, onBeforeUnmount, watch } from 'vue' import {
getCurrentInstance,
onMounted,
onBeforeUnmount,
watch,
watchEffect,
} from 'vue'
import { useThemeStore } from '@/store/theme/theme' import { useThemeStore } from '@/store/theme/theme'
import { throttle } from 'echarts' import { throttle } from 'echarts'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@ -63,6 +69,17 @@ function initChart<Opt extends ECBasicOption>(
} }
) )
watch(
() => option,
() => {
chart?.dispose()
init()
},
{
deep: true,
}
)
onMounted(() => { onMounted(() => {
init() init()
addEventListener('resize', resize) addEventListener('resize', resize)

20
dolphinscheduler-ui-next/src/components/chart/modules/Pie.tsx

@ -22,18 +22,21 @@ import type { Ref } from 'vue'
const props = { const props = {
height: { height: {
type: [String, Number] as PropType<string | number>, type: [String, Number] as PropType<string | number>,
default: 400, default: 590,
}, },
width: { width: {
type: [String, Number] as PropType<string | number>, type: [String, Number] as PropType<string | number>,
default: 400, default: '100%',
},
data: {
type: Array as PropType<Array<any>>,
}, },
} }
const PieChart = defineComponent({ const PieChart = defineComponent({
name: 'PieChart', name: 'PieChart',
props, props,
setup() { setup(props) {
const pieChartRef: Ref<HTMLDivElement | null> = ref(null) const pieChartRef: Ref<HTMLDivElement | null> = ref(null)
const option = { const option = {
@ -42,12 +45,11 @@ const PieChart = defineComponent({
backgroundColor: '#fff', backgroundColor: '#fff',
}, },
legend: { legend: {
top: '5%', bottom: '0%',
left: 'center', left: 'center',
}, },
series: [ series: [
{ {
name: 'Access From',
type: 'pie', type: 'pie',
radius: ['40%', '70%'], radius: ['40%', '70%'],
avoidLabelOverlap: false, avoidLabelOverlap: false,
@ -58,13 +60,7 @@ const PieChart = defineComponent({
labelLine: { labelLine: {
show: false, show: false,
}, },
data: [ data: props.data,
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' },
],
}, },
], ],
} }

21
dolphinscheduler-ui-next/src/views/home/index.module.scss

@ -1,21 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.card-table {
display: flex;
justify-content: space-between;
}

18
dolphinscheduler-ui-next/src/views/home/index.tsx

@ -15,14 +15,21 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineComponent, Ref, onMounted, ref, watch } from 'vue' import {
defineComponent,
Ref,
onMounted,
ref,
toRefs,
reactive,
isReactive,
} from 'vue'
import { NGrid, NGi } from 'naive-ui' import { NGrid, NGi } from 'naive-ui'
import { startOfToday, getTime } from 'date-fns' import { startOfToday, getTime } from 'date-fns'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useTaskState } from './use-task-state' import { useTaskState } from './use-task-state'
import StateCard from './state-card' import StateCard from './state-card'
import DefinitionCard from './definition-card' import DefinitionCard from './definition-card'
import styles from './index.module.scss'
export default defineComponent({ export default defineComponent({
name: 'home', name: 'home',
@ -30,7 +37,7 @@ export default defineComponent({
const { t } = useI18n() const { t } = useI18n()
const dateRef = ref([getTime(startOfToday()), Date.now()]) const dateRef = ref([getTime(startOfToday()), Date.now()])
const { getTaskState } = useTaskState() const { getTaskState } = useTaskState()
let taskStateRef: Ref<any> = ref([]) let taskStateRef = ref()
onMounted(() => { onMounted(() => {
taskStateRef.value = getTaskState(dateRef.value) taskStateRef.value = getTaskState(dateRef.value)
@ -52,11 +59,12 @@ export default defineComponent({
<StateCard <StateCard
title={t('home.task_state_statistics')} title={t('home.task_state_statistics')}
date={dateRef} date={dateRef}
tableData={this.taskStateRef.value} tableData={this.taskStateRef?.value.table}
chartData={this.taskStateRef?.value.chart}
onUpdateDatePickerValue={handleTaskDate} onUpdateDatePickerValue={handleTaskDate}
/> />
</NGi> </NGi>
<NGi class={styles['card-table']}> <NGi>
<StateCard <StateCard
title={t('home.process_state_statistics')} title={t('home.process_state_statistics')}
date={dateRef} date={dateRef}

21
dolphinscheduler-ui-next/src/views/home/state-card.tsx

@ -17,10 +17,10 @@
import { defineComponent, PropType } from 'vue' import { defineComponent, PropType } from 'vue'
import { useTable } from './use-table' import { useTable } from './use-table'
import styles from '@/views/home/index.module.scss' import { NDataTable, NDatePicker, NGrid, NGi } from 'naive-ui'
import PieChart from '@/components/chart/modules/Pie' import PieChart from '@/components/chart/modules/Pie'
import { NDataTable, NDatePicker } from 'naive-ui'
import Card from '@/components/card' import Card from '@/components/card'
import type { StateTableData, StateChartData } from './types'
const props = { const props = {
title: { title: {
@ -30,7 +30,12 @@ const props = {
type: Array as PropType<Array<any>>, type: Array as PropType<Array<any>>,
}, },
tableData: { tableData: {
type: [Array, Boolean] as PropType<Array<any> | false>, type: Array as PropType<Array<StateTableData>>,
default: () => [],
},
chartData: {
type: Array as PropType<Array<StateChartData>>,
default: () => [],
}, },
} }
@ -46,15 +51,16 @@ const StateCard = defineComponent({
return { onUpdateDatePickerValue } return { onUpdateDatePickerValue }
}, },
render() { render() {
const { title, date, tableData, onUpdateDatePickerValue } = this const { title, date, tableData, chartData, onUpdateDatePickerValue } = this
const { columnsRef } = useTable() const { columnsRef } = useTable()
return ( return (
<Card title={title}> <Card title={title}>
{{ {{
default: () => ( default: () => (
<div class={styles['card-table']}> <NGrid x-gap={12} cols={2}>
<PieChart /> <NGi>{chartData.length > 0 && <PieChart data={chartData} />}</NGi>
<NGi>
{tableData && ( {tableData && (
<NDataTable <NDataTable
columns={columnsRef} columns={columnsRef}
@ -63,7 +69,8 @@ const StateCard = defineComponent({
size={'small'} size={'small'}
/> />
)} )}
</div> </NGi>
</NGrid>
), ),
'header-extra': () => ( 'header-extra': () => (
<NDatePicker <NDatePicker

16
dolphinscheduler-ui-next/src/views/home/types.ts

@ -15,15 +15,25 @@
* limitations under the License. * limitations under the License.
*/ */
interface ChartData { interface DefinitionChartData {
xAxisData: Array<string> xAxisData: Array<string>
seriesData: Array<number> seriesData: Array<number>
} }
interface TaskStateTableData { interface StateTableData {
id: number id: number
number: number number: number
state: string state: string
} }
export { ChartData, TaskStateTableData } interface StateChartData {
value: number
name: string
}
interface StateData {
table: Array<StateTableData>
chart: Array<StateChartData>
}
export { DefinitionChartData, StateTableData, StateChartData, StateData }

4
dolphinscheduler-ui-next/src/views/home/use-process-definition.ts

@ -18,13 +18,13 @@
import { useAsyncState } from '@vueuse/core' import { useAsyncState } from '@vueuse/core'
import { countDefinitionByUser } from '@/service/modules/projects-analysis' import { countDefinitionByUser } from '@/service/modules/projects-analysis'
import type { ProcessDefinitionRes } from '@/service/modules/projects-analysis/types' import type { ProcessDefinitionRes } from '@/service/modules/projects-analysis/types'
import type { ChartData } from './types' import type { DefinitionChartData } from './types'
export function useProcessDefinition() { export function useProcessDefinition() {
const getProcessDefinition = () => { const getProcessDefinition = () => {
const { state } = useAsyncState( const { state } = useAsyncState(
countDefinitionByUser({ projectCode: 0 }).then( countDefinitionByUser({ projectCode: 0 }).then(
(res: ProcessDefinitionRes): ChartData => { (res: ProcessDefinitionRes): DefinitionChartData => {
const xAxisData = res.userList.map((item) => item.userName) const xAxisData = res.userList.map((item) => item.userName)
const seriesData = res.userList.map((item) => item.count) const seriesData = res.userList.map((item) => item.count)

17
dolphinscheduler-ui-next/src/views/home/use-task-state.ts

@ -19,7 +19,7 @@ import { useAsyncState } from '@vueuse/core'
import { format } from 'date-fns' import { format } from 'date-fns'
import { countTaskState } from '@/service/modules/projects-analysis' import { countTaskState } from '@/service/modules/projects-analysis'
import type { TaskStateRes } from '@/service/modules/projects-analysis/types' import type { TaskStateRes } from '@/service/modules/projects-analysis/types'
import type { TaskStateTableData } from './types' import type { StateData } from './types'
export function useTaskState() { export function useTaskState() {
const getTaskState = (date: Array<number>) => { const getTaskState = (date: Array<number>) => {
@ -28,16 +28,25 @@ export function useTaskState() {
startDate: format(date[0], 'yyyy-MM-dd HH:mm:ss'), startDate: format(date[0], 'yyyy-MM-dd HH:mm:ss'),
endDate: format(date[1], 'yyyy-MM-dd HH:mm:ss'), endDate: format(date[1], 'yyyy-MM-dd HH:mm:ss'),
projectCode: 0, projectCode: 0,
}).then((res: TaskStateRes): Array<TaskStateTableData> => { }).then((res: TaskStateRes): StateData => {
return res.taskCountDtos.map((item, index) => { const table = res.taskCountDtos.map((item, index) => {
return { return {
id: index + 1, id: index + 1,
state: item.taskStateType, state: item.taskStateType,
number: item.count, number: item.count,
} }
}) })
const chart = res.taskCountDtos.map((item) => {
return {
value: item.count,
name: item.taskStateType,
}
})
return { table, chart }
}), }),
[] { table: [], chart: [] }
) )
return state return state

Loading…
Cancel
Save