function buildTimelineCoordinates()

in client/src/components/special/timeline-chart/renderer/coordinates/index.js [59:232]


function buildTimelineCoordinates (options) {
  const {
    axis,
    valueShift = 0,
    stepPixelSize = 40,
    minimumStepPixelSize = 5.0,
    includeStart = true,
    includeEnd = true
  } = options;
  if (!axis || !axis.initialized || axis.pixelsSize <= 0) {
    return [];
  }
  const result = [];
  const {
    getLabelSize,
    releaseContext
  } = getLabelSizer(options);
  const expandConfig = (config) => {
    const {
      step,
      variations = [],
      unit,
      ...rest
    } = config;
    return {
      ...rest,
      unit,
      step,
      getNextStepDate: (currentDate, variation = 1) => moment(currentDate).add(
        variation,
        unit === 'date' ? 'day' : unit
      ),
      variations: [...new Set([1, ...variations])]
        .sort((a, b) => a - b)
        .map((variation) => ({
          variation,
          stepPxSize: axis.getPixelSizeForValueSize(step * variation)
        })),
      stepPxSize: axis.getPixelSizeForValueSize(step),
      labelSize: getLabelSize(config.maxLabel)
    };
  };
  const configs = TimelineConfigurations
    .map(expandConfig)
    .reverse();
  let mainIndex = configs.findIndex(
    (config) => config.stepPxSize > minimumStepPixelSize &&
      config.labelSize * 1.1 <= config.stepPxSize
  );
  if (mainIndex === -1) {
    mainIndex = configs.length - 1;
  }
  const smallIndex = Math.max(0, mainIndex - 1);
  const mainConfig = configs[mainIndex];
  let smallConfig;
  if (smallIndex !== mainIndex) {
    smallConfig = configs[smallIndex];
  }
  mainConfig.main = true;
  const significantUnitChangesPriority = ['year', 'month', 'date', 'hour', 'minute', 'second'];
  const getUnitsToCheck = (config) => significantUnitChangesPriority.slice(
    0,
    significantUnitChangesPriority.indexOf(config.unit)
  );

  const significantUnitChange = (date, previousDate, units = significantUnitChangesPriority) => {
    if (!previousDate || !date) {
      return undefined;
    }
    for (let i = 0; i < units.length; i += 1) {
      const unit = units[i];
      if (previousDate.get(unit) !== date.get(unit)) {
        return unit;
      }
    }
    return undefined;
  };

  const minValue = axis.correctActualValue(axis.from);
  const maxValue = axis.correctActualValue(axis.to);

  const addTick = (tickDate, tickOptions) => {
    const tickValue = tickDate.unix();
    const {
      config,
      start = false,
      end = false,
      change
    } = tickOptions || {};
    if (
      (!start && !end && tickValue - valueShift < minValue) ||
      result.find((tick) => tick.value === tickValue - valueShift)
    ) {
      return;
    }
    const {
      format: mainFormat,
      smallFormat = mainFormat,
      main = start || end
    } = config || {};
    const format = main ? mainFormat : smallFormat;
    let label = tickDate.format(format);
    if (change && main) {
      let newFormat = format;
      if (config && config.change && config.change[change]) {
        newFormat = config.change[change];
      } else if (config && config.change && config.change.default) {
        newFormat = config.change.default;
      }
      label = tickDate.format(newFormat);
    }
    const size = getLabelSize(label);
    result.push({
      value: tickValue - valueShift,
      main,
      start,
      end,
      config,
      label,
      size
    });
  };
  if (includeStart) {
    addTick(moment.unix(minValue + valueShift), {
      config: {
        format: 'D MMM YYYY, HH:mm:ss',
        unit: 'second'
      },
      start: true
    });
  }
  if (includeEnd) {
    addTick(moment.unix(maxValue + valueShift), {
      config: {
        format: 'D MMM YYYY, HH:mm:ss',
        unit: 'second'
      },
      end: true
    });
  }
  const iterateWithConfig = (config) => {
    if (config) {
      const {
        variation,
        stepPxSize
      } = config.variations
        .find((aVariation) => aVariation.stepPxSize >= stepPixelSize) ||
      config.variations[config.variations.length - 1];
      if (stepPxSize < minimumStepPixelSize) {
        return;
      }
      let tick = config.getNearest(minValue + valueShift);
      let tickDate = moment.unix(tick);
      let previous;
      let change;
      let iteration = 0;
      while (tick <= maxValue + valueShift && iteration < 500) {
        iteration += 1;
        addTick(tickDate, {config, change});
        previous = tickDate;
        tickDate = config.getNextStepDate(tickDate, variation);
        change = significantUnitChange(tickDate, previous, getUnitsToCheck(config));
        if (change) {
          tickDate = tickDate.startOf(change);
        }
        tick = tickDate.unix();
      }
    }
  };
  iterateWithConfig(mainConfig, true);
  iterateWithConfig(smallConfig, false);
  releaseContext();
  return result.sort(ticksSorter);
}