UNPKG

@amcharts/amcharts5

Version:
407 lines 15.3 kB
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