|
@@ -0,0 +1,365 @@
|
|
|
+<template>
|
|
|
+ <div class="chart-config">
|
|
|
+ <div class="config-tab">
|
|
|
+ <Tabs v-model:activeKey="activeTab" size="small" centered>
|
|
|
+ <TabPane key="1">
|
|
|
+ <template #tab>
|
|
|
+ <DatabaseOutlined />
|
|
|
+ <span>数据设置</span>
|
|
|
+ </template>
|
|
|
+ </TabPane>
|
|
|
+ <TabPane key="2">
|
|
|
+ <template #tab>
|
|
|
+ <SkinOutlined />
|
|
|
+ <span>样式设置</span>
|
|
|
+ </template>
|
|
|
+ </TabPane>
|
|
|
+ </Tabs>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <DataConfig
|
|
|
+ v-if="activeTab === '1'"
|
|
|
+ :dataSource="dataSource"
|
|
|
+ @change="handleDataSourceChange"
|
|
|
+ />
|
|
|
+ <CusForm
|
|
|
+ v-if="activeTab === '2'"
|
|
|
+ :columns="formItems"
|
|
|
+ :formModel="props"
|
|
|
+ @change="handleFormChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, defineProps, defineEmits } from "vue";
|
|
|
+import { Tabs, TabPane } from "ant-design-vue";
|
|
|
+import { DatabaseOutlined, SkinOutlined } from "@ant-design/icons-vue";
|
|
|
+import DataConfig from "../../../DataConfig.vue";
|
|
|
+import { CusForm, IFormItem } from "../../../../cusForm";
|
|
|
+import { componentProps } from "./props";
|
|
|
+import { chartFormItemsMap } from "../../../config/chartFormItemsMap";
|
|
|
+import { set, get, cloneDeep } from "lodash-es";
|
|
|
+
|
|
|
+const props = defineProps(componentProps);
|
|
|
+const activeTab = ref("1");
|
|
|
+const emit = defineEmits(["change"]);
|
|
|
+
|
|
|
+const formItems: IFormItem[] = [
|
|
|
+ chartFormItemsMap.title,
|
|
|
+ {
|
|
|
+ label: "标签",
|
|
|
+ prop: "label",
|
|
|
+ type: "group",
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ label: " ",
|
|
|
+ prop: "radiusAxis.axisLabel.show",
|
|
|
+ type: "checkboxGroup",
|
|
|
+ fieldProps: {
|
|
|
+ options: [{ label: "标签可见", value: true }],
|
|
|
+ },
|
|
|
+ defaultValue: [true],
|
|
|
+ format: (formatModel, value) => {
|
|
|
+ formatModel.value["radiusAxis.axisLabel.show"] = value?.length ? true : false;
|
|
|
+ },
|
|
|
+ valueToForm: (value) => {
|
|
|
+ return value ? [true] : [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "",
|
|
|
+ prop: "",
|
|
|
+ type: "dependency",
|
|
|
+ name: ["radiusAxis.axisLabel.show"],
|
|
|
+ children: (model) => {
|
|
|
+ return model["radiusAxis.axisLabel.show"].length
|
|
|
+ ? [
|
|
|
+ {
|
|
|
+ label: "文本",
|
|
|
+ prop: "radiusAxis.axisLabel.formatter",
|
|
|
+ type: "checkboxGroup",
|
|
|
+ fieldProps: {
|
|
|
+ options: [
|
|
|
+ { label: "分类名", value: "value" },
|
|
|
+ { label: "数值", value: "index" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ defaultValue: ["b"],
|
|
|
+ format: (formatModel, list) => {
|
|
|
+ formatModel.value["radiusAxis.axisLabel.formatter"] = list.map((item: any) => `{${item}}`).join(" ");
|
|
|
+ },
|
|
|
+ valueToForm: (_, model) => {
|
|
|
+ return get(model, 'radiusAxis.axisLabel.formatter')?.replace(/\{|\}/g, "")?.split(" ");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "样式",
|
|
|
+ prop: "radiusAxis.axisLabel",
|
|
|
+ type: "fontStyle",
|
|
|
+ defaultValue: {
|
|
|
+ color: "#000000ff",
|
|
|
+ size: 12,
|
|
|
+ bold: false,
|
|
|
+ italic: false,
|
|
|
+ },
|
|
|
+ format: (formatModel, value) => {
|
|
|
+ formatModel.value["radiusAxis.axisLabel.color"] = value.color;
|
|
|
+ formatModel.value["radiusAxis.axisLabel.fontSize"] = value.fontSize;
|
|
|
+ formatModel.value["radiusAxis.axisLabel.fontWeight"] = value.fontWeight;
|
|
|
+ formatModel.value["radiusAxis.axisLabel.fontStyle"] = value.fontStyle;
|
|
|
+ },
|
|
|
+ valueToForm: (_, model) => {
|
|
|
+ return {
|
|
|
+ color: get(model, 'radiusAxis.axisLabel.color', '#000000ff'),
|
|
|
+ size: get(model, 'radiusAxis.axisLabel.fontSize', 12),
|
|
|
+ bold: get(model, 'radiusAxis.axisLabel.fontWeight') === 'bold',
|
|
|
+ italic: get(model, 'radiusAxis.axisLabel.fontStyle') === 'italic',
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ : []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "图形",
|
|
|
+ prop: "",
|
|
|
+ type: "group",
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ label: "颜色",
|
|
|
+ prop: "seriesExtend.itemStyle.color",
|
|
|
+ type: "colorSelect",
|
|
|
+ defaultValue: "#fff",
|
|
|
+ valueToForm: (value) => {
|
|
|
+ if(typeof value === "object") {
|
|
|
+ return `linear-gradient(90deg, ${value?.colorStops?.[0]?.color},${value?.colorStops?.[1]?.color})`
|
|
|
+ } else {
|
|
|
+ return value
|
|
|
+ }
|
|
|
+ },
|
|
|
+ format(formatModel, value) {
|
|
|
+ if(value?.includes("linear-gradient")) {
|
|
|
+ console.log(value)
|
|
|
+ formatModel.value["seriesExtend.itemStyle.color"] = {
|
|
|
+ type: "linear",
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ x2: 1,
|
|
|
+ y2: 1,
|
|
|
+ colorStops: [
|
|
|
+ {
|
|
|
+ offset: 0,
|
|
|
+ color: value.replace('linear-gradient(90deg,', '').split(',')[0]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ offset: 1,
|
|
|
+ color: value.split(',')[2].replace(')', '')
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ formatModel.value["seriesExtend.itemStyle.color"] = value;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "内径占比",
|
|
|
+ prop: "polar.radius",
|
|
|
+ type: "slider",
|
|
|
+ format: (formatModel, value) => {
|
|
|
+ const inner = value * 0.75;
|
|
|
+ formatModel.value["polar.radius"] = [inner + "%", "80%"];
|
|
|
+ return value * 100;
|
|
|
+ },
|
|
|
+ valueToForm: (value) => {
|
|
|
+ const inner = (value || ["0%", "80%"])[0].replace("%", "");
|
|
|
+ return inner / 0.8;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "提示",
|
|
|
+ prop: "tooltip",
|
|
|
+ type: "group",
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ label: " ",
|
|
|
+ prop: "tooltip.show",
|
|
|
+ type: "checkboxGroup",
|
|
|
+ fieldProps: {
|
|
|
+ options: [{ label: "提示可见", value: true }],
|
|
|
+ },
|
|
|
+ defaultValue: [true],
|
|
|
+ format: (formatModel, value) => {
|
|
|
+ formatModel.value["tooltip.show"] = value?.length ? true : false;
|
|
|
+ },
|
|
|
+ valueToForm: (value) => {
|
|
|
+ return value ? [true] : [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "",
|
|
|
+ prop: "",
|
|
|
+ type: "dependency",
|
|
|
+ name: ["tooltip.show"],
|
|
|
+ children: (model) => {
|
|
|
+ return model["tooltip.show"].length
|
|
|
+ ? [
|
|
|
+ {
|
|
|
+ label: "文本",
|
|
|
+ prop: "tooltip.formatter",
|
|
|
+ type: "checkboxGroup",
|
|
|
+ fieldProps: {
|
|
|
+ options: [
|
|
|
+ { label: "分类名", value: "b" },
|
|
|
+ { label: "数值", value: "c" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ defaultValue: ["b"],
|
|
|
+ format: (formatModel, list) => {
|
|
|
+ formatModel.value["tooltip.formatter"] = list.map((item: any) => `{${item}}`).join(" ");
|
|
|
+ },
|
|
|
+ valueToForm: (_, model) => {
|
|
|
+ return get(model, 'tooltip.formatter')?.replace(/\{|\}/g, "")?.split(" ");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "样式",
|
|
|
+ prop: "tooltip.textStyle",
|
|
|
+ type: "fontStyle",
|
|
|
+ defaultValue: {
|
|
|
+ color: "#000000ff",
|
|
|
+ size: 12,
|
|
|
+ bold: false,
|
|
|
+ italic: false,
|
|
|
+ },
|
|
|
+ format: (formatModel, value) => {
|
|
|
+ formatModel.value["tooltip.textStyle"] = {
|
|
|
+ color: value.color,
|
|
|
+ fontSize: value.size,
|
|
|
+ fontWeight: value.bold ? "bold" : "normal",
|
|
|
+ fontStyle: value.italic ? "italic" : "normal",
|
|
|
+ };
|
|
|
+ },
|
|
|
+ valueToForm: (_, model) => {
|
|
|
+ return {
|
|
|
+ color: get(model, 'tooltip.textStyle.color', '#000000ff'),
|
|
|
+ size: get(model, 'tooltip.textStyle.fontSize', 12),
|
|
|
+ bold: get(model, 'tooltip.textStyle.fontWeight') === 'bold',
|
|
|
+ italic: get(model, 'tooltip.textStyle.fontStyle') === 'italic',
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "边框",
|
|
|
+ prop: "",
|
|
|
+ type: "divider",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "线宽",
|
|
|
+ prop: "tooltip.borderWidth",
|
|
|
+ type: "inputNumber",
|
|
|
+ fieldProps: {
|
|
|
+ addonAfter: "px",
|
|
|
+ },
|
|
|
+ defaultValue: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "颜色",
|
|
|
+ prop: "tooltip.borderColor",
|
|
|
+ type: "colorSelect",
|
|
|
+ defaultValue: "#ccc",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "圆角",
|
|
|
+ prop: "tooltip.borderRadius",
|
|
|
+ type: "inputNumber",
|
|
|
+ fieldProps: {
|
|
|
+ addonAfter: "px",
|
|
|
+ },
|
|
|
+ defaultValue: 4,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "背景",
|
|
|
+ prop: "",
|
|
|
+ type: "divider",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "填充",
|
|
|
+ prop: "tooltip.backgroundColor",
|
|
|
+ type: "backgroundSelect",
|
|
|
+ fieldProps: {
|
|
|
+ filterOptions: ["image"],
|
|
|
+ },
|
|
|
+ defaultValue: {
|
|
|
+ type: "color",
|
|
|
+ color: "#fff",
|
|
|
+ },
|
|
|
+ format: (formatModel, value) => {
|
|
|
+ formatModel.value["tooltip.backgroundColor"] = value?.type === 'color' ? value.color : 'none';
|
|
|
+ },
|
|
|
+ valueToForm: (value) => {
|
|
|
+ return !value || value === 'none'
|
|
|
+ ? {
|
|
|
+ type: 'none'
|
|
|
+ }
|
|
|
+ : {
|
|
|
+ type: "color",
|
|
|
+ color: value,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "阴影",
|
|
|
+ prop: "tooltip.extraCssText",
|
|
|
+ type: "radioGroup",
|
|
|
+ fieldProps: {
|
|
|
+ options: [
|
|
|
+ { label: "开启", value: true },
|
|
|
+ { label: "关闭", value: false },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ defaultValue: false,
|
|
|
+ format: (formatModel, value) => {
|
|
|
+ formatModel.value["tooltip.extraCssText"] = value
|
|
|
+ ? "box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);"
|
|
|
+ : "";
|
|
|
+ },
|
|
|
+ valueToForm: (_, model) => {
|
|
|
+ return get(model, 'tooltip.extraCssText') ? true : false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ : [];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+const handleDataSourceChange = (data: any) => {
|
|
|
+ emit("change", {
|
|
|
+ ...props,
|
|
|
+ dataSource: data,
|
|
|
+ });
|
|
|
+};
|
|
|
+const handleFormChange = (formatData: any) => {
|
|
|
+ const obj = cloneDeep(props);
|
|
|
+ Object.keys(formatData).forEach((key) => {
|
|
|
+ set(obj, key, formatData[key]);
|
|
|
+ });
|
|
|
+ emit("change", obj);
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.config-tab {
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 12px;
|
|
|
+}
|
|
|
+</style>
|