Friday, March 17, 2017

Typescript/JavaScript Angular Problem: Hashmap a dictionary of rescaled one dimensional coordinate values to their corresponding indices for a position based array mapping and more

Okay, so the title is rather a big one, but the problem goes like this:

You've had to squeeze your data down in such a way so that it fits into your canvas graphic...that is, it makes little sense if you have big numbers that can't be viewed because their plot values are outside of the dimension of your screen.  This problem is of 'squeezing' the data is otherwise re scaling it so that it fits into visual dimensions that can be read.  Its really not a big deal doing that since you can refactor a plot without changing its shape/form attributes by using a global scale factor.  But let's say you wanted to have a quick and easy search algorithm that matches a screen based coordinate that a user has supplied, say from mouseover position that relates to a position on the graph or at least as directly related to your big data.  How to do this?

As it turns out you may have stored your big data, in some sort of collection type that contains points which may have something like: x, y in 2 dimensions, and this collection type may be structured in the form of an array.  The problem is that with any mouseover, your first inclination may be to search the set of points and then break at a common match, but this is slow!  I say this since you are constantly search iterating points to find the match based on a screen position that is supplied.  Why not create an inverse map on the set of points and hashmap these?

As it turns out you can do it in Typescript/Javascript, but as I found out, keys say with the {} type string values.  If your data is on the other hand given by positions which are 'number' types you'd first have to likely Math.round(), Math.floor() or Math.ceiling your numbers.  Then you'd convert this to string using the position.x.toString(),  'number' types have a .toString() method.  Then you'd key the value while storing its array index in value position.

A sketch:

    public setScreenXCoords(){
        //called after screen coordinates have been setSceenXCoords
        //and that this.points is a screen coordinate set.  
        var i = 0;
        for (let pvec of this.screenpoints){
            let x = pvec.x;
            x = Math.round(x);
            /*
            console.log("key: ");
            console.log(x);
            console.log("value");
            console.log(i);
            */
            this.screenToIndex[x.toString()] = i;
            i += 1
        }
    }

In a given data range set of points, it is important to keep in mind that keying position data means also that truncation (by floor, rounding, or ceiling a number) may necessarily supply more than one position for a given key, and for this you may need to bucket the values in an array, and provide additional searching algorithms in refining a search, but at least this method provides nice fast lookup position addressing.

So when you search you need to account for undefined key values.  These are screen positions that do not have a corresponding key in, for instance, inverse2dVectorsMap.  For this, you simply omit the user supplied position until they have sufficiently toggled a position that corresponds to a point on the data set.

And example sketch:

    public getScreenPoint(xposnumber){
        let xpostr = xpos.toString();
        if (xpostr in this.screenToIndex){
            return this.screenToIndex[xpostr];
        }
        return undefined;
    }


Then filter 'undefined' return values relative to non 'undefined' ones.

For example:

    private mouseMoved(eMouseEvent){
        //(mousemove)="mouseMoved($event)"
        console.log(e.offsetX);
        let xstr = e.offsetX.toString();

        
        console.log("screen index: ");
        
        if (e.offsetX != undefined){
            let ind = this.dataCharts[0].getScreenPoint(e.offsetX - 80.0);
            console.log(ind);
            if (ind != undefined){
            this.pointindex[0] = ind;
            this.pointindex2 = ind;
            }
        }
    }

Thursday, March 16, 2017

Tip for determining an angular dom event

Dom events in html5 do have a translation to Angular, but it may not be immediately obvious.  For instance, in Angular the reference call (click) is equivalent to onclick for the corresponding dom event in Html5 outside of Angular.  As it turns the conversion process may follow the rule:
add parenthesis () and then drop the prefix "on"  so "onclick" becomes "(click)" or "onmousemove" becomes "(mousemove)".  This seems to be a general translation language pattern between Angular and non Angular usage in Html.

Sunday, March 12, 2017

Programming complications and work around in Angular

   In a previous post, I provided a simple recipe for passing simple type arrays to avoid more formal data binding in Angular.

Recently a problem emerged where in Typescript (translated to JS), I were instancing randomly generated class/struct data called lineData in working with a visual graph/charts data interface and this data was instanced inside the class of two canvas selector directives from a parent component controller.   My intent were to pass an array object of this class namely lineData[]

The problem:
When instancing a class array type of this data and while passing the array object of lineData, or  lineData[], I was repeatedly generating errors in the contstructor and ngOnInit() or ngOnChanges() methods when attempting to write data to either directive instance.  The error generated was an 'undefined' when accessing the lineData[] object even though it were supposedly populated in the constructor call with data.  Strangely when not passing from the parent controller component to the individual child directives, lineData[] instanced at the child level with non injection would not generate non persistence problems as seen in the parent to child injection case.

Solution:
I still needed to pass and coordinate data between two child directives on the lineData[] array object, so instead, I opted to generate the random lineData[] at the parent component controller level and then pass this to each child directive where data persistence would suffice.  This in retrospect still seems a bit troubling to me, one since evidently manipulating and instancing data in the child directive fails as an instancing source, but not if such origins are in the parent component controller class.  Technically though it should work, it my suspicions are that the ngOnChanges() method is cleaning the lineData[] object (beyond the constructor call) with the changes in the parent level controller binding of this object to its child directives.  Technically, I haven't set anything at the parent level to reset lineData[] (i.e., removing data or splicing or whatever), but the mystery remains as to what were occurring here.

Friday, March 3, 2017

Cool Trick in Angular to avoid formal data bindings

   How should I be passing parameter data, and how do I exactly do it without defining a directive or component?

  Let's say you wanted to defined a child class structure that is merely a object process that does something but you weren't as interested in angularizing syntax to pass parameter data.  There is a way to do this.  The secret goes to C and C++ and other non scripting high level languages that make use of pointers for referencing the memory of object data.  As it turns out in scripting languages commonly, though they don't make use of point or call by referencing exactly, but you can still do it!  


Scripting languages  (e.g., Java, Javascript, and Python for instance) are locked out from call by referencing on:

-number, float, integer, boolean, and so forth object types.  


But not on:

-array, list, hashlist, map, dictionary, class, struct, string, and so forth.  


Thus if you wrap a locked object type in one of the non locked out types such as an array, you can pass parameter data by modification.

The beauty of doing a 'binding' this way is that it is quite simple in terms of syntax.  Literally you use an object wrapper that does the same thing.  

I have avoided defining event listeners for parameter data changes.  Namely in my particular case synchronizing animation loop start and stops between two angular directives, the loop itself would act as an event listener thus omitting the need in explicitly defining an event detection structure in angular.  As it turns out though object wrapped types, I believe, are not detected by implicit changes say in the array such as modification of the array at a given already assigned index.  Thus defining event listeners in angular will likely have work around if you plan on constructing event listeners in conjunction with object wrapping methods that I have described.  

You can construct event listeners (without defining these formally) also by using recursion calls:

method(){
   requestAnimationFrame(()=>this.method())

Technically its an animation timer, but it should be safe for event handling processes.  You'd just need to define breaks if you want to pause or stop this event handler (e.g. a boolean structure that prevents reiteration of the recursion call).

Oblivion

 Between the fascination of an upcoming pandemic ridden college football season, Taylor Swift, and Kim Kardashian, wildfires, crazier weathe...