<commit_before>import * as utils from "base/utils";

/* Factory pattern for object creation as in 
 * https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e
 * https://medium.com/javascript-scene/common-misconceptions-about-inheritance-in-javascript-d5d9bab29b0a
 * 
 * We may want to have one DimensionManager singleton object for Vizabi. That way entities can be shared throughout instances.
 */

const DimensionManagerPrototype = {

  model: null,
  dimensionModels: new Map(),

  updateDimensionModels() {
    this.dimensionModels.clear();
    utils.forEach(this.model.state._data, (model, name) => {
      if (typeof model.dim === "undefined") return;
      this.dimensionModels.set(name, model);
    });
  },

  getDimensionModelsForSpace(oldSpace, newSpaceDimensions) {

    this.updateDimensionModels();

    // match new space to entities
    // assumption:
    // - no overlapping dimensionModels between markers or changing dimension models is fine
    // - one entities model per dimension
    // - only one time model (state.time)
    const oldSpaceEntities = Object.keys(oldSpace).filter(dim => oldSpace[dim]._type == "entities");
    const newSpace = newSpaceDimensions.map((dim, index) => {

    	/** 
    	 * HEURISTIC 1: use old space and map new space on those entities (works only for same-dimensional)
    	 */
    	let modelName;
    	if (this.model.dataManager.isConceptType(dim, "time")) {
    		modelName = "time";
  			oldSpace[modelName].dim = dim;
    	} else {
    		modelName = oldSpaceEntities.pop();
    		if (typeof modelName != "undefined") {
    			// entities model found
  				oldSpace[modelName].setDimension(dim);
  			} else {
  				// no more entities models left
		    	modelName = "entities_" + dim;
          const newEntities = {
		    		[modelName]: Object.assign(Entities.getClassDefaults(),	{ dim })
		    	};
		    	this.model.state.set(newEntities);
    		}
    	}
  		return modelName;

      /** 
       * HEURISTIC 2 (unused/untested): Look for entities models which already have dimensions, use time or create new entities model
       */

      // check if there is a entities model with this dimension, if so return it
      for (const [name, dimensionModel] of this.dimensionModels.entries()) {
        if (dimensionModel.dim == dim) {
          return name;
        }
      }

    	// if time, change the one time model
    	if (this.model.dataManager.isConceptType(dim, "time")) {
    		// we expect only one time model and update this (baaad, but state.time is still hardcoded in quite some places)
	    	for (const [name, dimensionModel] of this.dimensionModels.entries()) {
	    		if (dimensionModel.type == "time") {
	    			dimensionModel.dim = dim;
	    			return name;
	    		}
	    	}
    	}

    	// for others, create entities model for new dimension
      const newEntities = {
    		["entities_" + dim]: Object.assign(Entities.getClassDefaults(),	{ dim })
    	};
    	this.model.state.set(newEntities);
    	return "entities_" + dim;
    });

    return newSpace;

  }
};

function DimensionManager(model) {
  const dimMan = Object.create(DimensionManagerPrototype);
  dimMan.model = model;
  return dimMan;
}
<commit_msg>js linting tabs/spaces<commit_after>import * as utils from "base/utils";

/* Factory pattern for object creation as in 
 * https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e
 * https://medium.com/javascript-scene/common-misconceptions-about-inheritance-in-javascript-d5d9bab29b0a
 * 
 * We may want to have one DimensionManager singleton object for Vizabi. That way entities can be shared throughout instances.
 */

const DimensionManagerPrototype = {

  model: null,
  dimensionModels: new Map(),

  updateDimensionModels() {
    this.dimensionModels.clear();
    utils.forEach(this.model.state._data, (model, name) => {
      if (typeof model.dim === "undefined") return;
      this.dimensionModels.set(name, model);
    });
  },

  getDimensionModelsForSpace(oldSpace, newSpaceDimensions) {

    this.updateDimensionModels();

    // match new space to entities
    // assumption:
    // - no overlapping dimensionModels between markers or changing dimension models is fine
    // - one entities model per dimension
    // - only one time model (state.time)
    const oldSpaceEntities = Object.keys(oldSpace).filter(dim => oldSpace[dim]._type == "entities");
    const newSpace = newSpaceDimensions.map((dim, index) => {

      /** 
       * HEURISTIC 1: use old space and map new space on those entities (works only for same-dimensional)
       */
      let modelName;
      if (this.model.dataManager.isConceptType(dim, "time")) {
        modelName = "time";
        oldSpace[modelName].dim = dim;
      } else {
        modelName = oldSpaceEntities.pop();
        if (typeof modelName != "undefined") {
          // entities model found
          oldSpace[modelName].setDimension(dim);
        } else {
          // no more entities models left
          modelName = "entities_" + dim;
          const newEntities = {
            [modelName]: Object.assign(Entities.getClassDefaults(), { dim })
          };
          this.model.state.set(newEntities);
        }
      }
      return modelName;

      /** 
       * HEURISTIC 2 (unused/untested): Look for entities models which already have dimensions, use time or create new entities model
       */

      // check if there is a entities model with this dimension, if so return it
      for (const [name, dimensionModel] of this.dimensionModels.entries()) {
        if (dimensionModel.dim == dim) {
          return name;
        }
      }

      // if time, change the one time model
      if (this.model.dataManager.isConceptType(dim, "time")) {
        // we expect only one time model and update this (baaad, but state.time is still hardcoded in quite some places)
        for (const [name, dimensionModel] of this.dimensionModels.entries()) {
          if (dimensionModel.type == "time") {
            dimensionModel.dim = dim;
            return name;
          }
        }
      }

      // for others, create entities model for new dimension
      const newEntities = {
        ["entities_" + dim]: Object.assign(Entities.getClassDefaults(), { dim })
      };
      this.model.state.set(newEntities);
      return "entities_" + dim;
    });

    return newSpace;

  }
};

function DimensionManager(model) {
  const dimMan = Object.create(DimensionManagerPrototype);
  dimMan.model = model;
  return dimMan;
}

{'fraction_non_alphanumeric': 0.10999848277954787, 'fraction_numerical': 0.0036413290851160674, 'mean_word_length': 2.703370786516854, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6932605', 'n_tokens_mistral': 1942, 'n_tokens_neox': 1883, 'n_words': 518}