Compare commits

...

29 Commits

Author SHA1 Message Date
skie1997
4439a48f45 fix: 去除vchart标签描边 2025-06-17 11:08:43 +08:00
奔跑的面条
076c174cb7 feat: 新增线条配置 2025-06-16 17:39:20 +08:00
奔跑的面条
a9bb5e5397 feat: 堆叠图支持开启百分比模式 2025-06-16 16:51:30 +08:00
奔跑的面条
99366efc8c feat: 新增柱状图配置 2025-06-16 16:10:52 +08:00
奔跑的面条
8bb65e57f4 fix: 处理饼图动画错误的计算 2025-06-16 14:16:29 +08:00
奔跑的面条
f883fec1f6 feat: 新增饼图纹理配置器 2025-06-16 14:04:01 +08:00
奔跑的面条
9fa0ee630e feat: 新增饼图配置项 2025-06-16 12:55:46 +08:00
奔跑的面条
cfb2a667bd feat: 新增饼图配制 2025-06-15 16:36:31 +08:00
奔跑的面条
b3a8c23a47 feat: 升级vchart版本,新增横向柱状图,新增配置项,修复配制不生效bug 2025-06-14 22:51:20 +08:00
奔跑的面条
7309aa2e03 feat: 优化饼图半径修复的写法 2025-04-28 15:33:08 +08:00
xihai777
729c81aa61 fix: 修复已保存的饼图数据radius被watch修改为默认值bug https://gitee.com/dromara/go-view/issues/IBJ8QF 2025-04-28 15:32:01 +08:00
奔跑的面条
6af5f9ecf4 feat: 新增在线数据编辑 2025-04-28 15:09:02 +08:00
奔跑的面条
64d4c40c07 feat: 倒计时组件支持接口轮训,修改ts定义错误的写法 2025-04-15 13:47:20 +08:00
奔跑的面条
74abb136a4 !259 fix: register charts animation
Merge pull request !259 from Skie Chen/fix-vchart-build-error
2025-02-24 07:42:18 +00:00
skie1997
cb533a379c fix: register charts animation 2025-02-24 15:29:17 +08:00
奔跑的面条
d2c61f2de5 !253 fix-修复TableList组件报错不显示bug
Merge pull request !253 from QuietlyChan/fix-修复TableList组件报错不显示bug
2025-02-24 07:16:19 +00:00
奔跑的面条
9bf81b113e !257 style: 修改i18n配置文件
Merge pull request !257 from moxunjinmu/dev
2025-02-24 07:14:42 +00:00
奔跑的面条
3de0edcd4e !258 fix: register charts and components to avoid build error
Merge pull request !258 from Skie Chen/fix-vchart-build-error
2025-02-24 07:07:57 +00:00
skie1997
00578479e3 fix: register charts and components to avoid build error 2025-02-24 15:00:48 +08:00
moxunjingmu
9138d0b0bc style: 修改i18n配置文件 2025-02-22 00:05:12 +08:00
奔跑的面条
88e3cc19c8 build: 更新依赖 2025-02-21 10:04:09 +08:00
奔跑的面条
345c4020a6 build: 修改打包错误 2025-02-20 23:38:12 +08:00
奔跑的面条
7d0beec210 !255 feat: supply more chart types into vchart libs
Merge pull request !255 from Skie Chen/dev-vchart-supply-types
2025-02-20 14:38:27 +00:00
skie1997
54b393b456 feat: supply more chart types into vchart libs 2025-02-20 21:00:24 +08:00
QuietlyChan
8bfeca26c7 perf(TableList): 优化列表项数据格式化处理
- 增加对 valueFormatter 函数类型的判断,提高数据格式化处理的灵活性和安全性
- 优化数据排序逻辑,提高列表项数据的准确性和可靠性
- 修复部分变量命名和赋值问题,提升代码质量和可维护性
2025-02-12 16:56:56 +08:00
奔跑的面条
3b5e0fcdeb Merge branch 'dev-vchart' into dev 2025-01-15 17:31:23 +08:00
奔跑的面条
4a361dcfd9 Merge branch 'dev' of https://gitee.com/dromara/go-view into dev 2024-12-26 18:42:56 +08:00
奔跑的面条
168af60a67 chore: 优化进度条的代码写法 2024-12-22 13:04:42 +08:00
初级开发人员
f19dd0ee20 update src/packages/components/Charts/Mores/Process/index.vue.
之前那样UI值不会随着预览更新更新到UI上,接口数变了,UI不变。
前端小白不懂之前为啥要那么写,简单修改一下

Signed-off-by: 初级开发人员 <qinweiw@foxmail.com>
2024-12-22 13:03:05 +08:00
105 changed files with 10958 additions and 4866 deletions

View File

@@ -36,6 +36,13 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
- 可视化:基于开源图表库[ECharts](https://echarts.apache.org/zh/index.html) 和 [VChart](https://www.visactor.io/vchart) 编写,具有丰富的图表类型和适配大屏的主题效果;
- 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
说明文档:
![说明文档](readme/go-view-doc.png)
工作台:
![项目截图](readme/go-view-canvas.png)

View File

@@ -6,7 +6,7 @@
},
"scripts": {
"dev": "vite --host",
"build": "vue-tsc --noEmit && vite build",
"build": "vite build",
"preview": "vite preview",
"new": "plop --plopfile ./plop/plopfile.js",
"postinstall": "husky install",
@@ -21,7 +21,7 @@
"@types/crypto-js": "^4.1.1",
"@types/keymaster": "^1.6.30",
"@types/lodash": "^4.14.184",
"@visactor/vchart": "^1.12.12",
"@visactor/vchart": "^2.0.0",
"@visactor/vchart-theme": "^1.12.2",
"animate.css": "^4.1.1",
"axios": "^1.4.0",
@@ -77,7 +77,7 @@
"mockjs": "^1.1.0",
"plop": "^3.0.5",
"prettier": "^2.6.2",
"sass": "^1.49.11",
"sass": "1.49.11",
"sass-loader": "^12.6.0",
"typescript": "4.6.3",
"vite": "4.3.6",

10283
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -9,9 +9,13 @@
<script setup lang="ts">
import { ref, PropType, watch, onBeforeUnmount, nextTick, toRaw, toRefs } from 'vue'
import { VChart, type IVChart, type IInitOption, type ISpec } from '@visactor/vchart'
import { VChart, type IVChart, type IInitOption } from '@visactor/vchart'
import { transformHandler } from './transformProps'
import { IOption } from '@/packages/components/VChart/index.d'
import { registerChartsAndComponents } from './register'
// VChart按需加载: 注册图表及组件
registerChartsAndComponents()
// 事件说明 v1.13.0 https://www.visactor.io/vchart/api/API/event
const event = [
@@ -193,7 +197,7 @@ const createOrUpdateChart = (
}
) => {
if (vChartRef.value && !chart) {
const spec = transformHandler[chartProps.category](chartProps)
const spec = transformHandler[chartProps.category || '']?.(chartProps)
chart = new VChart(
{ ...spec, data: chartProps.dataset },
{
@@ -204,8 +208,12 @@ const createOrUpdateChart = (
chart.renderSync()
return true
} else if (chart) {
const spec = transformHandler[chartProps.category](chartProps)
chart.updateSpec({ ...spec, data: toRaw(chartProps.dataset), dataset: undefined })
const spec = transformHandler[chartProps.category || '']?.(chartProps)
chart.updateSpec({ ...spec, data: toRaw(chartProps.dataset), dataset: undefined }, false, undefined, {
change: false,
reMake: true,
reAnimate: true
})
return true
}
return false

View File

@@ -0,0 +1,29 @@
import { VChart } from '@visactor/vchart/esm/core';
import { registerBarChart, registerAreaChart, registerLineChart, registerPieChart, registerFunnelChart, registerWordCloudChart, registerScatterChart } from '@visactor/vchart/esm/chart';
import { registerTooltip, registerCartesianCrossHair, registerDiscreteLegend, registerLabel } from '@visactor/vchart/esm/component';
import { registerDomTooltipHandler } from '@visactor/vchart/esm/plugin/components';
import { registerAnimate } from '@visactor/vchart';
export const registerChartsAndComponents = () => {
VChart.useRegisters([
// 图表
registerBarChart,
registerAreaChart,
registerLineChart,
registerPieChart,
registerScatterChart,
registerFunnelChart,
registerWordCloudChart,
// 组件
registerTooltip,
registerDomTooltipHandler,
registerCartesianCrossHair,
registerDiscreteLegend,
registerLabel,
// 动画
registerAnimate
]);
}

View File

@@ -0,0 +1,32 @@
import { cloneDeep } from "lodash"
export default (chartProps: any) => {
const spec = cloneDeep(chartProps)
delete spec.category
// tooltip
const keyFill = spec.tooltip.style.keyLabel.fill
const valueFill = spec.tooltip.style.valueLabel.fill
const titleFill = spec.tooltip.style.titleLabel.keyFill
delete spec.tooltip.style.keyLabel.fill
delete spec.tooltip.style.valueLabel.fill
delete spec.tooltip.style.titleLabel.keyFill
spec.tooltip.style.keyLabel.fontColor = keyFill
spec.tooltip.style.valueLabel.fontColor = valueFill
spec.tooltip.style.titleLabel.fontColor = titleFill
// axis
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
spec.axes = [{
orient: 'bottom',
...restXAxisProps
}, {
orient: 'left',
...restYAxisProps
}]
delete spec.xAxis
delete spec.yAxis
// console.log('spec-area-transform', spec)
return spec
}

View File

@@ -1,4 +1,4 @@
import { cloneDeep } from "lodash"
import { cloneDeep } from 'lodash'
export default (chartProps: any) => {
const spec = cloneDeep(chartProps)
@@ -18,15 +18,28 @@ export default (chartProps: any) => {
// axis
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
spec.axes = [{
orient: 'bottom',
...restXAxisProps
}, {
orient: 'left',
...restYAxisProps
}]
spec.axes = [
{
orient: 'bottom',
...restXAxisProps
// paddingInner: 0.5
},
{
orient: 'left',
...restYAxisProps
}
]
delete spec.xAxis
delete spec.yAxis
console.log('spec-transform', spec)
spec.label = {
...spec.label,
style: {
...spec.label?.style,
lineWidth: 0
}
}
// console.log('spec-bar-transform', spec)
return spec
}
}

View File

@@ -0,0 +1,28 @@
import { Datum } from "@visactor/vchart/esm/typings"
import { cloneDeep } from "lodash"
const INNER_RADIUS = 0.75
const OUTER_RADIUS = 0.68
export default (chartProps: any) => {
const spec = cloneDeep(chartProps)
// tooltip
const keyFill = spec.tooltip.style.keyLabel.fill
const valueFill = spec.tooltip.style.valueLabel.fill
const titleFill = spec.tooltip.style.titleLabel.keyFill
delete spec.tooltip.style.keyLabel.fill
delete spec.tooltip.style.valueLabel.fill
delete spec.tooltip.style.titleLabel.keyFill
spec.tooltip.style.keyLabel.fontColor = keyFill
spec.tooltip.style.valueLabel.fontColor = valueFill
spec.tooltip.style.titleLabel.fontColor = titleFill
// label
spec.label = {
visible: true,
}
// console.log('spec-funnel-transform', spec)
return spec
}

View File

@@ -1,8 +1,20 @@
import { ChatCategoryEnum, IOption } from "@/packages/components/VChart/index.d";
import bars from './bars'
import pies from './pies'
import lines from './lines'
import areas from './areas'
import funnels from "./funnels";
import wordClouds from "./wordClouds";
import scatters from "./scatters";
export const transformHandler: {
[key: string]: (args: IOption) => any
} = {
[ChatCategoryEnum.BAR]: bars,
[ChatCategoryEnum.PIE]: pies,
[ChatCategoryEnum.LINE]: lines,
[ChatCategoryEnum.AREA]: areas,
[ChatCategoryEnum.FUNNEL]: funnels,
[ChatCategoryEnum.WORDCLOUD]: wordClouds,
[ChatCategoryEnum.SCATTER]: scatters,
// todo: more charts handler
}

View File

@@ -0,0 +1,43 @@
import { cloneDeep } from 'lodash'
export default (chartProps: any) => {
const spec = cloneDeep(chartProps)
delete spec.category
// tooltip
const keyFill = spec.tooltip.style.keyLabel.fill
const valueFill = spec.tooltip.style.valueLabel.fill
const titleFill = spec.tooltip.style.titleLabel.keyFill
delete spec.tooltip.style.keyLabel.fill
delete spec.tooltip.style.valueLabel.fill
delete spec.tooltip.style.titleLabel.keyFill
spec.tooltip.style.keyLabel.fontColor = keyFill
spec.tooltip.style.valueLabel.fontColor = valueFill
spec.tooltip.style.titleLabel.fontColor = titleFill
// axis
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
spec.axes = [
{
orient: 'bottom',
...restXAxisProps
},
{
orient: 'left',
...restYAxisProps
}
]
delete spec.xAxis
delete spec.yAxis
spec.label = {
...spec.label,
style: {
...spec.label?.style,
lineWidth: 0
}
}
// console.log('spec-line-transform', spec)
return spec
}

View File

@@ -0,0 +1,132 @@
import { Datum } from '@visactor/vchart/esm/typings'
import { cloneDeep } from 'lodash'
export default (chartProps: any) => {
const spec = cloneDeep(chartProps)
delete spec.category
// tooltip
const keyFill = spec.tooltip.style.keyLabel.fill
const valueFill = spec.tooltip.style.valueLabel.fill
const titleFill = spec.tooltip.style.titleLabel.keyFill
delete spec.tooltip.style.keyLabel.fill
delete spec.tooltip.style.valueLabel.fill
delete spec.tooltip.style.titleLabel.keyFill
spec.tooltip.style.keyLabel.fontColor = keyFill
spec.tooltip.style.valueLabel.fontColor = valueFill
spec.tooltip.style.titleLabel.fontColor = titleFill
if (spec.extensionMark) {
// extensionMark
spec.extensionMark = [
{
name: 'arc_inner_shadow',
type: 'arc',
dataId: 'id0',
style: {
interactive: false,
startAngle: (datum: Datum) => {
return datum['__VCHART_ARC_START_ANGLE']
},
endAngle: (datum: Datum) => {
return datum['__VCHART_ARC_END_ANGLE']
},
innerRadius: (datum: Datum, context: any) => {
return context.getLayoutRadius() * spec.innerRadius - 30
},
outerRadius: (datum: Datum, context: any) => {
return context.getLayoutRadius() * spec.innerRadius
},
fillOpacity: 0.3,
fill: (datum: Datum, context: any) => {
return context.seriesColor(datum[spec.seriesField])
},
visible: true,
x: (datum: Datum, context: any) => {
return context.getCenter().x()
},
y: (datum: Datum, context: any) => {
return context.getCenter().y()
}
}
},
{
name: 'arc_inner',
type: 'symbol',
// dataId: 'id0',
style: {
interactive: false,
size: (datum: Datum, context: any) => {
return context.getLayoutRadius() * 2 * spec.innerRadius - 100
},
fillOpacity: 0,
lineWidth: 1,
strokeOpacity: 0.5,
stroke: {
gradient: 'conical',
startAngle: 0,
endAngle: Math.PI * 2,
stops: [
{
offset: 0,
color: '#FFF',
opacity: 0
},
{
offset: 1,
color: '#FFF',
opacity: 1
}
]
},
visible: true,
x: (datum: Datum, context: any) => {
return context.getCenter().x()
},
y: (datum: Datum, context: any) => {
return context.getCenter().y()
}
}
},
{
name: 'arc_outer',
type: 'symbol',
// dataId: 'id0',
style: {
interactive: false,
size: (datum: Datum, context: any) => {
return context.getLayoutRadius() * 2 * spec.outerRadius + 50
},
fillOpacity: 0,
lineWidth: 1,
strokeOpacity: 0.5,
stroke: {
gradient: 'conical',
startAngle: 0,
endAngle: Math.PI * 2,
stops: [
{
offset: 0,
color: '#FFF',
opacity: 0
},
{
offset: 1,
color: '#FFF',
opacity: 1
}
]
},
visible: true,
x: (datum: Datum, context: any) => {
return context.getCenter().x()
},
y: (datum: Datum, context: any) => {
return context.getCenter().y()
}
}
}
]
}
return spec
}

View File

@@ -0,0 +1,35 @@
import { cloneDeep } from "lodash"
export default (chartProps: any) => {
const spec = cloneDeep(chartProps)
// tooltip
const keyFill = spec.tooltip.style.keyLabel.fill
const valueFill = spec.tooltip.style.valueLabel.fill
const titleFill = spec.tooltip.style.titleLabel.keyFill
delete spec.tooltip.style.keyLabel.fill
delete spec.tooltip.style.valueLabel.fill
delete spec.tooltip.style.titleLabel.keyFill
spec.tooltip.style.keyLabel.fontColor = keyFill
spec.tooltip.style.valueLabel.fontColor = valueFill
spec.tooltip.style.titleLabel.fontColor = titleFill
// axis
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
spec.axes = [{
orient: 'bottom',
...restXAxisProps,
label: {
formatMethod: (value: string) => Number(value).toFixed(2)
}
}, {
orient: 'left',
...restYAxisProps
}]
delete spec.xAxis
delete spec.yAxis
// console.log('spec-scatter-transform', spec)
return spec
}

View File

@@ -0,0 +1,21 @@
import { Datum } from "@visactor/vchart/esm/typings"
import { cloneDeep } from "lodash"
export default (chartProps: any) => {
const spec = cloneDeep(chartProps)
// tooltip
const keyFill = spec.tooltip.style.keyLabel.fill
const valueFill = spec.tooltip.style.valueLabel.fill
const titleFill = spec.tooltip.style.titleLabel.keyFill
delete spec.tooltip.style.keyLabel.fill
delete spec.tooltip.style.valueLabel.fill
delete spec.tooltip.style.titleLabel.keyFill
spec.tooltip.style.keyLabel.fontColor = keyFill
spec.tooltip.style.valueLabel.fontColor = valueFill
spec.tooltip.style.titleLabel.fontColor = titleFill
// console.log('spec-word-cloud-transform', spec)
return spec
}

View File

@@ -1,18 +1,29 @@
<template>
<collapse-item v-model:name="axis.name">
<collapse-item :name="axis.name">
<template #header>
<n-switch v-model:value="axis.visible" size="small"></n-switch>
</template>
<setting-item-box name="轴标签">
<setting-item-box name="单位">
<setting-item name="可见性">
<n-space>
<n-switch v-model:value="axis.unit.visible" size="small"></n-switch>
</n-space>
</setting-item>
<setting-item name="内容">
<n-input v-model:value="axis.unit.text" size="small"></n-input>
</setting-item>
<FontStyle :style="toRefs(axis.unit.style)"></FontStyle>
</setting-item-box>
<setting-item-box name="轴标签">
<setting-item v-if="axis.label" name="可见性">
<n-space>
<n-switch v-model:value="axis.label.visible" size="small"></n-switch>
</n-space>
</setting-item>
<setting-item name="角度">
<setting-item v-if="axis.label" name="角度">
<n-input-number v-model:value="axis.label.style.angle" :min="0" :max="360" size="small" />
</setting-item>
<FontStyle :style="axis.label.style"></FontStyle>
<FontStyle v-if="axis.label" :style="toRefs(axis.label.style)"></FontStyle>
</setting-item-box>
<setting-item-box name="轴标题">
<setting-item name="可见性">
@@ -20,10 +31,16 @@
<n-switch v-model:value="axis.title.visible" size="small"></n-switch>
</n-space>
</setting-item>
<setting-item name="标题内容">
<setting-item name="内容">
<n-input v-model:value="axis.title.style.text" size="small"></n-input>
</setting-item>
<FontStyle :style="axis.title.style"></FontStyle>
<setting-item name="位置">
<n-select v-model:value="axis.title.position" :options="legendsConfig.position" size="small" />
</setting-item>
<setting-item name="角度">
<n-input-number v-model:value="axis.title.angle" :min="0" :max="360" size="small" />
</setting-item>
<FontStyle :style="toRefs(axis.title.style)"></FontStyle>
</setting-item-box>
<setting-item-box name="轴线">
<setting-item name="可见性">
@@ -45,7 +62,11 @@
<n-switch v-model:value="axis.grid.visible" size="small"></n-switch>
</n-space>
</setting-item>
<setting-item name=""> </setting-item>
<setting-item name="开启虚线">
<n-space>
<n-switch v-model:value="isLineDashRef" size="small" @update:value="changeLineDash"></n-switch>
</n-space>
</setting-item>
<setting-item name="粗细">
<n-input-number v-model:value="axis.grid.style.lineWidth" :min="0" size="small" />
</setting-item>
@@ -57,15 +78,33 @@
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { PropType, ref, toRefs } from 'vue'
import FontStyle from './common/FontStyle.vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
defineProps({
const props = defineProps({
axis: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
// 判断是否是虚线
const isDash = (data: undefined | Array<number>) => {
if (!data || data.length === 0 || data[0] === 0) return false
return true
}
// 虚线
const isLineDashRef = ref(isDash(props.axis.grid.style.lineDash))
const changeLineDash = (data: boolean) => {
if (data) {
props.axis.grid.style.lineDash = [4, 4] // 设置为虚线
} else {
props.axis.grid.style.lineDash = [0] // 设置为实线
}
}
</script>

View File

@@ -0,0 +1,52 @@
<template>
<template v-if="optionData.bar">
<collapse-item name="柱体">
<SettingItemBox name="样式">
<setting-item v-if="'width' in optionData.bar.style" name="宽度">
<n-input-number v-model:value="optionData.bar.style.width" size="small" :min="1"></n-input-number>
</setting-item>
<setting-item v-if="'height' in (optionData.bar.style as any)" name="高度">
<n-input-number v-model:value="(optionData.bar.style as any).height" size="small" :min="1"></n-input-number>
</setting-item>
<setting-item name="圆角大小">
<n-input-number v-model:value="optionData.bar.style.cornerRadius" size="small" :min="0"></n-input-number>
</setting-item>
<setting-item name="填充透明度">
<n-input-number
v-model:value="optionData.bar.style.fillOpacity"
:step="0.1"
size="small"
:min="0"
:max="1"
></n-input-number>
</setting-item>
<setting-item name="整体透明度">
<n-input-number
v-model:value="optionData.bar.style.opacity"
:step="0.1"
size="small"
:min="0"
:max="1"
></n-input-number>
</setting-item>
<setting-item name="纹理类型">
<n-select v-model:value="optionData.bar.style.texture" :options="styleConfig.texture" size="small"></n-select>
</setting-item>
</SettingItemBox>
</collapse-item>
</template>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -0,0 +1,46 @@
<template>
<template v-if="optionData.label">
<collapse-item name="标签">
<template #header>
<n-switch v-model:value="optionData.label.visible" size="small"></n-switch>
</template>
<setting-item-box name="布局">
<setting-item name="位置">
<n-select
v-model:value="optionData.label.position"
size="small"
:options="positionOptions || labelConfig.barPosition"
/>
</setting-item>
<setting-item name="间距">
<n-input-number v-model:value="optionData.label.offset" :min="1" size="small" />
</setting-item>
</setting-item-box>
<setting-item-box name="字体">
<FontStyle :style="toRefs(optionData.label.style)"></FontStyle>
</setting-item-box>
</collapse-item>
</template>
</template>
<script setup lang="ts">
import { PropType, toRefs } from 'vue'
import { labelConfig } from '@/packages/chartConfiguration/vcharts/index'
import FontStyle from './common/FontStyle.vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
},
positionOptions: {
type: Array,
required: false
}
})
</script>

View File

@@ -15,7 +15,7 @@
</setting-item>
</setting-item-box>
<setting-item-box name="项配置">
<FontStyle :style="legendItem.item.label.style"></FontStyle>
<FontStyle :style="toRefs(legendItem.item.label.style)"></FontStyle>
</setting-item-box>
</collapse-item>
</div>
@@ -23,7 +23,7 @@
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { PropType, toRefs } from 'vue'
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
import FontStyle from './common/FontStyle.vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'

View File

@@ -0,0 +1,33 @@
<template>
<collapse-item name="线条" v-if="optionData.line">
<SettingItemBox name="样式">
<setting-item name="宽度">
<n-input-number v-model:value="optionData.line.style.lineWidth" size="small" :min="1"></n-input-number>
</setting-item>
<setting-item name="线条类型">
<n-select
v-model:value="optionData.line.style.curveType"
:options="styleConfig.curveType"
size="small"
></n-select>
</setting-item>
<setting-item name="末端样式">
<n-select v-model:value="optionData.line.style.lineCap" :options="styleConfig.lineCap" size="small"></n-select>
</setting-item>
</SettingItemBox>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -0,0 +1,56 @@
<template>
<template v-if="optionData.point">
<collapse-item name="实心点(图元)">
<template #header>
<n-switch v-model:value="optionData.point.visible" size="small"></n-switch>
</template>
<setting-item-box name="样式">
<setting-item name="位置">
<n-select v-model:value="optionData.point.style.symbolType" size="small" :options="styleConfig.symbolType" />
</setting-item>
<setting-item name="大小">
<n-input-number v-model:value="optionData.point.style.size" :min="0" size="small" />
</setting-item>
<setting-item name="填充透明度">
<n-input-number v-model:value="optionData.point.style.fillOpacity" :step="0.1" :min="0" size="small" />
</setting-item>
<setting-item name="边框宽度">
<n-input-number v-model:value="optionData.point.style.lineWidth" :min="0" size="small" />
</setting-item>
<setting-item name="边框颜色">
<n-color-picker v-model:value="optionData.point.style.stroke" size="small" />
</setting-item>
<setting-item name="边框透明度">
<n-input-number v-model:value="optionData.point.style.strokeOpacity" :step="0.1" :min="0" size="small" />
</setting-item>
<setting-item name="偏移X">
<n-input-number v-model:value="optionData.point.style.dx" :min="0" size="small" />
</setting-item>
<setting-item name="偏移Y">
<n-input-number v-model:value="optionData.point.style.dy" :min="0" size="small" />
</setting-item>
</setting-item-box>
</collapse-item>
</template>
</template>
<script setup lang="ts">
import { PropType, toRefs } from 'vue'
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
import FontStyle from './common/FontStyle.vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
},
positionOptions: {
type: Array,
required: false
}
})
</script>

View File

@@ -20,20 +20,20 @@
</setting-item>
</setting-item-box>
<setting-item-box name="标题">
<FontStyle :style="optionData.tooltip.style.titleLabel"></FontStyle>
<FontStyle :style="toRefs(optionData.tooltip.style.titleLabel)"></FontStyle>
</setting-item-box>
<setting-item-box name="名称">
<FontStyle :style="optionData.tooltip.style.keyLabel"></FontStyle>
<FontStyle :style="toRefs(optionData.tooltip.style.keyLabel)"></FontStyle>
</setting-item-box>
<setting-item-box name="值">
<FontStyle :style="optionData.tooltip.style.valueLabel"></FontStyle>
<FontStyle :style="toRefs(optionData.tooltip.style.valueLabel)"></FontStyle>
</setting-item-box>
</collapse-item>
</div>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { PropType, toRefs } from 'vue'
import FontStyle from './common/FontStyle.vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'

View File

@@ -1,21 +1,28 @@
<template>
<!-- todo 补充常用配置项 -->
<!-- <div v-if="style"> -->
<!-- <setting-item-box v-if="style" name=""> -->
<setting-item name="颜色">
<n-color-picker v-model:value="style.fill" size="small" />
</setting-item>
<setting-item name="大小">
<n-input-number v-model:value="style.fontSize" :min="1" size="small" />
</setting-item>
<setting-item name="字体">
<n-select v-model:value="style.fontFamily" :options="fontStyleConfig.fontFamily" size="small" />
</setting-item>
<setting-item name="字重">
<n-select v-model:value="style.fontSize" :options="fontStyleConfig.fontWeight" size="small" />
</setting-item>
<!-- </setting-item-box> -->
<!-- </div> -->
<template v-if="style">
<setting-item name="颜色">
<n-color-picker v-model:value="style.fill.value" size="small" />
</setting-item>
<setting-item name="大小">
<n-input-number v-model:value="style.fontSize.value" :min="1" size="small" />
</setting-item>
<setting-item name="字体">
<n-select v-model:value="style.fontFamily.value" :options="fontStyleConfig.fontFamily" size="small" />
</setting-item>
<setting-item name="字重">
<n-select v-model:value="style.fontWeight.value" :options="fontStyleConfig.fontWeight" size="small" />
</setting-item>
<setting-item v-if="style?.dx" name="X轴偏移">
<n-input-number v-model:value="style.dx.value" size="small" />
</setting-item>
<setting-item v-if="style?.dy" name="Y轴偏移">
<n-input-number v-model:value="style.dy.value" size="small" />
</setting-item>
<setting-item v-if="style?.angle" name="旋转">
<n-input-number v-model:value="style.angle.value" :step="0.1" :min="0" :max="360" size="small" />
</setting-item>
</template>
</template>
<script setup lang="ts">
@@ -26,7 +33,7 @@ import { SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
style: {
type: Object as PropType<FontType>,
type: Object as PropType<any>,
required: true
}
})

View File

@@ -0,0 +1,84 @@
<template>
<setting-item name="间距">
<n-input v-model:value="paddingArray" size="small" @update:value="updateHandle"/>
</setting-item>
</template>
<script setup lang="ts">
import type { ICartesianTitle } from '@visactor/vchart/esm/component/axis'
import { forEach, isNumber } from 'lodash'
import { SettingItem } from '@/components/Pages/ChartItemSetting'
import { PropType, ref } from 'vue'
const props = defineProps({
axis: {
type: Object as PropType<ICartesianTitle>,
required: true
}
})
// 解析间距
const paddingInit = (padding: ICartesianTitle['padding']) => {
const arr = [0, 0, 0, 0]
if (!padding) {
return arr
}
if (isNumber(padding)) {
arr.forEach((item, index) => {
arr[index] = padding
})
} else if (Array.isArray(padding)) {
if (padding.length === 1) {
arr.forEach((item, index) => {
arr[index] = padding[0]
})
} else if (padding.length === 2) {
arr[0] = padding[0]
arr[1] = padding[1]
arr[2] = padding[0]
arr[3] = padding[1]
} else if (padding.length === 3) {
arr[0] = padding[0]
arr[1] = padding[1]
arr[2] = padding[2]
arr[3] = padding[1]
} else if (padding.length === 4) {
arr[0] = padding[0]
arr[1] = padding[1]
arr[2] = padding[2]
arr[3] = padding[3]
}
}
// 转成字符串,逗号分隔
return arr.map(item => item.toString()).join(',')
}
// 间距处理
const paddingArray = ref(paddingInit(props.axis.padding))
// 字符串转成数组
const paddingArrayToNumber = (padding: string) => {
const arr = padding.split(',').map(item => parseFloat(item.trim()))
if (arr.length === 1) {
return [arr[0], arr[0], arr[0], arr[0]]
} else if (arr.length === 2) {
return [arr[0], arr[1], arr[0], arr[1]]
} else if (arr.length === 3) {
return [arr[0], arr[1], arr[2], arr[1]]
} else if (arr.length === 4) {
return arr
}
return [0, 0, 0, 0]
}
const updateHandle = (value: string) => {
const padding = paddingArrayToNumber(value)
forEach(padding, (item, index) => {
if (isNaN(item)) {
padding[index] = 0
}
})
props.axis.padding = padding
}
</script>

View File

@@ -1,4 +1,8 @@
import VChartGlobalSetting from './VChartGlobalSetting.vue'
import Axis from './Axis.vue'
import Label from './Label.vue'
import Bar from './Bar.vue'
import Line from './Line.vue'
import Point from './Point.vue'
export { VChartGlobalSetting, Axis }
export { VChartGlobalSetting, Axis, Label, Bar, Line, Point }

View File

@@ -5,7 +5,7 @@ export default {
my: 'My',
new_project: 'New Project',
all_project: 'All Project',
my_templete: 'My Templete',
my_template: 'My Template',
template_market: 'Template Market',
// items

View File

@@ -6,7 +6,7 @@ export default {
my: '我的',
new_project: '新项目',
all_project: '全部项目',
my_templete: '我的模板',
my_template: '我的模板',
template_market: '模板市场',
// items

View File

@@ -1 +1,3 @@
export * from './legends'
export * from './legends'
export * from './label'
export * from './style'

View File

@@ -0,0 +1,120 @@
export const labelConfig = {
position: [
{
label: '外部',
value: 'outside'
},
{
label: '内部',
value: 'inside'
},
{
label: '内部-外',
value: 'inside-outer'
},
{
label: '内部-里',
value: 'inside-inner'
},
{
label: '内部-居中',
value: 'inside-center'
}
],
barPosition: [
{
label: '外部',
value: 'outside'
},
{
label: '内部',
value: 'inside'
},
{
label: '顶部',
value: 'top'
},
{
label: '底部',
value: 'bottom'
},
{
label: '左侧',
value: 'left'
},
{
label: '右侧',
value: 'right'
},
{
label: '内部-顶',
value: 'inside-top'
},
{
label: '内部-底',
value: 'inside-bottom'
},
{
label: '内部-右',
value: 'inside-right'
},
{
label: '内部-左',
value: 'inside-left'
},
{
label: '顶部-右',
value: 'top-right'
},
{
label: '顶部-左',
value: 'top-left'
},
{
label: '底部-右',
value: 'bottom-right'
},
{
label: '底部-左',
value: 'bottom-left'
}
],
linePosition: [
{
label: '顶部',
value: 'top'
},
{
label: '底部',
value: 'bottom'
},
{
label: '左侧',
value: 'left'
},
{
label: '右侧',
value: 'right'
},
{
label: '顶部-右',
value: 'top-right'
},
{
label: '顶部-左',
value: 'top-left'
},
{
label: '底部-右',
value: 'bottom-right'
},
{
label: '底部-左',
value: 'bottom-left'
},
{
label: '居中',
value: 'center'
}
]
}

View File

@@ -0,0 +1,150 @@
export const styleConfig = {
texture: [
{
label: '无纹理',
value: ''
},
{
label: '圆形',
value: 'circle'
},
{
label: '钻石',
value: 'diamond'
},
{
label: '矩形',
value: 'rect'
},
{
label: '竖线',
value: 'horizontal-line'
},
{
label: '横线',
value: 'vertical-line'
},
{
label: '右向左斜线',
value: 'bias-rl'
},
{
label: '左向右斜线',
value: 'bias-lr'
},
{
label: '格子',
value: 'grid'
}
],
curveType: [
{
label: '线性',
value: 'linear'
},
{
label: '平滑',
value: 'monotone'
},
{
label: '平滑趋近X',
value: 'monotoneX'
},
{
label: '台阶',
value: 'step'
},
{
label: '连线闭合',
value: 'catmullRom'
},
{
label: '顺滑闭合',
value: 'catmullRomClosed'
}
],
lineCap: [
{
label: '默认',
value: 'butt'
},
{
label: '圆形',
value: 'round'
},
{
label: '方形',
value: 'square'
}
],
symbolType: [
{
label: '圆形',
value: 'circle'
},
{
label: '方形',
value: 'rect'
},
{
label: '菱形',
value: 'diamond'
},
{
label: '三角形',
value: 'square'
},
{
label: '指向向上',
value: 'arrow'
},
{
label: '指向向左',
value: 'arrow2Left'
},
{
label: '箭头向右',
value: 'arrow2Right'
},
{
label: '瘦箭头向上',
value: 'wedge'
},
{
label: '箭头向上',
value: 'triangle'
},
{
label: '箭头向下',
value: 'triangleDown'
},
{
label: '箭头向右',
value: 'triangleRight'
},
{
label: '箭头向左',
value: 'triangleLeft'
},
{
label: '星星',
value: 'star'
},
{
label: 'y字形物',
value: 'wye'
},
{
label: '矩形',
value: 'rect'
},
{
label: '圆角矩形',
value: 'rectRound'
},
{
label: '扁平矩形',
value: 'roundLine'
}
]
}

View File

@@ -49,16 +49,12 @@ const {
dataset
} = toRefs(props.chartConfig.option)
const option = shallowReactive({
dataset: configOption.dataset
})
// 手动更新
watch(
() => props.chartConfig.option.dataset,
(newData: any) => {
try {
option.dataset = toNumber(newData, 2)
dataset.value = toNumber(newData, 2)
} catch (error) {
console.log(error)
}
@@ -69,6 +65,6 @@ watch(
)
// 预览更新
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: number) => {
option.dataset = toNumber(newData, 2)
dataset.value = toNumber(newData, 2)
})
</script>

View File

@@ -66,7 +66,7 @@
:options="labelConfig.fontWeight"
/>
</SettingItem>
<setting-item name="文字边框大小" v-if="optionData.series[0].label.textBorderWidth">
<setting-item name="文字边框大小" v-if="optionData.series[0].label.textBorderWidth > -1">
<n-input-number
v-model:value="optionData.series[0].label.textBorderWidth"
size="small"
@@ -81,7 +81,7 @@
></n-color-picker>
</setting-item>
</setting-item-box>
<setting-item-box name="圆角">
<setting-item-box name="分段样式">
<setting-item name="圆角大小">
<n-input-number
v-model:value="optionData.series[0].itemStyle.borderRadius"

View File

@@ -12,7 +12,7 @@
</template>
<script setup lang="ts">
import { computed, PropType, onMounted, watch } from 'vue'
import { computed, PropType, onMounted, watch, ref } from 'vue'
import VChart from 'vue-echarts'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use } from 'echarts/core'
@@ -103,6 +103,10 @@ watch(
() => props.chartConfig.option.type,
newData => {
try {
// 防止初始化时触发修改,导致部分参数丢失
if (isPreview()) {
return
}
if (newData === 'nomal') {
props.chartConfig.option.series[0].radius = '70%'
props.chartConfig.option.series[0].roseType = false

View File

@@ -1,5 +1,5 @@
<template>
<div>
<div ref="vChartRef">
<n-countdown
ref="countdownRef"
:duration="totalDuration"
@@ -79,6 +79,8 @@ import { CreateComponentType } from '@/packages/index.d'
import { Flipper } from '@/components/Pages/Flipper'
import { OptionType } from './config'
import { CountdownInst, CountdownProps } from 'naive-ui/es/countdown/src/Countdown'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
const props = defineProps({
chartConfig: {
@@ -174,6 +176,10 @@ watch(
onMounted(() => {
updateTotalDuration()
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>
<style lang="scss" scoped>

View File

@@ -10,7 +10,11 @@
<div class="rank" :style="`color: ${color};font-size: ${indexFontSize}px`">No.{{ item.ranking }}</div>
<div class="info-name" :style="`font-size: ${leftFontSize}px`" v-html="item.name" />
<div class="ranking-value" :style="`color: ${textColor};font-size: ${rightFontSize}px`">
{{ status.mergedConfig.valueFormatter ? status.mergedConfig.valueFormatter(item) : item.value }}
{{
typeof status.mergedConfig.valueFormatter === 'function'
? status.mergedConfig.valueFormatter(item)
: item.value
}}
{{ unit }}
</div>
</div>
@@ -62,7 +66,8 @@ const status = reactive({
const calcRowsData = () => {
let { dataset, rowNum, sort } = status.mergedConfig
// @ts-ignore
sort &&dataset.sort(({ value: a }, { value: b } ) => {
sort &&
dataset.sort(({ value: a }, { value: b }) => {
if (a > b) return -1
if (a < b) return 1
if (a === b) return 0
@@ -137,7 +142,7 @@ const onRestart = async () => {
calcRowsData()
let flag = true
if (dataset.length <= rowNum) {
flag=false
flag = false
}
calcHeights(flag)
animation(flag)

View File

@@ -0,0 +1,47 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartAreaConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { IAreaOption } from '../../index.d'
export const includes = ['legends', 'tooltip']
export const option: IAreaOption & { dataset?: any } = {
// 图表配置
type: 'area',
dataset: data,
xField: 'type',
yField: 'value',
seriesField: 'country',
stack: true,
// 业务配置后续会被转换为图表spec)
category: VChartAreaConfig.category,
xAxis: {
name: 'x轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
visible: false
}
},
yAxis: {
name: 'y轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style,
lineDash: [3, 3]
}
}
}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartAreaConfig.key
public chartConfig = cloneDeep(VChartAreaConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@@ -0,0 +1,19 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -0,0 +1,16 @@
{
"values": [
{ "type": "Nail polish", "country": "China", "value": 3054 },
{ "type": "Nail polish", "country": "USA", "value": 12814 },
{ "type": "Eyebrow pencil", "country": "China", "value": 5067 },
{ "type": "Eyebrow pencil", "country": "USA", "value": 13012 },
{ "type": "Rouge", "country": "China", "value": 7004 },
{ "type": "Rouge", "country": "USA", "value": 11624 },
{ "type": "Lipstick", "country": "China", "value": 9054 },
{ "type": "Lipstick", "country": "USA", "value": 8814 },
{ "type": "Eyeshadows", "country": "China", "value": 12043 },
{ "type": "Eyeshadows", "country": "USA", "value": 12998 },
{ "type": "Eyeliner", "country": "China", "value": 15067 },
{ "type": "Eyeliner", "country": "USA", "value": 12321 }
]
}

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartAreaConfig: ConfigType = {
key: 'VChartArea',
chartKey: 'VVChartArea',
conKey: 'VCVChartArea',
title: 'VChart面积图',
category: ChatCategoryEnum.AREA,
categoryName: ChatCategoryEnumName.AREA,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_area.png'
}

View File

@@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@@ -0,0 +1,48 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartPercentAreaConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { IAreaOption } from '../../index.d'
export const includes = ['legends', 'tooltip']
export const option: IAreaOption & { dataset?: any } = {
// 图表配置
type: 'area',
dataset: data,
xField: 'type',
yField: 'value',
seriesField: 'country',
stack: true,
percent: true,
// 业务配置后续会被转换为图表spec)
category: VChartPercentAreaConfig.category,
xAxis: {
name: 'x轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
visible: false
}
},
yAxis: {
name: 'y轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style,
lineDash: [3, 3]
}
}
}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartPercentAreaConfig.key
public chartConfig = cloneDeep(VChartPercentAreaConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@@ -0,0 +1,19 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -0,0 +1,16 @@
{
"values": [
{ "type": "Nail polish", "country": "China", "value": 3054 },
{ "type": "Nail polish", "country": "USA", "value": 12814 },
{ "type": "Eyebrow pencil", "country": "China", "value": 5067 },
{ "type": "Eyebrow pencil", "country": "USA", "value": 13012 },
{ "type": "Rouge", "country": "China", "value": 7004 },
{ "type": "Rouge", "country": "USA", "value": 11624 },
{ "type": "Lipstick", "country": "China", "value": 9054 },
{ "type": "Lipstick", "country": "USA", "value": 8814 },
{ "type": "Eyeshadows", "country": "China", "value": 12043 },
{ "type": "Eyeshadows", "country": "USA", "value": 12998 },
{ "type": "Eyeliner", "country": "China", "value": 15067 },
{ "type": "Eyeliner", "country": "USA", "value": 12321 }
]
}

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartPercentAreaConfig: ConfigType = {
key: 'VChartPercentArea',
chartKey: 'VVChartPercentArea',
conKey: 'VCVChartPercentArea',
title: 'VChart百分比面积图',
category: ChatCategoryEnum.AREA,
categoryName: ChatCategoryEnumName.AREA,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_percent_area.png'
}

View File

@@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@@ -0,0 +1,4 @@
import { VChartAreaConfig } from './VChartArea/index'
import { VChartPercentAreaConfig } from './VChartPercentArea/index'
export default [VChartAreaConfig, VChartPercentAreaConfig]

View File

@@ -3,11 +3,11 @@ import { VChartBarCommonConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { IBarOption } from '../../index.d'
import { ChatCategoryEnum, IBarOption } from '../../index.d'
import { merge, cloneDeep } from 'lodash'
export const includes = ['legends', 'tooltip']
export const includes = ['legends', 'tooltip', 'label', 'bar']
export const option: IBarOption & { dataset?: any } = {
// 图表配置
type: 'bar',
@@ -17,10 +17,17 @@ export const option: IBarOption & { dataset?: any } = {
yField: ['value'],
seriesField: 'type',
// 业务配置后续会被转换为图表spec)
category: VChartBarCommonConfig.category,
category: VChartBarCommonConfig.category as ChatCategoryEnum.BAR,
xAxis: {
name: 'x轴',
...axisThemeJson,
...(merge(cloneDeep(axisThemeJson), {
unit: {
style: {
dx: 10,
dy: 0
}
}
}) as any),
grid: {
...axisThemeJson.grid,
visible: false
@@ -28,12 +35,18 @@ export const option: IBarOption & { dataset?: any } = {
},
yAxis: {
name: 'y轴',
...axisThemeJson,
...(merge(cloneDeep(axisThemeJson), {
unit: {
style: {
dx: 0,
dy: -10
}
}
}) as any),
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style,
lineDash: [3, 3]
...axisThemeJson.grid.style
}
}
}

View File

@@ -3,11 +3,15 @@
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
<!-- 标签 -->
<Label :optionData="optionData"></Label>
<!-- 柱体 -->
<Bar :optionData="optionData"></Bar>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
import { VChartGlobalSetting, Axis, Label, Bar } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({

View File

@@ -5,7 +5,7 @@ export const VChartBarCommonConfig: ConfigType = {
key: 'VChartBarCommon',
chartKey: 'VVChartBarCommon',
conKey: 'VCVChartBarCommon',
title: 'VChart柱状图',
title: '并列柱状图-VChart',
category: ChatCategoryEnum.BAR,
categoryName: ChatCategoryEnumName.BAR,
package: PackagesCategoryEnum.VCHART,

View File

@@ -0,0 +1,72 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartBarCrossrangeConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { ChatCategoryEnum, IBarOption } from '../../index.d'
import { merge, cloneDeep } from 'lodash'
import { vChartGlobalThemeJson } from '@/settings/vchartThemes'
const barConfig = merge(cloneDeep(vChartGlobalThemeJson.bar), {
style: {
height: 10
}
})
delete (barConfig.style as { width?: any }).width
export const includes = ['legends', 'tooltip', 'label']
export const option: IBarOption & { dataset?: any } = {
// 图表配置
type: 'bar',
dataset: data,
stack: true,
xField: ['value'],
yField: ['year', 'type'],
seriesField: 'type',
// 业务配置后续会被转换为图表spec)
category: VChartBarCrossrangeConfig.category as ChatCategoryEnum.BAR,
direction: 'horizontal',
xAxis: {
name: 'x轴',
...(merge(cloneDeep(axisThemeJson), {
unit: {
style: {
dx: 10,
dy: 0
}
}
}) as any),
grid: {
...axisThemeJson.grid,
visible: false
}
},
yAxis: {
name: 'y轴',
...(merge(cloneDeep(axisThemeJson), {
unit: {
style: {
dx: 0,
dy: -10
}
}
}) as any),
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style
}
}
},
bar: {
...barConfig
}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartBarCrossrangeConfig.key
public chartConfig = cloneDeep(VChartBarCrossrangeConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@@ -0,0 +1,23 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
<!-- 标签 -->
<Label :optionData="optionData"></Label>
<!-- 柱体 -->
<Bar :optionData="optionData"></Bar>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis, Label, Bar } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -0,0 +1,25 @@
{
"values": [
{ "type": "Autocracies", "year": "1930", "value": 129 },
{ "type": "Autocracies", "year": "1940", "value": 133 },
{ "type": "Autocracies", "year": "1950", "value": 130 },
{ "type": "Autocracies", "year": "1960", "value": 126 },
{ "type": "Autocracies", "year": "1970", "value": 117 },
{ "type": "Autocracies", "year": "1980", "value": 114 },
{ "type": "Autocracies", "year": "1990", "value": 111 },
{ "type": "Autocracies", "year": "2000", "value": 89 },
{ "type": "Autocracies", "year": "2010", "value": 80 },
{ "type": "Autocracies", "year": "2018", "value": 80 },
{ "type": "Democracies", "year": "1930", "value": 22 },
{ "type": "Democracies", "year": "1940", "value": 13 },
{ "type": "Democracies", "year": "1950", "value": 25 },
{ "type": "Democracies", "year": "1960", "value": 29 },
{ "type": "Democracies", "year": "1970", "value": 38 },
{ "type": "Democracies", "year": "1980", "value": 41 },
{ "type": "Democracies", "year": "1990", "value": 57 },
{ "type": "Democracies", "year": "2000", "value": 87 },
{ "type": "Democracies", "year": "2010", "value": 98 },
{ "type": "Democracies", "year": "2018", "value": 99 }
]
}

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartBarCrossrangeConfig: ConfigType = {
key: 'VChartBarCrossrange',
chartKey: 'VVChartBarCrossrange',
conKey: 'VCVChartBarCrossrange',
title: '并列柱状图-VChart',
category: ChatCategoryEnum.BAR,
categoryName: ChatCategoryEnumName.BAR,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_bar_y.png'
}

View File

@@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@@ -3,11 +3,18 @@ import { VChartBarStackConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { IBarOption } from '../../index.d'
import { ChatCategoryEnum, IBarOption } from '../../index.d'
import { merge, cloneDeep } from 'lodash'
import { vChartGlobalThemeJson } from '@/settings/vchartThemes'
export const includes = ['legends', 'tooltip']
const barConfig = merge(cloneDeep(vChartGlobalThemeJson.bar), {
style: {
width: 15
}
})
export const includes = ['legends', 'tooltip', 'label']
export const option: IBarOption & { dataset?: any } = {
// 图表配置
type: 'bar',
@@ -16,11 +23,20 @@ export const option: IBarOption & { dataset?: any } = {
yField: ['value'],
seriesField: 'year',
stack: true,
// 开启百分比
percent: false,
// 业务配置后续会被转换为图表spec)
category: VChartBarStackConfig.category,
category: VChartBarStackConfig.category as ChatCategoryEnum.BAR,
xAxis: {
name: 'x轴',
...axisThemeJson,
...(merge(cloneDeep(axisThemeJson), {
unit: {
style: {
dx: 10,
dy: 0
}
}
}) as any),
grid: {
...axisThemeJson.grid,
visible: false
@@ -28,14 +44,23 @@ export const option: IBarOption & { dataset?: any } = {
},
yAxis: {
name: 'y轴',
...axisThemeJson,
...(merge(cloneDeep(axisThemeJson), {
unit: {
style: {
dx: 0,
dy: -10
}
}
}) as any),
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style,
lineDash: [3, 3]
...axisThemeJson.grid.style
}
}
},
bar: {
...barConfig
}
}

View File

@@ -3,12 +3,26 @@
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
<!-- 标签 -->
<Label :optionData="optionData"></Label>
<!-- 柱体 -->
<Bar :optionData="optionData"></Bar>
<!-- 开启百分比 -->
<CollapseItem name="百分比堆叠">
<SettingItemBox name="配置" alone>
<n-space>
<span>开启百分比堆叠</span>
<n-switch v-model:value="optionData.percent" size="small"></n-switch>
</n-space>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
import { VChartGlobalSetting, Axis, Label, Bar } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
defineProps({
optionData: {

View File

@@ -5,7 +5,7 @@ export const VChartBarStackConfig: ConfigType = {
key: 'VChartBarStack',
chartKey: 'VVChartBarStack',
conKey: 'VCVChartBarStack',
title: 'VChart柱状图',
title: '堆叠柱状图-VChart',
category: ChatCategoryEnum.BAR,
categoryName: ChatCategoryEnumName.BAR,
package: PackagesCategoryEnum.VCHART,

View File

@@ -1,4 +1,5 @@
import { VChartBarCommonConfig } from './VChartBarCommon/index'
import { VChartBarCrossrangeConfig } from './VChartBarCrossrange/index'
import { VChartBarStackConfig } from './VChartBarStack/index'
export default [VChartBarCommonConfig, VChartBarStackConfig]
export default [VChartBarCommonConfig, VChartBarCrossrangeConfig, VChartBarStackConfig]

View File

@@ -0,0 +1,25 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartFunnelConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import { IFunnelOption } from '../../index.d'
export const includes = ['legends', 'tooltip']
export const option: IFunnelOption & { dataset?: any } = {
// 图表配置
type: 'funnel',
dataset: data,
categoryField: 'name',
valueField: 'value',
// 业务配置后续会被转换为图表spec)
category: VChartFunnelConfig.category,
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartFunnelConfig.key
public chartConfig = cloneDeep(VChartFunnelConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@@ -0,0 +1,17 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -0,0 +1,24 @@
{
"values": [
{
"value": 100,
"name": "Step1"
},
{
"value": 80,
"name": "Step2"
},
{
"value": 60,
"name": "Step3"
},
{
"value": 40,
"name": "Step4"
},
{
"value": 20,
"name": "Step5"
}
]
}

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartFunnelConfig: ConfigType = {
key: 'VChartFunnel',
chartKey: 'VVChartFunnel',
conKey: 'VCVChartFunnel',
title: '漏斗图-VChart',
category: ChatCategoryEnum.FUNNEL,
categoryName: ChatCategoryEnumName.FUNNEL,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_funnel.png'
}

View File

@@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@@ -0,0 +1,3 @@
import { VChartFunnelConfig } from './VChartFunnel/index'
export default [VChartFunnelConfig]

View File

@@ -0,0 +1,49 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartLineConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { ChatCategoryEnum, ILineOption } from '../../index.d'
export const includes = ['legends', 'tooltip', 'label', 'line', 'point']
export const option: ILineOption & { dataset?: any } = {
// 图表配置
type: 'line',
dataset: data,
xField: 'type',
yField: 'value',
seriesField: 'country',
stack: true,
// 开启百分比
percent: false,
// 业务配置后续会被转换为图表spec)
category: VChartLineConfig.category as ChatCategoryEnum.LINE,
xAxis: {
name: 'x轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
visible: false
}
} as any,
yAxis: {
name: 'y轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style,
lineDash: [3, 3]
}
}
} as any
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartLineConfig.key
public chartConfig = cloneDeep(VChartLineConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@@ -0,0 +1,33 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
<!-- 开启百分比 -->
<CollapseItem name="百分比堆叠">
<SettingItemBox name="配置" alone>
<n-space>
<span>开启百分比堆叠</span>
<n-switch v-model:value="optionData.percent" size="small"></n-switch>
</n-space>
</SettingItemBox>
</CollapseItem>
<Line :optionData="optionData"></Line>
<Label :optionData="optionData" :positionOptions="labelConfig.linePosition"></Label>
<Point :optionData="optionData"></Point>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis, Label, Line, Point } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { labelConfig } from '@/packages/chartConfiguration/vcharts/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -0,0 +1,16 @@
{
"values": [
{ "type": "Nail polish", "country": "China", "value": 3054 },
{ "type": "Nail polish", "country": "USA", "value": 12814 },
{ "type": "Eyebrow pencil", "country": "China", "value": 5067 },
{ "type": "Eyebrow pencil", "country": "USA", "value": 13012 },
{ "type": "Rouge", "country": "China", "value": 7004 },
{ "type": "Rouge", "country": "USA", "value": 11624 },
{ "type": "Lipstick", "country": "China", "value": 9054 },
{ "type": "Lipstick", "country": "USA", "value": 8814 },
{ "type": "Eyeshadows", "country": "China", "value": 12043 },
{ "type": "Eyeshadows", "country": "USA", "value": 12998 },
{ "type": "Eyeliner", "country": "China", "value": 15067 },
{ "type": "Eyeliner", "country": "USA", "value": 12321 }
]
}

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartLineConfig: ConfigType = {
key: 'VChartLine',
chartKey: 'VVChartLine',
conKey: 'VCVChartLine',
title: '折线图-VChart',
category: ChatCategoryEnum.LINE,
categoryName: ChatCategoryEnumName.LINE,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_line.png'
}

View File

@@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@@ -0,0 +1,3 @@
import { VChartLineConfig } from './VChartLine/index'
export default [VChartLineConfig]

View File

@@ -0,0 +1,77 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartPieConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import type { ChatCategoryEnum, IPieOption } from '../../index.d'
const OUTER_RADIUS = 0.75
export const includes = ['legends', 'tooltip']
export const option: IPieOption & { dataset?: any } = {
// 图表配置
type: 'pie',
dataset: data,
categoryField: 'year',
valueField: 'value',
seriesField: 'year',
// 中心
centerX: '50%',
centerY: '50%',
innerRadius: 0.68,
outerRadius: OUTER_RADIUS,
label: {
visible: true,
position: 'outside',
style: {
fontSize: 12,
fill: '#B9B8CE',
fontFamily: 'SimSun',
fontWeight: 'normal',
angle: 0
},
line: {
visible: true
}
},
pie: {
style: {
// 圆角
cornerRadius: 50,
// 描边宽度
outerBorder: {
// 透明度
strokeOpacity: 1,
// 外描边距离
distance: 0,
// 宽度
lineWidth: 0,
// 颜色
stroke: '#ffffff'
},
// 纹理
texture: ''
},
state: {
hover: {
outerRadius: 0.85
},
selected: {
outerRadius: 0.85
}
}
},
// 业务配置后续会被转换为图表spec)
category: VChartPieConfig.category as ChatCategoryEnum.PIE,
extensionMark: [],
// 动画
animationNormal: {}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartPieConfig.key
public chartConfig = cloneDeep(VChartPieConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@@ -0,0 +1,164 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<!-- 饼图配制 -->
<CollapseItem name="饼图" expanded>
<SettingItemBox name="动画">
<SettingItem>
<n-space>
<n-switch v-model:value="animationRef" size="small" @update:value="animationHandle"></n-switch>
<n-text>开启动画</n-text>
</n-space>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="图形">
<setting-item name="内圈范围">
<n-input-number v-model:value="optionData.innerRadius" :step="0.1" :min="0" size="small"></n-input-number>
</setting-item>
<setting-item name="外圈范围">
<n-input-number v-model:value="optionData.outerRadius" :step="0.1" :min="0" size="small"></n-input-number>
</setting-item>
<setting-item name="中心轴X">
<n-input v-model:value="optionData.centerX" :step="1" :min="0" size="small"></n-input>
</setting-item>
<setting-item name="中心轴Y">
<n-input v-model:value="optionData.centerY" :step="1" :min="0" size="small"></n-input>
</setting-item>
</SettingItemBox>
<SettingItemBox name="标签" v-if="optionData.label">
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.label.visible" size="small"></n-switch>
<n-text>展示标签</n-text>
</n-space>
</SettingItem>
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.label.line.visible" size="small"></n-switch>
<n-text>引导线</n-text>
</n-space>
</SettingItem>
<SettingItem name="位置">
<n-select v-model:value="optionData.label.position" :options="labelConfig.position" size="small" />
</SettingItem>
<FontStyle :style="toRefs(optionData.label.style)"></FontStyle>
</SettingItemBox>
<SettingItemBox name="分段样式">
<setting-item name="纹理类型">
<n-select v-model:value="optionData.pie.style.texture" :options="styleConfig.texture" size="small"></n-select>
</setting-item>
<setting-item name="圆角大小">
<n-input-number v-model:value="optionData.pie.style.cornerRadius" size="small" :min="0"></n-input-number>
</setting-item>
<setting-item name="描边宽度">
<n-input-number
v-model:value="optionData.pie.style.outerBorder.lineWidth"
size="small"
:min="0"
></n-input-number>
</setting-item>
<setting-item name="颜色">
<n-color-picker v-model:value="optionData.pie.style.outerBorder.stroke" size="small" />
</setting-item>
<setting-item name="外描边距离">
<n-input-number
v-model:value="optionData.pie.style.outerBorder.distance"
size="small"
:min="0"
></n-input-number>
</setting-item>
<setting-item name="描边透明度">
<n-input-number
v-model:value="optionData.pie.style.outerBorder.strokeOpacity"
:step="0.1"
size="small"
:min="0"
></n-input-number>
</setting-item>
</SettingItemBox>
<SettingItemBox name="内环形">
<setting-item name="可见性">
<n-space>
<n-switch v-model:value="extensionMarkRef" size="small" @update:value="markerHandle"></n-switch>
</n-space>
</setting-item>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType, ref, toRefs } from 'vue'
import { VChartGlobalSetting } from '@/components/Pages/VChartItemSetting'
import FontStyle from '@/components/Pages/VChartItemSetting/common/FontStyle.vue'
import type { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { labelConfig, styleConfig } from '@/packages/chartConfiguration/vcharts/index'
const props = defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
const animationRef = ref(props.optionData.animationNormal && Object.keys(props.optionData.animationNormal)?.length > 0)
const extensionMarkRef = ref(!!props.optionData?.extensionMark)
const markerHandle = (value: boolean) => {
if (value) {
props.optionData.extensionMark = []
} else {
delete props.optionData.extensionMark
}
}
const animationHandle = (value: boolean) => {
if (value) {
props.optionData.animationNormal = {
pie: [
{
loop: true,
startTime: 800,
oneByOne: true,
timeSlices: [
{
effects: {
channel: {
outerRadius: {
to: props.optionData.outerRadius * 100 + 10
}
},
easing: 'linear'
},
duration: 500
},
{
effects: {
channel: {
outerRadius: {
to: props.optionData.outerRadius * 100 + 10
}
},
easing: 'linear'
},
duration: 500
},
{
effects: {
channel: {
outerRadius: {
to: props.optionData.outerRadius * 100
}
}
},
duration: 500
}
]
}
]
}
} else {
props.optionData.animationNormal = {}
}
}
</script>

View File

@@ -0,0 +1,14 @@
{
"values": [
{ "type": "Autocracies", "year": "1930", "value": 129 },
{ "type": "Autocracies", "year": "1940", "value": 133 },
{ "type": "Autocracies", "year": "1950", "value": 130 },
{ "type": "Autocracies", "year": "1960", "value": 126 },
{ "type": "Autocracies", "year": "1970", "value": 117 },
{ "type": "Autocracies", "year": "1980", "value": 114 },
{ "type": "Autocracies", "year": "1990", "value": 111 },
{ "type": "Autocracies", "year": "2000", "value": 89 },
{ "type": "Autocracies", "year": "2010", "value": 80 },
{ "type": "Autocracies", "year": "2018", "value": 80 }
]
}

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartPieConfig: ConfigType = {
key: 'VChartPie',
chartKey: 'VVChartPie',
conKey: 'VCVChartPie',
title: '饼图多欢-VChart',
category: ChatCategoryEnum.PIE,
categoryName: ChatCategoryEnumName.PIE,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_pie.png'
}

View File

@@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@@ -0,0 +1,3 @@
import { VChartPieConfig } from './VChartPie/index'
export default [VChartPieConfig]

View File

@@ -0,0 +1,47 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartScatterConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { IAreaOption } from '../../index.d'
export const includes = ['legends', 'tooltip']
export const option: IAreaOption & { dataset?: any } = {
// 图表配置
type: 'scatter',
dataset: data,
stack: true,
xField: 'x',
yField: 'horsepower',
seriesField: 'cylinders',
// 业务配置后续会被转换为图表spec)
category: VChartScatterConfig.category,
xAxis: {
name: 'x轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
visible: false
}
},
yAxis: {
name: 'y轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style,
lineDash: [3, 3]
}
}
}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartScatterConfig.key
public chartConfig = cloneDeep(VChartScatterConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@@ -0,0 +1,19 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartScatterConfig: ConfigType = {
key: 'VChartScatter',
chartKey: 'VVChartScatter',
conKey: 'VCVChartScatter',
title: '散点图-VChart',
category: ChatCategoryEnum.SCATTER,
categoryName: ChatCategoryEnumName.SCATTER,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_scatter.png'
}

View File

@@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@@ -0,0 +1,3 @@
import { VChartScatterConfig } from './VChartScatter/index'
export default [VChartScatterConfig]

View File

@@ -0,0 +1,26 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartWordCloudConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import { IWordCloudOption } from '../../index.d'
export const includes = ['legends', 'tooltip']
export const option: IWordCloudOption & { dataset?: any } = {
// 图表配置
type: 'wordCloud',
dataset: data,
nameField: 'name',
valueField: 'value',
seriesField: 'name',
// 业务配置后续会被转换为图表spec)
category: VChartWordCloudConfig.category,
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartWordCloudConfig.key
public chartConfig = cloneDeep(VChartWordCloudConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@@ -0,0 +1,17 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@@ -0,0 +1,88 @@
{
"values": [
{
"name": "数据可视化",
"value": 8000
},
{
"name": "GO VIEW",
"value": 6181
},
{
"name": "低代码",
"value": 4386
},
{
"name": "Vue3",
"value": 4055
},
{
"name": "TypeScript4",
"value": 2467
},
{
"name": "Vite2",
"value": 2244
},
{
"name": "NaiveUI",
"value": 1898
},
{
"name": "ECharts5",
"value": 1484
},
{
"name": "VChart",
"value": 600
},
{
"name": "Axios",
"value": 1112
},
{
"name": "Pinia2",
"value": 965
},
{
"name": "PlopJS",
"value": 847
},
{
"name": "sfc",
"value": 582
},
{
"name": "SCSS",
"value": 555
},
{
"name": "pnpm",
"value": 550
},
{
"name": "eslint",
"value": 462
},
{
"name": "json",
"value": 366
},
{
"name": "图表",
"value": 360
},
{
"name": "地图",
"value": 282
},
{
"name": "时钟",
"value": 273
},
{
"name": "标题",
"value": 265
}
]
}

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartWordCloudConfig: ConfigType = {
key: 'VChartWordCloud',
chartKey: 'VVChartWordCloud',
conKey: 'VCVChartWordCloud',
title: '词云图-VChart',
category: ChatCategoryEnum.WORDCLOUD,
categoryName: ChatCategoryEnumName.WORDCLOUD,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_word_cloud.png'
}

View File

@@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@@ -0,0 +1,3 @@
import { VChartWordCloudConfig } from './VChartWordCloud/index'
export default [VChartWordCloudConfig]

View File

@@ -1,13 +1,25 @@
import { IBarChartSpec } from '@visactor/vchart'
import { IBarChartSpec, ILineChartSpec, IAreaChartSpec, IPieChartSpec, IFunnelChartSpec, IWordCloudChartSpec } from '@visactor/vchart'
import { ICartesianAxisCommonSpec } from '@visactor/vchart/esm/component/axis'
export enum ChatCategoryEnum {
BAR = 'Bars',
PIE = 'Pies',
LINE = 'Lines',
AREA = 'Areas',
FUNNEL = 'Funnels',
WORDCLOUD = 'WordClouds',
SCATTER = 'Scatters',
}
export enum ChatCategoryEnumName {
BAR = '柱状图',
PIE = '饼图',
LINE = '折线图',
AREA = '面积图',
FUNNEL = '漏斗图',
WORDCLOUD = '词云图',
SCATTER = '散点图',
}
export interface IBarOption extends Omit<IBarChartSpec, 'axes'> {
@@ -21,6 +33,54 @@ export interface IBarOption extends Omit<IBarChartSpec, 'axes'> {
} & ICartesianAxisCommonSpec
}
export interface ILineOption extends Omit<ILineChartSpec, 'axes'> {
category: ChatCategoryEnum.LINE
type: 'line'
xAxis?: {
name: string
} & ICartesianAxisCommonSpec
yAxis?: {
name: string
} & ICartesianAxisCommonSpec
}
export interface IAreaOption extends Omit<IAreaChartSpec, 'axes'> {
category: ChatCategoryEnum.AREA
type: 'area'
xAxis?: {
name: string
} & ICartesianAxisCommonSpec
yAxis?: {
name: string
} & ICartesianAxisCommonSpec
}
export interface IPieOption extends IPieChartSpec {
category?: ChatCategoryEnum.PIE
type: 'pie'
}
export interface IFunnelOption extends IFunnelChartSpec {
category: ChatCategoryEnum.FUNNEL
type: 'funnel'
}
export interface IWordCloudOption extends IWordCloudChartSpec {
category: ChatCategoryEnum.WORDCLOUD
type: 'wordCloud'
}
export interface IScatterOption extends Omit<IAreaChartSpec, 'axes'> {
category: ChatCategoryEnum.SCATTER
type: 'scatter'
xAxis?: {
name: string
} & ICartesianAxisCommonSpec
yAxis?: {
name: string
} & ICartesianAxisCommonSpec
}
// todo
// export type IOption = IBarOption | ILineOption ....
export type IOption = IBarOption
export type IOption = IBarOption | IPieOption | ILineOption | IAreaOption | IFunnelOption | IScatterOption

View File

@@ -1,3 +1,9 @@
import Bars from './Bars'
import Pies from './Pies'
import Lines from './Lines'
import Areas from './Areas'
import Funnels from './Funnels'
import WordClouds from './WordClouds'
import Scatters from './Scatters'
export const VChartList = [...Bars]
export const VChartList = [...Bars, ...Pies, ...Lines, ...Areas, ...Funnels, ...WordClouds, ...Scatters]

View File

@@ -27,9 +27,9 @@ export type ConfigType = {
// 标题
title: string
// 分类
category: ChatCategoryEnum
category: string
// 分类名称
categoryName: ChatCategoryEnumName
categoryName: string
// 所属包
package: PackagesCategoryEnum
// 归类

View File

@@ -103,7 +103,8 @@ import {
Filter as FilterIcon,
FilterEdit as FilterEditIcon,
Laptop as LaptopIcon,
ChartPie as ChartPieIcon
ChartPie as ChartPieIcon,
Edit as EditIcon
} from '@vicons/carbon'
const ionicons5 = {
@@ -303,7 +304,9 @@ const carbon = {
// 图层
LaptopIcon,
// 柱状图
ChartPieIcon
ChartPieIcon,
// 编辑
EditIcon
}
// https://www.xicons.org/#/ 还有很多

View File

@@ -1,5 +1,19 @@
{
"visible": true,
"unit": {
"visible": true,
"text": "",
"style": {
"text": "",
"fontSize": 12,
"fill": "#B9B8CE",
"fontFamily": "SimSun",
"fontWeight": "normal",
"angle": 0,
"dx": 0,
"dy": 0
}
},
"label": {
"visible": true,
"style": {
@@ -7,17 +21,25 @@
"fill": "#B9B8CE",
"fontFamily": "SimSun",
"fontWeight": "normal",
"angle": 0
"angle": 0,
"dx": 0,
"dy": 0
}
},
"title": {
"visible": true,
"position": "middle",
"angle": 0,
"padding": [],
"style": {
"text": "",
"fontSize": 12,
"fill": "#B9B8CE",
"fontFamily": "SimSun",
"fontWeight": "normal"
"fontWeight": "normal",
"angle": 0,
"dx": 0,
"dy": 0
}
},
"domainLine": {

View File

@@ -74,5 +74,49 @@
},
"spaceRow": 10
}
},
"label": {
"visible": false,
"position": "outside",
"offset": 5,
"type": "text",
"style": {
"fontSize": 12,
"fill": "#B9B8CE",
"fontFamily": "SimSun",
"fontWeight": "normal",
"angle": 0,
"dx": 0,
"dy": 0
}
},
"bar": {
"style": {
"width": 10,
"cornerRadius": 0,
"fillOpacity": 1,
"opacity": 1,
"texture": ""
}
},
"line": {
"style": {
"lineWidth": 1,
"lineCap": "butt",
"curveType": "linear"
}
},
"point": {
"visible": true,
"style": {
"symbolType": "circle",
"size": 10,
"fillOpacity": 1,
"lineWidth": 2,
"stroke": "#ffffff",
"strokeOpacity": 1,
"dx": 0,
"dy": 0
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More