How to change Background in a responsive way

I want responsive background that user can chage.

There are one file input filed and diagram.

This is my code. I use gojs-react package.

import * as go from 'gojs';
import { ReactDiagram } from 'gojs-react';
import React, { useRef, useEffect, useState } from 'react';

const MyDiagram = () => {
    function initDiagram() {
        const $ = go.GraphObject.make;
        // set your license key here before creating the diagram: go.Diagram.licenseKey = "...";
        const diagram = $(go.Diagram, {
            'undoManager.isEnabled': true, // must be set to allow for model change listening
            // 'undoManager.maxHistoryLength': 0,  // uncomment disable undo/redo functionality
            'clickCreatingTool.archetypeNodeData': { text: 'new node', color: 'lightblue' },
            model: new go.GraphLinksModel({
                linkKeyProperty: 'key', // IMPORTANT! must be defined for merges and data sync when using GraphLinksModel
            }),
        });

        // define a simple Node template
        diagram.nodeTemplate = $(
            go.Node,
            'Auto', // the Shape will go around the TextBlock
            new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
            $(
                go.Shape,
                'RoundedRectangle',
                { name: 'SHAPE', fill: 'white', strokeWidth: 0 },
                // Shape.fill is bound to Node.data.color
                new go.Binding('fill', 'color')
            ),
            $(
                go.TextBlock,
                { margin: 8, editable: true }, // some room around the text
                new go.Binding('text').makeTwoWay()
            )
        );

        diagram.add(
            $(
                go.Part,
                {
                    layerName: 'Background',
                    position: new go.Point(0, 0),
                    selectable: true,
                    pickable: false,
                },
                $(
                    go.Picture,
                    src ? src : ''
                    // 'https://dream.kotra.or.kr/attach/namo/images/000038/20211223105900346_TFLGAHXS.jpg'
                )
            )
        );

        return diagram;
    }

    /**
     * This function handles any changes to the GoJS model.
     * It is here that you would make any updates to your React state, which is dicussed below.
     */
    function handleModelChange(changes: go.IncrementalData) {
        // alert('GoJS model changed!');
        console.log(changes);
    }

    const [src, setSrc] = useState<string | undefined>();

    return (
        <>
            <div style={{ display: 'flex', gap: 10 }}>
                <ReactDiagram
                    divClassName="testDiv"
                    initDiagram={initDiagram}
                    style={{
                        border: '1px solid black',
                        width: '50%',
                        height: '800px',
                        marginTop: '10px',
                    }}
                    nodeDataArray={[
                        { key: 0, text: 'Alpha', color: 'lightblue', loc: '0 0' },
                        { key: 1, text: 'Beta', color: 'orange', loc: '150 0' },
                        { key: 2, text: 'Gamma', color: 'lightgreen', loc: '0 150' },
                        { key: 3, text: 'Delta', color: 'pink', loc: '150 150' },
                    ]}
                    linkDataArray={[
                        { key: -1, from: 0, to: 1 },
                        { key: -2, from: 0, to: 2 },
                        { key: -3, from: 1, to: 1 },
                        { key: -4, from: 2, to: 3 },
                        { key: -5, from: 3, to: 0 },
                    ]}
                    onModelChange={handleModelChange}
                />
                <div>
                    <input
                        type="file"
                        onChange={(file) => {
                            const image = file?.target?.files?.[0];
                            if (image) {
                                const reader = new FileReader();
                                reader.onload = () => setSrc(`${reader.result}`);
                                reader.readAsDataURL(image);
                            }
                        }}
                    />
                    <p style={{ width: '50px', whiteSpace: 'pre-wrap' }}>{src}</p>
                    <img src={src} alt="img" />
                </div>
            </div>
        </>
    );
};

export default MyDiagram;

First, you can just set the background image for the <div> that is hosting the Diagram.

Second, when the user scrolls or zooms the diagram, did you want that background image to be scrolled or zoomed too? If so, you’ll want to add a background Part that holds a Picture showing the image. Example: Kitten Monitor

@walter
I did add a background Part that holds a Picture like this.
It works at first render, but not works when changes image.

diagram.add(
            $(
                go.Part,
                {
                    layerName: 'Background',
                    position: new go.Point(0, 0),
                    selectable: true,
                    pickable: false,
                },
                $(
                    go.Picture,
                    src ? src : ''
                    // 'https://dream.kotra.or.kr/attach/namo/images/000038/20211223105900346_TFLGAHXS.jpg'
                )
            )
        );

ā€˜src’ is not a property of Picture, but ā€˜source’ is.

This works: https://codepen.io/simonsarris/pen/VwEWQOP?editors=1111

@simon
The src is state in this project.

I tried by your advide but didn’t work.
I’ve got type script error ā€œThe left-hand side of an assignment expression may not be an optional property accessā€.

I want update ā€˜background’.
Should I re-render when update ā€˜src’ state?

how to re render diagram?

are you using TypeScript? You may need to write:

const picture = staticPart.findObject('img') as go.Picture;
if (picture !== null) picture.source = ...
1 Like

@simon
It works! Thank you.