"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSingleKeyValues = exports.getFontSizeMapping = exports.processImageMask = exports.transform = void 0;
var tslib_1 = require("tslib");
var util_1 = require("@antv/util");
var utils_1 = require("../../utils");
var word_cloud_1 = require("../../utils/transform/word-cloud");
/**
 * 用 DataSet 转换词云图数据
 * @param params
 */
function transform(params) {
    var rawOptions = params.options, chart = params.chart;
    var data = rawOptions.data, imageMask = rawOptions.imageMask, wordField = rawOptions.wordField, weightField = rawOptions.weightField, colorField = rawOptions.colorField, wordStyle = rawOptions.wordStyle, timeInterval = rawOptions.timeInterval, random = rawOptions.random, spiral = rawOptions.spiral, placementStrategy = rawOptions.placementStrategy;
    if (!data || !data.length) {
        return [];
    }
    var fontFamily = wordStyle.fontFamily, fontWeight = wordStyle.fontWeight, padding = wordStyle.padding, fontSize = wordStyle.fontSize;
    var arr = getSingleKeyValues(data, weightField);
    var range = [min(arr), max(arr)];
    // 变换出 text 和 value 字段
    var words = data.map(function (datum) { return ({
        text: datum[wordField],
        value: datum[weightField],
        color: datum[colorField],
        datum: datum,
    }); });
    var options = {
        imageMask: imageMask,
        font: fontFamily,
        fontSize: getFontSizeMapping(fontSize, range),
        fontWeight: fontWeight,
        // 图表宽高减去 padding 之后的宽高
        size: getSize(params),
        padding: padding,
        timeInterval: timeInterval,
        random: random,
        spiral: spiral,
        rotate: getRotate(rawOptions),
    };
    // 自定义布局函数
    if (util_1.isFunction(placementStrategy)) {
        var result = words.map(function (word, index, words) { return (tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, word), { hasText: !!word.text, font: word_cloud_1.functor(options.font)(word, index, words), weight: word_cloud_1.functor(options.fontWeight)(word, index, words), rotate: word_cloud_1.functor(options.rotate)(word, index, words), size: word_cloud_1.functor(options.fontSize)(word, index, words), style: 'normal' }), placementStrategy.call(chart, word, index, words))); });
        // 添加两个参照数据，分别表示左上角和右下角
        result.push({
            text: '',
            value: 0,
            x: 0,
            y: 0,
            opacity: 0,
        });
        result.push({
            text: '',
            value: 0,
            x: options.size[0],
            y: options.size[1],
            opacity: 0,
        });
        return result;
    }
    // 数据准备在外部做，wordCloud 单纯就是做布局
    return word_cloud_1.wordCloud(words, options);
}
exports.transform = transform;
/**
 * 获取最终的实际绘图尺寸：[width, height]
 * @param chart
 */
function getSize(params) {
    var chart = params.chart, options = params.options;
    var _a = options.autoFit, autoFit = _a === void 0 ? true : _a;
    var width = chart.width, height = chart.height;
    // 由于词云图每个词语的坐标都是先通过 DataSet 根据图表宽高计算出来的，
    // 也就是说，如果一开始提供给 DataSet 的宽高信息和最终显示的宽高不相同，
    // 那么就会出现布局错乱的情况，所以这里处理的目的就是让一开始提供给 DataSet 的
    // 宽高信息与最终显示的宽高信息相同，避免显示错乱。
    if (autoFit) {
        var containerSize = utils_1.getContainerSize(chart.ele);
        width = containerSize.width || 0;
        height = containerSize.height || 0;
    }
    var _b = resolvePadding(chart), top = _b[0], right = _b[1], bottom = _b[2], left = _b[3];
    var result = [width - (left + right), height - (top + bottom)];
    return result;
}
/**
 * 根据图表的 padding 和 appendPadding 计算出图表的最终 padding
 * @param chart
 */
function resolvePadding(chart) {
    var padding = normalPadding(chart.padding);
    var appendPadding = normalPadding(chart.appendPadding);
    var top = padding[0] + appendPadding[0];
    var right = padding[1] + appendPadding[1];
    var bottom = padding[2] + appendPadding[2];
    var left = padding[3] + appendPadding[3];
    return [top, right, bottom, left];
}
/**
 * 把 padding 转换成统一的数组写法
 * @param padding
 */
function normalPadding(padding) {
    if (util_1.isNumber(padding)) {
        return [padding, padding, padding, padding];
    }
    if (util_1.isArray(padding)) {
        var length_1 = padding.length;
        if (length_1 === 1) {
            return [padding[0], padding[0], padding[0], padding[0]];
        }
        if (length_1 === 2) {
            return [padding[0], padding[1], padding[0], padding[1]];
        }
        if (length_1 === 3) {
            return [padding[0], padding[1], padding[2], padding[1]];
        }
        if (length_1 === 4) {
            return padding;
        }
    }
    return [0, 0, 0, 0];
}
/**
 * 处理 imageMask 可能为 url 字符串的情况
 * @param  {HTMLImageElement | string} img
 * @return {Promise}
 */
function processImageMask(img) {
    return new Promise(function (res, rej) {
        if (img instanceof HTMLImageElement) {
            res(img);
            return;
        }
        if (util_1.isString(img)) {
            var image_1 = new Image();
            image_1.crossOrigin = 'anonymous';
            image_1.src = img;
            image_1.onload = function () {
                res(image_1);
            };
            image_1.onerror = function () {
                utils_1.log(utils_1.LEVEL.ERROR, false, 'image %s load failed !!!', img);
                rej();
            };
            return;
        }
        utils_1.log(utils_1.LEVEL.WARN, img === undefined, 'The type of imageMask option must be String or HTMLImageElement.');
        rej();
    });
}
exports.processImageMask = processImageMask;
/**
 * 把用户提供的 fontSize 值转换成符合 DataSet 要求的值
 * @param options
 * @param range
 */
function getFontSizeMapping(fontSize, range) {
    if (util_1.isFunction(fontSize)) {
        return fontSize;
    }
    if (util_1.isArray(fontSize)) {
        var fMin_1 = fontSize[0], fMax_1 = fontSize[1];
        if (!range) {
            return function () { return (fMax_1 + fMin_1) / 2; };
        }
        var min_1 = range[0], max_1 = range[1];
        if (max_1 === min_1) {
            return function () { return (fMax_1 + fMin_1) / 2; };
        }
        return function fontSize(_a) {
            var value = _a.value;
            return ((fMax_1 - fMin_1) / (max_1 - min_1)) * (value - min_1) + fMin_1;
        };
    }
    return function () { return fontSize; };
}
exports.getFontSizeMapping = getFontSizeMapping;
function getSingleKeyValues(data, key) {
    return data
        .map(function (v) { return v[key]; })
        .filter(function (v) {
        // 过滤非 number
        if (typeof v === 'number' && !isNaN(v))
            return true;
        return false;
    });
}
exports.getSingleKeyValues = getSingleKeyValues;
/**
 * 把用户提供的关于旋转角度的字段值转换成符合 DataSet 要求的值
 * @param options
 */
function getRotate(options) {
    var _a = resolveRotate(options), rotation = _a.rotation, rotationSteps = _a.rotationSteps;
    if (!util_1.isArray(rotation))
        return rotation;
    var min = rotation[0];
    var max = rotation[1];
    // 等于 1 时不旋转，所以把每份大小设为 0
    var perSize = rotationSteps === 1 ? 0 : (max - min) / (rotationSteps - 1);
    return function rotate() {
        if (max === min)
            return max;
        return Math.floor(Math.random() * rotationSteps) * perSize;
    };
}
/**
 * 确保值在要求范围内
 * @param options
 */
function resolveRotate(options) {
    var rotationSteps = options.wordStyle.rotationSteps;
    if (rotationSteps < 1) {
        utils_1.log(utils_1.LEVEL.WARN, false, 'The rotationSteps option must be greater than or equal to 1.');
        rotationSteps = 1;
    }
    return {
        rotation: options.wordStyle.rotation,
        rotationSteps: rotationSteps,
    };
}
/**
 * 传入一个元素为数字的数组，
 * 返回该数组中值最小的数字。
 * @param numbers
 */
function min(numbers) {
    return Math.min.apply(Math, numbers);
}
/**
 * 传入一个元素为数字的数组，
 * 返回该数组中值最大的数字。
 * @param numbers
 */
function max(numbers) {
    return Math.max.apply(Math, numbers);
}
//# sourceMappingURL=utils.js.map