首页 > 其他分享 >图表封装组件

图表封装组件

时间:2025-01-15 13:45:15浏览次数:1  
标签:封装 type value LABEL 图表 组件 import CONFIG const

图表封装:

 


图表封装使用:
<template>
<!--软件模块复用率图表-->
<chart-and-table
ref="chartAndTableRef"
:chart-desc="chartDesc"
:chart-loading="chartLoading"
:columns="columns"
:list="list"
:table-loading="tableLoading"
:total-count="totalCount"
chart-title="模块复用率"
table-title="软件模块清单"
@changePage="getTableData"
>
<template #operation>
<div class="chart-operation" style="width: 400px; display: flex;align-items: center">
<div style="width: 80px;font-size: 15px;font-weight: bolder">排序维度:</div>
<el-select v-model="queryForm.sort" style="width: 150px;">

<el-option v-for="item in sortDimensionOptions"
:key="item.value"
:label="item.label"
:value="item.value">

</el-option>
</el-select>
<el-radio-group v-model="queryForm.sortDirection" style="margin-left: 20px;">
<el-radio label="升序" value="asc"/>
<el-radio label="降序" value="desc"/>
</el-radio-group>
</div>
</template>
</chart-and-table>
</template>
引用:
import {MODULE_REUSE_RATE_DESC} from "@/settings/base.ts";
import {AXIS_LABEL_CONFIG, AXIS_LINE_CONFIG, COLOR_DEFAULT, GRID, LEGEND_CONFIG, SERIES_LABEL_CONFIG, SPLIT_LINE_CONFIG, TOOLTIP_CONFIG} from "@/settings/charts.ts";
import {AG_SW_MODULE_COLUMNS} from "@/settings/columns.ts";
import {$swpT} from "@/utils";
import ChartAndTable from "@/views/platformMeasure/chartAndTable.vue";
import {onMounted, reactive, ref, watch} from "vue";

const chartLoading = ref(false);
const tableLoading = ref(false);
const totalCount = ref(0);

const chartDesc = MODULE_REUSE_RATE_DESC;
const columns = AG_SW_MODULE_COLUMNS;
const list = ref<any>([]);
const sourceData = ref<any>([]);
const chartAndTableRef = ref();
const queryForm = reactive<any>({});
const queryFormRef = ref<any>();

watch(() => [queryForm.sort, queryForm.sortDirection], () => {
getTableData();
});
onMounted(() => {
getBarData();
getTableData();
// 渲染默认数据
queryForm.sort = "checkReuseRate";
queryForm.sortDirection = "asc";
});
// 重置搜索
const resetSearch = () => {
if (queryFormRef.value) {
queryFormRef.value.resetFields();
}
Object.keys(queryForm).forEach(fieldName => {
delete queryForm[fieldName];
});
getTableData();
};

在这里使用import {MODULE_REUSE_RATE_DESC} from "@/settings/base.ts";
// 模块复用率
export const MODULE_REUSE_RATE_DESC = [{
title: "数据范围",
desc: "根据搜索条件,以“项目+ECU+是否自研”为单位,取“校验节点非空”的“最新审批发布”的“软件模块选型方案”中软件模块“Base版本和校验版本同时有值的数据条目”;"
}, {
title: "计算公式",
desc: "软件模块复用度=获取数据软件模块复用度求和÷软件模块条目总数;应用项目数=引用该软件模块项目去重求和;工时=该软件模块评估工时求和"
}, {
title: "展示形式",
desc: "显示排名前10或后10的数据(可人工定义排序规则)"
}, {
title: "术语说明",
desc: "校验复用率-代码维度计算,评估复用率-工时维度计算"
}];

在这里使用import {AXIS_LABEL_CONFIG, AXIS_LINE_CONFIG, COLOR_DEFAULT, GRID, LEGEND_CONFIG, SERIES_LABEL_CONFIG, SPLIT_LINE_CONFIG, TOOLTIP_CONFIG} from "@/settings/charts.ts";

/**
* 图表配置
*
*
* @date 2024-11-25
*/
import {variables} from "@/styles";

// 颜色值预设
export const COLOR_DEFAULT = [
"#5470c6",
"#ed7d31",
"#a3a3a3",
"#ffc30a",
"#5ab1ef",
"#d87a80",
"#8d98b3",
"#e5cf0d",
"#97b552",
"#2ec7c9"
];

// 糖果色
export const COLOR_CANDY = [
"#fc97af",
"#87f7cf",
"#f7f494",
"#72ccff",
"#f7c5a0",
"#d4a4eb",
"#d2f5a6",
"#76f2f2"
];

// 图例配置
export const LEGEND_CONFIG = {
top: "bottom",
itemWidth: 12,
itemHeight: 12,
textStyle: {
color: variables.black,
fontSize: 12,
lineHeight: 14
}
};

// 栅格配置
export const GRID = {
left: 10,
right: 10,
bottom: 25,
containLabel: true
};

// 提示器配置
export const TOOLTIP_CONFIG = {
padding: [5, 10, 5, 10],
axisPointer: {
label: {
backgroundColor: variables.black,
color: variables.white
},
type: "cross"
},
backgroundColor: variables.bgLight,
textStyle: {
color: variables.black,
fontSize: 13
}
};

// 栅格线配置
export const SPLIT_LINE_CONFIG = {
show: true,
lineStyle: {
color: variables.border,
type: "dashed",
width: 1.25
}
};

// 坐标标签配置
export const AXIS_LABEL_CONFIG = {
show: true,
color: variables.dark
};

// 坐标线配置
export const AXIS_LINE_CONFIG = {
lineStyle: {
color: variables.border
}
};

// 数据块配置
export const SERIES_LABEL_CONFIG = {
show: true,
position: "inside",
fontSize: 13
};

 

在这里使用import {AG_SW_MODULE_COLUMNS} from "@/settings/columns.ts";

// 平台化度量-软件模块清单
export const AG_SW_MODULE_COLUMNS = [AG_INDEXES, {
field: "project",
headerName: $swpT("page.swModulePlan.project"), // 项目
headerTooltip: $swpT("page.swModulePlan.project"), // 项目
tooltipField: "project",
minWidth: 150,
editable: false
}, {
field: "ecu",
headerName: "ECU",
headerTooltip: "ECU",
tooltipField: "",
minWidth: 150,
editable: false
}]


使用: 在这里拆出来options 为了适用多个图表

// 获取软件模块复用率柱状图数据
const getBarData = () => {
const dataset = {
dimensions: ["moduleName", "校验复用率", "评估复用率", "评估工时", "应用项目数"],
source: sourceData.value
};
const option = {
color: COLOR_DEFAULT,
legend: {
...LEGEND_CONFIG
},
tooltip: {
...TOOLTIP_CONFIG,
trigger: "axis"
},
xAxis: {
type: "category",
axisLabel: {
...AXIS_LABEL_CONFIG,
show: true,
interval: 0,
rotate: 20 // X轴文本过长时可倾斜
},
axisLine: AXIS_LINE_CONFIG
},
yAxis: [{
type: "value",
nameTextStyle: {
...AXIS_LABEL_CONFIG
},
name: "平均复用率",
position: "left",
axisLabel: {
...AXIS_LABEL_CONFIG,
formatter: "{value} %"
},
splitLine: SPLIT_LINE_CONFIG
}, {
type: "value",
nameTextStyle: {
...AXIS_LABEL_CONFIG
},
name: "应用项目数/评估工时",
position: "right",
splitLine: SPLIT_LINE_CONFIG,
axisLabel: {
...AXIS_LABEL_CONFIG
}
}],
dataZoom: {
show: true,
height: 20,
bottom: 40,
type: "slider",
start: 0,
end: 100, // 可根据数据长度调整
backgroundColor: "rgba(255,255,255,0)",
dataBackgroundColor: "rgba(114,204,255,1)",
fillerColor: "rgba(114,204,255,0.2)",
handleColor: "#72ccff",
textStyle: {
color: "#aaaaaa"
}
},
dataset: dataset,
grid: {
...GRID,
top: 70,
bottom: 55,
left: 60,
right: 60
},
series: [{
type: "bar", barMaxWidth: 60, label: {...SERIES_LABEL_CONFIG, show: true}
}, {
type: "bar", barMaxWidth: 60, label: {...SERIES_LABEL_CONFIG, show: true}
}, {
type: "line", yAxisIndex: 0, label: {
...SERIES_LABEL_CONFIG,
show: true, formatter: ({value}: { value: any }) => {
return `${value["评估工时"]} %`;
}
}
}, {
type: "line", yAxisIndex: 1, label: {...SERIES_LABEL_CONFIG, show: true}
}]
};
chartAndTableRef.value.init(option);
};
在这里使用import {$swpT} from "@/utils";
/**
* 注册template下国际化翻译
*
* @param key
* @param value
*/
export const $swpT = (key: any = "", value: any = "") => {
return window.$swpT(key, value);
};

在这里中的utils/common.js
/**
* 公共方法
*
*
* @date 2024-06-11
*/
import storage from "@/libs/storage.ts";
import {excelCellStyle, excelHeaderStyle, excelLinkCellStyleFont, excelTwoCellStyle} from "@/settings/exportExcelStyle.ts";
import {formatExportLink} from "@/settings/urlUtil";
import {ElMessage} from "element-plus";
import * as Exceljs from "exceljs";
import {saveAs} from "file-saver";
import _, {isEmpty} from "lodash";
import {LocationQueryValue} from "vue-router";

// *** 获取环境变量 - 不同于webpack的引入环境变量 *** //
const {VITE_APP_TITLE} = import.meta.env;

图表封装的页面:

<template>
<div
v-loading="props.chartLoading"
:fullscreen="isFullscreen"
:style="{ height: height ? `${chartItemHeight}` : '' }"
class="chart-item"
>
<!--图表-->
<div v-loading="props.chartLoading" class="chart-item">
<div class="chart-hd">
<span>{{ props.chartTitle }}</span>
<el-tooltip effect="dark" placement="right">
<template #content>
<TipWord :chart-desc="props.chartDesc"/>
</template>
<el-icon style="all: initial;margin-top: 3px;">
<InfoFilled/>
</el-icon>
</el-tooltip>
<span v-if="canFullscreen" class="pointer" style="font-size: 20px" title="全屏" @click="isFullscreen = !isFullscreen">
<el-icon :size="26">
<FullScreen/>
</el-icon>
</span>
<!-- <span v-if="isDataView" :title="dataView ? '图表' : '数据视图'" @click="chartDataView">-->
<!-- <el-icon :size="26"><PieChart/></el-icon>-->
<!-- </span>-->
<span v-if="hasDownload" title="下载" @click="onChartDownload">
<el-icon :size="26"><Download/></el-icon>
</span>
</div>
<div class="chart-bd">
<slot name="operation"/>
<div ref="chartRef" class="chart-instance"/>
</div>
</div>
</div>
<!--表格-->
<div v-loading="props.tableLoading" class="chart-item">
<div class="chart-hd">
<span>{{ props.tableTitle }}</span>
</div>
<div class="chart-bd">
<div class="chart-instance">
<div class="chart-operation">
<el-button plain type="primary" @click="exportData">
<el-icon :size="16">
<svg-icon iconName="icon-shujuguanli-daohang-daorushuju"/>
</el-icon>&nbsp;
{{ $swpT("common.export") }}
</el-button>
</div>
<ag-grid-vue
:columnDefs="props.columns"
:rowData="props.list"
style="height: calc(100% - 30px);padding: 50px 0 10px 0; "
v-bind="settings"
@grid-ready="readyTable"
/>
<div class="chart-operation">
<el-pagination
v-model:current-page="pageState.pageNo"
v-model:page-size="pageState.pageSize"
:total="total"
v-bind="PAGINATION_CONFIG"
@size-change="pageState.pageNo = 1;changePage();
"
@current-change="changePage()"
></el-pagination>
</div>
</div>
</div>
</div>
</template>

<script lang="ts" setup>
// 搜索+图表+表格
import SvgIcon from "@/components/iconfont/SvgIcon.vue";
import TipWord from "@/components/tipWord.vue";
import {PAGINATION_CONFIG, PAGINATION_DEFAULT} from "@/constant/golbalConstantDemo.ts";
import {AG_SETTINGS} from "@/settings/columns.ts";
import {$swpT} from "@/utils";
import {AgGridVue} from "ag-grid-vue3";
import * as echarts from "echarts";
import {computed, defineEmits, defineExpose, defineProps, reactive, ref} from "vue";

const emits = defineEmits(["changePage"]);
const chartRef = ref();
const chart = ref<{
instance: echarts.ECharts | null;
value: HTMLElement | null;
}>({
instance: null,
value: chartRef
});
const isFullscreen = ref(false);
const props = defineProps({
// 图表标题
chartTitle: {
type: String,
default: "图表"
},
// 表格标题
tableTitle: {
type: String,
default: "表格"
},
// 图表loading
chartLoading: {
type: Boolean,
default: false
},
// 表格loading
tableLoading: {
type: Boolean,
default: false
},
// 图表描述
chartDesc: {
type: Array,
default: () => []
},
// 列配置
columns: {
type: Array,
default: () => []
},
// 列表数据
list: {
type: Array,
default: () => []
},
// 图表 高度
height: {
type: [Number, String],
default: 390
},
// 是否全屏
canFullscreen: {
type: Boolean,
default: true
},
// 是否切换表格
isDataView: {
type: Boolean,
default: true
},
// 是否下载
hasDownload: {
type: Boolean,
default: true
},
// 总条数
totalCount: {
type: Number,
default: 0
}
});
const agInstance = ref<any>();
const settings = ref({
...AG_SETTINGS,
suppressContextMenu: true, // 关闭右键菜单
stopEditingWhenCellsLoseFocus: false
});
// 分页
let pageState = reactive({
...PAGINATION_DEFAULT
});
const total = computed(() => {
return props.totalCount || 0;
});

// 表格预处理
const readyTable = (params: any) => {
agInstance.value = params;
autoFixTable();
};

// 调整宽度
const autoFixTable = () => {
window.onresize = () => {
sizeColumnsToFit();
};
sizeColumnsToFit();
};

// 列宽充满表格
const sizeColumnsToFit = () => {
agInstance.value?.api.sizeColumnsToFit();
};

// 生成图表
const init = (option: any) => {
const _chart = echarts.init(chart.value.value);
_chart.clear();
_chart.setOption(option);
_chart.resize();
chart.value.instance = _chart;
window.addEventListener("resize", _chart.resize);
};

// 分页切换
const changePage = () => {
emits("changePage", pageState);
};

// 导出
const exportData = () => {
const fileName = props.tableTitle;
agInstance.value.api.exportDataAsExcel({fileName});
};

// 元素高度
const chartItemHeight = computed(() => {
const propHeight = props.height;
return typeof propHeight !== "number" ? propHeight : `${propHeight}px`;
});

// 触发下载事件
const onChartDownload = () => {
if (!chart.value.instance) {
console.error("ECharts instance is not initialized");
return;
}

// 获取图表数据url
const dataUrl = chart.value.instance.getDataURL({
type: "png",
backgroundColor: "#ffffff",
pixelRatio: 2 // 2倍清晰度
});

// 创建隐藏的a标签
const a = document.createElement("a");
a.href = dataUrl;
a.download = `${props.chartTitle}.png`;
document.body.appendChild(a);
// 触发点击
a.click();
document.body.removeChild(a);
};

defineExpose({
init
});
</script>

<script lang="ts">
export default {
name: "ChartAndTable"
};
</script>


在这里中的import TipWord from "@/components/tipWord.vue";
<template>
<div v-if="Array.isArray(props.chartDesc)">
<div v-for="(item, index) in props.chartDesc" :key="index" style="width: 600px;margin: 5px;">
<span :style="{ fontWeight: 'bold', color: '#ffa500' }">{{ index + 1 + "、" + item.title + ":" }}</span>
{{ item.desc }}<br/>
</div>
</div>
</template>

<script lang="ts" setup>
// 提示词
import {defineProps} from "vue";

interface ChartDescItem {
title: string;
desc: string;
}
// TODO: 后面可能会有其他类型的描述,这里先只处理数组的情况
const props = defineProps({
chartDesc: {
type: Array as () => ChartDescItem[]
}
});
</script>

<style lang="less" scoped>

</style>

 

标签:封装,type,value,LABEL,图表,组件,import,CONFIG,const
From: https://www.cnblogs.com/nwy2012/p/18672469

相关文章

  • vuex 构建多组件共享的数据环境
    Vuex是Vue.js的官方状态管理库,用于在Vue.js应用程序中构建多个组件共享的数据环境。Vuex可以帮助我们解决组件之间共享数据和状态管理的问题。它将应用程序的状态存储在一个单一的地方,称为"store",并且允许组件直接从store中获取和修改状态,而不需要通过事件或属性传递......
  • 《鸿蒙开发-鸿蒙教程-答案之书》组件margin左和右等于没偏?
    《鸿蒙开发-鸿蒙教程-答案之书》组件margin左和右等于没偏?鸿蒙的margin和Android的margin还是有点区别,Android的margin没有任何毛病,但是鸿蒙margin会导致组件偏移回来的。因为鸿蒙的组件可以超越父组件,往外面宽展。那怎么办呢?先看个有问题的代码:@Entry@Componentstruc......
  • Vue.js组件开发-使用地图绘制轨迹
    在Vue.js中开发一个组件来展示地图并绘制轨迹,可以使用诸如Leaflet.js、MapboxGLJS或百度地图等地图库。这些库提供了丰富的API来创建和定制地图,以及绘制路径、标记和其他地图元素。示例:1.安装Leaflet.js首先,需要安装Leaflet.js库。可以通过npm或yarn来安装:npminstalll......
  • 封装,继承,多态
    在Java中,封装、继承和多态是面向对象编程(OOP)的三大核心特性。它们共同构成了面向对象编程的基础,帮助开发者编写出模块化、可重用和可扩展的代码。以下是它们的详细讲解:1. 封装(Encapsulation)定义封装是指将对象的属性和行为(方法)包装在一起,并对外隐藏内部实现细节,只暴露必......
  • 深度剖析RabbitMQ:从基础组件到管理页面详解
    文章目录一、简介二、Overview2.1Overview->Totals2.2Overview->Nodesbroker的属性2.3Overview->Churnstatistics2.4Overview->Portsandcontexts2.5Overview->Exportdefinitions2.6Overview->Importdefinitions三、Connections连接的属性四、Channels通道的......
  • ESP-IDF esp32添加自己的组件
    esp32添加自己的组件:1.按键盘的F1,或者点击菜单view-CommandPalette都可以,选择EDP-IDF:CreaterNewESP-IDFComponent,输入组件名称(比如说esp_pwmout),确定2.看到已经新建了该组件,修改对应.h文件#ifndef__ESP_PWMOUT_H__#define__ESP_PWMOUT_H__voidsetup_pwm(void);......
  • 组件导航守卫 常见的使用场景
    组件导航守卫通常用于处理组件级别的特定逻辑。以下是一些常见的使用场景:1、表单数据保存提醒:<template><div><form@submit.prevent="handleSubmit"><inputv-model="formData.name"/><!--其他表单字段--></form></div>&......
  • 【VUE】父子组件联动实现动态样式控制
    相关组件:父组件:src/views/erp/contract/Form.vue子组件:src/views/erp/contract/modules/PlanTable.vue实现思路:1.根据已有的isEdit判断状态是不是编辑或者新增,将状态传递给子组件2.子组件根据状态来决定是否添加星号样式具体方法:1.将原来的固定样式,改为动态样式{title......
  • RN/H5多设备自适应组件库来了,高效实现鸿蒙原生应用多设备精致体验
    在原生鸿蒙应用开发中,华为针对ArkUI框架推出了一整套针对多设备适配的完善能力(如“一多”能力)以及高阶组件(如分栏、边看边评等),帮助开发者轻松实现“一次开发,多端部署”。然而,当前鸿蒙生态仍存在大量用跨平台框架开发的应用,部分页面采用ReactNative(RN)和H5等框架开发,这些框架在系统......
  • 鸿蒙开发 - 自定义组件 和 组件通信的方法
    自定义组件的基本结构@Entry@ComponentstructMyComponent{build(){//...}}build()函数build()函数用于描述组件的UI界面,自定义组件必须定义build()函数build(){Column(){Text('测试')Button('点击')}}struct关键字strcut用来......