projectstorm / react-diagrams

a super simple, no-nonsense diagramming library written in react that just works
https://projectstorm.cloud/react-diagrams
MIT License
8.46k stars 1.16k forks source link

Redrawn node with text field, engine.repaintCanvas - didn't help me, maybe I'm doing something wrong #883

Closed aimustaev closed 2 years ago

aimustaev commented 2 years ago

Help please, @renato-bohler , @dylanvorster

engine.repaintCanvas(); - didn't help me, maybe I'm doing something wrong

Please tell me, I'm just starting to use this wonderful library. I want to make a node with a text field so that when I type in the text field, the option in the node changes, and the component is redrawn along with the nested text field

ConstNode.model.ts

export class ConstNodeModel extends NodeModel<
    NodeModelGenerics &
    ConstNodeModelGenerics &
    DefaultNodeModelGenerics> {
    constructor(props: ConstNodeModelOptions) {
        const {
            name,
            icon = 'gps_fixed',
            color = '#9e9e9e',
            tooltip = 'Тип узла: Константа',
            value = '',
        } = props;

        const options = {
            tooltip,
            name,
            color,
            icon,
            value,
        } as ConstNodeModelOptions;

        super({
            type: CONST_NODE.name,
            ...options,
        });
    }

    setValue(value: any) {
        this.options.value = value;
    }

    deserialize(event: DeserializeEvent<this>) {
        super.deserialize(event);
        this.options.tooltip = event.data.tooltip;
        this.options.name = event.data.name;
        this.options.color = event.data.color;
        this.options.icon = event.data.icon;
        this.options.value = event.data.value;
    }

    serialize() {
        const {
            name, icon, color, tooltip, value,
        } = this.options;
        return {
            ...super.serialize(),
            name,
            icon,
            color,
            tooltip,
            value,
        };
    }
}

ConstNode.widget.tsx

export const ConstNodeWidget: FC<ConstNodeWidgetProps> = memo(
    ({ node, engine }) => {
        const classes = useStyles();

        const ports = node.getPorts() as Record<string, CustomPortModel>;
        const { name, value } = node.getOptions();

        const getMetaProps = (flag: boolean) => {
            const listPorts = Object.values(ports);
            return listPorts.filter(
                (port) => port.getOptions().isInput === flag,
            );
        };

        const outputPort = getMetaProps(false);

        if (outputPort.length === 0) {
            return (
                <div className={classes.root}>
                    <HeaderNode name={name} node={node} />
                    Error
                </div>
            );
        }

        const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
            node.setValue(event.target.value);
            // engine.repaintCanvas();
        };

        return (
            <div className={classes.root}>
                <HeaderNode name={name} node={node} />

                <TextFieldNode
                    {...{ handleChange }}
                    label="Value"
                    value={value}
                />
                <div>
                    {getMetaProps(false).map((port) => (
                        <CustomPortWidget engine={engine} port={port} />
                    ))}
                </div>
            </div>
        );
    },
);

image