@amcharts/amcharts5
Version:
amCharts 5
407 lines • 15.3 kB
TypeScript
import type { DataItem } from "../../core/render/Component";
import type { ColorSet } from "../../core/util/ColorSet";
import type { Percent } from "../../core/util/Percent";
import type { IPoint } from "../../core/util/IPoint";
import type { Time } from "../../core/util/Animation";
import { Series, ISeriesSettings, ISeriesDataItem, ISeriesPrivate } from "../../core/render/Series";
import { Label } from "../../core/render/Label";
import { Container } from "../../core/render/Container";
import { Graphics } from "../../core/render/Graphics";
import { ListTemplate } from "../../core/util/List";
import type { Color } from "../../core/util/Color";
export interface IWordCloudDataItem extends ISeriesDataItem {
/**
* Category.
*/
category: string;
/**
* Label.
*/
label: Label;
/**
* Fill color used for the slice and related elements, e.g. legend marker.
*/
fill: Color;
/**
* @ignore
*/
set: number;
/**
* @ignore
*/
angle: number;
/**
* @ignore
*/
fontSize: number;
}
export interface IWordCloudSettings extends ISeriesSettings {
/**
* Duration of word animation when chart resizes.
*/
animationDuration?: number;
/**
* An easing function to use for word animations.
*
* @see {@link https://www.amcharts.com/docs/v5/concepts/animations/#Easing_functions} for more info
* @default am5.ease.out($ease.cubic)
*/
animationEasing?: (t: Time) => Time;
/**
* @default false
*/
autoFit?: boolean;
/**
* Progress of current word layout animation. (0-1)
*
* @readonly
*/
progress?: number;
/**
* A [[ColorSet]] to use when asigning colors for slices.
*/
colors?: ColorSet;
/**
* A field in data that holds category names.
*/
categoryField?: string;
/**
* A field that holds color for label fill.
*/
fillField?: string;
/**
* Source text from which words are extracted.
*/
text?: string;
/**
* Absolute or relative font size for the smallest words.
*/
minFontSize?: number | Percent;
/**
* Absolute or relative font size for the biggest words.
*/
maxFontSize?: number | Percent;
/**
* Minimum occurances for a word to be included into cloud.
*/
minValue?: number;
/**
* Maximum number of words to show.
*/
maxCount?: number;
/**
* Array of words exclude from cloud.
*/
excludeWords?: Array<string>;
/**
* Randomness of word placement (0-1).
*/
randomness?: number;
/**
* Minimum number of characters for a word to be included in the cloud.
*/
minWordLength?: number;
/**
* An array of possible rotation angles for words.
*/
angles?: number[];
/**
* How a word's rotation is chosen from `angles`.
*
* When `true` (default) each word picks a random angle from `angles`, so the
* cloud looks different on every layout. When `false` words cycle through
* `angles` in order (word 0 gets `angles[0]`, word 1 `angles[1]`, and so on),
* which — together with `randomness: 0` — makes the layout reproducible.
*
* @since 5.20.1
* @default true
*/
randomizeAngles?: boolean;
/**
* Whether words may nest into each other's empty space.
*
* When `true` (default) a word is packed against its neighbors' letters, so
* small words tuck into the concavities of bigger ones and the cloud packs
* tightly — but bounding boxes may overlap. Set to `false` to pack whole
* bounding boxes instead, so they never overlap (useful when labels have an
* opaque `background`, whose rectangles would otherwise slide into a
* neighbor's gaps).
*
* @since 5.20.1
* @default true
*/
allowNesting?: boolean;
/**
* Step for next word placement.
*/
step?: number;
/**
* Experimental: if set, words are arranged to fill this shape. The path is
* scaled proportionally to fit the plot area.
*
* NOTE: this is an experimental feature and the fit is approximate. Favor
* simple, bold shapes over complex, thin, or highly concave ones, and tune
* `shapeTolerance`, `maskByShape`, `angles` (and `minFontSize`/`maxFontSize`)
* to get a better fill for a particular shape.
*
* @since 5.20.1
*/
svgPath?: string;
/**
* Extra distance (in pixels) a word may extend past the `svgPath` outline,
* on top of the automatic per-word overhang (a fraction of each word's own
* size). Words already spill over the edge proportionally to their size so
* the outline fills well at `0` (default); increase this to let them spill
* further.
*
* Can also be negative to pull words further inside the outline, creating
* visual padding between the words and the shape edge.
*
* Only affects placement — the drawn `shape` outline is unchanged. Requires
* `svgPath`.
*
* @since 5.20.1
* @default 0
*/
shapeTolerance?: number;
/**
* If set to `true`, words are clipped to the `svgPath` shape, so the parts
* of letters that overhang the outline (see `shapeTolerance`) are cut off at
* the edge for a crisp silhouette. Requires `svgPath`.
*
* @since 5.20.1
* @default false
*/
maskByShape?: boolean;
}
export interface IWordCloudPrivate extends ISeriesPrivate {
/**
* Indicates whether size of the font was adjusted for better fit.
*/
adjustedFontSize: number;
}
/**
* A bit-packed glyph mask of a single word (32 pixels per int), used by the
* layout for in-memory collision detection.
*
* @ignore
*/
interface IWordSprite {
bits: Int32Array;
stride: number;
bw: number;
bh: number;
}
/**
* A computed placement of a single word. No `point` means the word could not
* be placed (label gets hidden).
*
* @ignore
*/
interface IWordPlacement {
dataItem: DataItem<IWordCloudDataItem>;
point?: IPoint;
angle: number;
fontSize: number;
}
/**
* Creates a [[WordCloud]] series.
*
* @see {@link https://www.amcharts.com/docs/v5/charts/word-cloud/} for more info
* @important
*/
export declare class WordCloud extends Series {
static className: string;
static classNames: Array<string>;
_settings: IWordCloudSettings;
_privateSettings: IWordCloudPrivate;
_dataItemSettings: IWordCloudDataItem;
/**
* A [[Graphics]] element that draws the `svgPath` shape the words are
* arranged into, aligned exactly with the word-constraint region.
*
* By default it renders as a faint silhouette (the theme's alternative
* background color at 10% opacity) behind the words, and only when
* `svgPath` is set. Style it via
* `series.shape.setAll({ fill: color, fillOpacity: 0.1, ... })`.
*
* Its geometry (`svgPath`, `scale`, `x`, `y`) and visibility are managed
* by the series; `fill`/`stroke` and other styling are yours to set.
*
* It is added as the first child, so it always renders behind the words.
*
* @since 5.20.1
*/
readonly shape: Graphics;
protected _pointSets: Array<Array<IPoint>>;
protected _sets: number;
protected _board: Int32Array;
protected _boardW: number;
protected _boardH: number;
protected _boardStride: number;
protected _scratchCanvas?: HTMLCanvasElement;
protected _scratchContext?: CanvasRenderingContext2D;
protected _shapeMask?: Int32Array;
protected _shapeMaskKey?: string;
protected _shapeCandidates?: Array<IPoint>;
protected _labelsContainer: Container;
protected _maskApplied: boolean;
protected _shapeScale: number;
protected _shapeTx: number;
protected _shapeTy: number;
protected _svgPathWarned: boolean;
protected _afterNew(): void;
/**
* A [[ListTemplate]] of all labels in series.
*
* `labels.template` can also be used to configure labels.
*/
readonly labels: ListTemplate<Label>;
/**
* @ignore
*/
makeLabel(dataItem: DataItem<this["_dataItemSettings"]>): Label;
protected _makeLabels(): ListTemplate<Label>;
protected processDataItem(dataItem: DataItem<this["_dataItemSettings"]>): void;
_prepareChildren(): void;
_updateChildren(): void;
/**
* Measures, rasterizes and places all words in one synchronous pass.
* Occupancy is a bit-packed in-memory board tested with bitwise AND — no
* canvas readback and no per-frame word processing.
*/
protected _layoutAll(): void;
/**
* Runs one full placement pass with all font sizes scaled by `shrink`.
* Returns the computed placements, or `undefined` if a word did not fit
* and `autoFit` wants a retry at a smaller scale.
*/
protected _layoutAttempt(shrink: number): Array<IWordPlacement> | undefined;
/**
* Builds (or reuses) the `svgPath` shape mask for the current plot size.
* The mask marks the fitted shape's EXTERIOR, tested against an eroded word
* box so words stay (mostly) inside the shape. Placement is driven by the
* distance-ranked `_shapeCandidates` (thickest interior first).
*/
protected _prepareShapeMask(): void;
/**
* Shows or hides the `shape` silhouette and applies (or removes) the
* `maskByShape` clip on the labels container, based on whether a shape is
* currently active. Must run on EVERY `_prepareShapeMask` exit — otherwise a
* stale clip from a previous shape would keep the labels cut off after the
* shape is removed or its path becomes invalid.
*/
protected _updateShapeVisibility(): void;
/**
* Builds a FRESH clip-mask [[Graphics]] from the fitted-shape geometry and
* applies it to the labels container. Rebuilt on every apply because removing
* a mask disposes it (see [[Container]]), so a single reused instance would
* be dead after the first toggle-off.
*/
protected _applyMaskGraphics(): void;
/**
* Builds candidate placement points for a shape, ordered by distance to the
* shape's edge (thickest interior first). A two-pass chamfer distance
* transform measures how much room each interior pixel has; placing words
* biggest-first into the roomiest free spots fills the core first and lets
* progressively smaller words flow out to the edges — filling the whole
* silhouette instead of just an inscribed ellipse.
*/
protected _buildShapeCandidates(boardW: number, boardH: number, data: Uint8ClampedArray, resolution: number): Array<IPoint>;
/**
* Finds the bounding box of an SVG path (in path units) by rasterizing it
* onto the scratch canvas at decreasing probe scales until it fits, then
* scanning the ink bounds. Canvas-based, so it works without attaching
* any SVG element to the document.
*/
protected _svgPathBBox(path: Path2D): {
left: number;
top: number;
width: number;
height: number;
} | undefined;
/**
* Logs a one-time console warning about an unusable `svgPath` (invalid or
* degenerate). Warns once per series to avoid flooding the console.
*/
protected _warnSvgPath(message: string): void;
/**
* Builds the CSS font shorthand used to measure and rasterize a word's
* collision mask, mirroring the renderer's `CanvasText._getFontStyle` (same
* part order, same fallbacks) so the scratch-canvas raster lines up with the
* drawn glyph. The weight is forced to `900` so the mask is fatter than the
* displayed label — that extra thickness is what keeps natural spacing
* between words (the label itself is drawn with its own weight).
*/
protected _wordFontStyle(label: Label, fontSize: number): string;
protected _makeScratch(): CanvasRenderingContext2D;
/**
* Vertical advance between lines for a label, honoring its `lineHeight`
* setting (the theme default is 100%, i.e. one font size per line). Used to
* stack multi-line categories (`\n`) the way the label renders them.
*/
protected _lineStep(label: Label, fontSize: number): number;
/**
* Measures a word synchronously on the scratch canvas. Categories may span
* several lines (`\n`); the width is the widest line and the height stacks
* the lines by `lineStep`, matching the label's rendered footprint.
*/
protected _measureWord(text: string, font: string, fontSize: number, lineStep: number): {
width: number;
height: number;
};
/**
* Rasterizes a word (at its final font and rotation) on the scratch canvas
* and packs the alpha channel into a bit mask.
*/
protected _rasterizeWord(text: string, font: string, lw: number, lh: number, angle: number): IWordSprite;
/**
* Rasterizes a SOLID rectangle of the given (padded) dimensions at the
* word's angle, and packs it into a bit mask. Used as the collision
* footprint: at 0/90 degrees it equals the axis-aligned box, while for
* diagonal words it hugs the real footprint so neighbors can pack into
* the empty corners of the axis-aligned bounding box.
*/
protected _rasterizeBox(lw: number, lh: number, angle: number): IWordSprite;
/**
* Packs the alpha channel of the scratch canvas' top-left `bw x bh`
* region into a bit mask (32 pixels per int, MSB first).
*/
protected _packScratch(bw: number, bh: number): IWordSprite;
/**
* Tests a collision mask against the occupancy board at device
* coordinates `(px, py)` (top-left corner). Bitwise AND, exact to the
* pixel. The glyph-shaped nesting comes from the board containing only
* glyph ink; the mask itself is the word's solid oriented (padded) box.
*/
protected _collidesAt(sprite: IWordSprite, px: number, py: number, board?: Int32Array): boolean;
/**
* Stamps a sprite into the occupancy board (bitwise OR) at device
* coordinates `(px, py)` (top-left corner).
*/
protected _stampSprite(sprite: IWordSprite, px: number, py: number): void;
/**
* @ignore
*/
disposeDataItem(dataItem: DataItem<this["_dataItemSettings"]>): void;
/**
* Extracts words and number of their appearances from a text.
*
* @ignore
* @param input Source text
*/
protected _getWords(input?: string): Array<{
category: string;
value: number;
}>;
/**
* Checks if word is capitalized (starts with an uppercase) or not.
*
* @ignore
* @param word Word
* @return Capitalized?
*/
isCapitalized(word: string): boolean;
}
export {};
//# sourceMappingURL=WordCloud.d.ts.map