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.