Skip to content

以新增一个柱状图组件为例

WARNING

务必进行的测试:

  • 右侧属性响应式测试

  • 数据->动态数据更新测试

  • 使用 mock 数据,更新时间设置为 5S,点击预览查看 5S 后图表是否进行了更新

  • 打包编译测试,编译会报 TS 错误,请及时修改.
    注意: 开发环境并未做 tree-shaking 处理,以下按需导入等同于 import VChart from '@visactor/vchart'全量导入。但当打包编译时将会开启 tree-shaking,如缺少必要组件导入,项目运行将会报错!
    注册逻辑参考: https://www.visactor.io/vchart/guide/tutorial_docs/Load_on_Demand

  1. 首先在 packages 的文件夹里新增基础配置文件
路径功能
packages/index所有图表导出,图表动态加载方法等
packages/index.d类型定义
packages/public公共数据类,方法等
packages/chartConfiguration图表基础配置
packages/components/Charts图表模块
packages/components/VChartsVChart 图表模块
packages/components/Informations信息模块
packages/components/Tables表格模块
packages/components/Decorates装饰模块

选择在 packages/components/VChart/Bars 下创建 VChartBarCommon 文件夹

  1. 在文件夹内创建对应的文件 index.tsindex.vueconfig.tsconfig.vue
文件功能
index.ts图表声明文件
index.vue展示渲染文件
config.ts数据相关文件
config.vue设置项内容
data.json静态数据(可无)

index.ts 内容如下:

ts
// 公共类型声明
import {
  ConfigType,
  PackagesCategoryEnum,
  ChartFrameEnum,
} from "@/packages/index.d";
// 当前[信息模块]分类声明
import { ChatCategoryEnum, ChatCategoryEnumName } from "../../index.d";

export const VChartBarCommonConfig: ConfigType = {
  // 唯一key,注意!!!文件夹名称需要修改成与当前组件一致!!!
  key: "VChartBarCommon",
  // 图表组件渲染 Components 格式: V + key
  chartKey: "VVChartBarCommon",
  // 配置组件渲染 Components 格式: VC + key
  conKey: "VCVChartBarCommon",
  // 名称
  title: "VChart并列柱状图",
  // 子分类目录
  category: ChatCategoryEnum.BAR,
  // 子分类目录
  categoryName: ChatCategoryEnumName.BAR,
  // 包分类
  package: PackagesCategoryEnum.VCHART,
  chartFrame: ChartFrameEnum.VCHART,
  // 图片 (注意!图片存放的路径必须在 src/assets/images/chart/包分类名称/*)
  // 文件夹名称需要和包分类名称一致: PackagesCategoryEnum.VCHART
  image: "bar_x.png",
};

注意!

v1.1.9 / v2.1.6 版本以下,图片需要直接引入。但是开发环境生成的组件,在生产环境的层级展示中图片会有问题。

使用方式如下:

ts
// 展示图片
import image from "@/assets/images/chart/vchart/bar_x.png";

export const VChartBarCommonConfig: ConfigType = {
  // .....和上面一致
  // 图片
  image: image,
};

data.json 内容如下:

json
{
  "values": [
    { "type": "Autocracies", "year": "1930", "value": 129 },
    { "type": "Autocracies", "year": "1940", "value": 133 }
    // ...
  ]
}

config.ts 内容如下,在创建新图表时会执行 new Config()

ts
// 公共类型和方法
import { vChartOptionPrefixHandle, PublicConfigClass } from "@/packages/public";
// 公共类型
import { CreateComponentType } from "@/packages/index.d";
// 获取上面的 index 配置内容
import { VChartBarCommonConfig } from "./index";
// 深拷贝
import cloneDeep from "lodash/cloneDeep";
// 默认数据
import data from "./data.json";
// 图表公共主题配置
import axisThemeJson from "@/settings/vchartThemes/axis.theme.json";
// 图表配置的类型定义
import { IBarOption } from "../../index.d";

// 从VCharts 的默认配置项里取出需要的部分,详见 `src/settings/chartThemes/index`
export const includes = ["legends", "tooltip"];

export const option = {
  // 图表配置
  type: "bar",
  dataset: data,
  stack: true,
  xField: ["year", "type"],
  yField: ["value"],
  seriesField: "type",
  // 业务配置(后续会被转换为图表spec)
  category: VChartBarCommonConfig.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 = VChartBarCommonConfig.key;
  public chartConfig = cloneDeep(VChartBarCommonConfig);
  // 进行样式合并
  public option = vChartOptionPrefixHandle(option, includes);
}

index.vue 内容如下:

vue
<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>

config.vue 内容如下:

vue
<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>
  1. 然后把图表组件在 src\packages\components\VChart\Bars\index.ts 中进行导出
ts
import { VChartBarCommonConfig } from "./VChartBarCommon/index";
import { VChartBarStackConfig } from "./VChartBarStack/index";

// 这里的顺序决定着最终的展示顺序
export default [VChartBarCommonConfig, VChartBarStackConfig];

注意在 src\packages\components\VChart\index.ts 也有一个导出,这里是导出 VChart 模块的所有组件

ts
import Bars from "./Bars";

export const ChartList = [...Bars];
  1. src\components\GoVChart\transformProps\bars.ts 将业务配置转换为可供 VChart 绘制的标准 spec
ts
import { cloneDeep } from "lodash";

export default (chartProps: any) => {
  // 将业务配置拷贝出来处理, 避免影响原配置
  const spec = cloneDeep(chartProps);
  // 图表类型仅供索引到对应图表spec转换逻辑使用,。在VChart配置中, type即可识别图表类型
  delete spec.category;

  // tooltip spec 转换
  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;

  // 轴spec 转换
  const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis;
  const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis;
  spec.axes = [
    {
      orient: "bottom",
      ...restXAxisProps,
      // paddingInner: 0.5
    },
    {
      orient: "left",
      ...restYAxisProps,
    },
  ];
  // 去掉无用业务配置
  delete spec.xAxis;
  delete spec.yAxis;
  // console.log('spec-bar-transform', spec)
  // 返回VChart可识别的标准spec
  return spec;
};
  1. src\components\GoVChart\transformProps\index.ts进行导出
ts
import {
  ChatCategoryEnum,
  IOption,
} from "@/packages/components/VChart/index.d";
import bars from "./bars";
export const transformHandler: {
  [key: string]: (args: IOption) => any;
} = {
  // 业务配置中的category用于索引到对应的转换逻辑
  [ChatCategoryEnum.BAR]: bars,
  // todo: more charts handler
};
  1. src/components/GoVChart/register.ts中执行图表注册逻辑. 开发环境并未做 tree-shaking 处理,以下按需导入等同于 import VChart from '@visactor/vchart'全量导入。但需注意,当打包编译时将会开启 tree-shaking,如缺少必要组件导入,项目运行将会报错!
ts
import { VChart } from "@visactor/vchart/esm/core";
import { registerBarChart } 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";
// 不同图表类型需要注册什么样的组件可以参考: https://www.visactor.io/vchart/guide/tutorial_docs/Load_on_Demand
export const registerChartsAndComponents = () => {
  VChart.useRegisters([
    // 图表
    registerBarChart,

    // 组件
    registerTooltip,
    registerDomTooltipHandler,
    registerCartesianCrossHair,
    registerDiscreteLegend,
    registerLabel,

    // 动画
    registerAnimate,
  ]);
};

此时页面图表中将出现【柱状图】组件,试试把它拖拽到页面进行测试吧~

本文档内容版权属于 GoView 作者,保留所有权利 | 备案号 京ICP备2021034585号-1