Commit 9aa7dba0 by qlintonger xeno

feat: 重设结构变体

parent bef5c888
<script lang="ts" setup> <script lang="ts" setup>
import {ChartCompType} from "./lib/Table2Chart/const/chartCompType.ts";
const layout = [ const layout = [
{x: 0, y: 0, w: 4, h: 1,}, {x: 0, y: 0, w: 4, h: 1,},
...@@ -10,21 +11,22 @@ const layout = [ ...@@ -10,21 +11,22 @@ const layout = [
{x: 0, y: 1, w: 7, h: 1,}, {x: 0, y: 1, w: 7, h: 1,},
{x: 0, y: 3, w: 7, h: 2,} {x: 0, y: 3, w: 7, h: 2,}
].map((a, q) => ({ ].map((a, q) => ({
...a, title: `示例图${q + 1}`, chartData: a.w >= 4 ? [ ...a, title: `示例图${q + 1}`, chartData: Math.random() > .6 ? [
{type: 'bar', category: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], data: [120, 200, 150, 80, 70, 110, 130]},
{type: 'bar', category: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], data: [120, 200, 150, 80, 70, 110, 130]}
] : [
{ {
type: 'bar', category: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'], data: [{ type: ChartCompType.EChartsBar,
name: '2011', category: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
type: 'bar', data: [120, 200, 150, 80, 70, 110, 130]
data: [18203, 23489, 29034, 104970, 131744, 630230]
}, },
{ {
name: '2012', type: ChartCompType.EChartsBar,
type: 'bar', category: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: [19325, 23438, 31000, 121594, 134141, 681807] data: [120, 200, 150, 80, 70, 110, 130]
}] }
] : [
{
type: ChartCompType.EChartsBar,
category: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: [120, 200, 150, 80, 70, 110, 130]
}, },
] ]
})); }));
......
<template>
<v-scale-screen full-screen height="1080" width="1920">
<div class="grid-container w-full h-full">
<div v-for="item in layout" :key="item.i" :style="getItemStyle(item)" class="grid-item">
{{ item.i }}
</div>
</div>
</v-scale-screen>
</template>
<script lang="ts" setup>
import VScaleScreen from 'v-scale-screen';
const layout = [
{x: 0, y: 0, w: 4, h: 1, i: "0"},
{x: 4, y: 0, w: 8, h: 1, i: "1"},
{x: 0, y: 2, w: 2, h: 1, i: "2"},
{x: 2, y: 2, w: 2, h: 1, i: "3"},
{x: 4, y: 2, w: 3, h: 1, i: "4"},
{x: 7, y: 1, w: 5, h: 4, i: "5"},
{x: 0, y: 1, w: 7, h: 1, i: "6"},
{x: 0, y: 3, w: 7, h: 1, i: "7"}
];
function getItemStyle(item: any) {
return {
gridColumn: `${item.x + 1} / span ${item.w}`,
gridRow: `${item.y + 1} / span ${item.h}`,
};
}
</script>
<style scoped>
.grid-container {
display: grid;
grid-template-columns: repeat(12, 1fr); /* 定义 12 列 */
gap: 10px; /* 设置行和列的间距 */
grid-template-rows: repeat(4, 1fr);
}
.grid-item {
background-color: #ccc;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #999;
}
</style>
\ No newline at end of file
<template>
<template v-if="ps.type === ChartCompType.EChartsBar">
<global-echarts v-bind="$attrs" :height="ps.height" :width="ps.width" :options="ps.options"/>
</template>
<template v-else-if="ps.type === ChartCompType.EChartsPie">
<div class="flex flex-col items-center">
</div>
</template>
</template>
<script setup lang="ts">
import {ECBasicOption} from "echarts/types/dist/shared";
import {ChartCompType} from "../const/chartCompType.ts";
import GlobalEcharts from "./global-echarts.vue";
import {GeneralChartOptions} from "../types/ScreenChart.typing.ts";
interface Props {
options?: ECBasicOption;
width?: string | number;
height?: string | number;
type: ChartCompType;
item: GeneralChartOptions
}
const ps = withDefaults(defineProps<Props>(), {
options: () => {
return {};
},
width: "100%",
height: "100%",
type: ChartCompType.EChartsBar
});
</script>
\ No newline at end of file
...@@ -40,7 +40,6 @@ const es = defineEmits(['node-inserted']) ...@@ -40,7 +40,6 @@ const es = defineEmits(['node-inserted'])
onMounted(() => { onMounted(() => {
const el = chartRef.value; const el = chartRef.value;
const inst = getCurrentInstance() const inst = getCurrentInstance()
console.log('inst', {inst})
if (el) { if (el) {
nextTick(() => { nextTick(() => {
chartInstance = echarts.init(el); chartInstance = echarts.init(el);
......
<script lang="ts" setup> <script lang="ts" setup>
import {ScreenChartProps} from "./types/ScreenChart.typing.ts"; import {ScreenChartProps} from "./types/ScreenChart.typing.ts";
import { import {getAllGridSize, gridItemStyle, mapContainerStyle} from "./funcs/mapStyle.ts";
allGraphRegister,
containerRef,
getAllGridSize,
gridItemStyle,
mapContainerStyle,
startNow
} from "./funcs/mapStyle.ts";
import GlobalEcharts from "./Components/global-echarts.vue";
import {mapToEchartsOptions} from "./funcs/mapToEchartsOptions.ts"; import {mapToEchartsOptions} from "./funcs/mapToEchartsOptions.ts";
import {computed, nextTick, onMounted, onUnmounted, ref} from "vue"; import {computed, onMounted, onUnmounted} from "vue";
import {registerGraph} from "./funcs/mapStyle.ts"; import ChartsWrapper from "./Components/charts-wrapper.vue";
import {containerRef, isAllMounted, registerGraph} from "./funcs/procedureFunc.ts";
import {onNew, onRemoved} from "./funcs/hooksFunc.ts";
const props = withDefaults(defineProps<ScreenChartProps>(), { const props = withDefaults(defineProps<ScreenChartProps>(), {
gap: 16, containerPadding: 12, gridItemPadding: 12 gap: 16, containerPadding: 12, gridItemPadding: 12
}) })
const isAllMounted = ref(false)
let ro: ResizeObserver | null = null let ro: ResizeObserver | null = null
onUnmounted(function () { onUnmounted(function () {
if (ro) { onRemoved()
ro.disconnect()
ro = null
}
allGraphRegister.value = []
}) })
const gridConfig = computed(() => { const gridConfig = computed(() => {
return getAllGridSize(props.layout) return getAllGridSize(props.layout)
}) })
onMounted(function () { onMounted(function () {
nextTick(function () { onNew()
isAllMounted.value = true
})
if (!ro) {
ro = new ResizeObserver(startNow)
ro.observe(containerRef.value, {box: 'border-box'})
startNow()
}
}) })
</script> </script>
...@@ -48,7 +30,7 @@ onMounted(function () { ...@@ -48,7 +30,7 @@ onMounted(function () {
<component :is="item.renderTitle(item, props.layout)" v-else/> <component :is="item.renderTitle(item, props.layout)" v-else/>
<div v-if="isAllMounted" class="mt-[12px] w-full flex items-stretch justify-between" <div v-if="isAllMounted" class="mt-[12px] w-full flex items-stretch justify-between"
style="height: calc(100% - 12px - 12px)"> style="height: calc(100% - 12px - 12px)">
<global-echarts @node-inserted="registerGraph" v-for="(z,x) in item.chartData" :key="x" :options="mapToEchartsOptions(z)"/> <ChartsWrapper :type="z.type" :item="z" @node-inserted="registerGraph" v-for="(z,x) in item.chartData" :key="x" :options="mapToEchartsOptions(z)"/>
</div> </div>
</div> </div>
</div> </div>
......
export enum ChartCompType {
EChartsBar,
EChartsPie
}
\ No newline at end of file
import {allGraphRegister, containerRef, isAllMounted, startNow} from "./procedureFunc.ts";
import {nextTick} from "vue";
let ro: ResizeObserver | null = null
export function onRemoved() {
if (ro) {
ro.disconnect()
ro = null
}
allGraphRegister.value = []
}
export function onNew() {
nextTick(function () {
}).then(function () {
isAllMounted.value = true
if (!ro) {
ro = new ResizeObserver(startNow)
ro.observe(containerRef.value, {box: 'border-box'})
startNow()
}
})
}
\ No newline at end of file
import {ScreenChartProps, SingleLayoutConf} from "../types/ScreenChart.typing.ts"; import {ScreenChartProps, SingleLayoutConf} from "../types/ScreenChart.typing.ts";
import {geoContainer, mapHeight, mapWidth} from "./mapGEOStyle.ts"; import {geoContainer, mapHeight, mapWidth} from "./mapGEOStyle.ts";
import {nextTick, ref} from "vue";
export const containerRef = ref()
export const gridItemStyle = function (item: SingleLayoutConf, props: ScreenChartProps, geoConf: { rows: number, cols: number}) { export const gridItemStyle = function (item: SingleLayoutConf, props: ScreenChartProps, geoConf: { rows: number, cols: number}) {
return { return {
position: 'absolute', position: 'absolute',
...@@ -33,33 +31,6 @@ export const wholeGridGeo = function (item: SingleLayoutConf, geoConf: { rows: n ...@@ -33,33 +31,6 @@ export const wholeGridGeo = function (item: SingleLayoutConf, geoConf: { rows: n
}; };
} }
export const allGraphRegister = ref<Array<{uid: string, f: Function}>>([])
export function registerGraph(item: {uid: string, f: Function}) {
allGraphRegister.value.push(item)
}
export const startNow = function calcGEO() {
const rect = containerRef.value.getBoundingClientRect()
geoContainer.value.width = rect.width
geoContainer.value.height = rect.height
const allStyle = window.getComputedStyle(containerRef.value)
// @ts-ignore
geoContainer.value.contentWidth = parseFloat(allStyle['width']) - parseFloat(allStyle['padding-left']) - parseFloat(allStyle['padding-right'])
// @ts-ignore
geoContainer.value.contentHeight = parseFloat(allStyle['height']) - parseFloat(allStyle['padding-top']) - parseFloat(allStyle['padding-bottom'])
// @ts-ignore
geoContainer.value.paddingAll = parseFloat(allStyle['paddingLeft'])
nextTick(function () {
}).then(function () {
for (const item of allGraphRegister.value) {
const chart: any = item.f()
chart.resize();
}
})
}
export function getAllGridSize(items: Array<SingleLayoutConf>) { export function getAllGridSize(items: Array<SingleLayoutConf>) {
let maxCol = 0; let maxCol = 0;
let maxRow = 0; let maxRow = 0;
......
import {GeneralChartOptions} from "../types/ScreenChart.typing.ts"; import {BarChartOptions, GeneralChartOptions, PieCharOptions} from "../types/ScreenChart.typing.ts";
import {ChartCompType} from "../const/chartCompType.ts";
export function mapToEchartsOptions(item: GeneralChartOptions) { export function mapToEchartsOptions(item: GeneralChartOptions) {
if (item.type === 'bar') { if (item.type === ChartCompType.EChartsBar) {
let series: any[] = [] let series: any[]
// 简单类型数据 // 简单类型数据
item = <BarChartOptions>item;
if (item.data.every(a=>typeof a === 'number')) { if (item.data.every(a=>typeof a === 'number')) {
series = [{data: item.data, type:'bar'}] series = [{data: item.data, type:'bar'}]
} else { } else {
...@@ -40,4 +42,50 @@ export function mapToEchartsOptions(item: GeneralChartOptions) { ...@@ -40,4 +42,50 @@ export function mapToEchartsOptions(item: GeneralChartOptions) {
series series
} }
} }
if (item.type === ChartCompType.EChartsPie) {
item = <PieCharOptions>item;
const total = item.data.reduce((a, b) => a + b.value, 0);
return {
legend: {
top: '5%',
left: 'center'
},
radius: item.radius,
type: 'pie',
center: ['50%', '50%'],
avoidLabelOverlap: false,
emphasis: {
scaleSize: 3,
},
label: {
show: false,
},
labelLine: {
show: false,
},
data: item.data.map(function (item) {
return {
value: item.value,
name: item.name,
itemStyle: {
color: item.color
}
}
}),
toolbox: false,
tooltip: {
trigger: "item",
formatter: function (param: any) {
return `${param.name}${
total ? ((param.value * 100) / total).toFixed(2) : 100
}% ${param.value}`;
},
showDelay: 0,
hideDelay: 0,
extraCssText: "pointer-events: none;",
position: "top",
appendTo: "body",
},
}
}
} }
\ No newline at end of file
import {nextTick, ref} from "vue";
import {geoContainer} from "./mapGEOStyle.ts";
export const containerRef = ref()
export const isAllMounted = ref(false)
export const allGraphRegister = ref<Array<{ uid: string, f: Function }>>([])
export function registerGraph(item: { uid: string, f: Function }) {
allGraphRegister.value.push(item)
}
export const startNow = function calcGEO() {
const rect = containerRef.value.getBoundingClientRect()
geoContainer.value.width = rect.width
geoContainer.value.height = rect.height
const allStyle = window.getComputedStyle(containerRef.value)
// @ts-ignore
geoContainer.value.contentWidth = parseFloat(allStyle['width']) - parseFloat(allStyle['padding-left']) - parseFloat(allStyle['padding-right'])
// @ts-ignore
geoContainer.value.contentHeight = parseFloat(allStyle['height']) - parseFloat(allStyle['padding-top']) - parseFloat(allStyle['padding-bottom'])
// @ts-ignore
geoContainer.value.paddingAll = parseFloat(allStyle['paddingLeft'])
nextTick(function () {
}).then(function () {
for (const item of allGraphRegister.value) {
const chart: any = item.f()
chart.resize();
}
})
}
\ No newline at end of file
import {VNode} from "vue"; import {VNode} from "vue";
import {ChartCompType} from "../const/chartCompType.ts";
export type BarChartOptions = { export type BarChartOptions = {
category: string[] category: string[]
data: number[] | { name: string, data: number[] }[], data: number[] | { name: string, data: number[] }[],
type: 'bar' type: ChartCompType
}; };
export type GeneralChartOptions = BarChartOptions export type PieCharOptions = {
type: ChartCompType,
title: string,
radius: Array<string>,
data: Array<{value: number, name: string, color: string}>,
centerText?: string | Function
}
export type GeneralChartOptions = BarChartOptions | PieCharOptions
export type ChartOptionSet = Array<GeneralChartOptions> export type ChartOptionSet = Array<GeneralChartOptions>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment