{"version":3,"sources":["https://lively-kernel.org/lively4/BP2019RH1/components/bp2019-group-chaining-widget.js"],"names":["assertListenerInterface","ReGL","GroupingLayouter","d3","Zoomer","Selector","IndividualsGrouper","Morph","InspectAction","FilterAction","ColorAction","GroupAction","POINT_PADDING","GroupChainingWidget","initialize","listeners","name","regl","_createReglContextOnCanvas","canvasHeight","get","height","canvasWidth","width","nodes","transform","scale","zoomer","selector","updateNodes","drawNodes","drawZoomedPoints","points","animateNodes","duration","ease","easeCubic","timer","elapsed","t","Math","min","animateZoomedPoints","tick","stop","updateScale","updateTransform","setDataProcessor","dataProcessor","setColorStore","colorStore","setData","individuals","_initializeWithData","applyAction","action","_dispatchAction","addListener","listener","push","canvas","context","getContext","controlMenu","_registerControlWidget","individualsGrouper","_registerIndividualsGrouper","_start","initializeAfterDataFetch","groupingLayouter","_applyActionToListeners","forEach","_handleGroupAction","_handleColorAction","_handleInspectAction","_handleFilterAction","_handleNotSupportedAction","groupAction","addGrouping","attribute","colorAction","_recolorNodes","currentColorAttribute","node","nodeUniqueValue","getUniqueValueFromIndividual","data","colorString","getColorForValue","drawing","tcolor","convertRGBStringToReglColorObject","getGroupingStructure"],"mappings":"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","file":"bp2019-group-chaining-widget.js","sourcesContent":["import { assertListenerInterface } from \"../src/internal/individuals-as-points/common/interfaces.js\"\nimport { ReGL } from \"../src/internal/individuals-as-points/common/regl-point-wrapper.js\"\nimport { GroupingLayouter } from \"../src/internal/individuals-as-points/group-chaining/grouping-layouter.js\"\nimport d3 from \"src/external/d3.v5.js\"\nimport { Zoomer } from \"../src/internal/individuals-as-points/group-chaining/zoomer.js\"\nimport { Selector } from \"../src/internal/individuals-as-points/group-chaining/selection-with-zoom.js\"\nimport { IndividualsGrouper } from \"../src/internal/individuals-as-points/group-chaining/individuals-grouper.js\"\nimport Morph from 'src/components/widgets/lively-morph.js'\n\nimport { InspectAction, FilterAction, ColorAction, GroupAction } from '../src/internal/individuals-as-points/common/actions.js'\n\nconst POINT_PADDING = 3\n\nexport default class GroupChainingWidget extends Morph {\n  async initialize() {\n    this.listeners = []\n    \n    this.name = \"group-canvas-widget\"\n    this.regl = this._createReglContextOnCanvas()\n    \n    this.canvasHeight = this.get('#group-chaining-widget-canvas').height\n    this.canvasWidth = this.get('#group-chaining-widget-canvas').width\n    \n    this.nodes = null\n  \n    this.transform = null\n    this.scale = 1\n    this.zoomer = new Zoomer(this)\n    this.selector = new Selector(this)\n  }\n  \n  \n  // ------------------------------------------\n  // Public Methods\n  // ------------------------------------------\n  \n  // *** Interface to IndividualsGrouper ***\n  \n  updateNodes(nodes){\n    this.nodes = nodes\n  } \n  \n  drawNodes(){\n    this.regl.drawZoomedPoints(\n      {\n        points: this.nodes,\n        transform: this.transform,\n        scale: this.scale\n      });\n  }\n  \n  animateNodes() {\n\n    const duration = 2000;\n    const ease = d3.easeCubic;\n    let timer = d3.timer((elapsed) => {\n        const t = Math.min(1, ease(elapsed / duration))\n        this.regl.animateZoomedPoints({\n          points: this.nodes,\n          transform: this.transform,\n          scale: this.scale,\n          tick: t,\n        })\n\n        if (t === 1) {\n          timer.stop()\n        }\n      })\n  }\n  \n  // *** Interface to Zoomer *** \n  \n  updateScale(scale){\n    this.scale = scale\n  }\n  \n  updateTransform(transform){\n    this.transform = transform\n  }\n  \n  // *** Interface to application ***\n  \n  setDataProcessor(dataProcessor) {\n    this.dataProcessor = dataProcessor\n  }\n  \n  setColorStore(colorStore) {\n    this.colorStore = colorStore\n  }\n  \n  async setData(individuals) {\n    this.individuals = individuals;\n    await this._initializeWithData()\n  }\n  \n  // *** Interface to control menu ***\n  \n  async applyAction(action){\n    this._dispatchAction(action)  \n  }\n  \n  addListener(listener) {\n    assertListenerInterface(listener);\n    this.listeners.push(listener);\n  }\n  \n  // ------------------------------------------\n  // Private Methods\n  // ------------------------------------------\n  \n  _createReglContextOnCanvas(){\n    this.canvas = this.get(\"#group-chaining-widget-canvas\");\n    let context = this.canvas.getContext(\"webgl\"); \n    return new ReGL(context);\n  }\n  \n  _initializeWithData(){\n    this.controlMenu = this._registerControlWidget();\n    this.individualsGrouper = this._registerIndividualsGrouper();\n    \n    this._start()\n  }\n  \n  _registerControlWidget() {\n    let controlMenu = this.get(\"#group-chaining-widget-control-widget\");\n    controlMenu.addListener(this);\n    controlMenu.initializeAfterDataFetch();\n    \n    return controlMenu;\n  }\n  \n  _registerIndividualsGrouper(){\n    let groupingLayouter = new GroupingLayouter(this.canvasWidth, this.canvasHeight, POINT_PADDING);\n    let individualsGrouper = new IndividualsGrouper(this, this.individuals, groupingLayouter);\n    \n    return individualsGrouper;\n  }\n  \n  _applyActionToListeners(action){\n    this.listeners.forEach((listener) => {\n      listener.applyAction(action);\n    })\n  }\n  \n  _dispatchAction(action) {\n    switch(true) {\n      case (action instanceof GroupAction):\n        this._handleGroupAction(action);\n        break;\n      case (action instanceof ColorAction):\n        this._handleColorAction(action);\n        break;\n      case (action instanceof InspectAction):\n        this._handleInspectAction(action);\n        break;\n      case (action instanceof FilterAction):\n        this._handleFilterAction(action);\n        break;\n      default:\n        this._handleNotSupportedAction(action);\n     }\n  }\n  \n  _handleGroupAction(groupAction) {\n    this.individualsGrouper.addGrouping(groupAction.attribute);\n  }\n  \n  _handleColorAction(colorAction) {\n    this._recolorNodes(colorAction.attribute);\n    this.drawNodes();\n  }\n  \n  _recolorNodes(currentColorAttribute){\n    this.nodes.forEach((node) => {\n      let nodeUniqueValue = this.dataProcessor.getUniqueValueFromIndividual(node.data, currentColorAttribute)\n      let colorString = this.colorStore.getColorForValue(currentColorAttribute, nodeUniqueValue);\n      node.drawing.tcolor = this.colorStore.convertRGBStringToReglColorObject(colorString);\n    })\n  }\n  \n  _handleInspectAction(action) {\n    this.drawNodes();\n  }\n  \n  _handleNotSupportedAction(action) {\n  }\n  \n  _handleFilterAction(action){\n    \n  }\n  \n  _start(){\n    this.nodes = this.individualsGrouper.getGroupingStructure();\n    this.drawNodes();\n  }\n\n}"]}