{"version":3,"file":"nw-style-guide-word-cloud.mjs","sources":["../../../projects/nw-style-guide/word-cloud/word-cloud.component.ts","../../../projects/nw-style-guide/word-cloud/word-cloud.component.html","../../../projects/nw-style-guide/word-cloud/word.component.ts","../../../projects/nw-style-guide/word-cloud/word.component.html","../../../projects/nw-style-guide/word-cloud/public-api.ts","../../../projects/nw-style-guide/word-cloud/nw-style-guide-word-cloud.ts"],"sourcesContent":["import {\n    ChangeDetectionStrategy,\n    ChangeDetectorRef,\n    Component,\n    ElementRef,\n    EventEmitter,\n    Input,\n    OnChanges,\n    Output,\n    Renderer2,\n    SimpleChanges,\n    DOCUMENT,\n    inject\n} from '@angular/core';\nimport { IBoundingBox } from './models/IBoundingBox';\nimport { IPoint } from './models/IPoint';\nimport { IWordCloudConfig } from './models/IWordCloudConfig';\nimport { IWord } from './models/IWord';\nimport { IWordWithFontSize } from './models/IWordWithFontSize';\nimport { IWordWithPosition } from './models/IWordWithPosition';\nimport { interval, Observable, of } from 'rxjs';\nimport { catchError, filter, map, startWith, take, timeout } from 'rxjs/operators';\nimport { ResizeObserverDirective } from 'nw-style-guide/resize-observer';\n\n@Component({\n    selector: 'nw-word-cloud',\n    templateUrl: './word-cloud.component.html',\n    changeDetection: ChangeDetectionStrategy.OnPush,\n    imports: [ResizeObserverDirective]\n})\nexport class WordCloudComponent<T extends IWord> implements OnChanges {\n    private _elRef = inject<ElementRef<HTMLElement>>(ElementRef);\n    private _renderer = inject(Renderer2);\n    private _cdRef = inject(ChangeDetectorRef);\n    private _document = inject<Document>(DOCUMENT);\n    elRef = inject<ElementRef<HTMLElement>>(ElementRef);\n\n    @Input() words: T[];\n    @Input() options: Partial<IWordCloudConfig> = {};\n\n    @Output() wordsPositioned: EventEmitter<IWordWithPosition<T>[]> = new EventEmitter();\n\n    private _truncatedWordsWithFontSize: IWordWithFontSize<T>[];\n    private _positionedWords: IWordWithPosition<T>[];\n    private _canvas: HTMLCanvasElement;\n    private _ctx: CanvasRenderingContext2D;\n    private _centerPoint: IPoint;\n    /**\n     * Controls how many points are generated on the spiral. Should be kept between 0 and 1. Lower values generate more\n     * points on the spiral but it can take a lot longer to position the words. If updating this value to <= 0.3, consider\n     * all the places where this is used and for each one the amount of words in the cloud. It could also be a good idea to\n     * make this value configurable by allowing it to be specified in the `options` input\n     */\n    private _spiralResolution = 0.3;\n\n    public config: IWordCloudConfig;\n\n    ngOnChanges(changes: SimpleChanges): void {\n        const wordsChange = changes.words?.currentValue !== changes.words?.previousValue;\n        const optionsChange = changes.options?.currentValue !== changes.options?.previousValue;\n\n        if (wordsChange || optionsChange) {\n            this._init();\n        }\n    }\n\n    /**\n     * Exports the canvas to a PNG image and returns the base64-encoded PNG data\n     *\n     * @returns A string containing the base64-encoded PNG data of the canvas\n     */\n    exportCanvas(): string {\n        /**\n         * Create a new canvas matching the dimensions of the original canvas. At this point, `_positionedWords` contains\n         * the final positions of the words and we have no need to check for intersections, so we loop through our words\n         * and draw them on our `exportCanvas`\n         */\n        const exportCanvas = this._renderer.createElement('canvas') as HTMLCanvasElement;\n        const exportCtx = exportCanvas.getContext('2d');\n        const ratio = window.devicePixelRatio;\n\n        exportCanvas.width = this._canvas.width * ratio;\n        exportCanvas.height = this._canvas.height * ratio;\n        exportCtx.scale(ratio, ratio);\n\n        this._positionedWords.forEach(pw => {\n            const point: IPoint = { x: pw.canvasX, y: pw.canvasY };\n            this._setFontDetails(exportCtx, pw.fontSize);\n            this._drawWord(pw, point, exportCtx);\n        });\n\n        /*\n         * Get the lowest & highest words positions from the y-axis and based on that we get the word cloud content height\n         * which we then use in order to extract only the content of the word cloud excluding white space and set it to a new canvas.\n         */\n        const lowestPointOnTheYAxis = Math.min(...this._positionedWords.map(pw => pw.canvasY - pw.height / 2));\n        const highestPointOnTheYAxis = Math.max(...this._positionedWords.map(pw => pw.canvasY + pw.height / 2));\n        const heightOfWordCloudContent = (highestPointOnTheYAxis - lowestPointOnTheYAxis) * ratio;\n        const extractWordCloudImageData = exportCtx.getImageData(\n            0,\n            lowestPointOnTheYAxis * ratio,\n            exportCanvas.width,\n            heightOfWordCloudContent\n        );\n\n        const canvas = this._renderer.createElement('canvas') as HTMLCanvasElement;\n        const context = canvas.getContext('2d');\n\n        canvas.width = exportCanvas.width;\n        canvas.height = heightOfWordCloudContent;\n        context.putImageData(extractWordCloudImageData, 0, 0);\n\n        return canvas.toDataURL('image/png');\n    }\n\n    downloadCanvas(filename: string): void {\n        const dataUrl = this.exportCanvas();\n        const link = document.createElement('a');\n\n        link.download = `${filename}.png`;\n        link.href = dataUrl;\n        link.click();\n    }\n\n    onResize() {\n        this._init();\n    }\n\n    private _init(): void {\n        this.config = this._getConfig();\n        this._truncatedWordsWithFontSize = this._getTruncatedWordsWithFontSize(this.words);\n        this._positionedWords = [];\n        this._drawCanvas();\n        this._centerPoint = { x: this._canvas.width / 2, y: this._canvas.height / 2 };\n\n        this._isFontLoaded().subscribe(() => {\n            this._positionWords();\n\n            if (this.config.debugMode) {\n                console.info('Config', this.config);\n                this._drawSprial();\n            }\n\n            this._cdRef.detectChanges();\n        });\n    }\n\n    /**\n     * Calculates the font size for each word based on its weight and the range of weights in the list of words\n     *\n     * @param words List of words with their respective weights\n     * @returns A new list of words sorted by weight (largest to smallest) with their respective font sizes\n     */\n    private _getTruncatedWordsWithFontSize(words: T[]): IWordWithFontSize<T>[] {\n        const weights = words.map(w => w.weight);\n        const minWeight: number = Math.min(...weights);\n        const maxWeight: number = Math.max(...weights);\n\n        return words\n            .map(word => {\n                return {\n                    ...word,\n                    fontSize: this._getFontSize(word.weight, minWeight, maxWeight),\n                    truncatedValue: this._truncateWord(word.value)\n                };\n            })\n            .sort((a, b) => b.weight - a.weight);\n    }\n\n    private _drawCanvas(): void {\n        this._canvas = this._canvas || this._renderer.createElement('canvas');\n        this._canvas.width = this._elRef.nativeElement.parentElement.clientWidth;\n        this._canvas.height = this._elRef.nativeElement.parentElement.clientHeight;\n        this._ctx = this._canvas.getContext('2d');\n\n        if (this.config.debugMode) {\n            this._renderer.appendChild(this._elRef.nativeElement, this._canvas);\n        }\n    }\n\n    /**\n     * This method is responsible for positioning the words onto a canvas by iterating through each word, finding a suitable location for\n     * it using a spiral algorithm, and checking if the word's bounding box intersects with any existing bounding boxes\n     */\n    private _positionWords(): void {\n        const t1 = performance.now();\n\n        /**\n         * Sets the font details, places the word on the spiral, and calculates the bounding box of the word based on its font size. If the\n         * bounding box intersects with another bounding box, the index is incremented and we try to place it again\n         */\n        const positionWord = (wordWithFontSize: IWordWithFontSize<T>, index: number = 0) => {\n            this._setFontDetails(this._ctx, wordWithFontSize.fontSize);\n\n            const point = this._placeOnSpiral(index);\n            const metrics = this._ctx.measureText(wordWithFontSize.truncatedValue);\n            const fontHeight = (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent) * 1.1;\n            const { paddingX, paddingY } = this.config;\n            const width = metrics.width + paddingX;\n            const height = fontHeight + paddingY;\n\n            /**\n             * Adjust the x and y based on textAlign = \"center\" and textBaseline = \"middle\";\n             */\n            const boundingBox: IBoundingBox = {\n                x: point.x - width / 2,\n                y: point.y - height / 2,\n                width,\n                height\n            };\n\n            /**\n             * If this bounding box intersects another bounding box, increment the index and try the next place\n             */\n            if (this._isIntersecting(boundingBox)) {\n                return positionWord(wordWithFontSize, index + 1);\n            }\n\n            this._positionedWords = this._positionedWords.concat({\n                ...boundingBox,\n                ...wordWithFontSize,\n                canvasX: point.x,\n                canvasY: point.y\n            });\n\n            if (this.config.debugMode) {\n                this._ctx.strokeStyle = 'blue';\n                this._ctx.strokeRect(boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height);\n                this._drawWord(wordWithFontSize, point, this._ctx);\n            }\n        };\n\n        this._truncatedWordsWithFontSize.forEach(word => {\n            positionWord(word);\n        });\n\n        this._positionedWords = this._scalePositionedWords(this._positionedWords);\n\n        /**\n         * Sort words before emitting so that a trackBy function will work correctly with the collection\n         */\n        const sortedWords = this._positionedWords.sort((a, b) => a.value.localeCompare(b.value));\n        this.wordsPositioned.emit(sortedWords);\n\n        if (this.config.debugMode) {\n            console.info(`Words positioned on sprial in ${performance.now() - t1}ms`);\n        }\n    }\n\n    private _truncateWord(value: string): string {\n        if (value.length > this.config.maxCharCount) {\n            return value.substring(0, this.config.maxCharCount) + '...';\n        }\n        return value;\n    }\n\n    private _drawWord(wordWithFontSize: IWordWithFontSize<T>, point: IPoint, ctx: CanvasRenderingContext2D) {\n        ctx.fillStyle = wordWithFontSize.exportColor;\n        ctx.fillText(wordWithFontSize.truncatedValue, point.x, point.y);\n    }\n\n    private _setFontDetails(ctx: CanvasRenderingContext2D, fontSize: number): void {\n        ctx.font = `${this.config.fontWeight} ${fontSize}px/1 ${this.config.fontFamily}`;\n        ctx.textAlign = 'center';\n        ctx.textBaseline = 'middle';\n    }\n\n    private _isIntersecting(boundingBox: IBoundingBox): boolean {\n        /**\n         * Check whether or not two bounding boxes overlap\n         */\n        const doBoxesOverlap = (boxA: IBoundingBox, boxB: IBoundingBox): boolean => {\n            return !(\n                boxA.x + boxA.width < boxB.x ||\n                boxB.x + boxB.width < boxA.x ||\n                boxA.y + boxA.height < boxB.y ||\n                boxB.y + boxB.height < boxA.y\n            );\n        };\n\n        /**\n         * Check if any bounding boxes overlap\n         */\n        return this._positionedWords.some(word => doBoxesOverlap(boundingBox, word));\n    }\n\n    /**\n     * Calculate the font size for a given word weight based on the minimum and maximum weights and the minimum and maximum font sizes\n     * defined in the word cloud configuration object\n     */\n    private _getFontSize(wordWeight: number, minWeight: number, maxWeight: number): number {\n        const weightDiff = maxWeight - minWeight;\n        const factor = (wordWeight - minWeight) / weightDiff;\n        const fontSize = (this.config.maxFontSize - this.config.minFontSize) * factor + this.config.minFontSize;\n\n        /**\n         * fontSize may be NaN if all words have the same weight. If they do, return the fontSize that is midway\n         * between the minFontSize and the maxFontSize\n         */\n        if (fontSize) {\n            return Math.round(fontSize);\n        }\n        return Math.round((this.config.minFontSize + this.config.maxFontSize) / 2);\n    }\n\n    /**\n     * @description This method is used to place a point on a spiral based on the input n. It calculates the coordinates of the\n     * point on the spiral using the spiral helper function and returns an object of type IPoint. The spiral is defined using a combination\n     * of trigonometric functions and aspects such as factor, aspectRatio, and angle.\n     *\n     * @returns An object of type `IPoint` with `x` and `y` properties\n     */\n    private _placeOnSpiral(n: number): IPoint {\n        const spiral = (i: number) => {\n            const aspectRatio = this._canvas.width / this._canvas.height;\n            const angle = i;\n            const x = this._centerPoint.x + (1 + angle) * Math.cos(angle) * this._spiralResolution * aspectRatio;\n            const y = this._centerPoint.y + (1 + angle) * Math.sin(angle) * this._spiralResolution;\n\n            return { x, y };\n        };\n\n        return spiral(n);\n    }\n\n    private _isOutsideCanvas(boundingBox: IBoundingBox, canvasWidth: number, canvasHeight: number): boolean {\n        return (\n            boundingBox.x + boundingBox.width > canvasWidth ||\n            boundingBox.x < 0 ||\n            boundingBox.y + boundingBox.height > canvasHeight ||\n            boundingBox.y < 0\n        );\n    }\n\n    /**\n     * Retrieve the word cloud configuration object by merging default values with any options passed to this component instance\n     */\n    private _getConfig(): IWordCloudConfig {\n        const defaultConfig: IWordCloudConfig = {\n            debugMode: false,\n            fontFamily: 'ProximaNova',\n            fontWeight: 'normal',\n            maxFontSize: 48,\n            minFontSize: 16,\n            paddingX: 8,\n            paddingY: 8,\n            maxCharCount: 20,\n            resizeTolerance: 0\n        };\n\n        return {\n            ...defaultConfig,\n            ...this.options\n        };\n    }\n\n    private _drawSprial(): void {\n        this._ctx.save();\n        this._ctx.fillStyle = 'white';\n\n        for (let i = 0; i < 3000; i++) {\n            const { x, y } = this._placeOnSpiral(i);\n            this._ctx.fillRect(x, y, 1, 1);\n        }\n\n        this._ctx.restore();\n    }\n\n    /**\n     * Determine the amount of overflow for the words that have been placed outside the canvas, calculate the scaling factor for repositioning these\n     * words back inside the canvas, and update and return the placed words with the scaling factor applied\n     */\n    private _scalePositionedWords(positionedWords: IWordWithPosition<T>[]): IWordWithPosition<T>[] {\n        const outOfBounds = positionedWords.filter(word =>\n            this._isOutsideCanvas(word, this._canvas.width, this._canvas.height)\n        );\n\n        /**\n         * Determine the minimum and maximum x-coordinates of the words that are outside the canvas. The minimum x-coordinate is the leftmost\n         * point of any out-of-bounds word, and the maximum x-coordinate is the rightmost point of any out-of-bounds word\n         */\n        const minX = Math.min(...outOfBounds.map(oob => oob.x));\n        const maxX = Math.max(...outOfBounds.map(oob => oob.x + oob.width));\n        /**\n         * Calculate the amount of overflow for the words that are outside the canvas. `overflowLeft` is the amount by which the out-of-bounds words\n         * exceed the left edge of the canvas, and `overflowRight` is the amount by which they exceed the right edge of the canvas\n         */\n        const overflowLeft = minX < 0 ? Math.abs(minX) : 0;\n        const overflowRight = maxX > this._canvas.width ? maxX - this._canvas.width : 0;\n        /**\n         * Find the largest horizontal overflow and double it. As we're scaling towards the center, rather than summing the left\n         * and right overflows we need to take the largest and double it to ensure we don't end up with words being positioned out\n         * of bounds on the x-axis\n         */\n        const overflowX = Math.max(overflowLeft, overflowRight) * 2;\n        const xScale = this._canvas.width / (this._canvas.width + overflowX);\n\n        if (this.config.debugMode) {\n            console.info(`minX: ${minX}, maxX: ${maxX}, overflowX: ${overflowX}, xScale: ${xScale}`);\n        }\n\n        /**\n         * Determine the minimum and maximum y-coordinates of the words that are outside the canvas. The minimum y-coordinate is the topmost\n         * point of any out-of-bounds word, and the maximum Y-coordinate is the bottom-most point of any out-of-bounds word\n         */\n        const minY = Math.min(...outOfBounds.map(oob => oob.y));\n        const maxY = Math.max(...outOfBounds.map(oob => oob.y + oob.height));\n        const overflowTop = minY < 0 ? Math.abs(minY) : 0;\n        const overflowBottom = maxY > this._canvas.height ? maxY - this._canvas.height : 0;\n        /**\n         * Find the largest vertical overflow and double it. As we're scaling towards the center, rather than summing the top\n         * and bottom overflows we need to take the largest and double it to ensure we don't end up with words being positioned out\n         * of bounds on the y-axis\n         */\n        const overflowY = Math.max(overflowTop, overflowBottom) * 2;\n        const yScale = this._canvas.height / (this._canvas.height + overflowY);\n        const minScale = Math.min(xScale, yScale);\n\n        if (this.config.debugMode) {\n            console.info(`minY: ${minY}, maxY: ${maxY}, overflowY: ${overflowY}, yScale: ${yScale}`);\n        }\n\n        const moveTowardsCenter = (x: number, y: number, height: number, scale: number) => {\n            const scaledHeightOffset = (height / 4) * scale;\n            const dx = this._centerPoint.x - x;\n            const dy = this._centerPoint.y - y + scaledHeightOffset;\n            /**\n             * Determine the distance between the current position and the target position (the center) and\n             * multiply it by our scale (between 0 and 1) to move partway towards the target\n             */\n            const dist = Math.sqrt(dx * dx + dy * dy) * (1 - scale);\n            /**\n             * Calculate the angle at which we should move and the update our x and y using our calculated distance and angle\n             *\n             * ref: https://stackoverflow.com/a/5995931/1128290\n             */\n            const angle = Math.atan2(dy, dx);\n\n            return {\n                x: x + dist * Math.cos(angle),\n                y: y + dist * Math.sin(angle)\n            };\n        };\n\n        return this._positionedWords.map(pw => {\n            const { x, y } = moveTowardsCenter(pw.x, pw.y, pw.height, minScale);\n            const { x: canvasX, y: canvasY } = moveTowardsCenter(pw.canvasX, pw.canvasY, pw.height, minScale);\n            const width = pw.width * minScale;\n            const height = pw.height * minScale;\n            const fontSize = pw.fontSize * minScale;\n\n            return {\n                ...pw,\n                canvasX,\n                canvasY,\n                x,\n                y,\n                width,\n                height,\n                fontSize\n            };\n        });\n    }\n\n    private _isFontLoaded(): Observable<{ isLoaded: boolean }> {\n        const fontTimeout = 5000;\n        /**\n         * Needs to be a valid font string\n         * ref: https://developer.mozilla.org/en-US/docs/Web/CSS/font\n         */\n        const fontString = `${this.config.fontWeight} 12px ${this.config.fontFamily}`;\n\n        return interval(250).pipe(\n            startWith(0),\n            map(_x => this._document.fonts.check(fontString)),\n            filter(isLoaded => isLoaded),\n            map(isLoaded => ({ isLoaded })),\n            take(1),\n            timeout(fontTimeout),\n            catchError(_e => {\n                console.warn(`The font \"${fontString}\" failed to load within ${fontTimeout}ms`);\n                return of({ isLoaded: false });\n            })\n        );\n    }\n}\n","<div\n    class=\"nw-word-cloud-container\"\n    nwResizeObserver\n    [element]=\"elRef.nativeElement\"\n    [tolerance]=\"config.resizeTolerance\"\n    (nwResize)=\"onResize()\">\n    <div\n        class=\"font-loader\"\n        [style.fontFamily]=\"config.fontFamily\"\n        [style.fontWeight]=\"config.fontWeight\">\n        This element is hidden and is used to delay drawing to the canvas until the font is loaded. If we don't wait and\n        the font has not loaded, the word will be drawn to the canvas with a fallback font and, as a result, will not be\n        positioned correctly when used with the supplied font details\n    </div>\n    <ng-content></ng-content>\n</div>\n","import { ChangeDetectionStrategy, Component, HostBinding, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { IWord } from './models/IWord';\nimport { IWordWithPosition } from './models/IWordWithPosition';\n\n@Component({\n    selector: 'nw-word',\n    templateUrl: './word.component.html',\n    changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class WordComponent<T extends IWord> implements OnChanges {\n    @Input() word: IWordWithPosition<T>;\n\n    @HostBinding('style.translate')\n    public translate: string;\n    @HostBinding('style.fontSize.px')\n    public fontSize: number;\n    @HostBinding('style.lineHeight.px')\n    public lineHeight: number;\n    @HostBinding('style.width.px')\n    public width: number;\n\n    ngOnChanges(changes: SimpleChanges) {\n        if (changes.word?.currentValue !== changes.word?.previousValue) {\n            this.translate = `${this.word.x}px ${this.word.y}px`;\n            this.fontSize = this.word.fontSize;\n            this.lineHeight = this.word.height;\n            this.width = this.word.width;\n        }\n    }\n}\n","{{ word.truncatedValue }}\n","export { IWord } from './models/IWord';\nexport { IWordWithPosition } from './models/IWordWithPosition';\nexport { IWordCloudConfig } from './models/IWordCloudConfig';\nexport { WordCloudComponent } from './word-cloud.component';\nexport { WordComponent } from './word.component';\n\nimport { WordCloudComponent } from './word-cloud.component';\nimport { WordComponent } from './word.component';\n\n/**\n * Export cooperating directives\n * https://v17.angular.io/guide/standalone-components#standalone-components-for-library-authors\n */\nexport const WORD_CLOUD_COMPONENTS = [WordCloudComponent, WordComponent] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}