<commit_before>import { Scene } from "../scene/scene";
import { Group } from "../scene/group";
import { Series, SeriesNodeDatum } from "./series/series";
import { Padding } from "../util/padding";
import { Shape } from "../scene/shape/shape";
import { Node } from "../scene/node";
import { Rect } from "../scene/shape/rect";
import { Legend, LegendDatum } from "./legend";
import { BBox } from "../scene/bbox";
import { find } from "../util/array";
import { Caption } from "../caption";
import { Observable, reactive, PropertyChangeEventListener } from "../util/observable";
import { ChartAxis, ChartAxisDirection } from "./chartAxis";
import { CartesianSeries } from "./series/cartesian/cartesianSeries";
import { createId } from "../util/id";

const defaultTooltipCss = `
.ag-chart-tooltip {
    display: table;
    position: absolute;
    user-select: none;
    pointer-events: none;
    white-space: nowrap;
    z-index: 99999;
    font: 12px Verdana, sans-serif;
    color: black;
    background: rgb(244, 244, 244);
    border-radius: 5px;
    box-shadow: 0 0 1px rgba(3, 3, 3, 0.7), 0.5vh 0.5vh 1vh rgba(3, 3, 3, 0.25);
    opacity: 0;
    transform: scale(0.90);
    transition: 0.3s cubic-bezier(0.19, 1, 0.22, 1);
    transition-property: opacity, transform;
}

.ag-chart-tooltip-visible {
    opacity: 1;
    transform: scale(1);
}

.ag-chart-tooltip-title {
    font-weight: bold;
    padding: 7px;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    color: white;
    background-color: #888888;
}

.ag-chart-tooltip-content {
    padding: 7px;
    line-height: 1.7em;
}
`;

export abstract class Chart extends Observable {
    readonly id = createId(this);

    readonly scene: Scene;
    readonly background: Rect = new Rect();
    readonly legend = new Legend();

    protected legendAutoPadding = new Padding();
    protected captionAutoPadding = 0; // top padding only

    private tooltipElement: HTMLDivElement;
    static readonly defaultTooltipClass = 'ag-chart-tooltip';
    tooltipOffset: [number, number] = [20, 20];

    set container(value: HTMLElement | undefined) {
        this.scene.container = value;
    }
    get container(): HTMLElement | undefined {
        return this.scene.container;
    }

    private _data: any[] = [];
    set data(data: any[]) {
        this._data = data;
        this.series.forEach(series => series.data = data);
    }
    get data(): any[] {
        return this._data;
    }

    private pendingSize?: [number, number];

    set width(value: number) {
        if (this.width !== value) {
            this.pendingSize = [value, this.height];
            this.fireEvent({ type: 'layoutChange' });
        }
    }
    get width(): number {
        return this.pendingSize ? this.pendingSize[0] : this.scene.width;
    }

    set height(value: number) {
        if (this.height !== value) {
            this.pendingSize = [this.width, value];
            this.fireEvent({ type: 'layoutChange' });
        }
    }
    get height(): number {
        return this.pendingSize ? this.pendingSize[1] : this.scene.height;
    }

    @reactive('layoutChange') padding = new Padding(20);
    @reactive('layoutChange') title?: Caption;
    @reactive('layoutChange') subtitle?: Caption;

    private static tooltipDocuments: Document[] = [];

    protected constructor(document = window.document) {
        super();

        const root = new Group();
        const background = this.background;

        background.fill = 'white';
        root.appendChild(background);

        const scene = new Scene(document);
        this.scene = scene;
        scene.root = root;

        const { legend } = this;
        legend.addEventListener('layoutChange', this.onLayoutChange);
        legend.addPropertyListener('position', this.onLegendPositionChange);

        this.tooltipElement = document.createElement('div');
        this.tooltipClass = '';
        document.body.appendChild(this.tooltipElement);

        if (Chart.tooltipDocuments.indexOf(document) < 0) {
            const styleElement = document.createElement('style');
            styleElement.innerHTML = defaultTooltipCss;
            document.head.appendChild(styleElement);
            Chart.tooltipDocuments.push(document);
        }
<commit_msg>AG-3110 - Make sure the default tooltip style goes before other styles so it can be overridden.<commit_after>import { Scene } from "../scene/scene";
import { Group } from "../scene/group";
import { Series, SeriesNodeDatum } from "./series/series";
import { Padding } from "../util/padding";
import { Shape } from "../scene/shape/shape";
import { Node } from "../scene/node";
import { Rect } from "../scene/shape/rect";
import { Legend, LegendDatum } from "./legend";
import { BBox } from "../scene/bbox";
import { find } from "../util/array";
import { Caption } from "../caption";
import { Observable, reactive, PropertyChangeEventListener } from "../util/observable";
import { ChartAxis, ChartAxisDirection } from "./chartAxis";
import { CartesianSeries } from "./series/cartesian/cartesianSeries";
import { createId } from "../util/id";

const defaultTooltipCss = `
.ag-chart-tooltip {
    display: table;
    position: absolute;
    user-select: none;
    pointer-events: none;
    white-space: nowrap;
    z-index: 99999;
    font: 12px Verdana, sans-serif;
    color: black;
    background: rgb(244, 244, 244);
    border-radius: 5px;
    box-shadow: 0 0 1px rgba(3, 3, 3, 0.7), 0.5vh 0.5vh 1vh rgba(3, 3, 3, 0.25);
    opacity: 0;
    transform: scale(0.90);
    transition: 0.3s cubic-bezier(0.19, 1, 0.22, 1);
    transition-property: opacity, transform;
}

.ag-chart-tooltip-visible {
    opacity: 1;
    transform: scale(1);
}

.ag-chart-tooltip-title {
    font-weight: bold;
    padding: 7px;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    color: white;
    background-color: #888888;
}

.ag-chart-tooltip-content {
    padding: 7px;
    line-height: 1.7em;
}
`;

export abstract class Chart extends Observable {
    readonly id = createId(this);

    readonly scene: Scene;
    readonly background: Rect = new Rect();
    readonly legend = new Legend();

    protected legendAutoPadding = new Padding();
    protected captionAutoPadding = 0; // top padding only

    private tooltipElement: HTMLDivElement;
    static readonly defaultTooltipClass = 'ag-chart-tooltip';
    tooltipOffset: [number, number] = [20, 20];

    set container(value: HTMLElement | undefined) {
        this.scene.container = value;
    }
    get container(): HTMLElement | undefined {
        return this.scene.container;
    }

    private _data: any[] = [];
    set data(data: any[]) {
        this._data = data;
        this.series.forEach(series => series.data = data);
    }
    get data(): any[] {
        return this._data;
    }

    private pendingSize?: [number, number];

    set width(value: number) {
        if (this.width !== value) {
            this.pendingSize = [value, this.height];
            this.fireEvent({ type: 'layoutChange' });
        }
    }
    get width(): number {
        return this.pendingSize ? this.pendingSize[0] : this.scene.width;
    }

    set height(value: number) {
        if (this.height !== value) {
            this.pendingSize = [this.width, value];
            this.fireEvent({ type: 'layoutChange' });
        }
    }
    get height(): number {
        return this.pendingSize ? this.pendingSize[1] : this.scene.height;
    }

    @reactive('layoutChange') padding = new Padding(20);
    @reactive('layoutChange') title?: Caption;
    @reactive('layoutChange') subtitle?: Caption;

    private static tooltipDocuments: Document[] = [];

    protected constructor(document = window.document) {
        super();

        const root = new Group();
        const background = this.background;

        background.fill = 'white';
        root.appendChild(background);

        const scene = new Scene(document);
        this.scene = scene;
        scene.root = root;

        const { legend } = this;
        legend.addEventListener('layoutChange', this.onLayoutChange);
        legend.addPropertyListener('position', this.onLegendPositionChange);

        this.tooltipElement = document.createElement('div');
        this.tooltipClass = '';
        document.body.appendChild(this.tooltipElement);

        if (Chart.tooltipDocuments.indexOf(document) < 0) {
            const styleElement = document.createElement('style');
            styleElement.innerHTML = defaultTooltipCss;
            // Make sure the default tooltip style goes before other styles so it can be overridden.
            document.head.insertBefore(styleElement, document.head.querySelector('style'));
            Chart.tooltipDocuments.push(document);
        }

{'fraction_non_alphanumeric': 0.1362599771949829, 'fraction_numerical': 0.01733181299885975, 'mean_word_length': 2.7708512467755804, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3130996', 'n_tokens_mistral': 2676, 'n_tokens_neox': 2498, 'n_words': 657}