gamify.js

import _ from 'lodash';
import Chart from './chart';
import Interaction from './interaction';
import Effect from './effects/effect';

/**
 * GamifyJS의 최상단 클래스입니다.
 * <p>해당 클래스를 통해 Gamify를 생성하고, 제어할 수 있습니다.
 * @alias Gamify
 */
export default class Gamify {
  /**
   * @description DOM의 크기를 계산해서 DOM의 크기에 딱 맞게 Gamify를 생성해준다.
   * @param  { string } domId - Gamify가 들어갈 DOM의 id
   * @param  { object } option - Gamify를 통해 생설할 차트의 데이터
   */
  constructor(domId, option) {
    const rootSize = {
      width: document.getElementById(domId).offsetWidth,
      height: document.getElementById(domId).offsetHeight,
    };
    option.rootSize = rootSize;
    option.domId = domId;
    option.rootSize = rootSize;

    const standardResolution = {
      width: 1280,
      height: 720,
    };
    const { width, height } = option.rootSize;
    const widthRatio = width / standardResolution.width;
    const heightRatio = height / standardResolution.height;

    /**
     * @description 웹브라우저 해상도에 따른 폰트 및 이미지 사이즈 조절하기 위한 비율
     * @type { object }
     * @property { number } min 가로, 세로 중 작은 비율
     * @property { number } mid 가로, 세로의 중간 비율
     * @property { number } max 가로, 세로 중 큰 비율
     */
    this.ratio = {
      min: Math.min(widthRatio, heightRatio),
      mid: Math.min(widthRatio, heightRatio) + Math.abs(widthRatio - heightRatio) / 2,
      max: Math.max(widthRatio, heightRatio),
    };

    // setInterval(() => this.update(), 16);
    return new Promise((resolve) => {
      /**
       * @description Gamify에서 차트를 담당하는 클래스
       * @type { Chart }
       */
      this.chart = new Chart(option, this);
      this.chart.then((result) => {
        if (option.type !== 'treemap' && option.type !== 'map') {
          /**
           * @description Gamify에서 효과를 담당하는 클래스
           * @type { Effect }
           */
          this.effect = new Effect(option, result);
        }
        this.chart = result;
        resolve(this);
      });

      /**
       * @description Gamify에서 상호작용 담당하는 클래스
       * @type { Interaction }
       */
      this.interaction = new Interaction();
    });
  }

  /**
   * ChartJS로 생성된 차트에 한해서 새롭게 넣어준 데이터로 업데이트 해준다.
   * @param {object} datasets 변경할 datasets
   * @memberof Gamify
   * @instance
   */
  update(datasets) {
    let missileObject;
    const isMissileEffect = _.some(this.effect.list, (el) => {
      if (el.name === 'missile') {
        missileObject = el.object;
        return el;
      }
      return null;
    });
    if (isMissileEffect) {
      // console.log('missile launch detected');
      missileObject.missile(datasets);
    } else {
      for (let i = 0; i < this.chart.config.data.datasets.length; i++) {
        this.chart.config.data.datasets[i].data = datasets[i].data;
      }
      this.chart.update();
    }
  }
}