Skip to content
D
Documentation

Edit data models visually

how-to
3 min readUpdated

Use the ER diagram kit when you want readers to rename tables and columns in place, add or remove columns, and see relationships stay attached to their fields as the schema changes.

The kit turns entity and relationship data into table cards with typed columns, key badges, and crow’s-foot relationships. Set editable: true to add inline editing controls; a TABLE.column relationship endpoint pins its edge to that column’s row. erDiagram builds the spec, and render or a framework diagram component mounts it.

Build an editable ER diagram

Use this pattern when your data is a relational schema and the diagram itself should be the editor. The example includes a field-level foreign-key relationship from ORDERS.customer_id to CUSTOMERS.id, plus a table-level relationship from PRODUCTS to ORDERS.

The mounted diagram shows three entity cards, their columns and key badges, and orthogonal crow’s-foot edges. Double-click a table header or column name to edit it; use the card’s add and delete controls to change columns. Each edit is an undoable step, and the field-level edge remains attached to its column when rows move.

Create the same kit spec in JavaScript, Angular, React, or Vue, then mount it with the framework’s diagram component. The JavaScript example mounts the spec directly. Each sample gives the canvas a real height.

React’s GrafloriaDiagram and Vue’s GrafloriaDiagram mount the kit spec directly. Angular’s diagram component takes the spec as an input.

js
import { erDiagram, render } from '@grafloria/element';

const spec = erDiagram({
  editable: true,
  entities: [
    { id: 'PRODUCTS', name: 'Products', position: { x: 80, y: 96 }, columns: [
      { name: 'id', type: 'int', pk: true },
      { name: 'sku', type: 'varchar' },
      { name: 'price', type: 'decimal' },
    ] },
    { id: 'CUSTOMERS', name: 'Customers', position: { x: 80, y: 360 }, columns: [
      { name: 'id', type: 'int', pk: true },
      { name: 'name', type: 'varchar' },
      { name: 'email', type: 'varchar' },
    ] },
    { id: 'ORDERS', name: 'Orders', position: { x: 500, y: 150 }, columns: [
      { name: 'id', type: 'int', pk: true },
      { name: 'status', type: 'varchar' },
      { name: 'customer_id', type: 'int', fk: true },
      { name: 'total', type: 'decimal' },
    ] },
  ],
  relationships: [
    { from: 'ORDERS.customer_id', to: 'CUSTOMERS.id', id: 'fk_customer', fromSide: 'left', toSide: 'right' },
    { from: 'PRODUCTS', to: 'ORDERS', label: 'ordered as', fromSide: 'right', toSide: 'left' },
  ],
});

const host = document.createElement('div');
host.style.height = '640px';
document.body.append(host);
const instance = render(spec, host);
instance.fitView(40);
window.addEventListener('pagehide', () => instance.dispose(), { once: true });

The kit spec is regular diagram data plus a finalization step that installs the row interactions and, when editing is enabled, the inline editing behavior. Framework bindings mount that same spec; the JavaScript call returns a live instance, which the sample uses to fit the diagram and dispose it when its host page leaves.

For a model that is not a relational schema, use the generic canvas: React’s GrafloriaFlow, Vue’s GrafloriaFlow, or Angular’s DiagramCanvasComponent.

For a non-relational model, the generic canvas changes the task: readers move entity nodes and create or remove connections, rather than editing table and column names or rows. See the React quick start for typed flow data and framework binding patterns, and How Grafloria works for the shared model and Angular controlled-binding example.

Options that shape the schema

OptionTypeDefaultWhat it does
entitiesArray of entity specsRequiredDeclares each table’s id, optional display name, columns, and optional position. Each column can specify a name, type, primary-key flag, and foreign-key flag.
relationshipsArray of relationship specsEmptyDeclares links between entity ids or between ENTITY.column endpoints. A column endpoint anchors the edge to that row.
editablebooleanfalseAdds table rename, column rename, add-column, and delete-column controls. Every edit is one undoable step.
rowSelectionbooleantrueEnables column-row selection and the kit’s row selection events. Set it to false to opt out.

Pitfalls

  • Use the exact entity id and column name in a field endpoint such as ORDERS.customer_id. The kit throws if an entity or referenced column does not exist.
  • editable is opt-in. Without it, the diagram remains the read-only ER card view.
  • Deleting a column removes a relationship attached to that column. Other field relationships stay connected to their columns as those rows shift.
  • Give the canvas host a resolved height. The renderer fills its parent; a zero-height parent leaves no visible diagram.

See it running

Open the live ERD editor demo to try inline table and column edits, column insertion and deletion, row selection, and field-level relationships.

Was this page helpful?

Edit data models visually — Grafloria · GPT-6 Luna