<commit_before>import {CodeMapNode} from "../data/model/CodeMap";
import {node} from "../../ui/codeMap/rendering/node";
import {DataService} from "../data/data.service";

export interface ValuedCodeMapNode {
    data: CodeMapNode;
    children?: ValuedCodeMapNode[];
    value: number;
}

export interface SquarifiedValuedCodeMapNode {
    data: CodeMapNode;
    children?: SquarifiedValuedCodeMapNode[];
    value: number;
    x0: number;
    y0: number;
    width: number;
    length: number;
}

/**
 *  Y
 * y1       *-------*
 *  |       |       |
 *  |       l       |
 *  |       e       |
 *  |       n       |
 *  |       g       |
 *  |       t       |
 *  |       h       |
 *  |       |       |
 * y0       *-width-*
 *  |
 *  0 - - - x0- - - x1 - - X
 */
export class TreeMapService {

    public static SELECTOR = "treeMapService";

    /* @ngInject */
    constructor(private dataService: DataService) {
    }

    public createTreemapNodes(data: CodeMapNode,
                              w: number,
                              l: number,
                              areaKey: string,
                              heightKey: string
    ): node[] {
        let valued: ValuedCodeMapNode = this.valueCodeMapNodes(data, areaKey);
        this.scaleValuedCodeMapNodesToMapSize(valued, w, l);
        let squarified: SquarifiedValuedCodeMapNode = this.squarify(valued, w, l);
        let resultingNodes: node[] = [];
        console.log(this.addHeightDimension(squarified, heightKey, resultingNodes));
        return resultingNodes;
    }

    public addHeightDimension(squaredNode: SquarifiedValuedCodeMapNode, key: string, collected: node[] = [], depth = 0, height = 5): node {

        let finalNode = {
            name : squaredNode.data.name,
            width : Math.max(squaredNode.width,1),
            height : height,
            length : Math.max(squaredNode.length,1),
            depth : depth,
            x0 : squaredNode.x0,
            z0 : depth*height,
            y0 : squaredNode.y0,
            isLeaf : false,
            attributes : squaredNode.data.attributes,
            deltas : squaredNode.data.deltas,
            parent : null,
            heightDelta : 0,
            visible : true,
            path : "some path",
            children : []
        };

        if (squaredNode.children) {
            let finalChildren: node[] = [];
            for (let i = 0; i < squaredNode.children.length; i++) {
                finalChildren.push(this.addHeightDimension(squaredNode.children[i], key, collected, depth + 1));
            }
            finalNode.children = finalChildren;
        }

        collected.push(finalNode);
        return finalNode;
    }

    public squarify(node: ValuedCodeMapNode, containerWidth: number, containerLength: number, xContainerOffset: number = 0, yContainerOffset = 0): SquarifiedValuedCodeMapNode {

        console.log(containerWidth, containerLength);
        let squarifiedNode: SquarifiedValuedCodeMapNode = {
            value: node.value,
            data: node.data,
            x0: xContainerOffset,
            y0: yContainerOffset,
            width: containerWidth,
            length: containerLength,
        };

        if (node.children) {
            let squarifiedChildren: SquarifiedValuedCodeMapNode[] = [];
            let sortedValuedCodeMapNodes = node.children.sort((a, b) => b.value - a.value);

            let xRowOffset = xContainerOffset;
            let yRowOffset = yContainerOffset;

            for (let i = 0; i < sortedValuedCodeMapNodes.length; i++) {

                let x0 = xRowOffset;
                let y0 = yRowOffset;
                let childWidth = 0;
                let childLength = 0;

                if (containerWidth + xContainerOffset - xRowOffset> containerLength + yContainerOffset - yRowOffset) {
                    childLength = containerLength-yRowOffset;
                    childWidth = sortedValuedCodeMapNodes[i].value / containerLength;
                    xRowOffset += childWidth;
                } else {
                    childWidth = containerWidth-xRowOffset;
                    childLength = sortedValuedCodeMapNodes[i].value / containerWidth;
                    yRowOffset += childLength;
                }

                squarifiedChildren.push(
                    this.squarify(sortedValuedCodeMapNodes[i], childWidth-xRowOffset, childLength-yRowOffset, x0, y0)
                );

                //TODO step back when aspect ratio gets worse

            }
            squarifiedNode.children = squarifiedChildren;
        }

        return squarifiedNode;

    }<commit_msg>WIP: works in one dimension<commit_after>import {CodeMapNode} from "../data/model/CodeMap";
import {node} from "../../ui/codeMap/rendering/node";
import {DataService} from "../data/data.service";

export interface ValuedCodeMapNode {
    data: CodeMapNode;
    children?: ValuedCodeMapNode[];
    value: number;
}

export interface SquarifiedValuedCodeMapNode {
    data: CodeMapNode;
    children?: SquarifiedValuedCodeMapNode[];
    value: number;
    x0: number;
    y0: number;
    width: number;
    length: number;
}

/**
 *  Y
 * y1       *-------*
 *  |       |       |
 *  |       l       |
 *  |       e       |
 *  |       n       |
 *  |       g       |
 *  |       t       |
 *  |       h       |
 *  |       |       |
 * y0       *-width-*
 *  |
 *  0 - - - x0- - - x1 - - X
 */
export class TreeMapService {

    public static SELECTOR = "treeMapService";

    /* @ngInject */
    constructor(private dataService: DataService) {
    }

    public createTreemapNodes(data: CodeMapNode,
                              w: number,
                              l: number,
                              areaKey: string,
                              heightKey: string
    ): node[] {
        let valued: ValuedCodeMapNode = this.valueCodeMapNodes(data, areaKey);
        this.scaleValuedCodeMapNodesToMapSize(valued, w, l);
        let squarified: SquarifiedValuedCodeMapNode = this.squarify(valued, w, l);
        let resultingNodes: node[] = [];
        console.log(this.addHeightDimension(squarified, heightKey, resultingNodes));
        return resultingNodes;
    }

    public addHeightDimension(squaredNode: SquarifiedValuedCodeMapNode, key: string, collected: node[] = [], depth = 0, height = 5): node {

        let finalNode = {
            name : squaredNode.data.name,
            width : Math.max(squaredNode.width,1),
            height : height,
            length : Math.max(squaredNode.length,1),
            depth : depth,
            x0 : squaredNode.x0,
            z0 : depth*height,
            y0 : squaredNode.y0,
            isLeaf : false,
            attributes : squaredNode.data.attributes,
            deltas : squaredNode.data.deltas,
            parent : null,
            heightDelta : 0,
            visible : true,
            path : "some path",
            children : []
        };

        if (squaredNode.children) {
            let finalChildren: node[] = [];
            for (let i = 0; i < squaredNode.children.length; i++) {
                finalChildren.push(this.addHeightDimension(squaredNode.children[i], key, collected, depth + 1));
            }
            finalNode.children = finalChildren;
        }

        collected.push(finalNode);
        return finalNode;
    }

    public squarify(node: ValuedCodeMapNode, containerWidth: number, containerLength: number, xContainerOffset: number = 0, yContainerOffset = 0): SquarifiedValuedCodeMapNode {

        console.log(containerWidth, containerLength);
        let squarifiedNode: SquarifiedValuedCodeMapNode = {
            value: node.value,
            data: node.data,
            x0: xContainerOffset,
            y0: yContainerOffset,
            width: containerWidth,
            length: containerLength,
        };

        if (node.children) {
            let squarifiedChildren: SquarifiedValuedCodeMapNode[] = [];
            let sortedValuedCodeMapNodes = node.children.sort((a, b) => b.value - a.value);

            let xRowOffset = xContainerOffset;
            let yRowOffset = yContainerOffset;

            let x0 = squarifiedNode.x0;
            let y0 = squarifiedNode.y0;

            let childWidth = squarifiedNode.width;
            let childLength = squarifiedNode.length;

            for (let i = 0; i < sortedValuedCodeMapNodes.length; i++) {

                childLength = containerLength;
                childWidth = sortedValuedCodeMapNodes[i].value / childLength;
                squarifiedChildren.push(this.squarify(sortedValuedCodeMapNodes[i], childWidth, childLength, x0, y0));
                x0 += childWidth;

                //TODO step back when aspect ratio gets worse

            }
            squarifiedNode.children = squarifiedChildren;
        }

        return squarifiedNode;

    }
{'fraction_non_alphanumeric': 0.10140686550365785, 'fraction_numerical': 0.006865503657850309, 'mean_word_length': 1.7562034739454093, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1790415', 'n_tokens_mistral': 2572, 'n_tokens_neox': 2442, 'n_words': 530}