function infertype()

in src/infertypes.ts [256:332]


    function infertype(key: string, hint: HiPlotValueDef): ParamDef {
        var url_state = url_states.children(key);
        var optional = false;
        var numeric = ["uid", "from_uid"].indexOf(key) == -1;
        var can_be_timestamp = numeric;
        var setVals = [];
        var addValue = function(v) {
            if (v === undefined) {
                optional = true;
                return;
            }
            var is_special_num = is_special_numeric(v);
            setVals.push(v);
            // Detect non-numeric column
            if ((typeof v != "number" && !is_special_num && isNaN(v)) ||
                    v === true || v === false) {
                numeric = false;
                can_be_timestamp = false;
            }
            if (!Number.isSafeInteger(v) || v < 0) {
                can_be_timestamp = false;
            }
        }
        table.forEach(function(row) {
            addValue(row[key]);
        });
        var values = setVals;
        var distinct_values = Array.from(new Set(values));
        const numericSorted = numeric ? get_numeric_values_sorted(distinct_values) : [];
        var spansMultipleOrdersOfMagnitude = false;
        if (numericSorted.length > 10 && numericSorted[0] > 0) {
            var top5pct = numericSorted[Math.min(numericSorted.length - 1, ~~(19 * numericSorted.length / 20))];
            var bot5pct = numericSorted[~~(numericSorted.length / 20)];
            spansMultipleOrdersOfMagnitude = (top5pct / bot5pct) > 100;
        }
        var categorical = !numeric || ((Math.max(values.length, 10) / distinct_values.length) > 10 && distinct_values.length < 6);
        var type = ParamType.CATEGORICAL;
        if (numeric && !categorical) {
            type = ParamType.NUMERIC;
            if (spansMultipleOrdersOfMagnitude) {
                type = numericSorted[0] > 0 ? ParamType.NUMERICLOG : ParamType.NUMERICPERCENTILE;
            }
        }
        if (hint !== undefined && hint.type !== null) {
            type = hint.type;
        } else {
            type = url_state.get('type', type);
        }

        var info = {
            'name': key,
            'optional': optional,
            'numeric': numeric,
            'distinct_values': distinct_values,
            'type_options': [ParamType.CATEGORICAL],

            'type': type,
            'colors': hint !== undefined ? hint.colors : null,
            'colormap': hint !== undefined ? hint.colormap : null,
            'force_value_min': hint !== undefined && hint.force_value_min != null ? hint.force_value_min : null,
            'force_value_max': hint !== undefined && hint.force_value_max != null ? hint.force_value_max : null,
            'label_css': hint !== undefined && hint.label_css !== null ? hint.label_css : "",
            'label_html': hint !== undefined && hint.label_html !== null && hint.label_html !== undefined ? hint.label_html : $("<div>").text(key).html(),
        };
        // What other types we can render as?
        if (numeric) {
            info.type_options.push(ParamType.NUMERIC);
            if (numericSorted[0] > 0) {
                info.type_options.push(ParamType.NUMERICLOG);
            }
            info.type_options.push(ParamType.NUMERICPERCENTILE);
            if (can_be_timestamp) {
                info.type_options.push(ParamType.TIMESTAMP);
            }
        }
        return info;
    }