Skip to content

Element component render 问题 #746

@pittle

Description

@pittle

function EnergyConservation(props) {
const { state, connectDrag, setProps, getNodeProps, projId } = useComponent(props)
const otherStyle = extractOtherStyles(state);
const [form] = Form.useForm()
const [timeGranularityOptions, setTimeGranularityOptions] = useState<any[]>([]);

const {
downloadIcon,
} = state

console.log("state====>", state)

const onSearch = (values) => {
console.log('onSearch', values)
// 处理查询逻辑
// 可以在这里调用接口获取数据
}

const aggregateOptions = useMemo(() => {
return [
{ value: 'avg', label: '平均值' },
{ value: 'sum', label: '总和' },
{ value: 'max', label: '最大值' },
{ value: 'min', label: '最小值' },
]
}, [])

const tabsProps = useMemo(() => {
return { form, onSearch, timeGranularityOptions, aggregateOptions, downloadIcon }
}, [form, onSearch, timeGranularityOptions, aggregateOptions, downloadIcon])

const onChange = (key: string) => {
console.log(key)
}

const items = [
{
id: '1',
label: '时间对比分析',
key: '1',
children: <TimerAnalysis {...tabsProps} style={{ padding: '0px 25px' }} />,
},
{
id: '2',
label: '参数相关性分析',
key: '2',
children: <ParameterAnalysis {...tabsProps} style={{ padding: '0px 25px' }} />,
},
]
return (
<Drag connectDrag={connectDrag} style={{ ...otherStyle }}>
{/* */}


);
}

EnergyConservation.craft = craft(meta, {})

export default memo(EnergyConservation)

这是我写的一个craft组件,里面用了craft自带的Element 和我自己实现的一个craft组件Text,我这样写能够实现Text组件的展示和渲染,使用query.serialize()能够拿到json如下所示
{"ROOT":{"type":{"resolvedName":"Page"},"isCanvas":true,"props":{"title":"页面标题","showTitle":true,"theme":{"algorithm":"darkBlue","token":{"colorPrimary":"#1677ff"}},"style":{"position":"relative","width":"100%","height":"100vh","widthType":"relative","heightType":"viewport","fontSize":18,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all","background":"url(/assets/images/bg-light.webp) 50% 50% / 100% 100% no-repeat,linear-gradient(rgba(36, 66, 105, 1), rgba(36, 66, 105, 1))","padding":0,"borderRadius":0,"backgroundList":[{"id":"EnzfEc_Z30","type":"image","key":"EnzfEc_Z30","value":{"backgroundImage":"9amN2wcWRb17XbWX_diPRu","backgroundRepeat":"no-repeat","backgroundSize":"100% 100%","backgroundPosition":"50% 50%"},"disabled":false},{"id":"PZF0nxG2iR","key":"PZF0nxG2iR","disabled":false,"value":"rgba(36, 66, 105, 1)"}],"heightUnit":"vh","overflow":"hidden"},"global":{},"points":{"ELEC_CH_GROUP":0,"T_OUTDOOR":0,"TW_OUTDOOR":0,"RH_OUTDOOR":0}},"displayName":"Page","custom":{"componentName":"Page","title":"页面","category":"布局","screenshot":null,"isElement":true,"props":[{"name":"title","title":{"label":"标题","tip":"title | 页面标题,当页面在弹窗里展示时,会作为弹窗的标题"},"defaultValue":"页面标题","propType":"string"},{"name":"showTitle","title":{"label":"展示标题","tip":"showTitle | 当页面在弹窗里展示时,是否展示标题"},"defaultValue":true,"propType":"boolean"},{"name":"theme","title":{"label":"主题配置","tip":"theme | 页面主题"},"defaultValue":{"algorithm":"defaultAlgorithm","token":{"colorPrimary":"#1677ff"}},"setter":{"component":"ThemeSetter","props":[{"name":"algorithm","title":{"label":"主题配置","tip":"theme | 页面主题"},"propType":"select","defaultValue":"defaultAlgorithm","values":{"defaultAlgorithm":"白色","darkAlgorithm":"黑色","darkBlue":"蓝色","deepBlue":"深蓝","darkScience":"科技风"}},{"name":"token","title":{"label":"页面主题","tip":"token | 用于设置页面主题"},"propType":"object","defaultValue":{"colorPrimary":"#1677ff","borderRadius":6},"props":[{"name":"colorPrimary","title":{"label":"主色","tip":"colorPrimary | 设置页面的主题色"},"propType":"color","defaultValue":"#1677ff"},{"name":"borderRadius","title":{"label":"圆角","tip":"borderRadius | 设置页面组件的圆角"},"propType":"number","defaultValue":6}]}]}}],"style":{"name":"style","title":{"label":"样式","tip":"style | 样式"},"propType":"object","setter":{"component":"StyleSetter","props":{"open":true,"values":{"position":"relative","width":"100%","height":"auto","widthType":"relative","heightType":"fit-content","fontFamily":"Microsoft YaHei","fontSize":14,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all"}}}},"isGroup":false,"isDevice":false},"hidden":false,"nodes":["e8K4Catze1"],"linkedNodes":{}},"e8K4Catze1":{"type":{"resolvedName":"EnergyConservation"},"isCanvas":true,"props":{"displayName":"EnergyConservation","gap":0,"style":{"position":"relative","width":"100%","height":"100%","widthType":"relative","heightType":"relative","fontSize":18,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all","padding":0,"heightUnit":"%","display":"flex","flexDirection":"column","rowGap":0,"columnGap":0}},"displayName":"EnergyConservation","custom":{},"parent":"ROOT","hidden":false,"nodes":[],"linkedNodes":{"zngnlBJz2SHMJ8XVKqhtM":"6vqnbFacgJ"}},"6vqnbFacgJ":{"type":{"resolvedName":"Text"},"isCanvas":true,"props":{"value":123,"defaultValue":"","showEmptyText":false,"thousandth":false,"status":[],"events":{},"style":{"position":"relative","width":"100%","height":"auto","widthType":"relative","heightType":"fit-content","fontFamily":"Microsoft YaHei","fontSize":14,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all","show":["size","font","background","border","spacing","css"]},"gap":10},"displayName":"Typography.Text","custom":{"componentName":"Typography.Text","category":"数据展示","title":"文本","screenshot":"/@fs/Users/pittle/yyds.dpsz/self/deepx.frontend/packages/materials/components/base/general/typography.text/screenshots/Text_thumbnail.png","isElement":false,"props":[{"name":"value","title":{"label":"文本内容","tip":"value | 文本内容"},"defaultValue":"文本内容","propType":"string"},{"name":"defaultValue","title":{"label":"默认值","tip":"defaultValue | 当文本内容为空时,显示的默认值"},"defaultValue":"","hiddenBind":true,"propType":"string"},{"name":"showEmptyText","title":{"label":"空状态","tip":"showEmptyText | 是否展示空状态 \"-\" "},"propType":"boolean","hiddenBind":true,"defaultValue":false},{"name":"thousandth","title":{"label":"千分位","tip":"thousandth | 数字时是否格式化为千分位"},"propType":"boolean","hiddenBind":true,"defaultValue":false},{"name":"status","title":{"label":"状态","tip":"status | 用于绑定点表状态"},"propType":"array","defaultValue":[],"props":[{"name":"label","title":{"label":"标签","tip":"label | 选项的标签"},"propType":"string","defaultValue":""},{"name":"value","title":{"label":"值","tip":"value | 选项的值"},"propType":"string","defaultValue":""},{"name":"expression","title":{"label":"表达式","tip":"expression | 选项的值"},"propType":"string","defaultValue":""},{"name":"color","title":{"label":"文本颜色","tip":"color | 选择文字颜色"},"propType":"color","defaultValue":""},{"name":"backgroundColor","title":{"label":"背景颜色","tip":"color | 选择颜色"},"propType":"color","defaultValue":""},{"name":"title","title":{"label":"默认值","tip":"title | 提示信息"},"defaultValue":"","hiddenBind":true,"propType":"string"}]}],"style":{"name":"style","title":{"label":"样式","tip":"style | 样式"},"propType":"object","setter":{"component":"StyleSetter","props":{"open":true,"values":{"position":"relative","width":"100%","height":"auto","widthType":"relative","heightType":"fit-content","fontFamily":"Microsoft YaHei","fontSize":14,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all","show":["size","font","background","border","spacing","css"]}}}},"events":{"name":"events","title":{"label":"事件","tip":"events | 用于绑定事件"},"setter":{"component":"EventSetter","props":[{"name":"onClick","title":{"label":"点击","tip":"onClick | 点击"},"fieldProps":{"labelWidth":80},"props":{"type":"event","placeholder":"点击事件"}}]}},"isGroup":false,"isDevice":false},"parent":"e8K4Catze1","hidden":false,"nodes":[],"linkedNodes":{}}}

但是当我修改了这个可编辑的Text属性编辑了Text 输入123123123 以后,我发现,json如下
{"ROOT":{"type":{"resolvedName":"Page"},"isCanvas":true,"props":{"title":"页面标题","showTitle":true,"theme":{"algorithm":"darkBlue","token":{"colorPrimary":"#1677ff"}},"style":{"position":"relative","width":"100%","height":"100vh","widthType":"relative","heightType":"viewport","fontSize":18,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all","background":"url(/assets/images/bg-light.webp) 50% 50% / 100% 100% no-repeat,linear-gradient(rgba(36, 66, 105, 1), rgba(36, 66, 105, 1))","padding":0,"borderRadius":0,"backgroundList":[{"id":"EnzfEc_Z30","type":"image","key":"EnzfEc_Z30","value":{"backgroundImage":"9amN2wcWRb17XbWX_diPRu","backgroundRepeat":"no-repeat","backgroundSize":"100% 100%","backgroundPosition":"50% 50%"},"disabled":false},{"id":"PZF0nxG2iR","key":"PZF0nxG2iR","disabled":false,"value":"rgba(36, 66, 105, 1)"}],"heightUnit":"vh","overflow":"hidden"},"global":{},"points":{"ELEC_CH_GROUP":0,"T_OUTDOOR":0,"TW_OUTDOOR":0,"RH_OUTDOOR":0}},"displayName":"Page","custom":{"componentName":"Page","title":"页面","category":"布局","screenshot":null,"isElement":true,"props":[{"name":"title","title":{"label":"标题","tip":"title | 页面标题,当页面在弹窗里展示时,会作为弹窗的标题"},"defaultValue":"页面标题","propType":"string"},{"name":"showTitle","title":{"label":"展示标题","tip":"showTitle | 当页面在弹窗里展示时,是否展示标题"},"defaultValue":true,"propType":"boolean"},{"name":"theme","title":{"label":"主题配置","tip":"theme | 页面主题"},"defaultValue":{"algorithm":"defaultAlgorithm","token":{"colorPrimary":"#1677ff"}},"setter":{"component":"ThemeSetter","props":[{"name":"algorithm","title":{"label":"主题配置","tip":"theme | 页面主题"},"propType":"select","defaultValue":"defaultAlgorithm","values":{"defaultAlgorithm":"白色","darkAlgorithm":"黑色","darkBlue":"蓝色","deepBlue":"深蓝","darkScience":"科技风"}},{"name":"token","title":{"label":"页面主题","tip":"token | 用于设置页面主题"},"propType":"object","defaultValue":{"colorPrimary":"#1677ff","borderRadius":6},"props":[{"name":"colorPrimary","title":{"label":"主色","tip":"colorPrimary | 设置页面的主题色"},"propType":"color","defaultValue":"#1677ff"},{"name":"borderRadius","title":{"label":"圆角","tip":"borderRadius | 设置页面组件的圆角"},"propType":"number","defaultValue":6}]}]}}],"style":{"name":"style","title":{"label":"样式","tip":"style | 样式"},"propType":"object","setter":{"component":"StyleSetter","props":{"open":true,"values":{"position":"relative","width":"100%","height":"auto","widthType":"relative","heightType":"fit-content","fontFamily":"Microsoft YaHei","fontSize":14,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all"}}}},"isGroup":false,"isDevice":false},"hidden":false,"nodes":["e8K4Catze1"],"linkedNodes":{}},"e8K4Catze1":{"type":{"resolvedName":"EnergyConservation"},"isCanvas":true,"props":{"displayName":"EnergyConservation","gap":0,"style":{"position":"relative","width":"100%","height":"100%","widthType":"relative","heightType":"relative","fontSize":18,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all","padding":0,"heightUnit":"%","display":"flex","flexDirection":"column","rowGap":0,"columnGap":0}},"displayName":"EnergyConservation","custom":{},"parent":"ROOT","hidden":false,"nodes":[],"linkedNodes":{"zngnlBJz2SHMJ8XVKqhtM":"6vqnbFacgJ"}},"6vqnbFacgJ":{"type":{"resolvedName":"Text"},"isCanvas":true,"props":{"value":"123123123","defaultValue":"","showEmptyText":false,"thousandth":false,"status":[],"events":{},"style":{"position":"relative","width":"100%","height":"auto","widthType":"relative","heightType":"fit-content","fontFamily":"Microsoft YaHei","fontSize":14,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all","show":["size","font","background","border","spacing","css"]},"gap":10},"displayName":"Typography.Text","custom":{"componentName":"Typography.Text","category":"数据展示","title":"文本","screenshot":"/@fs/Users/pittle/yyds.dpsz/self/deepx.frontend/packages/materials/components/base/general/typography.text/screenshots/Text_thumbnail.png","isElement":false,"props":[{"name":"value","title":{"label":"文本内容","tip":"value | 文本内容"},"defaultValue":"文本内容","propType":"string"},{"name":"defaultValue","title":{"label":"默认值","tip":"defaultValue | 当文本内容为空时,显示的默认值"},"defaultValue":"","hiddenBind":true,"propType":"string"},{"name":"showEmptyText","title":{"label":"空状态","tip":"showEmptyText | 是否展示空状态 \"-\" "},"propType":"boolean","hiddenBind":true,"defaultValue":false},{"name":"thousandth","title":{"label":"千分位","tip":"thousandth | 数字时是否格式化为千分位"},"propType":"boolean","hiddenBind":true,"defaultValue":false},{"name":"status","title":{"label":"状态","tip":"status | 用于绑定点表状态"},"propType":"array","defaultValue":[],"props":[{"name":"label","title":{"label":"标签","tip":"label | 选项的标签"},"propType":"string","defaultValue":""},{"name":"value","title":{"label":"值","tip":"value | 选项的值"},"propType":"string","defaultValue":""},{"name":"expression","title":{"label":"表达式","tip":"expression | 选项的值"},"propType":"string","defaultValue":""},{"name":"color","title":{"label":"文本颜色","tip":"color | 选择文字颜色"},"propType":"color","defaultValue":""},{"name":"backgroundColor","title":{"label":"背景颜色","tip":"color | 选择颜色"},"propType":"color","defaultValue":""},{"name":"title","title":{"label":"默认值","tip":"title | 提示信息"},"defaultValue":"","hiddenBind":true,"propType":"string"}]}],"style":{"name":"style","title":{"label":"样式","tip":"style | 样式"},"propType":"object","setter":{"component":"StyleSetter","props":{"open":true,"values":{"position":"relative","width":"100%","height":"auto","widthType":"relative","heightType":"fit-content","fontFamily":"Microsoft YaHei","fontSize":14,"fontWeight":400,"lineHeight":1.5,"textAlign":"left","spacing":0,"paddingSide":"all","marginSide":"all","show":["size","font","background","border","spacing","css"]}}}},"events":{"name":"events","title":{"label":"事件","tip":"events | 用于绑定事件"},"setter":{"component":"EventSetter","props":[{"name":"onClick","title":{"label":"点击","tip":"onClick | 点击"},"fieldProps":{"labelWidth":80},"props":{"type":"event","placeholder":"点击事件"}}]}},"isGroup":false,"isDevice":false},"parent":"e8K4Catze1","hidden":false,"nodes":[],"linkedNodes":{}}}

我把修改后的这个json给后端,希望他给我存起来,他确实是可以存起来,
等到我下来获取过来json的时候,我发现,直接渲染成123了, 我希望还是能渲染出最新的数据(我修改过后的网页的数据)

我们之前的问题在于:在EnergyConservation组件中,我们使用了<Element id={nanoid()} ...>来创建Text组件。每次渲染时,nanoid()都会生成一个新的ID。这样会导致在反序列化(从JSON恢复)时,由于ID变化,craft.js无法正确匹配节点,从而无法恢复之前保存的状态。
解决方案:

  1. 在序列化(保存)时,每个节点都有一个唯一的ID,这个ID在组件的整个生命周期中应该是稳定的。
  2. 在反序列化(加载)时,我们需要使用相同的ID来恢复节点。
    因此,我们不能在每次渲染时都生成新的ID,而应该确保每个节点在创建时生成一个ID,并且在后续的渲染中保持不变。
    如何做?
    使用craft.js的useNode钩子来管理节点的ID。但是,在EnergyConservation组件中,我们目前是作为容器组件,它内部使用Element来创建Text组件。我们需要确保这个Text组件的ID在组件的整个生命周期中保持不变。
    修改EnergyConservation组件:
  • 不再使用nanoid()动态生成ID,而是使用一个固定的ID(但注意,同一个容器内多个节点需要不同ID,所以固定ID不适用于多个节点)。
  • 或者,我们可以利用craft.js的节点管理机制,让craft.js来管理ID。
    实际上,在反序列化时,JSON中已经包含了节点的ID。所以,在加载时,我们不需要重新生成ID,而是使用JSON中保存的ID。
    但是,在第一次创建(没有保存过的状态)时,我们需要生成一个ID,并且在后续的渲染中保持这个ID不变。
    我们可以使用useState来保存这个ID:
const [textId] = useState(() => nanoid());

这样,在组件的整个生命周期中,这个ID就是固定的。
修改后的代码:

function EnergyConservation(props) {
  // ...其他代码不变
  // 使用useState来固定Text组件的ID
  const [textId] = useState(() => nanoid());
  return (
    <Drag connectDrag={connectDrag} style={{ ...otherStyle }}>
      <Element id={textId} is={Text} canvas gap={10} />
    </Drag>
  );
}

但是,请注意:这样修改后,每个EnergyConservation实例中的Text组件都会有一个固定的ID。但是,如果同一个EnergyConservation组件内有多个Text组件,我们需要为每个Text组件生成一个唯一的固定ID。我们可以使用一个数组来管理多个子节点。
不过,目前只有一个Text组件,所以这样修改即可。
但是,还有一个问题:在反序列化时,我们并不希望使用这个新生成的ID,因为JSON中已经保存了节点的ID。所以,我们需要在反序列化时使用JSON中的ID。
实际上,craft.js在反序列化时会忽略我们在代码中写的id,而是使用JSON中的节点ID。因此,我们只需要保证在创建新节点(而不是反序列化)时生成一个ID即可。
但是,我们如何区分是创建新节点还是反序列化呢?实际上,我们不需要区分。因为:

  • 在反序列化时,整个节点树是由JSON构建的,我们代码中渲染的节点会被忽略(因为JSON中已经包含了节点树结构)。
  • 只有在第一次创建时,我们才需要生成ID,并且这个ID会被保存到序列化的JSON中。
    所以,使用useState来生成固定ID是可行的。
    但是,还有一个潜在的问题:如果同一个EnergyConservation组件被多次使用(在同一个页面中),那么每个实例都会生成一个ID,这些ID可能会冲突吗?不会,因为nanoid()生成的是全局唯一的ID。
    因此,修改后的EnergyConservation组件如下:
function EnergyConservation(props) {
  const { state, connectDrag, setProps, getNodeProps, projId } = useComponent(props);
  const otherStyle = extractOtherStyles(state);
  const [form] = Form.useForm();
  const [timeGranularityOptions, setTimeGranularityOptions] = useState<any[]>([]);
  const {
    downloadIcon,
  } = state;
  // ...其他代码不变
  // 为Text组件生成一个固定的ID,在整个组件生命周期中不变
  const [textId] = useState(() => nanoid());
  return (
    <Drag connectDrag={connectDrag} style={{ ...otherStyle }}>
      <Element id={textId} is={Text} canvas gap={10} />
    </Drag>
  );
}

这样,在第一次创建时,Text节点会有一个固定的ID(textId),当用户修改了Text的内容后,序列化时会保存这个ID以及它的属性(包括value)。当从后端获取JSON后,通过actions.deserialize(savedJSON)恢复整个节点树,此时Text节点的ID与序列化时一致,因此可以正确恢复状态。
但是,请注意:在反序列化时,EnergyConservation组件内部的这个useState生成的textId并不会被使用,因为craft.js会使用JSON中的节点树结构来渲染,包括节点的ID。所以,在反序列化后,这个textId实际上并没有被使用,所以不用担心。
总结:

  • 在组件的第一次渲染中,我们为子节点生成一个固定ID,并用于创建节点。
  • 当用户修改子节点属性后,序列化时会保存这个ID及其属性。
  • 反序列化时,craft.js会根据JSON中的节点ID重建节点树,此时我们生成的固定ID不会被使用(因为节点树已经由JSON决定了)。
    因此,这样修改后,应该能够正确保存和恢复Text组件的状态。
    但是,还有一个问题:如果我们在同一个EnergyConservation组件内添加多个Text组件怎么办?我们需要为每个子节点生成固定ID。这时,我们可以使用一个数组来存储多个ID,或者使用一个对象来为每个子节点位置分配一个固定ID。不过,这已经超出当前问题的范围。
    针对当前问题(只有一个Text组件),我们这样修改即可。
    另外,请确保Text组件的实现能够从节点属性中获取值(如之前所述),即使用useNode来获取节点当前的props。
    最后,注意:在反序列化后,Text组件的值应该从节点属性中获取,而不是从父组件传递。因此,在Text组件中,我们这样实现:
import { useNode } from '@craftjs/core';
const Text = (props) => {
  const { nodeProps } = useNode((node) => ({
    nodeProps: node.data.props
  }));
  // 显示的值:使用节点属性中的value,如果没有则使用传入的props.value(但通常节点属性优先)
  const value = nodeProps.value || props.value || props.defaultValue;
  return (
    <div>
      {value}
    </div>
  );
};
// 或者更准确地说,我们可以完全依赖节点属性,因为craft.js会注入节点属性
const Text = ({ craft }) => {
  // 注意:craft.js会将节点属性注入到组件的craft prop中,但更推荐使用useNode
  const { 
    connectors: { connect, drag },
    props: nodeProps
  } = useNode();
  return (
    <div ref={ref => connect(drag(ref))}>
      {nodeProps.value || nodeProps.defaultValue}
    </div>
  );
};

因此,我们修改Text组件,使其完全从useNode中获取属性,这样在反序列化后,它就能显示正确的值。
综上所述,请按照以下步骤修改:

  1. 修改EnergyConservation组件,为Text组件生成固定ID(使用useState和nanoid)。
  2. 修改Text组件,使用useNode钩子获取节点属性,并显示nodeProps.value
    这样,保存后再加载,就能正确显示修改后的文本了。

以上是AI回答,使用Element 写的组件保存以后 数据回显就有冲突了

import React,{ memo, useEffect } from 'react'
import { Element } from '@craftjs/core'
import { useState, useMemo } from 'react'
import { nanoid } from 'nanoid'
import { Button, DatePicker, Form, Input, message, Segmented, Select, Space, Tabs as AntTabs, Row, Col, Modal, InputNumber } from 'antd'
import { craft, extractOtherStyles } from '../../../_utils/utils'
import { useComponent } from '../../../useComponent'
import Container from '../../layout/container';
import meta from './meta'
import { CustomNode, Drag, Icon } from '../../../common'
import dayjs from 'dayjs'
import Cascader from '../report.list/_components/Cascader'
import Flex from '../../../base/layout/flex'
import Text from '../../../base/general/typography.text'
import StateText from '../../../base/general/state.text'
import Line from '../../../charts/line'
import Bar from '../../../charts/bar'
import Table from '../../../base/display/table'
import Divider from '../../../base/layout/divider'
import {
BarChartOutlined,
LineChartOutlined,
TableOutlined
} from '@ant-design/icons';
import css from './styles.module.less'
import display from '../../general/typography.text/display'
import { r } from './utils'
import { set } from 'lodash-es'
import { use } from 'echarts'

const { RangePicker } = DatePicker

// 选项卡数据源
export const allIconOptions = [
{ value: 'table', icon: },
{ value: 'line', icon: },
// { value: 'bar', icon: }
];

const formatMap = {
time: 'HH', // 时
day: 'YYYY-MM-DD', // 日
week: 'YYYY-ww', // 周(注意 week 格式需要 weekOfYear 插件)
month: 'YYYY-MM', // 月
year: 'YYYY', // 年
}

let idCounter = 0
export const generateEnergyId = () => {
idCounter++
return EnergyConservation-${idCounter}
}

function EnergyConservation(props) {
const { state, connectDrag, setProps, getNodeProps, projId } = useComponent(props)
const otherStyle = extractOtherStyles(state);
const [form] = Form.useForm()
const [timeGranularityOptions, setTimeGranularityOptions] = useState<any[]>([
{ value: 'time', label: '时' },
{ value: 'day', label: '日' },
{ value: 'week', label: '周' },
{ value: 'month', label: '月' },
{ value: 'year', label: '年' },
])
const [resp, setResp] = useState(r)

const {
downloadIcon,
} = state

const onSearch = (values) => {
const { TimeRangeType, BaselineTimePoint, OptimizedTimePoint, ...rest } = values

const payload =  {
  ...rest,
  TimeRangeType,
  BaselineTimePoint: dayjs(BaselineTimePoint).format(formatMap[TimeRangeType]),
  OptimizedTimePoint: dayjs(OptimizedTimePoint).format(formatMap[TimeRangeType]),
}


// 处理查询逻辑
// 可以在这里调用接口获取数据

}

const aggregateOptions = useMemo(() => {
return [
{ value: 'avg', label: '平均值' },
{ value: 'sum', label: '总和' },
{ value: 'max', label: '最大值' },
{ value: 'min', label: '最小值' },
]
}, [])

const tabsProps = useMemo(() => {
return { form, onSearch, timeGranularityOptions, aggregateOptions, downloadIcon }
}, [form, onSearch, timeGranularityOptions, aggregateOptions, downloadIcon])

const onChange = (key: string) => {
console.log(key)
}

const items = useMemo(() => {
return [
{
id: '1',
label: '时间对比分析',
key: '1',
children: <TimerAnalysis {...tabsProps} style={{ padding: '0px 25px' }} resp={resp} />,
},
{
id: '2',
label: '参数相关性分析',
key: '2',
children: <ParameterAnalysis {...tabsProps} style={{ padding: '0px 25px' }} resp={resp} />,
},
]
}, [resp])

useEffect(() => {

}, [])

return (
<Drag connectDrag={connectDrag} style={{ ...otherStyle }}>
{/* */}
<Element
id={"pittle"}
// id="pittle"
is={Text}
canvas
value="基准平均值"
defaultValue=""
showEmptyText={false}
thousandth={false}
status={[]}
events={{}}
style={{
position: 'relative',
width: '100px',
height: 'auto',
widthType: 'fixed',
heightType: 'fit-content',
fontFamily: 'Microsoft YaHei',
fontSize: 14,
fontWeight: 400,
lineHeight: 1.5,
textAlign: 'center',
spacing: 0,
paddingSide: 'all',
marginSide: 'all',
widthUnit: 'px',
}}
/>
<Element
id={"pittle2"}
// id="pittle1"
is={Text}
canvas
value="基准平均值"
defaultValue=""
showEmptyText={false}
thousandth={false}
status={[]}
events={{}}
style={{
position: 'relative',
width: '100px',
height: 'auto',
widthType: 'fixed',
heightType: 'fit-content',
fontFamily: 'Microsoft YaHei',
fontSize: 14,
fontWeight: 400,
lineHeight: 1.5,
textAlign: 'center',
spacing: 0,
paddingSide: 'all',
marginSide: 'all',
widthUnit: 'px',
}}
/>

)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions