<commit_before>import Config = require('../config');
import ErrorHandling = require('../error-handling');
import Queries = require('../../core/queries/queries');
import Api = require('../../core/api');
import _ = require('underscore');
import Common = require('../visualization');
import Loader = require('../loader');
import ResultHandling = require('../result-handling');
import Dom = require('../dom');
import Counter = require('./counter');
import Classes = require('../css-classes');
import deepExtend = require('deep-extend');

class Text implements Common.Visualization {
    private _options: Config.VisualizationOptions;
    private _currentValue: number;
    private _rendered: boolean;
    private _destroyDom: () => void;
    private _valueTextElement: HTMLElement;
    private _valueContainerElement: HTMLElement;
    private _counter: Counter;
    private _counterDuration: number;

    constructor(textOptions: Config.VisualizationOptions) {
        var defaultOptions = { 
            transitionOnReload: true,
            text: {
                counterDurationMs: 800
            },
            fields: {} 
        };

        this._options = deepExtend({}, defaultOptions, textOptions);
        this._currentValue = 0;
    }

    public renderDom(vizElement: HTMLElement, resultsElement: HTMLElement){
        var spanForValues = Dom.createElement('span'),
            valueTextElement = Dom.createElement('span', Classes.textValue),
            valueIncreaseIconElement = Dom.createElement('span', Classes.textIcon, Classes.textIconInc, Classes.arrowUp),
            valueDecreaseIconElement = Dom.createElement('span', Classes.textIcon, Classes.textIconDec, Classes.arrowDown);

        vizElement.classList.add(Classes.text)

        spanForValues.appendChild(valueIncreaseIconElement);
        spanForValues.appendChild(valueDecreaseIconElement);
        spanForValues.appendChild(valueTextElement);
        resultsElement.appendChild(spanForValues);

        this._valueContainerElement = resultsElement;
        this._valueTextElement = valueTextElement;
        this._valueTextElement.innerHTML = '&nbsp;';
    }

    public displayResults(results: Api.QueryResults, isQueryUpdate: boolean): void {
        var options = this._options,
            metadata = results.metadata,
            selects = results.selects(),
            onlyResult = results.results[0],
            aliasOfSelect = selects[0],
            defaultFieldOption = { valueFormatter: (value) => value },
            fieldOption = options.fields[aliasOfSelect] || defaultFieldOption,
            valueFormatter = fieldOption.valueFormatter,
            value = onlyResult[aliasOfSelect],
            animationElementClassList = this._valueContainerElement.classList,
            isIncreasing = value > this._currentValue,
            hasChanged = valueFormatter(this._currentValue) !== valueFormatter(value),
            duration = options.text.counterDurationMs,
            transitionClass = isIncreasing ? Classes.textValueInc : Classes.textValueDec; 

        this._currentValue = value;
        this._counter = this._counter || new Counter(this._valueTextElement, duration, valueFormatter);

        if (!hasChanged)
            return;
        
        if (!options.transitionOnReload && isQueryUpdate){<commit_msg>Fixes crash when options with no value formatter is provided<commit_after>import Config = require('../config');
import ErrorHandling = require('../error-handling');
import Queries = require('../../core/queries/queries');
import Api = require('../../core/api');
import _ = require('underscore');
import Common = require('../visualization');
import Loader = require('../loader');
import ResultHandling = require('../result-handling');
import Dom = require('../dom');
import Counter = require('./counter');
import Classes = require('../css-classes');
import deepExtend = require('deep-extend');

class Text implements Common.Visualization {
    private _options: Config.VisualizationOptions;
    private _currentValue: number;
    private _rendered: boolean;
    private _destroyDom: () => void;
    private _valueTextElement: HTMLElement;
    private _valueContainerElement: HTMLElement;
    private _counter: Counter;
    private _counterDuration: number;

    constructor(textOptions: Config.VisualizationOptions) {
        var defaultOptions = { 
            transitionOnReload: true,
            text: {
                counterDurationMs: 800
            },
            fields: {} 
        };

        this._options = deepExtend({}, defaultOptions, textOptions);
        this._currentValue = 0;
    }

    public renderDom(vizElement: HTMLElement, resultsElement: HTMLElement){
        var spanForValues = Dom.createElement('span'),
            valueTextElement = Dom.createElement('span', Classes.textValue),
            valueIncreaseIconElement = Dom.createElement('span', Classes.textIcon, Classes.textIconInc, Classes.arrowUp),
            valueDecreaseIconElement = Dom.createElement('span', Classes.textIcon, Classes.textIconDec, Classes.arrowDown);

        vizElement.classList.add(Classes.text)

        spanForValues.appendChild(valueIncreaseIconElement);
        spanForValues.appendChild(valueDecreaseIconElement);
        spanForValues.appendChild(valueTextElement);
        resultsElement.appendChild(spanForValues);

        this._valueContainerElement = resultsElement;
        this._valueTextElement = valueTextElement;
        this._valueTextElement.innerHTML = '&nbsp;';
    }

    public displayResults(results: Api.QueryResults, isQueryUpdate: boolean): void {
        var options = this._options,
            metadata = results.metadata,
            selects = results.selects(),
            onlyResult = results.results[0],
            aliasOfSelect = selects[0],
            defaultFieldOption = { valueFormatter: (value) => value },
            fieldOption = options.fields[aliasOfSelect] || defaultFieldOption,
            valueFormatter = fieldOption.valueFormatter || defaultFieldOption.valueFormatter,
            value = onlyResult[aliasOfSelect],
            animationElementClassList = this._valueContainerElement.classList,
            isIncreasing = value > this._currentValue,
            hasChanged = valueFormatter(this._currentValue) !== valueFormatter(value),
            duration = options.text.counterDurationMs,
            transitionClass = isIncreasing ? Classes.textValueInc : Classes.textValueDec; 

        this._currentValue = value;
        this._counter = this._counter || new Counter(this._valueTextElement, duration, valueFormatter);

        if (!hasChanged)
            return;
        
        if (!options.transitionOnReload && isQueryUpdate){
{'fraction_non_alphanumeric': 0.10765336509827278, 'fraction_numerical': 0.001786777843954735, 'mean_word_length': 3.1539888682745825, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '3786253', 'n_tokens_mistral': 1695, 'n_tokens_neox': 1626, 'n_words': 343}