# Use ER and UML kits

Use `erDiagram()` for table-shaped entities and `umlDiagram()` for class compartments. Each kit returns a normal render spec, so mount it through the standard instance used by other Grafloria diagrams. Give the host a resolved height such as `height: 100vh`.

## Build an ER diagram

Pass `entities` and `relationships` to [`erDiagram`](https://bench-grafloria-56.atloria.app/p/bench-grafloria-56-62cg8vR5rF/developer/grafloria-element-diagram-kit-functions). Entities support `width` and fixed `height`; use `ENTITY.column` at either relationship end to attach it to that row.

```ts
import { erDiagram, erTable, render } from '@grafloria/element';

const host = document.getElementById('diagram')!;
host.style.height = '100vh';
const spec = erDiagram({
  entities: [
    { id: 'CUSTOMER', name: 'Customer', position: { x: 40, y: 80 }, width: 220, height: 150,
      columns: [{ name: 'id', type: 'int', pk: true }, { name: 'email', type: 'varchar' }] },
    { id: 'ORDER', name: 'Order', position: { x: 380, y: 80 }, width: 220,
      columns: [{ name: 'id', type: 'int', pk: true }, { name: 'customer_id', type: 'int', fk: true }] },
  ],
  relationships: [{ from: 'ORDER.customer_id', to: 'CUSTOMER.id', label: 'belongs to' }],
});
const instance = render(spec, host);
instance.fitView(40);
const customer = erTable(instance, 'CUSTOMER');
async function editCustomer(): Promise<void> {
  await customer.rename('Customers');
  await customer.resize({ width: 240 });
}
void editCustomer();
```

You see table cards with typed rows, PK/FK badges, and a crow’s-foot relationship. The typed [`erTable`](https://bench-grafloria-56.atloria.app/p/bench-grafloria-56-62cg8vR5rF/developer/grafloria-element-diagram-kit-functions) handle edits the live domain object; its `spec` getter returns a copy.

:::code-group
```html title="JavaScript"
<div id="diagram" style="height:100vh"></div>
<script type="module">
import { erDiagram, render } from '@grafloria/element';
const host = document.getElementById('diagram');
const spec = erDiagram({ entities: [{ id: 'CUSTOMER', name: 'Customer', position: { x: 40, y: 80 }, columns: [{ name: 'id', type: 'int', pk: true }] }], relationships: [] });
const instance = render(spec, host);
instance.fitView(40);
</script>
```
```ts title="Angular"
import { Component } from '@angular/core';
import { GrafloriaDiagramComponent } from '@grafloria/angular';
import { erDiagram } from '@grafloria/element';
@Component({ standalone: true, imports: [GrafloriaDiagramComponent], template: `<grafloria-diagram [spec]="spec" style="display:block;height:100vh" />` })
export class ErDiagramComponent {
  spec = erDiagram({ entities: [{ id: 'CUSTOMER', name: 'Customer', position: { x: 40, y: 80 }, columns: [{ name: 'id', type: 'int', pk: true }] }], relationships: [] });
}
```
```text title="Qwik"
import { component$ } from '@builder.io/qwik';
import { GrafloriaDiagram } from '@grafloria/qwik';
import { erDiagram } from '@grafloria/element';

const spec = erDiagram({
  entities: [{ id: 'CUSTOMER', name: 'Customer', position: { x: 40, y: 80 }, columns: [{ name: 'id', type: 'int', pk: true }] }],
  relationships: [],
});

export default component$(() => (
  <div style={{ height: '100vh' }}>
    <GrafloriaDiagram spec={spec} />
  </div>
));
```
```tsx title="React"
import { GrafloriaDiagram } from '@grafloria/react';
import { erDiagram } from '@grafloria/element';
const spec = erDiagram({ entities: [{ id: 'CUSTOMER', name: 'Customer', position: { x: 40, y: 80 }, columns: [{ name: 'id', type: 'int', pk: true }] }], relationships: [] });
export default function ErDiagramDemo() { return <div style={{ height: '100vh' }}><GrafloriaDiagram spec={spec} /></div>; }
```
```vue title="Vue"
<script setup lang="ts">
import { GrafloriaDiagram } from '@grafloria/vue';
import { erDiagram } from '@grafloria/element';
const spec = erDiagram({ entities: [{ id: 'CUSTOMER', name: 'Customer', position: { x: 40, y: 80 }, columns: [{ name: 'id', type: 'int', pk: true }] }], relationships: [] });
</script>
<template><div style="height:100vh"><GrafloriaDiagram :spec="spec" /></div></template>
```
:::

## Build a UML class diagram

Pass `classes` and `relationships` to [`umlDiagram`](https://bench-grafloria-56.atloria.app/p/bench-grafloria-56-62cg8vR5rF/developer/grafloria-element-diagram-kit-functions). Class data supports `attributes`, `methods`, `stereotype`, `abstract`, `width`, and `height`. Relationship kinds include inheritance, realization, association, directed association, aggregation, composition, and dependency.

```ts
import { render, umlClass, umlDiagram } from '@grafloria/element';
const host = document.getElementById('diagram')!;
host.style.height = '100vh';
const spec = umlDiagram({
  classes: [
    { id: 'Animal', abstract: true, position: { x: 60, y: 40 }, width: 240, attributes: ['# name: String'], methods: ['+ speak(): void'] },
    { id: 'Dog', position: { x: 60, y: 300 }, height: 150, attributes: ['+ breed: String'], methods: ['+ fetch(): void'] },
  ],
  relationships: [{ from: 'Dog', to: 'Animal', kind: 'inheritance' }],
});
const strokeWidth = 3;
spec.edges[0].style = { strokeWidth };
const instance = render(spec, host);
spec.finalize(instance);
instance.fitView(40);
const animal = umlClass(instance, 'Animal');
async function editAnimal(): Promise<void> {
  await animal.rename('BaseAnimal');
  await animal.setAbstract(false);
  await animal.resize({ height: 180 });
}
void editAnimal();
```

You see three-compartment class cards and a hollow-triangle inheritance marker. The typed [`umlClass`](https://bench-grafloria-56.atloria.app/p/bench-grafloria-56-62cg8vR5rF/developer/grafloria-element-diagram-kit-functions) handle edits the live class. Call `spec.finalize(instance)` after `render()` so multiplicity labels and other live-model wiring are installed.

The kit does not expose `strokeWidth` as a UML option; its relationship notation supplies stroke styling. When you need a different stroke width, adjust the returned edge data before mounting it, as the sample does.

## Edit in the canvas

Set `editable: true` on either kit. ER cards provide header rename, column rename, add-column, and row-delete controls. UML cards provide class-name and member editing plus add/delete controls. Every edit is one undoable step. Leave the option out for read-only cards and use `erTable()` or `umlClass()` for controlled programmatic edits.

## Live demos

- [Table / ER diagram](https://grafloria.com/demos/diagrams/table-er.html)
- [Class diagram (UML)](https://grafloria.com/demos/diagrams/class-uml.html)
- [UML relationships](https://grafloria.com/demos/diagrams/uml-relationships.html)
- [Advanced ER](https://grafloria.com/demos/diagrams/er-advanced.html)

## Related

- [How Grafloria works](https://bench-grafloria-56.atloria.app/p/bench-grafloria-56-62cg8vR5rF/developer/how-grafloria-works)
- [The DiagramInstance](https://bench-grafloria-56.atloria.app/p/bench-grafloria-56-62cg8vR5rF/developer/grafloria-renderer-instance-diagraminstance)
- [Edit Mermaid diagrams](https://bench-grafloria-56.atloria.app/p/bench-grafloria-56-62cg8vR5rF/developer/edit-mermaid-diagrams)
