import React, { useState, useMemo, useCallback, useEffect } from 'react'; import { Form, InputNumber, Tabs, Collapse, Row, Col, Input, Select, Checkbox, Tag, Button } from 'antd'; import AnimateComponent from './AnimateComponent'; import EventComponent from '../lineComponent/EventComponent'; import ReactComponent from './ReactComponent'; import HttpComponent from './HttpComponent'; import Tags from './DataComponent/tags'; import Device from './DataComponent/device'; import DeviceLineBar from './DataComponent/deviceLineBar'; import { attrPanel, lineBarChart } from '../topTools/dataComponent' import EventStatus from './CustomComponent/eventStatus'; import './index.css'; import { useForm } from 'antd/lib/form/Form'; import { Topology, Node } from '@topology/core'; import topTools from '../topTools'; import { update } from 'lodash'; import { canvas } from '../..'; const { Panel } = Collapse; const { TabPane } = Tabs; const { Option } = Select; const { TextArea } = Input; const CanvasProps = ({ data, onFormValueChange, onEventValueChange, onUpdateComponentProps, onUpdateHttpProps }) => { const { x, y, width, height } = data?.node?.rect || {}; const { rotate, visible, lineWidth, strokeStyle, dash, text, title, id, tags, fontColor, fontSize, fontFamily } = data?.node || {}; const myData = data?.node?.myData || null; // const { color, fontSize, fontFamily } = data?.node?.font || {}; let extraFields; // 用户自定义数据 try { extraFields = data?.node?.data ? JSON.stringify(data?.node?.data) : null; } catch { extraFields = null; } console.log('============== >><<', data?.node, data?.node.id) const [form] = useForm(); const [form2] = useForm(); const [form3] = useForm(); const [form4] = useForm(); const [myDataState, setMyDataState] = useState(myData); useEffect(() => { form.resetFields(); form2.resetFields(); form3.resetFields(); form4.resetFields(); setMyDataState(myData) }, [form, form2, form3, form4, data]) const handleFormFinish = useCallback((val, values) => { const payload = {x, y, width, height,rotate, visible, lineWidth, strokeStyle, dash, text, title, id, fontColor: fontColor || data?.node.fillStyle, fontSize, fontFamily, data: extraFields, myData}; console.log('values =======', values) console.log('payload ====', {...payload, ...values }) onFormValueChange({...payload, ...values }); }, [x, y, width, height, rotate, visible, lineWidth, strokeStyle, dash, text, title, id, fontColor, fontSize, fontFamily, myData, extraFields, onFormValueChange]) const createChildren = (values) => { switch (data.node.name) { case 'echarts': lineBarChart.handelSave(values, data.node); handleFormFinish(null, { myData: values }) break; case 'testImg': console.log('attrPanel ===', attrPanel) const nodeStatus = attrPanel.handelSave(values, data.node); console.log('nodeStatus ======= ', nodeStatus.attrCount) handleFormFinish(null, { height: nodeStatus.attrCount * 40 + 50, myData: values }) break; default: handleFormFinish(null, { myData: values }) break; } setMyDataState(values || null); // handleFormFinish(null, { myData: values }) } /** * 渲染位置和大小的表单 */ const renderForm = useMemo(() => { return <Form form={form2} initialValues={{ x, y, width, height, rotate, visible }} onValuesChange={ handleFormFinish }> <Row> <Col span={12}> <Form.Item label="X(px)" name='x'> <InputNumber /> </Form.Item> </Col> <Col span={12}> <Form.Item label="Y(px)" name="y"> <InputNumber /> </Form.Item> </Col> <Col span={12}> <Form.Item label="宽(px)" name="width"> <InputNumber /> </Form.Item> </Col> <Col span={12}> <Form.Item label="高(px)" name="height"> <InputNumber /> </Form.Item> </Col> <Col span={12}> <Form.Item label="角度(deg)" name="rotate"> <InputNumber /> </Form.Item> </Col> <Col span={12}> <Form.Item label="是否显示" name="visible" valuePropName="checked"> <Checkbox /> </Form.Item> </Col> <Col span={12}> <Button size='small' onClick={ () => { canvas.top(data?.node) canvas.render(); }}>置顶</Button> <Button size='small' onClick={ () => { canvas.bottom(data?.node) canvas.render(); }} style={{ marginLeft: 10 }}>置底</Button> </Col> </Row> </Form> }, [x, y, width, height, rotate, handleFormFinish, form2]); /** * 渲染样式的表单 */ const renderStyleForm = useMemo(() => { return <Form form={form3} initialValues={{ strokeStyle, dash, lineWidth }} onValuesChange={ handleFormFinish }> <Row> <Col span={24}> <Form.Item label="线条颜色" name='strokeStyle'> <Input type="color" /> </Form.Item> </Col> <Col span={24}> <Form.Item label="线条样式" name='dash'> <Select style={{ width: '95%' }}> <Option value={0}>_________</Option> <Option value={1}>---------</Option> <Option value={2}>_ _ _ _ _</Option> <Option value={3}>- . - . - .</Option> </Select> </Form.Item> </Col> <Col span={24}> <Form.Item label="线条宽度" name='lineWidth'> <InputNumber style={{ width: '100%' }} /> </Form.Item> </Col> </Row> </Form> }, [lineWidth, strokeStyle, dash, handleFormFinish, form3]); /** * 渲染字体的表单 */ const renderFontForm = useMemo(() => { return <Form form={form4} initialValues={{ fontColor, fontFamily, fontSize, text, title }} onValuesChange={ handleFormFinish }> <Col span={24}> <Form.Item label="字体颜色" name='fontColor'> <Input type="color" /> </Form.Item> </Col> <Col span={24}> <Form.Item label="字体类型" name='fontFamily'> <Select> <Select.Option value='Microsoft YaHei'>微软雅黑</Select.Option> <Select.Option value='SimSun'>宋体</Select.Option> <Select.Option value='SimHei'>黑体</Select.Option> <Select.Option value='Times New Roman'>Times New Roman</Select.Option> <Select.Option value='Arial'>Arial</Select.Option> <Select.Option value='Impact'>Impact</Select.Option> </Select> </Form.Item> </Col> <Col span={24} offset={1}> <Form.Item label="字体大小" name='fontSize'> <InputNumber /> </Form.Item> </Col> <Col span={24}> <Form.Item label="标题" name='title'> <TextArea /> </Form.Item> <Form.Item label="内容" name='text'> <TextArea /> </Form.Item> </Col> </Form> }, [fontColor, fontFamily, fontSize, text, title, handleFormFinish, form4]) /** * 渲染元素本身数据 */ const renderDataForm = useMemo(() => { const formLayout = { labelCol: { span: 6 }, wrapperCol: { span: 18 }, }; const formItemLayout = { labelCol: { span: 24 }, wrapperCol: { span: 24 }, }; return <><Form form={form} {...formLayout}> <Col> <Form.Item label="ID"> <span className="ant-form-text"><Tag color="#f50">{id}</Tag></span> </Form.Item> <Form.Item label="标签" extra='多个标签用,号分隔'> <Tags onChange={(values) => handleFormFinish(null, { tags: values })} value={tags} /> </Form.Item> { (data?.node?.name) && <Form.Item label="关联设备" {...formItemLayout}> { data.node.name === 'attrPanel' && <Device device={myDataState} onChange={ createChildren } /> } { data.node.name === 'testImg' && <Device device={myDataState} onChange={ createChildren } /> } { data.node.name === 'echarts' && <DeviceLineBar device={myDataState} onChange={ createChildren } /> } { data.node?.eventList && <EventStatus eventList={data.node?.eventList} device={myDataState} onChange={ createChildren } /> } </Form.Item> } </Col> </Form> </> }, [id, tags, handleFormFinish, form, myDataState]); const renderReactComponent = useMemo(() => { return ( <ReactComponent onUpdateComponentProps={(value) => onUpdateComponentProps(value)} data={data} /> ); }, [onUpdateComponentProps, data]); const renderHttpComponent = useMemo(() => { return <HttpComponent onUpdateHttpProps={(value) => { onUpdateHttpProps(value); }} data={data} />; }, [onUpdateHttpProps, data]); /** * 渲染元素额外数据 */ const renderExtraDataForm = useMemo(() => { return <Form form={form} initialValues={{ data: extraFields }} onValuesChange={ handleFormFinish }> <Col> <Form.Item label="自定义数据字段" name='data'> <TextArea rows={10} /> </Form.Item> </Col> </Form> }, [extraFields, handleFormFinish, form]) return ( <div className="rightArea"> <Tabs defaultActiveKey="1"> <TabPane tab="外观" key="1" style={{ margin: 0 }}> <Collapse defaultActiveKey={['1', '2', '3']}> <Panel header="位置和大小" key="1"> { renderForm } </Panel> <Panel header="文字" key="3" > { renderFontForm } </Panel> <Panel header="样式" key="2"> { renderStyleForm } </Panel> </Collapse> </TabPane> <TabPane tab="数据" key="2" style={{ margin: 0 }}> <Collapse defaultActiveKey={['1', '2']}> <Panel header="本身数据" key="1"> { renderDataForm } </Panel> <Panel style={{ display: 'none' }} header="自定义数据" key="2"> { renderExtraDataForm } </Panel> </Collapse> </TabPane> <TabPane tab="事件" key="3" style={{ margin: 0 }}> <EventComponent canvasData={data} onEventValueChange={onEventValueChange} /> </TabPane> <TabPane tab="动效" key="4" style={{ margin: 0 }}> <AnimateComponent canvasData={data} /> </TabPane> { data?.node?.data?.props && <TabPane tab="组件" key="5" style={{ margin: 0 }}> {renderReactComponent} </TabPane> } { data?.node?.data?.http && <TabPane tab="http" key="6" style={{ margin: 0 }}> {renderHttpComponent} </TabPane> } {/* <TabPane tab="结构" key="5" style={{ margin: 0 }}> 待开发... </TabPane> */} </Tabs> </div> ); }; export default (CanvasProps);