Atomic Angular — Doc interne

Word Cloud

Aggregation values packed into a compact spiral layout — large words centered, smaller ones tucked into the gaps, some rotated.

The denser, classic "word cloud" look: words placed by a spiral search with collision detection, some rotated, sized and colored like <TagCloud> but laid out rather than wrapped. Reach for <TagCloud> first — this component carries a real placement algorithm, and is worth its cost only when the packed look is the point.

Minimal example

A packed cloud of entities
sample.component.ts
import { Component, signal } from "@angular/core";
import { WordCloudComponent } from "@sinequa/atomic-angular";
import type { AggregationLike, TagCloudEntry } from "@sinequa/atomic-angular";

@Component({
  selector: "sample-component",
  imports: [WordCloudComponent],
  template: `
    <div class="h-64">
      <WordCloud [aggregations]="[companies(), people()]" (tagSelected)="onTag($event)" />
    </div>
  `,
})
export class SampleComponent {
  readonly companies = signal<AggregationLike | undefined>(undefined);
  readonly people = signal<AggregationLike | undefined>(undefined);

  protected onTag(entry: TagCloudEntry) {
    console.log(`Filter ${entry.source} on`, entry.value);
  }
}

How it works

aggregations input buildTagCloud() — shared with TagCloud layoutWordCloud() — spiral placement, collision detection ResizeObserver on the host document.fonts.ready placed words (SVG text) + skipped count

Rendered as SVG rather than absolutely-positioned <div>s: one coordinate system, rotation for free through transform, and a native <title> tooltip needs no JavaScript. The words stay real, focusable DOM nodes.

The layout re-runs whenever the aggregation data, the container size, or web-font readiness changes — the last one matters because the canvas used to measure each word's ink box needs the real font metrics, not a fallback, to place words tightly.

Recipes

Reacting to dropped words

A cloud needs space: words that find no room are dropped rather than shown overlapping, and the count is surfaced so the omission is never silent.

Surfacing the skipped count
roomy-cloud.component.ts
import { Component, signal } from "@angular/core";
import { WordCloudComponent } from "@sinequa/atomic-angular";
import type { AggregationLike } from "@sinequa/atomic-angular";

@Component({
  selector: "roomy-cloud",
  imports: [WordCloudComponent],
  template: `
    <p class="text-sm text-(--font-neutral-muted)">
      Showing the most frequent terms — some may not fit a narrow window.
    </p>
    <div class="h-72">
      <WordCloud [aggregations]="[terms()]" [limit]="80" />
    </div>
  `,
})
export class RoomyCloudComponent {
  readonly terms = signal<AggregationLike | undefined>(undefined);
}

Options

Prop

Type

Pitfalls

What's next

On this page