Source: visual-group/src/visual-group/visual-group.js

import { transactor, generateGetterSetters } from 'muze-utils';
import localOptions from './local-options';
import { SimpleGroup } from '../simple-group';
import {
    MatrixResolver,
    initStore,
    findInGroup
} from '../group-helper';
import { setupChangeListeners } from './change-listener';
import { PROPS } from './props';
import {
    CONFIG,
    MOUNT,
    RETINAL,
    Y
} from '../enums/constants';

/**
 * VisualGroup is instantiated by canvas for creating {@link VisualUnit} and axes instances.It creates the
 * the matrix of visual units and axes. It also creates the layout instance which manages the allocation
 * of space of matrices.
 *
 * To get instance of visual group,
 * ```
 *      const visualGroup = canvas.composition().visualGroup;
 * ```
 * @public
 *
 * @class VisualGroup
 */
class VisualGroup extends SimpleGroup {

    /**
     * Creates an instance of VisualGroup. Requires dependencies and other registry options for placeholders
     * and layers that create individual units.
     *
     * @param {Object} registry Key value pair of compostions for the group
     * @param {Object} dependencies Dependencies needed to run the group
     * @memberof VisualGroup
     */
    constructor (registry, dependencies) {
        super();

        const {
            componentSubRegistry
        } = registry;

        this._dependencies = dependencies;
        // Generate getter/setter methods for all properties of the class
        // One can get each property by calling the method and can set it
        // by passing paramaters for the same. Thus, one can chain setter
        // getter methods.
        generateGetterSetters(this, PROPS);
        // Populate the store with default values
        this.store(initStore());

        // initialize group compositions
        this._composition = {};
        // store reference to data
        this._data = [];
        // matrix instance store each of the matrices
        this._matrixInstance = {};
        // store reference to mountpoint
        this._mount = null;
        // selection object that takes care of updating of components
        this._selection = {};
        // stores info about the placeholders generated after creation of matrices
        this._placeholderInfo = {};
        // corner matrices are the headers/footers for the application
        this._cornerMatrices = {};
        // Create instance of matrix resolver
        this.resolver(new MatrixResolver(this._dependencies));

         // Getting indiviual registered items
        this.registry({
            layerRegistry: componentSubRegistry.layerRegistry.get(),
            cellRegistry: componentSubRegistry.cellRegistry.get()
        });
        // Add local options to the store
        transactor(this, localOptions, this.store().model);
        // Register listeners
        setupChangeListeners(this);
    }

    /**
     * Return the instances of matrices created by the visual group.
     *
     * @return {Object} Instance of matrices.
     */
    matrixInstance (...matrices) {
        if (matrices.length) {
            return this;
        }
        return this.composition().matrices;
    }

    /**
     * Returns the composition of visual group.
     *
     * @public
     *
     * @return {Object} Composition of visual group. It contains instance of matrices {@link ValueMatrix}
     * and instances of axis.
     * ```
     *          {
     *              matrices: {
     *                  value: // Instance of center value matrix.
     *                  left: // Instance of left value matrix
     *                  right: // Instance of right value matrix
     *                  bottom: // Instance of bottom value matrix
     *                  top: // Instance of top value matrix.
     *              },
     *              axes: {
     *                  x: // Array of x axis.
     *                  y: // Array of y axis
     *                  color: // Array of color axis
     *                  shape: // Array of shape axis
     *                  size: // Array of size axis.
     *              }
     *          }
     * ```
     */
    composition (...params) {
        if (params.length) {
            return this;
        }
        return this._composition;
    }

    /**
     * Locks the model to prevent change listeners to be triggered until unlocked
     *
     * @return {Object} Instance of class VisualGroup
     * @memberof VisualGroup
     */
    lockModel () {
        this.store().model.lock();
        return this;
    }

    /**
     * Unlocks the model so that all change listeners can be triggered
     *
     * @return {Object} Instance of class VisualGroup
     */
    unlockModel () {
        this.store().model.unlock();
        return this;
    }

    /**
     * Returns the channel name of the variable. Channels are rows, columns, color, shape and size.
     *
     * @public
     * @param {string} variable Name of the variable.
     *
     * @return {string} Name of the channel.
     */
    where (variable) {
        return findInGroup(variable, this.resolver().getAllFields());
    }

    /**
     * Gets the axis instances of the visual group based on the given axis type.
     *
     * @public
     * @param {string} type Type of axis. X,Y or retinal axes.
     *
     * @return {Array} Array of axis instances.
     */
    getAxes (type) {
        if (type === RETINAL) {
            return this.resolver().getRetinalAxes();
        }
        return this.resolver().getSimpleAxes(type);
    }

    /**
     * Returns the instances of cells based on the given type. Type can be given as `row' or `col`.
     *
     * @public
     * @return {Array} Two dimensional array of cells.
     */
    getCells (type) {
        return this.resolver()[`${type}Cells`]();
    }

    getFieldsFromChannel (channel) {
        const {
            rowProjections,
            colProjections
        } = this.resolver().getAllFields();

        return channel === Y ? rowProjections : colProjections;
    }

    getCellsByFacetKey (facetKey) {
        const resolver = this.resolver();
        const cells = resolver.rowCells()[facetKey] || resolver.colCells()[facetKey] || [];
        return cells;
    }

    getAxesByFacetKey (axisType, facetKey) {
        const resolver = this.resolver();
        const cells = resolver.rowCells()[facetKey] || resolver.colCells()[facetKey];
        const axes = cells[0].valueOf().axes()[axisType] || [];

        return axes;
    }

    /**
     * This method is used to return a serialized representation of the instance's properties.
     *
     * @return {Object} Object with config proprties.
     * @memberof VisualGroup
     */
    serialize () {
        const store = this.store();

        return {
            [CONFIG]: store.get(CONFIG),
            [MOUNT]: store.get(MOUNT)
        };
    }

    /**
     * Returns the grouped datamodel prepared by visual group. If there is no group by performed, then it returns the
     * original data model passed to visual group.
     *
     * @return {DataModel} Grouped data model.
     */
    getGroupByData () {
        return this._groupedDataModel;
    }
}

export default VisualGroup;