## Elements

In the first part of the tutorial, we saw a working example of a simple JointJS application:

In the previous section, we have created a graph and learned how to modify the appearance of the paper that shows it on our page:

In this section, we will learn how to create graph elements and how to change their appearance. This is an introduction to elements as they appear in the Hello, World! application; more advanced topics are covered later in the tutorial series. We will continue with the code we modified in the previous section:

    <!DOCTYPE html>
    <html>
    <head>
        <link rel="stylesheet" type="text/css" href="node_modules/jointjs/dist/joint.css" />
    </head>
    <body>
        <!-- content -->
        <div id="myholder"></div>

        <!-- dependencies -->
        <script src="node_modules/jquery/dist/jquery.js"></script>
        <script src="node_modules/lodash/lodash.js"></script>
        <script src="node_modules/backbone/backbone.js"></script>
        <script src="node_modules/jointjs/dist/joint.js"></script>

        <!-- code -->
        <script type="text/javascript">

            var graph = new joint.dia.Graph;

            var paper = new joint.dia.Paper({
                el: document.getElementById('myholder'),
                model: graph,
                width: 600,
                height: 100,
                gridSize: 10,
                drawGrid: true,
                background: {
                    color: 'rgba(0, 255, 0, 0.3)'
                }
            });

            var rect = new joint.shapes.standard.Rectangle();
            rect.position(100, 30);
            rect.resize(100, 40);
            rect.attr({
                body: {
                    fill: 'blue'
                },
                label: {
                    text: 'Hello',
                    fill: 'white'
                }
            });
            rect.addTo(graph);

            var rect2 = rect.clone();
            rect2.translate(300, 0);
            rect2.attr('label/text', 'World!');
            rect2.addTo(graph);

            var link = new joint.shapes.standard.Link();
            link.source(rect);
            link.target(rect2);
            link.addTo(graph);

        </script>
    </body>
    </html>

The code illustrates the basic idea of working with elements:

- First, an element is created by calling its constructor.
- Then, different methods are called on the element to set its properties (position, size, attributes...).
- Finally, the element is added to the graph.

In our case, the two elements are instances of `joint.shapes.standard.Rectangle`. The standard shape library contains many more ready-made element definitions (e.g. Ellipse, Embedded Image, Cylinder...) that can be used in your document. Moreover, advanced users may supply their own element definitions instead, by extending the basic `joint.dia.Element` class.

Our demo showcases some of the most important Element methods:

- `element.position()` - sets the position of the origin of the element (the top-left corner), relative to the paper's coordinate system (taking into account paper scaling and other transformations).
- `element.resize()` - sets the dimensions of the element.
- `element.clone()` - clones an existing element, including its position, dimensions, and attributes (attributes are explained in more detail below).
- `element.translate()` - moves the element by the specified distance along the two coordinate axes. There are methods to scale and rotate elements, too.
- `element.addTo()` - adds the element to a graph so it can be rendered.

### Element Styling

Visually, the most important function is the one that changes element styling:

- `element.attr()` - programmatically assigns SVG attributes directly to the SVGElements of the shape's markup. (CSS styles may still be used on top of the styling defined here, and they will have precedence over these attributes.)

When `element.attr()` is called with one object as argument, the keys of the object are selectors that correspond to SVGElements of the shape's markup; each of those can have one or more attributes defined alongside the value to be set. If you only need to change one value, you can also call `element.attr()` with two arguments; the first is the path of the attribute in the form `'selector/attribute'` and the second is the value to be assigned.

If you are completely new to SVG, you may want to have a look at, for example, the Fills and Strokes tutorial on MDN. JointJS is able to handle all standard SVG attributes, however, please note that we strongly encourage everyone to use camelCase versions of attribute names for consistency and in order to avoid the need for quotation marks in attribute name keys. In addition, JointJS provides an extensive set of non-standard special JointJS attributes; these allow you to specify attributes relatively to other shape selectors, among other things. Special attributes are discussed in detail later in the tutorial.

The `joint.shapes.standard.Rectangle` shape used in our example has two selectors defined: `body` (the `<rect>` SVGElement itself), and `label` (the `<text>` SVGElement inside the shape). Other element shapes have their own selector names (although consistency was preserved where applicable, e.g. with `body`); please refer to the `joint.shapes.standard` documentation for detailed information.

In the case of the `rect` element, we can see that the `body` selector is assigned a `fill` color attribute, while the `label` selector also has its `text` content set to `'Hello'` (via a JointJS special attribute).

    rect.attr({
        body: { // selector for the <rect> SVGElement
            fill: 'blue'
        },
        label: { // selector for the <text> SVGElement
            text: 'Hello',
            fill: 'white'
        }
    });

In the case of the `rect2` element, we are assigning the value `'World!'` to `'label/text'`. Here `label` is the selector for the `<text>` SVGElement; `text` is the attribute we want to modify.

    rect2.attr('label/text', 'World!');

Note that this is equivalent to calling:

    rect2.attr('label', {
        text: 'World!'
    });

The same effect can also be achieved by passing a single object argument to `rect2.attr()`:

    rect2.attr({
        label: {
            text: 'World!'
        }
    });

### Example

Now let us use `element.attr()` to change the look of our elements:

    <!DOCTYPE html>
    <html>
    <head>
        <link rel="stylesheet" type="text/css" href="node_modules/jointjs/dist/joint.css" />
    </head>
    <body>
        <!-- content -->
        <div id="myholder"></div>

        <!-- dependencies -->
        <script src="node_modules/jquery/dist/jquery.js"></script>
        <script src="node_modules/lodash/lodash.js"></script>
        <script src="node_modules/backbone/backbone.js"></script>
        <script src="node_modules/jointjs/dist/joint.js"></script>

        <!-- code -->
        <script type="text/javascript">

            var graph = new joint.dia.Graph;

            var paper = new joint.dia.Paper({
                el: document.getElementById('myholder'),
                model: graph,
                width: 600,
                height: 300, // height had to be increased
                gridSize: 10,
                drawGrid: true,
                background: {
                    color: 'rgba(0, 255, 0, 0.3)'
                }
            });

            var rect = new joint.shapes.standard.Rectangle();
            rect.position(100, 30);
            rect.resize(100, 40);
            rect.attr({
                body: {
                    fill: 'blue'
                },
                label: {
                    text: 'Hello',
                    fill: 'white'
                }
            });
            rect.addTo(graph);

            var rect2 = new joint.shapes.standard.Rectangle();
            rect2.position(400, 30);
            rect2.resize(100, 40);
            rect2.attr({
                body: {
                    fill: '#2C3E50',
                    rx: 5,
                    ry: 5,
                    strokeWidth: 2
                },
                label: {
                    text: 'World!',
                    fill: '#3498DB',
                    fontSize: 18,
                    fontWeight: 'bold',
                    fontVariant: 'small-caps'
                }
            });
            rect2.addTo(graph);

            var link = new joint.shapes.standard.Link();
            link.source(rect);
            link.target(rect2);
            link.addTo(graph);

            var rect3 = new joint.shapes.standard.Rectangle();
            rect3.position(100, 130);
            rect3.resize(100, 40);
            rect3.attr({
                body: {
                    fill: '#E74C3C',
                    rx: 20,
                    ry: 20,
                    strokeWidth: 0
                },
                label: {
                    text: 'Hello',
                    fill: '#ECF0F1',
                    fontSize: 11,
                    fontVariant: 'small-caps'
                }
            });
            rect3.addTo(graph);

            var rect4 = new joint.shapes.standard.Rectangle();
            rect4.position(400, 130);
            rect4.resize(100, 40);
            rect4.attr({
                body: {
                    fill: '#8E44AD',
                    strokeWidth: 0
                },
                label: {
                    text: 'World!',
                    fill: 'white',
                    fontSize: 13
                }
            });
            rect4.addTo(graph);

            var link2 = new joint.shapes.standard.Link();
            link2.source(rect3);
            link2.target(rect4);
            link2.addTo(graph);

            var rect5 = new joint.shapes.standard.Rectangle();
            rect5.position(100, 230);
            rect5.resize(100, 40);
            rect5.attr({
                body: {
                    fill: '#2ECC71',
                    strokeDasharray: '10,2'
                },
                label: {
                    text: 'Hello',
                    fill: 'black',
                    fontSize: 13
                }
            });
            rect5.addTo(graph);

            var rect6 = new joint.shapes.standard.Rectangle();
            rect6.position(400, 230);
            rect6.resize(100, 40);
            rect6.attr({
                body: {
                    fill: '#F39C12',
                    rx: 20,
                    ry: 20,
                    strokeDasharray: '1,1'
                },
                label: {
                    text: 'World!',
                    fill: 'gray',
                    fontSize: 18,
                    fontWeight: 'bold',
                    fontVariant: 'small-caps',
                    textShadow: '1px 1px 1px black'
                }
            });
            rect6.addTo(graph);

            var link3 = new joint.shapes.standard.Link();
            link3.source(rect5);
            link3.target(rect6);
            link3.addTo(graph);

        </script>
    </body>
    </html>

JointJS source code: elements.js

The Filters and Gradients tutorial illustrates some more advanced methods of SVG styling when applied to elements.

We now know how to change the appearance of our elements.

The next step is to learn how to work with links.