--- a/integ/js/vs/_vs.js Fri Apr 26 16:40:03 2013 +0200
+++ b/integ/js/vs/_vs.js Mon Apr 29 15:02:35 2013 +0200
@@ -1,649 +1,649 @@
-// ....................................................................
-// Main Visual Sedimentation Code
-// ....................................................................
-
-// TODO :
-// - callback on rollOut
-
-(function($){
-
-// Name Space Plug in Jquery Objects
-$.fn.vs = function (){}
-$.fn._vs={}
-
-// All this objects are define in correspondant .js files
-$.fn._vs.token = {}
-$.fn._vs.draw = {}
-$.fn._vs.stream = {}
-$.fn._vs.chart = {}
-$.fn._vs.phy = {}
-$.fn._vs.decay = {}
-$.fn._vs.flocculate = {}
-$.fn._vs.strata = {}
-$.fn._vs.aggregate = {}
-
-
-// Core Classe
-var VisualSedimentation = function(element,options){
-
- // Attach objects
- this.token = $.fn._vs.token
- this.draw = $.fn._vs.draw
- this.stream = $.fn._vs.stream
- this.chart = $.fn._vs.chart
- this.phy = $.fn._vs.phy
- this.decay = $.fn._vs.decay
- this.flocculate = $.fn._vs.flocculate
- this.strata = $.fn._vs.strata
-// this.aggregate = $.fn._vs.aggregate
- this.requestAnimFrame;
-
-
- // Mouse object have to be refactor
- this.mouse ={}
- this.mouse.x = 0
- this.mouse.y = 0
- this.mouse.isMouseDragging = false
- this.mouse.isMouseDown = false
- this.mouse.selectedBody = null
-
-
- // Variables
- this.dataFlow = [];
- this.chartPhySetup= {}
- this.tokens = [];
- this.world = null;
- this.ctx = null;
- var elem = $(element);
- var self = this;
- var tokens = [];
- var B2D;
- var canvas;
-
-
- // Default Settings
- var defaultSettings = {
- x:0,
- y:0,
- width:290.5,
- height:300.5,
- DOMelement:null,
-
- chart:{
- x:undefined,
- y:undefined,
- width:undefined,
- height:undefined,
- colorRange:d3.scale.category10(),
- scale:d3.scale,
- type:'StackedAreaChart',
- /*
- name are based on prefuse tollokit layout :
- - CircleLayout,
- - StackedAreaChart,
- //- bubbleAreaChart,
- x AxisLabelLayout,
- x AxisLayout,
- x CollapsedStackLayout,
- x GridLayout,
- */
- spacer:5,
- //treeLayout:false,
- column:3,
- wallColor:"rgba(230,230,230,0)",
- label:true,
- radius:10 // for CircleLayout
- },
- data:{
- model:[
- {label:"Column A"},
- {label:"Column B"},
- {label:"Column C"},
- ],
- strata:[
- [
- {initValue: 100, label: "Strata 1 col A"}
- ],[
- {initValue: 20, label: "Strata 1 col B"}
- ],[
- {initValue: 175, label: "Strata 2 col C"}
- ]
- ],
- token:[
- {
- timestamp:1,
- category:1,
- value: 1,
- userdata:{},
- callback:{}
- }
- ],
- tokenPast:0,
- stream:{
- provider:'generator',
- refresh:10000/8,
- now:0
- },
- }
- ,
- sedimentation:{
- token:{size:{original:4
- ,minimum:2}
- ,visible:true}, // fill color, shape,
- incoming:{
- strategy:1, // 1 = one element by one, more = by Groupe
- point:[{x:50,y:0},
- {x:100,y:0},
- {x:150,y:0}],
-
- target:[{x:50,y:0},
- {x:100,y:0},
- {x:150,y:0}]
- },
- granulate:{visible:false},
- flocculate:{
- number:1, // 1 = one element by one, more = by groupe of n
- action:"buffer", // [buffer,continue]
- strategy:"Size", // [BufferSize, Time, AcummulationAreaHeight, Fps, Manual]
- bufferSize:5, // number of token to make floculation
- bufferTime:1000, // time buffer to make flocullation
- bufferHeight:50, // height (pixel) to make floculation
- bufferFrameRate:25, // if the computer is to slow floculate
- buffer:[]
- },
- suspension:{
- height:null, // pourcent,adaptative
- incomming:'top',
- decay:{power:1.001}, // null
- refresh:200
- },
- accumulation:{height:null}, // pourcent ,adaptative
- aggregation:{height:0, maxData:0, invertStrata:false}, // pourcent ,adaptative
- },
- options:{
- refresh:1000/25,
- panel:false,
- scale:30,
- layout:false,
- canvasFirst:true
- }
- }
-
-
- this.now = function(){
- return(new Date().getTime())
- }
-
- // get Box2d World
- this.globalDecay = function (value){
- if(typeof(value)=='undefined'){
- return this.settings.sedimentation.suspension.decay.power
- }else{
- return this.settings.sedimentation.suspension.decay.power=value
- }
- }
-
- // get Box2d World
- this.getWorld = function (){
- return this.world;
- }
-
- this.chartUpdate = function (cat,y){
- var options = {cat:cat,y:y}
- this.chart[this.settings.chart.type](self,'update',options)
- }
-
- // Todo ......
- this.flocculateTokens = function (number){
- return this.flocculate.update(self,number)
- }
-
- // TODO DESTROY ALL TOKENS
- this.flocculateAll = function(){
- return this.flocculate.all(self)
- }
-
- // Add token function
- this.addToken = function (element){
- //var token = this.token.addToken(self,element)
- return this.token.addToken(self,element);
- }
-
- // Select token fonction
- this.selectAll = function (key,value){
- return this.token.selectAll(self,key,value);
- }
-
- // Select token fonction
- this.select = function (key,value){
- return this.token.select(self,key,value);
- }
-
- // update a categoryr in the chart
- this.updateAll = function (values){
- var tokens = this.chart.updateAll(self,key,value)
- return tokens;
- }
-
- // update a category in the chart
- this.update = function (key,value){
- var tokens = this.chart.update(self,key,value)
- return tokens;
- }
-
-
- /// Settings without
-
-
- //////////////////////////////////////////////////////// TO CLEAN
- // SAM @ROM1 : are you sure you need that ? extend doing it well normally
- // Merge options with defaults
- // http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
-
- //console.log("////////")
- //options.model = modelToStrata(options.data.model)
-
- function merge_options(obj1,obj2){
- var obj3 = {};
- for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
- for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
- return obj3;
- }
-
- merge_options(defaultSettings, options);
- if(options.data!=undefined)
- defaultSettings.data = options.data;
-
- ////////////////////////////////////////////////////////////////////////////////////
- // Merge option and add the DOMelement to setting
- //this.settings = $.extend(defaultSettings, options || {});
- this.settings = $.extend(true,defaultSettings, options);
- this.settings.DOMelement = element
- //console.log('settings after extend',this.settings)
-
- // -----------------------------------------------
- // SIMPLE DEFAULT SETTING FOR RETRO COMPATIBILITY
- //
- if(typeof(this.settings.chart.width) =="undefined"){this.settings.chart.width = this.settings.width}
- if(typeof(this.settings.chart.x) =="undefined")this.settings.chart.x=0
- if(typeof(this.settings.chart.y) =="undefined")this.settings.chart.y=0
- if(typeof(this.settings.chart.height)=="undefined")this.settings.chart.height=this.settings.height
- if(typeof(this.settings.stream) =="undefined"){this.settings.stream={}}
- if(typeof(this.settings.stream.now) =="undefined"){this.settings.stream.now=0}
- if(typeof(this.settings.stream.provider)=="undefined"){this.settings.stream.provider='generator'}
- if(typeof(this.settings.stream.refresh)=="undefined"){this.settings.stream.refresh=1000}
- if(typeof(this.settings.data.tokenPast)=="undefined"){this.settings.data.tokenPast=0}
- if(typeof(this.settings.data.tokens)=="undefined"){this.settings.data.tokens=[]}
-
- // FOR ROM1 setting by default aggregation :
- if(typeof(this.settings.data.strata) !="undefined" && this.settings.data.strata.length!=0){
- if(typeof(this.settings.sedimentation.aggregation) =="undefined"){
- this.settings.sedimentation.aggregation = {}
- }
- if(typeof(this.settings.sedimentation.aggregation.height) =="undefined"){
- this.settings.sedimentation.aggregation.height = this.settings.chart.height/2
- }
- if(typeof(this.settings.sedimentation.aggregation.maxData) =="undefined"){
- this.settings.sedimentation.aggregation.maxData = 10
- }
- }
- // END
-
-
- // Initialisation - Private method
- this.init = function(){
- // requestAnim shim layer by Paul Irish
- // not use yet, to add
- this.requestAnimFrame = (function(){
- return window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function(/* function */ callback, /* DOMElement */ element){
- window.setTimeout(callback, 1000 / 60);
- };
- })();
-
- //console.log(this.settings)
- //console.log('Initialisation');
-
- // Create the physical simulation
- this.world = new this.phy.b2World(
- new this.phy.b2Vec2(0, 0) //gravity
- , true //allow sleep
- );
-
- // Create container and canvas for physical simulation drawing
- var container = element.appendChild(document.createElement("div"));
- container.id = "box_sediviz_"+GUID()
- container.width = this.settings.width; // TOFIX
- container.height = this.settings.height;
-
- //console.log(container.id)
- // Allocate the new Element
- this.settings.DOMelement = container
-
- canvas = container.appendChild(document.createElement("canvas"));
- canvas.id = "canvas";
- canvas.width = this.settings.width; // TOFIX
- canvas.height = this.settings.height;
- canvas.style.position = "absolute"
-
- //console.log(this.settings.width,this.settings.height)
- this.ctx = canvas.getContext("2d");
-
- // Construct the Chart
- this.chart[this.settings.chart.type](self,'init')
-
-
- // Draw d3
- //if(typeof(this.settings.options.debugaggregate)=="undefined"){
- // this.aggregate.init(self);
- //}
- // Initiatlise stream
- this.stream.init(self)
- // Initiatlise decay
- this.flocculate.init(self)
- // Update stream
- this.stream.update(self);
-
- // Initiatlise tokens
- this.token.init(self)
-
- //FORCE UPDATE CHART due to (bug positionnement ) @rom1
- this.strata.init(this)
-
- // Update the physical simulation
- window.setInterval(
- function(){self.update(self);},
- self.settings.options.refresh/2
- );
- // Refresh canvas drawings
- window.setInterval(
- function(){self.draw.update(self);},
- self.settings.options.refresh
- );
- // Update Decay
- window.setInterval(
- function(){self.decay.update(self);},
- self.settings.sedimentation.suspension.refresh
- );
- //this.decay.update(self);
-
- self.strata.update(self)
-
-
- // MOUSE PART
- // inspired by box2d stuffs, have to clean and finish this !
- // http://www.emanueleferonato.com/2008/11/20/dragging-objects-with-box2d-flash/
- // --------------------------
- this.getBodyAtMouse=function (_this) {
-
- var x = _this.mouse.x/_this.settings.options.scale
- var y =_this.mouse.y/_this.settings.options.scale
- var mousePVec = new _this.phy.b2Vec2(x,y);
- var aabb = new _this.phy.b2AABB();
- var area = 0.001
-
- //console.log(_this.mouse.x,_this.mouse.y)
- aabb.lowerBound.Set(x - area, y - area);
- aabb.upperBound.Set(x + area, y + area);
-
- // Query the world for overlapping shapes.
- _this.mouse.selectedToken = null;
-
- // MERCI JULIEN POUR LE CLOSURE
- //selectedBody
- _this.world.QueryAABB(function(fixture){
- return getBodyCB(fixture,_this,mousePVec)
- }, aabb);
-
- return _this.mouse.selectedToken;
- }
- //http://stackoverflow.com/questions/11674200/how-to-send-prototype-method-as-a-callback-in-javascript
- // pb here
- function getBodyCB(fixture,_this,mousePVec) {
- //console.log("phy",phy)
- //console.log("fixture",fixture.m_userData.type,fixture)
- //_this.mouse.elementpoi = fixture.GetBody()
- _this.mouse.selectedToken = fixture;
-
- if(fixture.GetBody().GetType() != _this.phy.b2Body.b2_staticBody) {
- if(fixture.GetShape().TestPoint(fixture.GetBody().GetTransform(), mousePVec)) {
- _this.mouse.selectedToken = fixture;
- return false;
- }
- }
- return true;
- }
-
- this.handleMouseMove = function(e,_this) {
- canvasPosition = DOMabsOffset(_this.settings.DOMelement)
- _this.mouse.x = (e.clientX - (canvasPosition.offsetLeft- this.getScrollPosition()[0]));
- _this.mouse.y = (e.clientY - (canvasPosition.offsetTop- this.getScrollPosition()[1]));
- //if( _this.mouse.isMouseDown){ console.log(_this.mouse.y,canvasPosition.y)}
- //console.log("mouse",e.clientX,e.clientY )
- //console.log("mouse",canvasPosition.x,canvasPosition.y )
- //console.log("=",_this.mouse.x,_this.mouse.y)
- };
- // from
- this.getScrollPosition= function(){
- return Array((document.documentElement && document.documentElement.scrollLeft) || window.pageXOffset || self.pageXOffset || document.body.scrollLeft,(document.documentElement && document.documentElement.scrollTop) || window.pageYOffset || self.pageYOffset || document.body.scrollTop);
- }
-
- document.addEventListener("mousemove", function (e){onDocumentMouseMove(e,self)});
- document.addEventListener("mouseup", function (e){onDocumentMouseUp(e,self)});
- document.addEventListener("mousedown", function (e){onDocumentMouseDown(e,self)});
-
-
-
- function onDocumentMouseOver(e,_this) {
-
- var s = _this.getBodyAtMouse(_this);
- if(s!=null){
- if(typeof(s.m_userData)!="undefined"){
- if(typeof(s.m_userData.callback)!="undefined"){
- if(typeof(s.m_userData.callback.mouseover)=="function"){
- var t = _this.select('ID',s.m_userData.ID)
- s.m_userData.callback.mouseover(t)
- }
-
- if(typeof(s.m_userData.callback.mouseout)=="function"){
- //console.log("mouseout exist")
- var t = _this.select('ID',s.m_userData.ID)
- var mouseoutTrigger
- var rollOut = function(){
- var mt = mouseoutTrigger
- var tt = t
- var ici = _this
- var ss = s
- return function(){
- var s = ici.getBodyAtMouse(ici);
- var mo = false;
- if(s!=null){
- if(typeof(s.m_userData)!="undefined"){
- if(s.m_userData.ID==tt.attr('ID')){
- mo=false
- }else{
- mo=true
- }
- }else{
- mo=true
- }
- }else{
- mo=true;
- }
- if(mo){
- ss.m_userData.callback.mouseout(tt)
- clearInterval(mouseoutTrigger)
- }
- }
- };
- mouseoutTrigger = window.setInterval(rollOut(),100)
- }
- }
- }
- }
- }
-
- function onDocumentMouseDown(e,_this) {
- //console.log("onDocumentMouseDown")
- _this.mouse.isMouseDown = true;
- // return false;
- _this.handleMouseMove(e,_this);
- var s = _this.getBodyAtMouse(_this);
- if(s!=null){
- if(typeof(s.m_userData)!="undefined"){
- if(typeof(s.m_userData.callback)!="undefined"){
- if(typeof(s.m_userData.callback.onclick)=="function"){
- var t = _this.select('ID',s.m_userData.ID)
- s.m_userData.callback.onclick(t)
- }
- }
- }
- }
- }
-
- function onDocumentMouseUp(e,_this) {
- _this.mouse.isMouseDown = false;
- // isMouseDown = false;
- // return false;
- //console.log("onDocumentMouseUp")
- }
- function onDocumentMouseMove( e,_this ) {
-
- if(_this.mouse.isMouseDown){
- _this.mouse.isMouseDragging = true;
- _this.mouse.x = e.clientX;
- _this.mouse.y = e.clientY;
-
- }else{
- _this.handleMouseMove(e,_this);
- onDocumentMouseOver("move",_this)
- }
- //console.log("m",_this)
- }
- }
-
-
- this.mouse.update = function (s) {
- if(isMouseDown && (!mouseJoint)) {
- var body = getBodyAtMouse();
- if(body) {
- var md = new b2MouseJointDef();
- md.bodyA = world.GetGroundBody();
- md.bodyB = body;
- md.target.Set(mouseX, mouseY);
- md.collideConnected = true;
- md.maxForce = 300.0 * body.GetMass();
- mouseJoint = world.CreateJoint(md);
- body.SetAwake(true);
- }
- }
-
- if(mouseJoint) {
- if(isMouseDown) {
- mouseJoint.SetTarget(new b2Vec2(mouseX, mouseY));
- } else {
- world.DestroyJoint(mouseJoint);
- mouseJoint = null;
- }
- }
-
- };
-
-
-
- // MOUSE END
- // --------------------------
-
- this.update = function (s) {
- this.world.Step(1 / 60, 10, 10);
- this.world.DrawDebugData();
- this.world.ClearForces();
- //console.log('u')
- }
-
- var drawInit = function(){
- ctx.fillStyle = "rgb(200,0,0)";
- this.ctx.font = "14pt Calibri,Geneva,Arial";
- this.ctx.fillText("Canvas ready for Visual Sedimentation ", 10, 20);
- window.setInterval(
- $.fn.vs.draw.refresh(ctx,world,this.settings)
- , this.settings.options.refresh);
- console.log("draw Init ")
- }
-
-
- var DOMabsOffset = function(target){
- var top = target.offsetTop;
- var left = target.offsetLeft;
-
- while(target = target.offsetParent) {
- top += target.offsetTop;
- left += target.offsetLeft;
- }
-
- return {offsetLeft:left, offsetTop:top};
- };
-
- // GUID generator from :
- // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
- var GUID = function(){
- var S4 = function ()
- {
- return Math.floor(
- Math.random() * 0x10000 /* 65536 */
- ).toString(16);
- };
-
- return (
- S4() + S4() + "-" +
- S4() + "-" +
- S4() + "-" +
- S4() + "-" +
- S4() + S4() + S4()
- );
- }
-
- // clone object
- // http://stackoverflow.com/questions/728360/copying-an-object-in-javascript
- function clone(obj) {
- if (null == obj || "object" != typeof obj) return obj;
- var copy = obj.constructor();
- for (var attr in obj) {
- if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
- }
- return copy;
- }
- this.utile = {}
- this.utile.GUID = GUID
- this.utile.clone = clone
-
- this.settings = $.extend(this.settings, {} || {});
- //console.log("ici",this.settings)
- this.init();
-
- };
-
-$.fn.vs = function(options){
- if (!arguments.length){var options={}}
- //console.log('$.fn.vs settings',options)
- return this.each(function(){
- var element = $(this);
- // Return early if this element already has a plugin instance
- if (element.data('VisualSedimentation')) return;
- var visualSedimentation = new VisualSedimentation(this,options);
- // Store plugin object in this element's data
- element.data('visualSedimentation', visualSedimentation);
- //visualSedimentation.test();
- });
- };
-
-})(jQuery);
-
-
-
-
-
+// ....................................................................
+// Main Visual Sedimentation Code
+// ....................................................................
+
+// TODO :
+// - callback on rollOut
+
+(function($){
+
+// Name Space Plug in Jquery Objects
+$.fn.vs = function (){}
+$.fn._vs={}
+
+// All this objects are define in correspondant .js files
+$.fn._vs.token = {}
+$.fn._vs.draw = {}
+$.fn._vs.stream = {}
+$.fn._vs.chart = {}
+$.fn._vs.phy = {}
+$.fn._vs.decay = {}
+$.fn._vs.flocculate = {}
+$.fn._vs.strata = {}
+$.fn._vs.aggregate = {}
+
+
+// Core Classe
+var VisualSedimentation = function(element,options){
+
+ // Attach objects
+ this.token = $.fn._vs.token
+ this.draw = $.fn._vs.draw
+ this.stream = $.fn._vs.stream
+ this.chart = $.fn._vs.chart
+ this.phy = $.fn._vs.phy
+ this.decay = $.fn._vs.decay
+ this.flocculate = $.fn._vs.flocculate
+ this.strata = $.fn._vs.strata
+// this.aggregate = $.fn._vs.aggregate
+ this.requestAnimFrame;
+
+
+ // Mouse object have to be refactor
+ this.mouse ={}
+ this.mouse.x = 0
+ this.mouse.y = 0
+ this.mouse.isMouseDragging = false
+ this.mouse.isMouseDown = false
+ this.mouse.selectedBody = null
+
+
+ // Variables
+ this.dataFlow = [];
+ this.chartPhySetup= {}
+ this.tokens = [];
+ this.world = null;
+ this.ctx = null;
+ var elem = $(element);
+ var self = this;
+ var tokens = [];
+ var B2D;
+ var canvas;
+
+
+ // Default Settings
+ var defaultSettings = {
+ x:0,
+ y:0,
+ width:290.5,
+ height:300.5,
+ DOMelement:null,
+
+ chart:{
+ x:undefined,
+ y:undefined,
+ width:undefined,
+ height:undefined,
+ colorRange:d3.scale.category10(),
+ scale:d3.scale,
+ type:'StackedAreaChart',
+ /*
+ name are based on prefuse tollokit layout :
+ - CircleLayout,
+ - StackedAreaChart,
+ //- bubbleAreaChart,
+ x AxisLabelLayout,
+ x AxisLayout,
+ x CollapsedStackLayout,
+ x GridLayout,
+ */
+ spacer:5,
+ //treeLayout:false,
+ column:3,
+ wallColor:"rgba(230,230,230,0)",
+ label:true,
+ radius:10 // for CircleLayout
+ },
+ data:{
+ model:[
+ {label:"Column A"},
+ {label:"Column B"},
+ {label:"Column C"},
+ ],
+ strata:[
+ [
+ {initValue: 100, label: "Strata 1 col A"}
+ ],[
+ {initValue: 20, label: "Strata 1 col B"}
+ ],[
+ {initValue: 175, label: "Strata 2 col C"}
+ ]
+ ],
+ token:[
+ {
+ timestamp:1,
+ category:1,
+ value: 1,
+ userdata:{},
+ callback:{}
+ }
+ ],
+ tokenPast:0,
+ stream:{
+ provider:'generator',
+ refresh:10000/8,
+ now:0
+ },
+ }
+ ,
+ sedimentation:{
+ token:{size:{original:4
+ ,minimum:2}
+ ,visible:true}, // fill color, shape,
+ incoming:{
+ strategy:1, // 1 = one element by one, more = by Groupe
+ point:[{x:50,y:0},
+ {x:100,y:0},
+ {x:150,y:0}],
+
+ target:[{x:50,y:0},
+ {x:100,y:0},
+ {x:150,y:0}]
+ },
+ granulate:{visible:false},
+ flocculate:{
+ number:1, // 1 = one element by one, more = by groupe of n
+ action:"buffer", // [buffer,continue]
+ strategy:"Size", // [BufferSize, Time, AcummulationAreaHeight, Fps, Manual]
+ bufferSize:5, // number of token to make floculation
+ bufferTime:1000, // time buffer to make flocullation
+ bufferHeight:50, // height (pixel) to make floculation
+ bufferFrameRate:25, // if the computer is to slow floculate
+ buffer:[]
+ },
+ suspension:{
+ height:null, // pourcent,adaptative
+ incomming:'top',
+ decay:{power:1.001}, // null
+ refresh:200
+ },
+ accumulation:{height:null}, // pourcent ,adaptative
+ aggregation:{height:0, maxData:0, invertStrata:false}, // pourcent ,adaptative
+ },
+ options:{
+ refresh:1000/25,
+ panel:false,
+ scale:30,
+ layout:false,
+ canvasFirst:true
+ }
+ }
+
+
+ this.now = function(){
+ return(new Date().getTime())
+ }
+
+ // get Box2d World
+ this.globalDecay = function (value){
+ if(typeof(value)=='undefined'){
+ return this.settings.sedimentation.suspension.decay.power
+ }else{
+ return this.settings.sedimentation.suspension.decay.power=value
+ }
+ }
+
+ // get Box2d World
+ this.getWorld = function (){
+ return this.world;
+ }
+
+ this.chartUpdate = function (cat,y){
+ var options = {cat:cat,y:y}
+ this.chart[this.settings.chart.type](self,'update',options)
+ }
+
+ // Todo ......
+ this.flocculateTokens = function (number){
+ return this.flocculate.update(self,number)
+ }
+
+ // TODO DESTROY ALL TOKENS
+ this.flocculateAll = function(){
+ return this.flocculate.all(self)
+ }
+
+ // Add token function
+ this.addToken = function (element){
+ //var token = this.token.addToken(self,element)
+ return this.token.addToken(self,element);
+ }
+
+ // Select token fonction
+ this.selectAll = function (key,value){
+ return this.token.selectAll(self,key,value);
+ }
+
+ // Select token fonction
+ this.select = function (key,value){
+ return this.token.select(self,key,value);
+ }
+
+ // update a categoryr in the chart
+ this.updateAll = function (values){
+ var tokens = this.chart.updateAll(self,key,value)
+ return tokens;
+ }
+
+ // update a category in the chart
+ this.update = function (key,value){
+ var tokens = this.chart.update(self,key,value)
+ return tokens;
+ }
+
+
+ /// Settings without
+
+
+ //////////////////////////////////////////////////////// TO CLEAN
+ // SAM @ROM1 : are you sure you need that ? extend doing it well normally
+ // Merge options with defaults
+ // http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
+
+ //console.log("////////")
+ //options.model = modelToStrata(options.data.model)
+
+ function merge_options(obj1,obj2){
+ var obj3 = {};
+ for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
+ for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
+ return obj3;
+ }
+
+ merge_options(defaultSettings, options);
+ if(options.data!=undefined)
+ defaultSettings.data = options.data;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Merge option and add the DOMelement to setting
+ //this.settings = $.extend(defaultSettings, options || {});
+ this.settings = $.extend(true,defaultSettings, options);
+ this.settings.DOMelement = element
+ //console.log('settings after extend',this.settings)
+
+ // -----------------------------------------------
+ // SIMPLE DEFAULT SETTING FOR RETRO COMPATIBILITY
+ //
+ if(typeof(this.settings.chart.width) =="undefined"){this.settings.chart.width = this.settings.width}
+ if(typeof(this.settings.chart.x) =="undefined")this.settings.chart.x=0
+ if(typeof(this.settings.chart.y) =="undefined")this.settings.chart.y=0
+ if(typeof(this.settings.chart.height)=="undefined")this.settings.chart.height=this.settings.height
+ if(typeof(this.settings.stream) =="undefined"){this.settings.stream={}}
+ if(typeof(this.settings.stream.now) =="undefined"){this.settings.stream.now=0}
+ if(typeof(this.settings.stream.provider)=="undefined"){this.settings.stream.provider='generator'}
+ if(typeof(this.settings.stream.refresh)=="undefined"){this.settings.stream.refresh=1000}
+ if(typeof(this.settings.data.tokenPast)=="undefined"){this.settings.data.tokenPast=0}
+ if(typeof(this.settings.data.tokens)=="undefined"){this.settings.data.tokens=[]}
+
+ // FOR ROM1 setting by default aggregation :
+ if(typeof(this.settings.data.strata) !="undefined" && this.settings.data.strata.length!=0){
+ if(typeof(this.settings.sedimentation.aggregation) =="undefined"){
+ this.settings.sedimentation.aggregation = {}
+ }
+ if(typeof(this.settings.sedimentation.aggregation.height) =="undefined"){
+ this.settings.sedimentation.aggregation.height = this.settings.chart.height/2
+ }
+ if(typeof(this.settings.sedimentation.aggregation.maxData) =="undefined"){
+ this.settings.sedimentation.aggregation.maxData = 10
+ }
+ }
+ // END
+
+
+ // Initialisation - Private method
+ this.init = function(){
+ // requestAnim shim layer by Paul Irish
+ // not use yet, to add
+ this.requestAnimFrame = (function(){
+ return window.requestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ function(/* function */ callback, /* DOMElement */ element){
+ window.setTimeout(callback, 1000 / 60);
+ };
+ })();
+
+ //console.log(this.settings)
+ //console.log('Initialisation');
+
+ // Create the physical simulation
+ this.world = new this.phy.b2World(
+ new this.phy.b2Vec2(0, 0) //gravity
+ , true //allow sleep
+ );
+
+ // Create container and canvas for physical simulation drawing
+ var container = element.appendChild(document.createElement("div"));
+ container.id = "box_sediviz_"+GUID()
+ container.width = this.settings.width; // TOFIX
+ container.height = this.settings.height;
+
+ //console.log(container.id)
+ // Allocate the new Element
+ this.settings.DOMelement = container
+
+ canvas = container.appendChild(document.createElement("canvas"));
+ canvas.id = "canvas";
+ canvas.width = this.settings.width; // TOFIX
+ canvas.height = this.settings.height;
+ canvas.style.position = "absolute"
+
+ //console.log(this.settings.width,this.settings.height)
+ this.ctx = canvas.getContext("2d");
+
+ // Construct the Chart
+ this.chart[this.settings.chart.type](self,'init')
+
+
+ // Draw d3
+ //if(typeof(this.settings.options.debugaggregate)=="undefined"){
+ // this.aggregate.init(self);
+ //}
+ // Initiatlise stream
+ this.stream.init(self)
+ // Initiatlise decay
+ this.flocculate.init(self)
+ // Update stream
+ this.stream.update(self);
+
+ // Initiatlise tokens
+ this.token.init(self)
+
+ //FORCE UPDATE CHART due to (bug positionnement ) @rom1
+ this.strata.init(this)
+
+ // Update the physical simulation
+ window.setInterval(
+ function(){self.update(self);},
+ self.settings.options.refresh/2
+ );
+ // Refresh canvas drawings
+ window.setInterval(
+ function(){self.draw.update(self);},
+ self.settings.options.refresh
+ );
+ // Update Decay
+ window.setInterval(
+ function(){self.decay.update(self);},
+ self.settings.sedimentation.suspension.refresh
+ );
+ //this.decay.update(self);
+
+ self.strata.update(self)
+
+
+ // MOUSE PART
+ // inspired by box2d stuffs, have to clean and finish this !
+ // http://www.emanueleferonato.com/2008/11/20/dragging-objects-with-box2d-flash/
+ // --------------------------
+ this.getBodyAtMouse=function (_this) {
+
+ var x = _this.mouse.x/_this.settings.options.scale
+ var y =_this.mouse.y/_this.settings.options.scale
+ var mousePVec = new _this.phy.b2Vec2(x,y);
+ var aabb = new _this.phy.b2AABB();
+ var area = 0.001
+
+ //console.log(_this.mouse.x,_this.mouse.y)
+ aabb.lowerBound.Set(x - area, y - area);
+ aabb.upperBound.Set(x + area, y + area);
+
+ // Query the world for overlapping shapes.
+ _this.mouse.selectedToken = null;
+
+ // MERCI JULIEN POUR LE CLOSURE
+ //selectedBody
+ _this.world.QueryAABB(function(fixture){
+ return getBodyCB(fixture,_this,mousePVec)
+ }, aabb);
+
+ return _this.mouse.selectedToken;
+ }
+ //http://stackoverflow.com/questions/11674200/how-to-send-prototype-method-as-a-callback-in-javascript
+ // pb here
+ function getBodyCB(fixture,_this,mousePVec) {
+ //console.log("phy",phy)
+ //console.log("fixture",fixture.m_userData.type,fixture)
+ //_this.mouse.elementpoi = fixture.GetBody()
+ _this.mouse.selectedToken = fixture;
+
+ if(fixture.GetBody().GetType() != _this.phy.b2Body.b2_staticBody) {
+ if(fixture.GetShape().TestPoint(fixture.GetBody().GetTransform(), mousePVec)) {
+ _this.mouse.selectedToken = fixture;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ this.handleMouseMove = function(e,_this) {
+ canvasPosition = DOMabsOffset(_this.settings.DOMelement)
+ _this.mouse.x = (e.clientX - (canvasPosition.offsetLeft- this.getScrollPosition()[0]));
+ _this.mouse.y = (e.clientY - (canvasPosition.offsetTop- this.getScrollPosition()[1]));
+ //if( _this.mouse.isMouseDown){ console.log(_this.mouse.y,canvasPosition.y)}
+ //console.log("mouse",e.clientX,e.clientY )
+ //console.log("mouse",canvasPosition.x,canvasPosition.y )
+ //console.log("=",_this.mouse.x,_this.mouse.y)
+ };
+ // from
+ this.getScrollPosition= function(){
+ return Array((document.documentElement && document.documentElement.scrollLeft) || window.pageXOffset || self.pageXOffset || document.body.scrollLeft,(document.documentElement && document.documentElement.scrollTop) || window.pageYOffset || self.pageYOffset || document.body.scrollTop);
+ }
+
+ document.addEventListener("mousemove", function (e){onDocumentMouseMove(e,self)});
+ document.addEventListener("mouseup", function (e){onDocumentMouseUp(e,self)});
+ document.addEventListener("mousedown", function (e){onDocumentMouseDown(e,self)});
+
+
+
+ function onDocumentMouseOver(e,_this) {
+
+ var s = _this.getBodyAtMouse(_this);
+ if(s!=null){
+ if(typeof(s.m_userData)!="undefined"){
+ if(typeof(s.m_userData.callback)!="undefined"){
+ if(typeof(s.m_userData.callback.mouseover)=="function"){
+ var t = _this.select('ID',s.m_userData.ID)
+ s.m_userData.callback.mouseover(t)
+ }
+
+ if(typeof(s.m_userData.callback.mouseout)=="function"){
+ //console.log("mouseout exist")
+ var t = _this.select('ID',s.m_userData.ID)
+ var mouseoutTrigger
+ var rollOut = function(){
+ var mt = mouseoutTrigger
+ var tt = t
+ var ici = _this
+ var ss = s
+ return function(){
+ var s = ici.getBodyAtMouse(ici);
+ var mo = false;
+ if(s!=null){
+ if(typeof(s.m_userData)!="undefined"){
+ if(s.m_userData.ID==tt.attr('ID')){
+ mo=false
+ }else{
+ mo=true
+ }
+ }else{
+ mo=true
+ }
+ }else{
+ mo=true;
+ }
+ if(mo){
+ ss.m_userData.callback.mouseout(tt)
+ clearInterval(mouseoutTrigger)
+ }
+ }
+ };
+ mouseoutTrigger = window.setInterval(rollOut(),100)
+ }
+ }
+ }
+ }
+ }
+
+ function onDocumentMouseDown(e,_this) {
+ //console.log("onDocumentMouseDown")
+ _this.mouse.isMouseDown = true;
+ // return false;
+ _this.handleMouseMove(e,_this);
+ var s = _this.getBodyAtMouse(_this);
+ if(s!=null){
+ if(typeof(s.m_userData)!="undefined"){
+ if(typeof(s.m_userData.callback)!="undefined"){
+ if(typeof(s.m_userData.callback.onclick)=="function"){
+ var t = _this.select('ID',s.m_userData.ID)
+ s.m_userData.callback.onclick(t)
+ }
+ }
+ }
+ }
+ }
+
+ function onDocumentMouseUp(e,_this) {
+ _this.mouse.isMouseDown = false;
+ // isMouseDown = false;
+ // return false;
+ //console.log("onDocumentMouseUp")
+ }
+ function onDocumentMouseMove( e,_this ) {
+
+ if(_this.mouse.isMouseDown){
+ _this.mouse.isMouseDragging = true;
+ _this.mouse.x = e.clientX;
+ _this.mouse.y = e.clientY;
+
+ }else{
+ _this.handleMouseMove(e,_this);
+ onDocumentMouseOver("move",_this)
+ }
+ //console.log("m",_this)
+ }
+ }
+
+
+ this.mouse.update = function (s) {
+ if(isMouseDown && (!mouseJoint)) {
+ var body = getBodyAtMouse();
+ if(body) {
+ var md = new b2MouseJointDef();
+ md.bodyA = world.GetGroundBody();
+ md.bodyB = body;
+ md.target.Set(mouseX, mouseY);
+ md.collideConnected = true;
+ md.maxForce = 300.0 * body.GetMass();
+ mouseJoint = world.CreateJoint(md);
+ body.SetAwake(true);
+ }
+ }
+
+ if(mouseJoint) {
+ if(isMouseDown) {
+ mouseJoint.SetTarget(new b2Vec2(mouseX, mouseY));
+ } else {
+ world.DestroyJoint(mouseJoint);
+ mouseJoint = null;
+ }
+ }
+
+ };
+
+
+
+ // MOUSE END
+ // --------------------------
+
+ this.update = function (s) {
+ this.world.Step(1 / 60, 10, 10);
+ this.world.DrawDebugData();
+ this.world.ClearForces();
+ //console.log('u')
+ }
+
+ var drawInit = function(){
+ ctx.fillStyle = "rgb(200,0,0)";
+ this.ctx.font = "14pt Calibri,Geneva,Arial";
+ this.ctx.fillText("Canvas ready for Visual Sedimentation ", 10, 20);
+ window.setInterval(
+ $.fn.vs.draw.refresh(ctx,world,this.settings)
+ , this.settings.options.refresh);
+ console.log("draw Init ")
+ }
+
+
+ var DOMabsOffset = function(target){
+ var top = target.offsetTop;
+ var left = target.offsetLeft;
+
+ while(target = target.offsetParent) {
+ top += target.offsetTop;
+ left += target.offsetLeft;
+ }
+
+ return {offsetLeft:left, offsetTop:top};
+ };
+
+ // GUID generator from :
+ // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
+ var GUID = function(){
+ var S4 = function ()
+ {
+ return Math.floor(
+ Math.random() * 0x10000 /* 65536 */
+ ).toString(16);
+ };
+
+ return (
+ S4() + S4() + "-" +
+ S4() + "-" +
+ S4() + "-" +
+ S4() + "-" +
+ S4() + S4() + S4()
+ );
+ }
+
+ // clone object
+ // http://stackoverflow.com/questions/728360/copying-an-object-in-javascript
+ function clone(obj) {
+ if (null == obj || "object" != typeof obj) return obj;
+ var copy = obj.constructor();
+ for (var attr in obj) {
+ if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
+ }
+ return copy;
+ }
+ this.utile = {}
+ this.utile.GUID = GUID
+ this.utile.clone = clone
+
+ this.settings = $.extend(this.settings, {} || {});
+ //console.log("ici",this.settings)
+ this.init();
+
+ };
+
+$.fn.vs = function(options){
+ if (!arguments.length){var options={}}
+ //console.log('$.fn.vs settings',options)
+ return this.each(function(){
+ var element = $(this);
+ // Return early if this element already has a plugin instance
+ if (element.data('VisualSedimentation')) return;
+ var visualSedimentation = new VisualSedimentation(this,options);
+ // Store plugin object in this element's data
+ element.data('visualSedimentation', visualSedimentation);
+ //visualSedimentation.test();
+ });
+ };
+
+})(jQuery);
+
+
+
+
+