Commit 38208deb by qlintonger xeno

feat: 使用定位实现布局

parent b6b22918
<script lang="ts" setup> <script lang="ts" setup>
import {ScreenChartProps} from "./types/ScreenChart.typing.ts"; import {ScreenChartProps} from "./types/ScreenChart.typing.ts";
import {gridItemStyle, mapContainerStyle, getAllGridSize} from "./funcs/mapStyle.ts"; import {containerRef, getAllGridSize, gridItemStyle, mapContainerStyle} from "./funcs/mapStyle.ts";
import GlobalEcharts from "./Components/global-echarts.vue"; import GlobalEcharts from "./Components/global-echarts.vue";
import {mapToEchartsOptions} from "./funcs/mapToEchartsOptions.ts"; import {mapToEchartsOptions} from "./funcs/mapToEchartsOptions.ts";
import {nextTick, onMounted, onUnmounted, ref, computed} from "vue"; import {computed, nextTick, onMounted, onUnmounted, ref} from "vue";
import {geoContainer, } from "./funcs/mapGEOStyle.ts"; import {geoContainer,} from "./funcs/mapGEOStyle.ts";
const props = withDefaults(defineProps<ScreenChartProps>(), { const props = withDefaults(defineProps<ScreenChartProps>(), {
gap: 16, containerPadding: 12, gridItemPadding: 12 gap: 16, containerPadding: 12, gridItemPadding: 12
...@@ -24,6 +24,13 @@ const startNow = function calcGEO() { ...@@ -24,6 +24,13 @@ const startNow = function calcGEO() {
const rect = containerRef.value.getBoundingClientRect() const rect = containerRef.value.getBoundingClientRect()
geoContainer.value.width = rect.width geoContainer.value.width = rect.width
geoContainer.value.height = rect.height 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'])
} }
onMounted(function () { onMounted(function () {
nextTick(function () { nextTick(function () {
...@@ -35,12 +42,11 @@ onMounted(function () { ...@@ -35,12 +42,11 @@ onMounted(function () {
startNow() startNow()
} }
}) })
const containerRef = ref()
</script> </script>
<template> <template>
<div :style="mapContainerStyle(props, gridConfig)" class="w-full h-full pr" ref="containerRef"> <div :style="mapContainerStyle(props)" class="w-full h-full pr" ref="containerRef">
<div v-for="(item, w) in props.layout" :key="w" :style="gridItemStyle(item, props)" class="flex flex-col"> <div v-for="(item, w) in props.layout" :key="w" :style="gridItemStyle(item, props, gridConfig)" class="flex flex-col">
<div v-if="!item.renderTitle" class="w-full">{{ item.title }}</div> <div v-if="!item.renderTitle" class="w-full">{{ item.title }}</div>
<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"
......
import {ref} from "vue"; import {ref} from "vue";
export const geoContainer = ref({ export const geoContainer = ref({
width: 0, height: 0, designGraphWidth: 1920, designGraphHeight: 1080 width: 0, height: 0, designGraphWidth: 1920, designGraphHeight: 1080,
contentWidth: 0, contentHeight: 0, paddingAll: 0
}) })
export function mapWidth(designWidth: number) { export function mapWidth(designWidth: number) {
......
import {ScreenChartProps, SingleLayoutConf} from "../types/ScreenChart.typing.ts"; import {ScreenChartProps, SingleLayoutConf} from "../types/ScreenChart.typing.ts";
import {mapHeight, mapWidth} from "./mapGEOStyle.ts"; import {geoContainer, mapHeight, mapWidth} from "./mapGEOStyle.ts";
import {ref} from "vue";
export const gridItemStyle = function (item: SingleLayoutConf, props: ScreenChartProps) { export const containerRef = ref()
export const gridItemStyle = function (item: SingleLayoutConf, props: ScreenChartProps, geoConf: { rows: number, cols: number}) {
return { return {
gridColumn: `${item.x + 1} / span ${item.w}`, position: 'absolute',
gridRow: `${item.y + 1} / span ${item.h}`,
background: '#f1f1f1', background: '#f1f1f1',
boxSizing: 'border-box', boxSizing: 'border-box',
// @ts-ignore // @ts-ignore
padding: `${mapHeight(props.gridItemPadding)}px ${mapWidth(props.gridItemPadding)}px ${mapHeight(props.gridItemPadding)}px ${mapWidth(props.gridItemPadding)}px`, padding: `${mapHeight(props.gridItemPadding)}px ${mapWidth(props.gridItemPadding)}px ${mapHeight(props.gridItemPadding)}px ${mapWidth(props.gridItemPadding)}px`,
fontSize: `${mapWidth(14)}px` fontSize: `${mapWidth(14)}px`,
...wholeGridGeo(item, geoConf, props.gap!)
} }
} }
export const wholeGridGeo = function (item: SingleLayoutConf, geoConf: { rows: number, cols: number}, gap: number) {
const {rows, cols} = geoConf
const cellWidth = (geoContainer.value.contentWidth - (cols - 1) * gap) / cols
const cellHeight = (geoContainer.value.contentHeight - (rows - 1) * gap) / rows
const left = item.x * (cellWidth + gap) + geoContainer.value.paddingAll;
const top = item.y * (cellHeight + gap) + geoContainer.value.paddingAll;
const width = item.w * cellWidth + (item.w - 1) * gap;
const height = item.h * cellHeight + (item.h - 1) * gap;
return {
left: `${left}px`,
top: `${top}px`,
width: `${width}px`,
height: `${height}px`,
};
}
export function getAllGridSize(items: Array<SingleLayoutConf>) { export function getAllGridSize(items: Array<SingleLayoutConf>) {
let maxCol = 0; let maxCol = 0;
let maxRow = 0; let maxRow = 0;
...@@ -34,15 +53,9 @@ export function getAllGridSize(items: Array<SingleLayoutConf>) { ...@@ -34,15 +53,9 @@ export function getAllGridSize(items: Array<SingleLayoutConf>) {
return { rows: maxRow, cols: maxCol }; return { rows: maxRow, cols: maxCol };
} }
export const mapContainerStyle = function (props: ScreenChartProps, gridConfig: { rows: number, cols: number}) { export const mapContainerStyle = function (props: ScreenChartProps) {
return { return {
display: 'grid', display: 'grid',
// @ts-ignore
gridRowGap: mapHeight(props.gap) + 'px',
// @ts-ignore
gridColumnGap: mapWidth(props.gap) + 'px',
gridTemplateColumns: `repeat(${gridConfig.cols}, 1fr)`,
gridTemplateRows: `repeat(${gridConfig.rows}, 1fr)`,
boxSizing: 'border-box', boxSizing: 'border-box',
// @ts-ignore // @ts-ignore
padding: `${mapHeight(props.containerPadding)}px ${mapWidth(props.containerPadding)}px ${mapHeight(props.containerPadding)}px ${mapWidth(props.containerPadding)}px`, padding: `${mapHeight(props.containerPadding)}px ${mapWidth(props.containerPadding)}px ${mapHeight(props.containerPadding)}px ${mapWidth(props.containerPadding)}px`,
......
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