feat: 新增剪切

This commit is contained in:
MTrun 2022-02-04 12:17:50 +08:00
parent 47a7ce9d6e
commit abaf8f07ad
11 changed files with 224 additions and 45 deletions

View File

@ -1,17 +1,12 @@
import { getUUID } from '@/utils' import { echartOptionProfixHandle, publicConfig } from '@/packages/utils'
import { echartOptionProfixHandle } from '@/packages/utils/chart'
import { BarCommonConfig } from './index' import { BarCommonConfig } from './index'
import { ConfigType, CreateComponentType } from '@/packages/index.d' import { ConfigType, CreateComponentType } from '@/packages/index.d'
import omit from 'lodash/omit' import omit from 'lodash/omit'
export default class Config implements CreateComponentType { export default class Config extends publicConfig implements CreateComponentType {
public id = getUUID()
public key = BarCommonConfig.key public key = BarCommonConfig.key
public rename = undefined
public chartData: Exclude<ConfigType, ['node']> = omit(BarCommonConfig, ['node']) public chartData: Exclude<ConfigType, ['node']> = omit(BarCommonConfig, ['node'])
public attr = { x: 0, y: 0, w: 500, h: 300 }
// 图表配置项 // 图表配置项
public option = echartOptionProfixHandle({ public option = echartOptionProfixHandle({
tooltip: { tooltip: {
@ -34,10 +29,4 @@ export default class Config implements CreateComponentType {
} }
] ]
}) })
// 设置坐标
public setPosition(x: number, y: number): void {
this.attr.x = x
this.attr.y = y
}
} }

View File

@ -13,14 +13,16 @@ export type ConfigType = {
} }
// 组件实例类 // 组件实例类
export interface CreateComponentType { export interface PublicConfigType {
id: string id: string
key: string
rename?: string rename?: string
attr: { x: number; y: number; w: number; h: number } attr: { x: number; y: number; w: number; h: number; zIndex: number }
setPosition: Function
}
export interface CreateComponentType extends PublicConfigType {
key: string
chartData: ConfigType chartData: ConfigType
option: object option: object
setPosition: Function
} }
// 包分类枚举 // 包分类枚举

View File

@ -1 +1,2 @@
export * from '@/packages/utils/chart' export * from '@/packages/utils/chart'
export * from '@/packages/utils/publicConfig'

View File

@ -0,0 +1,15 @@
import { getUUID } from '@/utils'
import { PublicConfigType } from '@/packages/index.d'
export class publicConfig implements PublicConfigType{
public id = getUUID()
// 重命名
public rename = undefined
// 基本信息
public attr = { x: 0, y: 0, w: 500, h: 300, zIndex: 0 }
// 设置坐标
public setPosition(x: number, y: number): void {
this.attr.x = x
this.attr.y = y
}
}

View File

@ -41,7 +41,8 @@ import {
ChevronUp as ChevronUpIcon, ChevronUp as ChevronUpIcon,
ChevronDown as ChevronDownIcon, ChevronDown as ChevronDownIcon,
TimeOutline as TimeOutlineIcon, TimeOutline as TimeOutlineIcon,
ClipboardOutline as ClipboardOutlineIcon ClipboardOutline as ClipboardOutlineIcon,
Cut as CutIcon
} from '@vicons/ionicons5' } from '@vicons/ionicons5'
import { import {
@ -143,7 +144,9 @@ const ionicons5 = {
// 时间 // 时间
TimeOutlineIcon, TimeOutlineIcon,
// 剪贴板 // 剪贴板
ClipboardOutlineIcon ClipboardOutlineIcon,
// 剪贴
CutIcon
} }
const carbon = { const carbon = {

View File

@ -1,4 +1,5 @@
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d'
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
// 编辑画布属性 // 编辑画布属性
export enum EditCanvasTypeEnum { export enum EditCanvasTypeEnum {
@ -13,6 +14,7 @@ export enum EditCanvasTypeEnum {
BACKGROUND = 'background' BACKGROUND = 'background'
} }
// 编辑区域
export type EditCanvasType = { export type EditCanvasType = {
// 编辑区域 DOM // 编辑区域 DOM
[EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null [EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null
@ -53,6 +55,12 @@ export type TargetChartType = {
selectId?: string selectId?: string
} }
// 数据记录
export type RecordChartType = {
charts: CreateComponentType | CreateComponentType[]
type: HistoryActionTypeEnum.CUT | HistoryActionTypeEnum.COPY
}
// Store 枚举 // Store 枚举
export enum ChartEditStoreEnum { export enum ChartEditStoreEnum {
EDIT_RANGE = 'editRange', EDIT_RANGE = 'editRange',
@ -60,7 +68,7 @@ export enum ChartEditStoreEnum {
RIGHT_MENU_SHOW = 'rightMenuShow', RIGHT_MENU_SHOW = 'rightMenuShow',
MOUSE_POSITION = 'mousePosition', MOUSE_POSITION = 'mousePosition',
TARGET_CHART = 'targetChart', TARGET_CHART = 'targetChart',
RECORD_CHARTS = 'recordCharts', RECORD_CHART = 'recordChart',
COMPONENT_LIST = 'componentList' COMPONENT_LIST = 'componentList'
} }
@ -70,6 +78,6 @@ export interface chartEditStoreType {
[ChartEditStoreEnum.RIGHT_MENU_SHOW]: boolean [ChartEditStoreEnum.RIGHT_MENU_SHOW]: boolean
[ChartEditStoreEnum.MOUSE_POSITION]: MousePositionType [ChartEditStoreEnum.MOUSE_POSITION]: MousePositionType
[ChartEditStoreEnum.TARGET_CHART]: TargetChartType [ChartEditStoreEnum.TARGET_CHART]: TargetChartType
[ChartEditStoreEnum.RECORD_CHARTS]?: CreateComponentType | CreateComponentType[] [ChartEditStoreEnum.RECORD_CHART]?: RecordChartType
[ChartEditStoreEnum.COMPONENT_LIST]: CreateComponentType[] [ChartEditStoreEnum.COMPONENT_LIST]: CreateComponentType[]
} }

View File

@ -7,12 +7,13 @@ import {
chartEditStoreType, chartEditStoreType,
EditCanvasType, EditCanvasType,
MousePositionType, MousePositionType,
TargetChartType TargetChartType,
RecordChartType
} from './chartEditStore.d' } from './chartEditStore.d'
// 记录记录 // 记录记录
import { useChartHistoryStoreStore } from '@/store/modules/chartHistoryStore/chartHistoryStore' import { useChartHistoryStoreStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d' import { HistoryActionTypeEnum, HistoryItemType } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
const chartHistoryStoreStore = useChartHistoryStoreStore() const chartHistoryStoreStore = useChartHistoryStoreStore()
@ -53,7 +54,7 @@ export const useChartEditStoreStore = defineStore({
selectId: undefined selectId: undefined
}, },
// 记录临时数据(复制等) // 记录临时数据(复制等)
recordCharts: undefined, recordChart: undefined,
// 图表数组 // 图表数组
componentList: [] componentList: []
}), }),
@ -70,8 +71,8 @@ export const useChartEditStoreStore = defineStore({
getTargetChart():TargetChartType { getTargetChart():TargetChartType {
return this.targetChart return this.targetChart
}, },
getRecordCharts(): CreateComponentType | CreateComponentType[] | undefined { getRecordChart(): RecordChartType | undefined {
return this.recordCharts return this.recordChart
}, },
getComponentList(): CreateComponentType[] { getComponentList(): CreateComponentType[] {
return this.componentList return this.componentList
@ -95,14 +96,13 @@ export const useChartEditStoreStore = defineStore({
this.targetChart.selectId = selectId this.targetChart.selectId = selectId
}, },
// * 设置记录数据 // * 设置记录数据
setRecordCharts(item: CreateComponentType | CreateComponentType[] | undefined) { setRecordChart(item: RecordChartType | undefined) {
this.recordCharts = cloneDeep(item) this.recordChart = cloneDeep(item)
}, },
// * 找到目标 id 数据下标位置 // * 找到目标 id 数据下标位置
fetchTargetIndex(): number { fetchTargetIndex(): number {
const index = this.componentList.findIndex(e => e.id === this.getTargetChart.selectId) const index = this.componentList.findIndex(e => e.id === this.getTargetChart.selectId)
if (index === -1) { if (index === -1) {
window['$message'].success(`操作失败,无法找到此元素`)
loadingError() loadingError()
} }
return index return index
@ -202,7 +202,6 @@ export const useChartEditStoreStore = defineStore({
const index:number = this.fetchTargetIndex() const index:number = this.fetchTargetIndex()
if (index !== -1) { if (index !== -1) {
// 下移排除最底层, 上移排除最顶层 // 下移排除最底层, 上移排除最顶层
if ((isDown && index === 0) || (!isDown && index === length - 1)) { if ((isDown && index === 0) || (!isDown && index === length - 1)) {
loadingFinish() loadingFinish()
@ -233,24 +232,32 @@ export const useChartEditStoreStore = defineStore({
this.wrap(true) this.wrap(true)
}, },
// * 复制 // * 复制
setCopy() { setCopy(isCut = false) {
try { try {
loadingStart() loadingStart()
const index:number = this.fetchTargetIndex() const index:number = this.fetchTargetIndex()
if (index !== -1) { if (index !== -1) {
this.setRecordCharts(this.getComponentList[index]) const copyData:RecordChartType = {
window['$message'].success('复制成功!') charts :this.getComponentList[index],
type: isCut ? HistoryActionTypeEnum.CUT : HistoryActionTypeEnum.COPY
}
this.setRecordChart(copyData)
window['$message'].success(isCut ? '剪切成功' : '复制成功!')
loadingFinish() loadingFinish()
} }
} catch(value) { } catch(value) {
loadingError() loadingError()
} }
}, },
// * 剪切
setCut() {
this.setCopy(true)
},
// * 粘贴 // * 粘贴
setParse() { setParse() {
try { try {
loadingStart() loadingStart()
const recordCharts = this.getRecordCharts const recordCharts = this.getRecordChart
if (recordCharts === undefined) { if (recordCharts === undefined) {
loadingFinish() loadingFinish()
return return
@ -264,20 +271,90 @@ export const useChartEditStoreStore = defineStore({
e.attr.y = e.attr.y + 30 e.attr.y = e.attr.y + 30
return e return e
} }
if (Array.isArray(recordCharts)) { const isCut = recordCharts.type === HistoryActionTypeEnum.CUT
recordCharts.forEach((e: CreateComponentType) => { // 多项
console.log(parseHandle(e)); if (Array.isArray(recordCharts.charts)) {
recordCharts.charts.forEach((e: CreateComponentType) => {
this.addComponentList(parseHandle(e), undefined, true) this.addComponentList(parseHandle(e), undefined, true)
// 剪切需删除原数据
if (isCut) {
this.setTargetSelectChart(e.id)
this.removeComponentList()
}
}) })
if (isCut) this.setRecordChart(undefined)
loadingFinish() loadingFinish()
return return
} }
this.addComponentList(parseHandle(recordCharts), undefined, true) // 单项
this.addComponentList(parseHandle(recordCharts.charts), undefined, true)
if(isCut) {
this.setTargetSelectChart(recordCharts.charts.id)
this.removeComponentList()
this.setRecordChart(undefined)
}
loadingFinish() loadingFinish()
} catch(value) { } catch(value) {
loadingError() loadingError()
} }
}, },
// 撤回处理
setBackAndSetForwardHandle(item: HistoryItemType, isForward = false) {
// 前进
if (isForward) {
return
}
console.log(item);
},
// * 撤回
setBack() {
try {
loadingStart()
console.log('撤回');
const targetData = chartHistoryStoreStore.backAction()
if (!targetData) {
loadingFinish()
return
}
if (Array.isArray(targetData)) {
targetData.forEach((e: HistoryItemType) => {
this.setBackAndSetForwardHandle(e)
})
loadingFinish()
return
}
this.setBackAndSetForwardHandle(targetData)
loadingFinish()
} catch(value) {
loadingError()
}
},
// * 前进
setForward() {
try {
loadingStart()
console.log('前进');
const targetData = chartHistoryStoreStore.forwardAction()
if (!targetData) {
loadingFinish()
return
}
if (Array.isArray(targetData)) {
targetData.forEach((e: HistoryItemType) => {
this.setBackAndSetForwardHandle(e, true)
})
loadingFinish()
return
}
this.setBackAndSetForwardHandle(targetData, true)
loadingFinish()
} catch(value) {
loadingError()
}
},
// ----------------
// * 设置鼠标位置 // * 设置鼠标位置
setMousePosition(x: number, y: number): void { setMousePosition(x: number, y: number): void {
this.mousePosition.x = x this.mousePosition.x = x

View File

@ -11,6 +11,10 @@ export enum HistoryActionTypeEnum {
UPDATE = 'update', UPDATE = 'update',
// 移动 // 移动
MOVE = 'move', MOVE = 'move',
// 复制
COPY = 'copy',
// 剪切
CUT = 'cut',
// 粘贴 // 粘贴
PASTE = 'paste', PASTE = 'paste',
// 改变层级 // 改变层级

View File

@ -2,6 +2,7 @@ import { defineStore } from 'pinia'
import { CreateComponentType } from '@/packages/index.d' import { CreateComponentType } from '@/packages/index.d'
import { ChartLayoutType } from '@/store/modules/chartLayoutStore/chartLayoutStore.d' import { ChartLayoutType } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore' import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
import { loadingStart, loadingFinish, loadingError } from '@/utils'
import { import {
HistoryStackEnum, HistoryStackEnum,
HistoryStackItemEnum, HistoryStackItemEnum,
@ -47,9 +48,13 @@ export const useChartHistoryStoreStore = defineStore({
this.createStackItem(canvas, HistoryActionTypeEnum.ADD, HistoryTargetTypeEnum.CANVAS) this.createStackItem(canvas, HistoryActionTypeEnum.ADD, HistoryTargetTypeEnum.CANVAS)
}, },
// * 推入记录栈 // * 推入记录栈
pushBackStackItem(item: HistoryItemType | Array<HistoryItemType>): void { pushBackStackItem(item: HistoryItemType | Array<HistoryItemType>, notClear = false): void {
if (item instanceof Array) this.backStack = [...this.backStack, ...item] if (item instanceof Array) this.backStack = [...this.backStack, ...item]
else this.backStack.push(item) else this.backStack.push(item)
// 新动作需清空前进栈
if(notClear) return
this.clearForwardStack()
}, },
// * 推入前进栈 // * 推入前进栈
pushForwardStack(item: HistoryItemType | Array<HistoryItemType>): void { pushForwardStack(item: HistoryItemType | Array<HistoryItemType>): void {
@ -77,6 +82,51 @@ export const useChartHistoryStoreStore = defineStore({
return this.forwardStack.pop() return this.forwardStack.pop()
} }
}, },
// * 清空前进栈
clearForwardStack() {
this.forwardStack = []
},
// * 撤回
backAction() {
try {
loadingStart()
// 排除画布初始化
if (this.getBackStack.length > 1) {
const targetData = this.popBackStackItem()
if (!targetData) {
loadingFinish()
return
}
// 移除记录到前进堆
this.pushForwardStack(targetData)
loadingFinish()
return targetData
}
loadingFinish()
} catch (error) {
loadingError()
}
},
// * 前进
forwardAction() {
try {
loadingStart()
if (this.getForwardStack.length) {
const targetData = this.popForwardStack()
if (!targetData) {
loadingFinish()
return
}
// 放入后退栈
this.pushBackStackItem(targetData, true)
loadingFinish()
return targetData
}
loadingFinish()
} catch (error) {
loadingError()
}
},
// * 新增组件记录 // * 新增组件记录
createAddHistory(item: CreateComponentType) { createAddHistory(item: CreateComponentType) {
this.createStackItem(item, HistoryActionTypeEnum.ADD, HistoryTargetTypeEnum.CHART) this.createStackItem(item, HistoryActionTypeEnum.ADD, HistoryTargetTypeEnum.CHART)

View File

@ -1,26 +1,49 @@
import { isMac, addEventListener, removeEventListener } from '@/utils' import { isMac, addEventListener, removeEventListener } from '@/utils'
import { getChartEditStore } from './useStore.hook' import { getChartEditStore } from './useStore.hook'
import { MenuEnum } from '@/views/chart/hooks/useContextMenu.hook'
const chartEditStore = getChartEditStore() const chartEditStore = getChartEditStore()
export const keyboardValue = {
[MenuEnum.COPY]: 'c',
[MenuEnum.CUT]: 'x',
[MenuEnum.PARSE]: 'v',
[MenuEnum.DELETE]: 'delete',
back: 'z',
}
const KeyboardHandle = (e: KeyboardEvent) => { const KeyboardHandle = (e: KeyboardEvent) => {
const ismacRes = isMac() const ismacRes = isMac()
// 暂不支持mac因为我没有😤👻 // 暂不支持mac因为我没有😤👻
if(ismacRes) return if (ismacRes) return
const key = e.key.toLowerCase() const key = e.key.toLowerCase()
if (key === 'delete') { // 删除
if (key === keyboardValue.delete) {
chartEditStore.removeComponentList() chartEditStore.removeComponentList()
return return
} }
// 前进
if (e.ctrlKey && e.shiftKey && key == keyboardValue.back) {
chartEditStore.setForward()
return
}
if (e.ctrlKey) { if (e.ctrlKey) {
switch (key) { switch (key) {
// 复制 // 复制
case 'c': chartEditStore.setCopy() case keyboardValue.copy: chartEditStore.setCopy()
break;
// 剪切
case keyboardValue.cut: chartEditStore.setCut()
break; break;
// 粘贴 // 粘贴
case 'v': chartEditStore.setParse() case keyboardValue.parse: chartEditStore.setParse()
break;
// 撤回
case keyboardValue.back: chartEditStore.setBack()
break; break;
} }
e.preventDefault() e.preventDefault()

View File

@ -4,14 +4,15 @@ import { CreateComponentType } from '@/packages/index.d'
import { renderIcon, loadingError } from '@/utils' import { renderIcon, loadingError } from '@/utils'
import { icon } from '@/plugins' import { icon } from '@/plugins'
const { CopyIcon, ClipboardOutlineIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } = icon.ionicons5 const { CopyIcon, CutIcon, ClipboardOutlineIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } = icon.ionicons5
const { UpToTopIcon, DownToBottomIcon } = icon.carbon const { UpToTopIcon, DownToBottomIcon } = icon.carbon
const chartEditStore = useChartEditStoreStore() const chartEditStore = useChartEditStoreStore()
enum MenuEnum { export enum MenuEnum {
DELETE = 'delete', DELETE = 'delete',
COPY = 'copy', COPY = 'copy',
CUT = 'cut',
PARSE = 'parse', PARSE = 'parse',
TOP = 'top', TOP = 'top',
BOTTOM = 'bottom', BOTTOM = 'bottom',
@ -35,6 +36,12 @@ const defaultOptions: MenuOptionsItemType[] = [
icon: renderIcon(CopyIcon), icon: renderIcon(CopyIcon),
fnHandle: chartEditStore.setCopy fnHandle: chartEditStore.setCopy
}, },
{
label: '剪切',
key: MenuEnum.CUT,
icon: renderIcon(CutIcon),
fnHandle: chartEditStore.setCut
},
{ {
label: '粘贴', label: '粘贴',
key: MenuEnum.PARSE, key: MenuEnum.PARSE,