"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useColorRange = exports.influencerColorScaleFactory = exports.colorRangeScaleOptions = exports.colorRangeOptions = exports.COLOR_RANGE_SCALE = exports.COLOR_RANGE = void 0;
var _d = _interopRequireDefault(require("d3"));
var _i18n = require("@kbn/i18n");
var _use_current_eui_theme = require("../../../hooks/use_current_eui_theme");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

/**
 * Custom color scale factory that takes the amount of feature influencers
 * into account to adjust the contrast of the color range. This is used for
 * color coding for outlier detection where the amount of feature influencers
 * affects the threshold from which the influencers value can actually be
 * considered influential.
 *
 * @param n number of influencers
 * @returns a function suitable as a preprocessor for d3.scale.linear()
 */
const influencerColorScaleFactory = n => t => {
  // for 1 influencer or less we fall back to a plain linear scale.
  if (n <= 1) {
    return t;
  }
  if (t < 1 / n) {
    return 0;
  }
  if (t < 3 / n) {
    return n / 4 * (t - 1 / n);
  }
  return 0.5 + (t - 3 / n);
};
exports.influencerColorScaleFactory = influencerColorScaleFactory;
let COLOR_RANGE_SCALE;
/**
 * Color range scale options in the format for EuiSelect's options prop.
 */
exports.COLOR_RANGE_SCALE = COLOR_RANGE_SCALE;
(function (COLOR_RANGE_SCALE) {
  COLOR_RANGE_SCALE["LINEAR"] = "linear";
  COLOR_RANGE_SCALE["INFLUENCER"] = "influencer";
  COLOR_RANGE_SCALE["SQRT"] = "sqrt";
})(COLOR_RANGE_SCALE || (exports.COLOR_RANGE_SCALE = COLOR_RANGE_SCALE = {}));
const colorRangeScaleOptions = [{
  value: COLOR_RANGE_SCALE.LINEAR,
  text: _i18n.i18n.translate('xpack.dataVisualizer.components.colorRangeLegend.linearScaleLabel', {
    defaultMessage: 'Linear'
  })
}, {
  value: COLOR_RANGE_SCALE.INFLUENCER,
  text: _i18n.i18n.translate('xpack.dataVisualizer.components.colorRangeLegend.influencerScaleLabel', {
    defaultMessage: 'Influencer custom scale'
  })
}, {
  value: COLOR_RANGE_SCALE.SQRT,
  text: _i18n.i18n.translate('xpack.dataVisualizer.components.colorRangeLegend.sqrtScaleLabel', {
    defaultMessage: 'Sqrt'
  })
}];
exports.colorRangeScaleOptions = colorRangeScaleOptions;
let COLOR_RANGE;
/**
 * Color range options in the format for EuiSelect's options prop.
 */
exports.COLOR_RANGE = COLOR_RANGE;
(function (COLOR_RANGE) {
  COLOR_RANGE["BLUE"] = "blue";
  COLOR_RANGE["RED"] = "red";
  COLOR_RANGE["RED_GREEN"] = "red-green";
  COLOR_RANGE["GREEN_RED"] = "green-red";
  COLOR_RANGE["YELLOW_GREEN_BLUE"] = "yellow-green-blue";
})(COLOR_RANGE || (exports.COLOR_RANGE = COLOR_RANGE = {}));
const colorRangeOptions = [{
  value: COLOR_RANGE.BLUE,
  text: _i18n.i18n.translate('xpack.dataVisualizer.components.colorRangeLegend.blueColorRangeLabel', {
    defaultMessage: 'Blue'
  })
}, {
  value: COLOR_RANGE.RED,
  text: _i18n.i18n.translate('xpack.dataVisualizer.components.colorRangeLegend.redColorRangeLabel', {
    defaultMessage: 'Red'
  })
}, {
  value: COLOR_RANGE.RED_GREEN,
  text: _i18n.i18n.translate('xpack.dataVisualizer.components.colorRangeLegend.redGreenColorRangeLabel', {
    defaultMessage: 'Red - Green'
  })
}, {
  value: COLOR_RANGE.GREEN_RED,
  text: _i18n.i18n.translate('xpack.dataVisualizer.components.colorRangeLegend.greenRedColorRangeLabel', {
    defaultMessage: 'Green - Red'
  })
}, {
  value: COLOR_RANGE.YELLOW_GREEN_BLUE,
  text: _i18n.i18n.translate('xpack.dataVisualizer.components.colorRangeLegend.yellowGreenBlueColorRangeLabel', {
    defaultMessage: 'Yellow - Green - Blue'
  })
}];

/**
 * A custom Yellow-Green-Blue color range to demonstrate the support
 * for more complex ranges with more than two colors.
 */
exports.colorRangeOptions = colorRangeOptions;
const coloursYGB = ['#FFFFDD', '#AAF191', '#80D385', '#61B385', '#3E9583', '#217681', '#285285', '#1F2D86', '#000086'];
const colourRangeYGB = _d.default.range(0, 1, 1.0 / (coloursYGB.length - 1));
colourRangeYGB.push(1);
const colorDomains = {
  [COLOR_RANGE.BLUE]: [0, 1],
  [COLOR_RANGE.RED]: [0, 1],
  [COLOR_RANGE.RED_GREEN]: [0, 1],
  [COLOR_RANGE.GREEN_RED]: [0, 1],
  [COLOR_RANGE.YELLOW_GREEN_BLUE]: colourRangeYGB
};

/**
 * Custom hook to get a d3 based color range to be used for color coding in table cells.
 *
 * @param colorRange COLOR_RANGE enum.
 * @param colorRangeScale COLOR_RANGE_SCALE enum.
 * @param featureCount
 */
const useColorRange = (colorRange = COLOR_RANGE.BLUE, colorRangeScale = COLOR_RANGE_SCALE.LINEAR, featureCount = 1) => {
  const euiTheme = (0, _use_current_eui_theme.useCurrentEuiTheme)();
  const colorRanges = {
    [COLOR_RANGE.BLUE]: [_d.default.rgb(euiTheme.euiColorEmptyShade).toString(), _d.default.rgb(euiTheme.euiColorVis1).toString()],
    [COLOR_RANGE.RED]: [_d.default.rgb(euiTheme.euiColorEmptyShade).toString(), _d.default.rgb(euiTheme.euiColorDanger).toString()],
    [COLOR_RANGE.RED_GREEN]: ['red', 'green'],
    [COLOR_RANGE.GREEN_RED]: ['green', 'red'],
    [COLOR_RANGE.YELLOW_GREEN_BLUE]: coloursYGB
  };
  const linearScale = _d.default.scale.linear().domain(colorDomains[colorRange]).range(colorRanges[colorRange]);
  const influencerColorScale = influencerColorScaleFactory(featureCount);
  const influencerScaleLinearWrapper = n => linearScale(influencerColorScale(n));
  const scaleTypes = {
    [COLOR_RANGE_SCALE.LINEAR]: linearScale,
    [COLOR_RANGE_SCALE.INFLUENCER]: influencerScaleLinearWrapper,
    [COLOR_RANGE_SCALE.SQRT]: _d.default.scale.sqrt().domain(colorDomains[colorRange])
    // typings for .range() incorrectly don't allow passing in a color extent.
    // @ts-ignore
    .range(colorRanges[colorRange])
  };
  return scaleTypes[colorRangeScale];
};
exports.useColorRange = useColorRange;