mirror of
https://gitee.com/devlive-community/datacap.git
synced 2024-12-02 20:17:45 +08:00
[Core] [Visual] Add radar
This commit is contained in:
parent
c96280aa91
commit
12e3f6897c
@ -61,6 +61,7 @@ export default {
|
||||
visualTypeHistogram: 'Histogram',
|
||||
visualTypeWordCloud: 'Word Cloud',
|
||||
visualTypeScatter: 'Scatter',
|
||||
visualTypeRadar: 'Radar',
|
||||
visualConfigure: 'Visual Configure',
|
||||
visualConfigureNotSpecified: 'No configuration items are available',
|
||||
visualConfigureXAxis: 'X Axis',
|
||||
|
@ -61,6 +61,7 @@ export default {
|
||||
visualTypeHistogram: '直方图',
|
||||
visualTypeWordCloud: '词云图',
|
||||
visualTypeScatter: '散点图',
|
||||
visualTypeRadar: '雷达图',
|
||||
visualConfigure: '可视化配置',
|
||||
visualConfigureNotSpecified: '暂无可用配置项',
|
||||
visualConfigureXAxis: 'X轴',
|
||||
|
@ -31,3 +31,12 @@ export interface IChart
|
||||
outerRadius?: number[]
|
||||
invalidType?: string
|
||||
}
|
||||
|
||||
export interface ChartField
|
||||
{
|
||||
label?: string
|
||||
field?: string
|
||||
value?: any
|
||||
type?: string
|
||||
defaultValues?: any[]
|
||||
}
|
||||
|
@ -8,4 +8,5 @@ export enum Type
|
||||
HISTOGRAM = ('HISTOGRAM'),
|
||||
WORDCLOUD = ('WORDCLOUD'),
|
||||
SCATTER = ('SCATTER'),
|
||||
RADAR = ('RADAR')
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
<VisualHistogram v-else-if="configuration?.type === Type.HISTOGRAM" :configuration="configuration" @change="handlerCommit"/>
|
||||
<VisualWordCloud v-else-if="configuration?.type === Type.WORDCLOUD" :configuration="configuration" @change="handlerCommit"/>
|
||||
<VisualScatter v-else-if="configuration?.type === Type.SCATTER" :configuration="configuration" @change="handlerCommit"/>
|
||||
<VisualRadar v-else-if="configuration?.type === Type.RADAR" :configuration="configuration" @change="handlerCommit"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -125,6 +126,18 @@
|
||||
</svg>
|
||||
</Tooltip>
|
||||
</ToggleGroupItem>
|
||||
<ToggleGroupItem :value="Type.RADAR">
|
||||
<Tooltip :content="$t('dataset.common.visualTypeRadar')">
|
||||
<svg width="22" height="21" viewBox="0 0 22 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M1.57045 8.16646L10.3949 1.45986C10.7525 1.18808 11.2475 1.18808 11.6051 1.45986L20.4296 8.16646C20.7706 8.42565 20.9087 8.87328 20.7729 9.27956L17.4187 19.3169C17.2824 19.7249 16.9004 20 16.4703 20H5.52971C5.09956 20 4.7176 19.7249 4.58127 19.3169L1.22709 9.27956C1.09132 8.87328 1.2294 8.42565 1.57045 8.16646Z"
|
||||
stroke="#21252C" stroke-width="1.7" stroke-linecap="round"></path>
|
||||
<path
|
||||
d="M6.11243 9.82863L10.8826 6.2478C10.951 6.19642 11.0446 6.19428 11.1153 6.24249L16.3379 9.80252C16.4279 9.8639 16.4522 9.98606 16.3926 10.0773L13.5468 14.4281C13.5169 14.4739 13.4696 14.5054 13.4158 14.5153L7.91428 15.5328C7.81444 15.5513 7.71661 15.492 7.68675 15.395L6.04134 10.0474C6.01654 9.96678 6.04498 9.87927 6.11243 9.82863Z"
|
||||
stroke="#21252C" stroke-width="1.7" stroke-linecap="round"></path>
|
||||
</svg>
|
||||
</Tooltip>
|
||||
</ToggleGroupItem>
|
||||
</div>
|
||||
</ToggleGroup>
|
||||
</div>
|
||||
@ -140,6 +153,8 @@
|
||||
<VisualHistogramConfigure v-else-if="configuration.type === Type.HISTOGRAM" :configuration="configuration" @change="configuration.chartConfigure = $event"/>
|
||||
<VisualWordCloudConfigure v-else-if="configuration.type === Type.WORDCLOUD" :configuration="configuration" @change="configuration.chartConfigure = $event"/>
|
||||
<VisualScatterConfigure v-else-if="configuration.type === Type.SCATTER" :configuration="configuration" @change="configuration.chartConfigure = $event"/>
|
||||
<VisualConfigure v-else-if="configuration.type === Type.RADAR" :configuration="configuration" :fields="forwardFiled(configuration.type)"
|
||||
@change="configuration.chartConfigure = $event"/>
|
||||
<Alert v-else :title="$t('dataset.common.visualConfigureNotSpecified')"/>
|
||||
</div>
|
||||
</Card>
|
||||
@ -152,7 +167,7 @@ import VisualWordCloud from '@/views/components/visual/components/VisualWordClou
|
||||
import VisualHistogram from '@/views/components/visual/components/VisualHistogram.vue'
|
||||
import VisualPie from '@/views/components/visual/components/VisualPie.vue'
|
||||
import VisualArea from '@/views/components/visual/components/VisualArea.vue'
|
||||
import { Configuration } from './Configuration'
|
||||
import { ChartField, Configuration } from './Configuration'
|
||||
import VisualBar from '@/views/components/visual/components/VisualBar.vue'
|
||||
import VisualLine from '@/views/components/visual/components/VisualLine.vue'
|
||||
import VisualTable from '@/views/components/visual/components/VisualTable.vue'
|
||||
@ -172,6 +187,8 @@ import VisualHistogramConfigure from '@/views/components/visual/components/Visua
|
||||
import VisualWordCloudConfigure from '@/views/components/visual/components/VisualWordCloudConfigure.vue'
|
||||
import VisualScatter from '@/views/components/visual/components/VisualScatter.vue'
|
||||
import VisualScatterConfigure from '@/views/components/visual/components/VisualScatterConfigure.vue'
|
||||
import VisualConfigure from '@/views/components/visual/components/VisualConfigure.vue'
|
||||
import VisualRadar from '@/views/components/visual/components/VisualRadar.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'VisualEditor',
|
||||
@ -182,6 +199,8 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
components: {
|
||||
VisualRadar,
|
||||
VisualConfigure,
|
||||
VisualScatterConfigure,
|
||||
VisualScatter,
|
||||
VisualWordCloudConfigure,
|
||||
@ -212,6 +231,18 @@ export default defineComponent({
|
||||
handlerCommit(value: any)
|
||||
{
|
||||
this.$emit('commitOptions', value)
|
||||
},
|
||||
forwardFiled(type: Type): ChartField[]
|
||||
{
|
||||
const fields: Array<ChartField> = new Array<ChartField>()
|
||||
const categoryField: ChartField = { label: this.$t('dataset.common.visualConfigureCategoryField'), field: 'xAxis', value: undefined }
|
||||
const valueField: ChartField = { label: this.$t('dataset.common.visualConfigureValueField'), field: 'yAxis', value: undefined }
|
||||
switch (type) {
|
||||
case Type.RADAR:
|
||||
fields.push(categoryField, valueField)
|
||||
break
|
||||
}
|
||||
return fields
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div v-if="configuration && formState" class="space-y-2">
|
||||
<FormField v-for="item in fields" class="flex items-center" :name="item.field as string">
|
||||
<FormItem class="flex-1">
|
||||
<div class="flex items-center">
|
||||
<FormLabel class="mr-1 w-2/3 text-right">{{ item.label }}</FormLabel>
|
||||
<FormControl>
|
||||
<Select v-model="formState[item.field as keyof IChart] as string" :disabled="configuration.headers.length === 0">
|
||||
<SelectTrigger class="w-full">
|
||||
<SelectValue :placeholder="`Select ${item.label}`"/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem v-if="item.defaultValues" v-for="data in item.defaultValues" :value="data as string">{{ data }}</SelectItem>
|
||||
<SelectItem v-else v-for="item in configuration.headers" :value="item as string">{{ item }}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { FormControl, FormDescription, FormField, FormItem, FormLabel } from '@/components/ui/form'
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { ChartField, Configuration, IChart } from '@/views/components/visual/Configuration.ts'
|
||||
import { cloneDeep, keys } from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'VisualConfigure',
|
||||
components: {
|
||||
SelectGroup, SelectTrigger, SelectContent, SelectItem, Select, SelectLabel, SelectValue,
|
||||
FormDescription, FormControl, FormLabel, FormField, FormItem
|
||||
},
|
||||
props: {
|
||||
configuration: {
|
||||
type: Object as () => Configuration
|
||||
},
|
||||
fields: {
|
||||
type: Array as () => ChartField[],
|
||||
default: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
formState: {
|
||||
handler: 'handlerCommit',
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
formState: null as IChart | null
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
if (this.configuration && keys(this.configuration.chartConfigure).length > 0) {
|
||||
this.formState = cloneDeep(this.configuration.chartConfigure) as IChart
|
||||
}
|
||||
else {
|
||||
const obj = {} as any
|
||||
this.fields.forEach(field => {
|
||||
if (field.field) {
|
||||
obj[field.field] = undefined
|
||||
}
|
||||
})
|
||||
this.formState = obj
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handlerCommit()
|
||||
{
|
||||
this.$emit('change', this.formState)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div ref="content" :style="{width: width, height: height}"/>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import VChart from '@visactor/vchart'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { Configuration } from '../Configuration'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
let instance: VChart
|
||||
|
||||
export default defineComponent({
|
||||
name: 'VisualRadar',
|
||||
props: {
|
||||
configuration: {
|
||||
type: Object as () => Configuration
|
||||
},
|
||||
submitted: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: () => '100%'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: () => '400px'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
configuration: {
|
||||
handler: 'handlerReset',
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
this.handlerInitialize(false)
|
||||
},
|
||||
methods: {
|
||||
handlerInitialize(reset: boolean)
|
||||
{
|
||||
setTimeout(() => {
|
||||
try {
|
||||
if (this.configuration) {
|
||||
const options = {
|
||||
type: 'radar',
|
||||
data: { values: this.configuration.columns },
|
||||
categoryField: this.configuration.chartConfigure?.xAxis,
|
||||
valueField: this.configuration.chartConfigure?.yAxis
|
||||
} as any
|
||||
if (!reset) {
|
||||
instance = new VChart(options, { dom: this.$refs.content as HTMLElement })
|
||||
instance.renderAsync()
|
||||
}
|
||||
else {
|
||||
instance.updateSpec(options, true)
|
||||
}
|
||||
if (this.submitted) {
|
||||
const cloneOptions = cloneDeep(this.configuration)
|
||||
cloneOptions.headers = []
|
||||
cloneOptions.columns = []
|
||||
this.$emit('change', cloneOptions)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
})
|
||||
},
|
||||
handlerReset()
|
||||
{
|
||||
this.handlerInitialize(true)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user