Skip to content

Text and Shape Styles

Learn how to customize the appearance of text annotations, boxes, polygons, and comments with colors, borders, backgrounds, and typography.

Text Annotations

Text annotations support extensive styling through the TextStyle interface.

Typography

Control font properties for text content:

typescript
import { createText } from "@linkurious/ogma-annotations";

// Basic text with custom font
const styledText = createText(50, 50, 200, 60, "Hello World", {
  fontSize: 16,
  fontFamily: "Arial, sans-serif",
  color: "#2c3e50",
  fontWeight: "bold"
});

// Text with custom styling
const fancyText = createText(50, 120, 250, 80, "Important Note", {
  fontSize: 18,
  fontFamily: "Georgia, serif",
  color: "#e74c3c",
  fontWeight: "600",
  textAlign: "center"
});

controller.add(styledText);
controller.add(fancyText);

Background and Borders

Customize the text box appearance:

typescript
// Text with background and border
const boxedText = createText(50, 50, 200, 60, "Highlighted", {
  color: "#2c3e50",
  background: "#f39c12",
  strokeColor: "#e67e22",
  strokeWidth: 2,
  borderRadius: 8,
  padding: 12
});

// Transparent background with border
const outlineText = createText(50, 120, 200, 60, "Outline Only", {
  color: "#3498db",
  background: "transparent",
  strokeColor: "#3498db",
  strokeWidth: 2,
  strokeType: "dashed",
  borderRadius: 4
});

// Solid background, no border
const solidText = createText(50, 190, 200, 60, "No Border", {
  color: "#ffffff",
  background: "#9b59b6",
  strokeWidth: 0,
  borderRadius: 12,
  padding: 16
});

controller.add(boxedText);
controller.add(outlineText);
controller.add(solidText);

Fixed Size Text

Create text that doesn't scale with graph zoom:

typescript
const fixedText = createText(100, 100, 150, 40, "Always visible", {
  fixedSize: true,
  fontSize: 14,
  color: "#ffffff",
  background: "#3498db",
  padding: 10,
  borderRadius: 6
});

controller.add(fixedText);

Box Annotations

Boxes use the BoxStyle interface for styling:

typescript
import { createBox } from "@linkurious/ogma-annotations";

// Highlight box with semi-transparent background
const highlight = createBox(0, 0, 200, 150, {
  background: "rgba(52, 152, 219, 0.2)",
  strokeColor: "#3498db",
  strokeWidth: 2,
  strokeType: "plain",
  borderRadius: 8
});

// Border-only box (no fill)
const borderBox = createBox(0, 160, 200, 150, {
  background: "transparent",
  strokeColor: "#e74c3c",
  strokeWidth: 3,
  strokeType: "dashed",
  borderRadius: 0
});

// Rounded filled box
const roundedBox = createBox(0, 320, 200, 150, {
  background: "rgba(46, 204, 113, 0.3)",
  strokeColor: "#27ae60",
  strokeWidth: 2,
  strokeType: "plain",
  borderRadius: 16
});

controller.add(highlight);
controller.add(borderBox);
controller.add(roundedBox);

Polygon Annotations

Polygons use the PolygonStyle interface:

typescript
import { createPolygon } from "@linkurious/ogma-annotations";

// Create a styled polygon
const styledPolygon = createPolygon(
  [
    [
      [0, 0],
      [100, 20],
      [120, 100],
      [50, 150],
      [0, 100],
      [0, 0]
    ]
  ],
  {
    style: {
      background: "rgba(155, 89, 182, 0.3)",
      strokeColor: "#8e44ad",
      strokeWidth: 2,
      strokeType: "plain"
    }
  }
);

// Outline-only polygon
const outlinePolygon = createPolygon(
  [
    [
      [0, 0],
      [100, 0],
      [50, 100],
      [0, 0]
    ]
  ],
  {
    style: {
      background: "transparent",
      strokeColor: "#e74c3c",
      strokeWidth: 3,
      strokeType: "dashed"
    }
  }
);

controller.add(styledPolygon);
controller.add(outlinePolygon);

Comment Annotations

Comments combine text styling with arrow styling through the CommentStyle interface:

typescript
import { createCommentWithArrow } from "@linkurious/ogma-annotations";

const { comment, arrow } = createCommentWithArrow(
  100,
  100, // Target position
  300,
  50, // Comment position
  "This is important!",
  {
    commentStyle: {
      style: {
        background: "#FFFACD",
        color: "#333",
        fontSize: 14,
        strokeColor: "#DAA520",
        strokeWidth: 1,
        borderRadius: 6,
        padding: 12
      },
      width: 200,
      height: 80
    },
    arrowStyle: {
      strokeColor: "#DAA520",
      strokeWidth: 2,
      head: "arrow",
      tail: "none"
    }
  }
);

controller.add(comment);
controller.add(arrow);

Updating Styles

Update annotation styles dynamically using the update() method:

typescript
// Get an annotation
const text = controller.getAnnotation("text-id");

if (text && text.properties.type === "text") {
  // Update text style
  text.properties.style.color = "#e74c3c";
  text.properties.style.background = "#ffeaa7";
  text.properties.style.fontSize = 18;
  text.properties.style.fontWeight = "bold";

  // Apply changes
  controller.update(text);
}

// Update a box
const box = controller.getAnnotation("box-id");

if (box && box.properties.type === "box") {
  // Change box appearance
  box.properties.style.background = "rgba(52, 152, 219, 0.3)";
  box.properties.style.strokeColor = "#3498db";
  box.properties.style.strokeWidth = 3;

  // Apply changes
  controller.update(box);
}

Color Formats

All style properties that accept colors support multiple formats through the Color type:

typescript
// Hex colors
createText(0, 0, 150, 40, "Hex", {
  color: "#3498db",
  background: "#ecf0f1"
});

// RGB colors
createText(0, 50, 150, 40, "RGB", {
  color: "rgb(52, 152, 219)",
  background: "rgb(236, 240, 241)"
});

// RGBA with transparency
createBox(0, 100, 200, 100, {
  background: "rgba(52, 152, 219, 0.3)",
  strokeColor: "rgba(52, 152, 219, 0.8)"
});

Default Styles

The library provides default styles for each annotation type:

typescript
import {
  defaultTextStyle,
  defaultBoxStyle,
  defaultPolygonStyle,
  defaultCommentStyle
} from "@linkurious/ogma-annotations";

// View default styles
console.log(defaultTextStyle);
console.log(defaultBoxStyle);
console.log(defaultPolygonStyle);
console.log(defaultCommentStyle);

// Merge with defaults
const customText = createText(50, 50, 150, 40, "Custom", {
  ...defaultTextStyle,
  color: "#3498db",
  fontSize: 16
});

See the API reference for default styles:

Style Themes

Create consistent styling themes for your application:

typescript
import { TextStyle, BoxStyle } from "@linkurious/ogma-annotations";

// Define a color palette
const palette = {
  primary: "#3498db",
  secondary: "#2ecc71",
  accent: "#f39c12",
  danger: "#e74c3c",
  light: "#ecf0f1",
  dark: "#2c3e50"
};

// Create text style themes
const textThemes = {
  title: {
    fontSize: 20,
    fontWeight: "bold",
    color: palette.dark,
    background: "transparent"
  } as TextStyle,

  label: {
    fontSize: 14,
    color: palette.dark,
    background: palette.light,
    padding: 8,
    borderRadius: 4,
    strokeColor: palette.primary,
    strokeWidth: 1
  } as TextStyle,

  highlight: {
    fontSize: 16,
    fontWeight: "600",
    color: "#ffffff",
    background: palette.accent,
    padding: 12,
    borderRadius: 8,
    strokeWidth: 0
  } as TextStyle
};

// Create box style themes
const boxThemes = {
  selection: {
    background: "rgba(52, 152, 219, 0.2)",
    strokeColor: palette.primary,
    strokeWidth: 2,
    strokeType: "dashed" as const,
    borderRadius: 4
  } as BoxStyle,

  highlight: {
    background: "rgba(243, 156, 18, 0.3)",
    strokeColor: palette.accent,
    strokeWidth: 3,
    strokeType: "plain" as const,
    borderRadius: 8
  } as BoxStyle
};

// Use themes
const titleText = createText(50, 50, 300, 50, "Title", textThemes.title);
const labelText = createText(50, 110, 200, 40, "Label", textThemes.label);
const highlightBox = createBox(0, 0, 400, 200, boxThemes.highlight);

controller.add(titleText);
controller.add(labelText);
controller.add(highlightBox);

Best Practices

1. Readable Typography

Ensure text is readable with proper font sizes and contrast:

typescript
// Good: Readable text with good contrast
const goodText = createText(50, 50, 200, 60, "Readable Text", {
  fontSize: 14, // Minimum readable size
  color: "#2c3e50", // Dark text
  background: "#ecf0f1", // Light background
  padding: 10
});

// Avoid: Too small or low contrast
const badText = createText(50, 120, 200, 60, "Hard to read", {
  fontSize: 8, // Too small
  color: "#95a5a6", // Low contrast
  background: "#bdc3c7"
});

2. Consistent Styling

Use style objects or themes for consistency:

typescript
// Define reusable styles
const cardStyle: TextStyle = {
  fontSize: 14,
  color: "#2c3e50",
  background: "#ffffff",
  strokeColor: "#dfe6e9",
  strokeWidth: 1,
  borderRadius: 8,
  padding: 12
};

// Apply consistently
const card1 = createText(50, 50, 200, 80, "Card 1", cardStyle);
const card2 = createText(50, 140, 200, 80, "Card 2", cardStyle);

3. Semantic Colors

Use colors to convey meaning:

typescript
const statusStyles = {
  success: {
    background: "rgba(46, 204, 113, 0.2)",
    strokeColor: "#27ae60",
    color: "#27ae60"
  } as TextStyle,

  warning: {
    background: "rgba(243, 156, 18, 0.2)",
    strokeColor: "#f39c12",
    color: "#f39c12"
  } as TextStyle,

  error: {
    background: "rgba(231, 76, 60, 0.2)",
    strokeColor: "#e74c3c",
    color: "#e74c3c"
  } as TextStyle
};

const successLabel = createText(50, 50, 150, 40, "Success", statusStyles.success);
const errorLabel = createText(50, 100, 150, 40, "Error", statusStyles.error);

See Also