diff --git a/Guides/WAVE/README.md b/Guides/WAVE/README.md index cc5efe69..08697574 100644 --- a/Guides/WAVE/README.md +++ b/Guides/WAVE/README.md @@ -4,4 +4,4 @@ Web Applications with Enhanced Views (Web, Pipeline, MVC, Filters etc.) * Server-side [WAVE Server](Server.md) * MVC [MVC](MVC.md) -* Client-side Java Script Library [WAVE.js](WVJS.md) +* Client-side Java Script Library [WAVE.js](WVJS/README.md) diff --git a/Guides/WAVE/WVJS/ArrayFunctions.md b/Guides/WAVE/WVJS/ArrayFunctions.md new file mode 100644 index 00000000..f97cdb09 --- /dev/null +++ b/Guides/WAVE/WVJS/ArrayFunctions.md @@ -0,0 +1,19 @@ +# Array functions + +##### arrayClear(array) +Delete all elements from `array`. + +##### arrayDelete(array, object element): bool +Delete `element` from `array` and return true if `element` was found. + +##### arrayShallowCopy(source_array): object +Return new array - copy of `source_array`. + +##### arrayWalkable(array) +Provides walking (see WAVE.Walkable) capability for array. + +##### groupWalkable(array) +Converts array with {k : {}, v: []} structure to Walkable group operation result (inverse method to Walkable.wGroupToArray). + +##### inArray(array, object element): bool +Returns true when `array` contains `element`. diff --git a/Guides/WAVE/WVJS/EventManager.md b/Guides/WAVE/WVJS/EventManager.md new file mode 100644 index 00000000..87a6c0b3 --- /dev/null +++ b/Guides/WAVE/WVJS/EventManager.md @@ -0,0 +1,29 @@ +# WAVE.EventManager +Mixin that implements the event-handler mechanism and can be added to any class. + +##### eventInvocationSuspendCount: 0 +Increase to disable event firing for all events, decrease to enable, events are enabled again when value is <=0. This property is useful for batch updates to suppress many event firings that are not needed. + +##### eventBind(evtName, func) +Binds a function to the named event handler. + +##### eventUnbind(evtName, func) +Un-Binds a function from the named event handler. + +##### eventClear(evtName) +Clears all functions from the named event handler. + +##### eventInvoke(evtName) +Invokes all functions bound to the named event handler. + +##### eventSinkBind(sink) +Binds a sink instance (an object) that will receive all events dispatched by this manager. The `sink` must have a function called `eventNotify(evtName, sender, args)` that will be invoked. + +##### eventSinkUnbind(sink) +Un-Binds an object that received all events from this manager. + +##### eventSinkClear() +Clears all objects that cat as event sinks bound to this instance. + +##### eventSinks() +Returns a list of sink object that receive event notifications from this manager. diff --git a/Guides/WAVE/WVJS/Field.md b/Guides/WAVE/WVJS/Field.md new file mode 100644 index 00000000..71c7022d --- /dev/null +++ b/Guides/WAVE/WVJS/Field.md @@ -0,0 +1,125 @@ +# Field Class +Record consists of fields and Field represents a FieldDef from server-side NFX.DataAccess.CRUD.Schema on the client side along with view model/controller. + +## Field() +Constructor. Initializes a new instance using string field definition and value. +```js +new rec.Field(object fieldDef) +``` +### Examples +```js +var rec = new WAVE.RecordModel.Record("ID-123456", function(){ + new this.Field({Name: "FirstName", Type: "string", Required: true}); + new this.Field({Name: "LastName", Type: "string"}); + new this.Field({Name: "Age", Type: "int"}); + }); +``` +```js +var rec = new WAVE.RecordModel.Record("ID-123456"); +new rec.Field({Name: "FirstName", Type: "string"}); +new rec.Field({Name: "LastName", Type: "string"}); +new rec.Field({Name: "Age", Type: "int", Stored: false}); +``` + + +## drop() +Deletes this field from the record. + + +## deferValidation() +Defer or NOT validation event while changing of field’s value. +```js +deferValidation(bool flag) +``` +### Examples +```js +var rec = ... +var elog = ""; +rec.fldLastName.deferValidation(true); +rec.fldLastName.eventBind(WAVE.EventManager.ANY_EVENT, function(evtType, field, phase){ + elog += "|"+evtType + field.name() + phase + field.value(); + }); +rec.fldLastName.value("Brown"); +// elog = "|data-changeLastNamebeforeSmith|data-changeLastNameafterBrown" +``` +```js +var rec = ... +var elog = ""; +rec.fldLastName.deferValidation(false); +rec.fldLastName.eventBind(WAVE.EventManager.ANY_EVENT, function(evtType, field, phase){ + elog += "|"+evtType + field.name() + phase + field.value(); + }); +rec.fldLastName.value("Brown"); +// elog = "|data-changeLastNamebeforeSmith|validateLastNameundefinedBrown|validatedLastNameundefinedBrown|data-changeLastNameafterBrown" +``` + + +## eventBind() +Binds a function to the named event handler on field. +```js +eventBind(string evtName, function handler) +``` +| Parameter | Requirement | Description | +| --------- |:-----------:| --------------------------------------------- | +| evtName | required | name of event from WAVE.RecordModel namespace | +| handler | required | callback-function which fires on event | +### Examples +```js +var rec = ... +var elog = ""; +rec.eventBind(WAVE.RecordModel.EVT_FIELD_DROP, function(field, phase){ + elog += "|" + field.name() + phase; + }); +rec.fldLastName.drop(); +// elog = |LastNamebefore|LastNameafter +``` + + +## isGUIModified() +Returns true when this field was modified from an attached control. + + +## isModified() +Returns true when this field has been modified. + + +## loaded() +Returns true when this field has finished loading. + + +## toString() +Returns string like `[fieldType]Field(fieldName = 'fieldValue')`. + + +## stored() +Returns true if field must be stored back in the server (db). + + +## Validation functions +* valid() - returns true if field has not validation error. +* validate() - validates field and returns true if it is valid. +* validated() - returns true if field has been validated. +* validationError() - returns error thrown during validation. +### Examples +```js +var rec = new WAVE.RecordModel.Record("1", function(){ + new this.Field({Name: "A", Type: "string"}); + new this.Field({Name: "B", Type: "string", Required: true}); + }); + +rec.fldB.validated(); // false +rec.fldB.validate(); +rec.fldB.validated(); //true +rec.fldB.valid(); // false +var err = rec.fldB.validationError(); // contains: 'B' must have a value +rec.fldB.value("aaaaa"); +rec.fldB.valid(); // true +``` + + +## value() +`value()` - then returns field’s value. +`value(object value, bool fromGUI)` - Sets value and modified, validated flags if new value is different from an existing one. `fromGUI` indicates that field is being altered from an attached control. + + + diff --git a/Guides/WAVE/WVJS/OperObjFunc.md b/Guides/WAVE/WVJS/OperObjFunc.md new file mode 100644 index 00000000..052749d4 --- /dev/null +++ b/Guides/WAVE/WVJS/OperObjFunc.md @@ -0,0 +1,41 @@ +# Operations with objects and functions + +##### clone(object obj): object +Deep clones data object (not functions). + +##### extend(object obj, object ext, bool keepExisting): object +Mixin behavior - extends `obj` with properties of `ext`. +If flag `keepExisting=true` then existing object key is preserved, even if it is null. + +##### isArray(object obj): bool +Returns true when the passed parameter is an array, not a map or function. + +##### isFunction(object obj): bool +Returns true when the passed parameter is a function, not a map object or an array. + +##### isMapOrArray(obj): bool +Returns true when the passed parameter is an array, or map but not a function. + +##### isObject(object obj): bool +Returns true when the passed parameter is a map, not an array or function. + +##### isSame(object obj1, object obj2): bool +Returns true if both objects represent the same scalar value or complex structure/map that is keys/values of maps/arrays. Nulls are considered equivalent. + +##### overrideFunction(function original, function fn): function +Overrides existing function by wrapping in new one. May call base like so: +```js +object.about = WAVE.overrideFun(object.about, function(){ return this.baseFunction() + "overridden" }); +``` + +##### propStrAsObject(object obj, string prop) +Checks object property for string value and if it is then converts it to object (map). +Does nothing if prop does not exist, is null or not a string value. +```js +var o1 = {a: 1, b: '{"c": "yes", "d": "no"}'}; +// WAVE.isObject(o1.b)) = false + +WAVE.propStrAsObject(o1, "b"); +// WAVE.isObject(o1.b)) = true +``` + \ No newline at end of file diff --git a/Guides/WAVE/WVJS/README.md b/Guides/WAVE/WVJS/README.md new file mode 100644 index 00000000..a3e2f011 --- /dev/null +++ b/Guides/WAVE/WVJS/README.md @@ -0,0 +1,35 @@ +# NFX Wave.js +Java Script Client Library + +## General-Purpose Functions + +#### [Array functions](ArrayFunctions.md) +#### [Operations with objects and functions](OperObjFunc.md) +#### [String functions](StringFunctions.md) + +## Sub-libraries and mixins +#### [Geometry](geometry.md) +Contains a large number of functions to work with geometry tasks. + +#### [EventManager](EventManager.md) +Mixin that implements the event-handler mechanism and can be added to any class. + +#### SVG +Provides working with SVG objects. + +#### [UTest](UTest.md) +Implementation of unit testing concept. + +#### [Walkable](walkable.md) +Mixin that enables function chaining that facilitates lazy evaluation via lambda-functions. + + +## Record Model +Record model is in the WAVE.RecordModel namespace. + +### Classes +##### [Record](Record.md) +##### [Field](Field.md) +##### [RecordView](RecordView.md) + + diff --git a/Guides/WAVE/Record/readme.md b/Guides/WAVE/WVJS/Record.md similarity index 90% rename from Guides/WAVE/Record/readme.md rename to Guides/WAVE/WVJS/Record.md index 89c10ff0..10928196 100644 --- a/Guides/WAVE/Record/readme.md +++ b/Guides/WAVE/WVJS/Record.md @@ -42,20 +42,6 @@ var rec = new WAVE.RecordModel.Record({ID: 'REC-1', ]}); ``` - -### Examples -```js -var rec = new WAVE.RecordModel.Record("1", function(){ - new this.Field({Name: "A", Type: "string"}); - new this.Field({Name: "B", Type: "string", Required: true}); - }); - -rec.validate(); -var allErr = rec.allValidationErrorStrings(); -// allErr contains: 'B' must have a value -``` - - ## data() Returns a map of fields: `{fieldName:fieldValue,...}`. @@ -84,7 +70,6 @@ var d = JSON.stringify(rec.data(true)); // d = {"LastName":"Brown"} ``` - ## eventBind() Binds a function to the named event handler on record. ```js @@ -126,15 +111,12 @@ var v = rec.fldFirstName.value(); // v = John ``` - ## loaded() Returns true when record has finished loading data and constructing fields. - ##toString() Returns string like `Record[RecID]`. - ## Validation functions * allValidationErrorStrings() - returns all record and field-level validation errors. * validate() - validates record and returns true is everything is valid. @@ -151,5 +133,3 @@ var all = rec.allValidationErrorStrings(); // all contains 'B' must have a value // all contains 'C' must have a value ``` - - diff --git a/Guides/WAVE/RecordView/readme.md b/Guides/WAVE/WVJS/RecordView.md similarity index 100% rename from Guides/WAVE/RecordView/readme.md rename to Guides/WAVE/WVJS/RecordView.md diff --git a/Guides/WAVE/WVJS/StringFunctions.md b/Guides/WAVE/WVJS/StringFunctions.md new file mode 100644 index 00000000..76255bdb --- /dev/null +++ b/Guides/WAVE/WVJS/StringFunctions.md @@ -0,0 +1,130 @@ +# String functions + +##### charIsAZLetterOrDigit(char c): bool +Returns true if `c` is `[a-zA-Z0-9]`. + +##### intValid(string val): bool +Returns true if `val` is valid integer number. + +##### intValidPositive(string val): bool +Returns true if `val` is valid positive integer number. + +##### intValidPositiveOrZero(string val) +Returns true if `val` is valid positive integer number or zero. + +##### siNum(number num, int decimalPlaces): string +Converts `num` to its string representation in SI (Le Systeme International d’Unites) with precision desired. `1000 = "1.00k", .1="100.00m", 23.55 = "23.55", 999.999="1.00k"`. + +##### strCaps(string s, bool normalize): string +Capitalizes first chars after spaces or dots, optionally converting chars in between to lower case. + +##### strContains(string str, string seg, bool considCase): bool +Returns true when `str` contains a `seg` optionally respecting case. + +##### strDefault(string s, string dflt): string +If `s` is null or undefined then assigns `dflt` to it. If `dflt` is null or undefined then empty string. + +##### strEmpty(string s): bool +Returns true if string is undefined, null or empty. + +##### strEnsureEnding(string s, string ending): string +Ensures that string ends with the specified string: `strEnsureEnding("path",'/')`. + +##### strOneOf(string str, array set, string del): bool +Returns true if the case-insensitive trimmed string is in the set of values. Neither string nor set value may contain delimiter which is '|' by default: `strOneOf("car", ["car", "house", "tax"], ';')`. + +##### strTrim / strLTrim / strRTrim(string s): string +Remove spaces from both/left/right sides of `s`. + +##### strTrunc(string s, int maxLen, string endWith): string +Truncates `s` if its length exceeds `maxLen` and adds `endWith` string to result end. + +##### strSame(string str1, string str2): bool +Returns true if both string contain the same trimmed case-insensitive value. This method is useful for tasks like searches of components by name. + +##### strStartsWith / strEndsWith(string str, string seg, bool considCase): bool +Returns true if `str` starts/ends with `seg` optionally respecting case. + +##### strEscapeHTML(content): string +Replace html escape characters in `content` with special entities: `& --> &`. + +##### strHTMLTemplate(string tpl, object args): string +Returns content like `'@name@' --> 'Alex & Helen'` provided that `args = {name: 'Alex & Helen'}`. Data is HTML escaped. + +##### strTemplate(string tpl, object args): string +Returns content like `'{a: "@name@"}' -> '{a: "Alex & Boris"}'` provided that `args = {name: 'Alex & Boris'}`. Data is not HTML escaped. + +##### strIsEMail(string str): bool +Returns true if `str` is valid email like `a@bc.de` + +##### isValidScreenNameLetter(char c): bool +Returns true if `c` is allowable screen symbol including diacritic. + +##### isValidScreenNameLetterOrDigit(char c): bool +Returns true if `c` is number (0-9) or allowable screen symbol including diacritic. + +##### isValidScreenNameSeparator(char c): bool +Returns true if `c` is one from following set: ['.', '-', '_']. + +##### strIsScreenName(string s): bool +Returns true if `s` contains valid screen name/ID. + +##### strNormalizeUSPhone(string s) +Normalizes US phone string so it looks like (999) 999-9999x9999. If `s` starts with '+'(international phone, just return as-is). + +##### strLocalize(string iso, string schema, string fld, string val): string +Localizes string per supplied lang iso code within schema/field. + +##### toISODateTimeString(datetime dt): string +Returns '`dt` as string in ISO format (e.g. "2012-01-22T12:30:15.120Z"). + +##### toUSDateTimeString(datetime dt): string +Returns `dt` as string in "MM/DD/YYYY HH:MM:SS" format. + +##### toUSDateString(datetime dt): string +Returns `dt` as string in "MM/DD/YYYY" format. + +##### toSeconds(string dur): int +Parses duration string to total seconds. Example of duration string: "1d 10h 7m 13s". + +##### genRndKey(int keyLen, string alphabet): string +Generates random key with specified length from the alphabet of possible characters: `rndKey(10,"abcdefzq2")`. + +##### genAutoincKey(string seq, int val) +Returns next value of named sequence as result of: previous value (0 if function was not called for this sequence) + val. + +##### isScalar(val): bool +Returns true for scalar vars and false for arrays and objects. + +##### rnd(int min, int max): int +Returns random number in the range of min/max where min=0 max=100 by default: `rnd(10,57); rnd(30);` + +##### id(string s): object +`document.getElementById(s)`. + +##### getCookie(string name): string +Returns cookie by name or false if not found; + +##### setCookie(string name, string value) +Set cookie as `name = escape(value) + "; path=/"`. + +##### deleteCookie(string name) +Set expires as -1. + +##### Checking types +Returns true if `tp` is in: +* **isObjectType(tp)** - ["object", "json", "map", "array"] +* **isIntType(tp)** - ["int", "integer"] +* **isRealType(tp)** - ["float", "real", "double", "money"] +* **isBoolType(tp)** - ["bool", "boolean", "logical"] +* **isStringType(tp)** - ["str", "string", "char[]", "char", "varchar", "text"] +* **isDateType(tp)** - ["date", "datetime", "time", "timestamp"] + +##### convertScalarType(bool nullable, scalar value, string type, scalar dflt) +Converts scalar value into the specified type: +```js +var v; +v = convertScalarType(false, 13, "string", ""); // v = '13' +v = convertScalarType(true, "13", "int"); // v = 13 +v = convertScalarType(false, "abc", "int", 10); // v = 10 +``` \ No newline at end of file diff --git a/Guides/WAVE/WVJS/UTest.md b/Guides/WAVE/WVJS/UTest.md new file mode 100644 index 00000000..1498fd83 --- /dev/null +++ b/Guides/WAVE/WVJS/UTest.md @@ -0,0 +1,26 @@ +# WAVE.UTest +Static class which implements unit testing concept. + +##### run(string area, string name, function fn) +Wrapper for testing statements which placed in `fn`. +```js +run("Assertions", "assertTrue", function(){ + assertTrue(true); + log("This must pass 1"); +}); +``` + +##### testingStarted() +Returns true to indicate that testing has been activated. + +##### log(string msg) +Writes log message in new line. + +##### logi(string msg) +Writes log message inline. + +##### assertTrue(bool assertion, string msg) +If bool statement `assertion` is not true, then throws exception with `msg` ("Assertion not true" if empty). + +##### assertFalse(bool assertion, string msg) +If bool statement `assertion` is not false, then throws exception with `msg` ("Assertion not false" if empty). diff --git a/Guides/WAVE/WVJS/geometry.md b/Guides/WAVE/WVJS/geometry.md new file mode 100644 index 00000000..c96f640f --- /dev/null +++ b/Guides/WAVE/WVJS/geometry.md @@ -0,0 +1,141 @@ +# WAVE.Geometry + +## Properties + +* EARTH_RADIUS_KM : 6371 +* PI : 3.14159265 +* PI2 : 6.28318531 +* MapDirection: +{ + North: {Name: "North"}, + NorthEast: {Name: "NorthEast"}, + East: {Name: "East"}, + SouthEast: {Name: "SouthEast"}, + South: {Name: "South"}, + SouthWest: {Name: "SouthWest"}, + West: {Name: "West"}, + NorthWest: {Name: "NorthWest"} +} + + +## Functions + +##### angleToMapDirection(double angle): MapDirection +Converts a radian angular coordinate into map direction +##### azimuthDeg(double xc, double yc, double xd, double yd): double +Returns azimuth angle (theta) in degrees. +##### azimuthDegPoints(Point pc, Point pd) +Returns azimuth angle (theta) in degrees for two points: center and destination. +##### azimuthOfRadix(double xc, double yc, double xd, double yd, int radix): int +Returns azimuth angle (theta) in radix units. +##### azimuthOfRadixPoints(Point pc, Point pd, int radix): int +Returns azimuth angle (theta) in in radix units for two points: center and destination . +##### azimuthRad(double xc, double yc, double xd, double yd): double +Returns azimuth angle (theta) in radians. +##### azimuthRadPoints(Point pc, Point pd) +Returns azimuth angle (theta) in radians for two points: center and destination. +##### degToRad(int deg): double +Converts degrees to rads. +##### distance(double x1, double y1, double x2, double y2): double +Returns pixel distance between two points. +##### distancePoints(Point p1, Point p2): double +Returns pixel distance between two points. +##### findRayFromRectangleCenterSideIntersection(Rectangle rect, double theta): Point +Returns a point of intersection between a ray cast from the center of a rectangle under certain polar coordinate angle and a rectangle side. +##### getBBox(points): Rectangle +Returns 2D bounding box (with for a set of points (array of {x, y}). +##### lineIntersectsRect(double rx1, double ry1, double rx2, double ry2, double lx1, double ly1, double lx2, double ly2): bool +Defines if line has common points with rectangle (top-left/bottom-right coordinates). +##### mapDirectionToAngle(MapDirection direction): double +Converts map direction to angular coordinate in radians. +##### overlapAreaRect(Rectangle rect1, Rectangle rect2): double +Returns area of overlap between two rectangles. +##### overlapAreaWH(double x1, double y1, double w1, double h1, double x2, double y2, double w2, double h2): double +Returns area of overlap between two rectangles expressed as top-left/width-height pairs. +##### overlapAreaXY(double left1, double top1, double right1, double bott1, double left2, double top2, double right2, double bott2): double +Returns area of overlap between two rectangles expressed as top-left/bottom-right pairs. +##### perimeterViolationArea(Rectangle perimeter, Rectangle inner): double +Calculates a relative area of an inner rectangle that violates outside perimeter. The area is not 100% geometrically accurate - may be used for relative comparisons only. +##### radToDeg(double rad): double +Converts radians to degrees. +##### rotateRectAroundCircle(double cx, double cy, double cMargin, double rw, double rh, double angle): Rectangle +Calculates coordinates of rectangle given by width/height (`rw/`rh`) which center is rotated by `angle` (in radians) relatively to point (`cx`/`cy`) respecting rectangle size and `cMargin`. Returns coordinates of rotated rectangle. +##### toRectWH(double x1, double y1, double w, double h): Rectangle +Returns rectangle from coordinates and dimensions (width and height). +##### toRectXY(double x1, double y1, double x2, double y2): Rectangle +Returns rectangle from coordinate pairs. +##### vectorizeBalloon(Rectangle body, Point target, double legSweep) +Calculates call out balloon vertices suitable for contour curve drawing. Returns an array of vertex points. +* body - Balloon body coordinates. +* target - Balloon leg attachment point +* legSweep - Length of balloon leg attachment breach at balloon body edge, expressed in radians (arc length). A value such as PI/16 yields good results. +##### wrapAngle(double angle, double delta): double +Modifies an angle by delta value ensuring that resulting angle is always between 0 and 2pi. + + +## Classes + +### Point +Represents x,y pair on a Cartesian plane. +##### Point(double x, double y) +Constructor. +##### isEqual(Point p): bool +Determines whether the two points contain equivalent coordinates. +##### offset(double dx, double dy) +Changes point coordinates. +##### toPolarPoint(Point center): PolarPoint +Returns point as polar point relative to the specified center. +##### toString(): string +Returns coordinates in string like: `(10 , 12)`. +##### x(double val): double +Sets/returns X coordinate. +##### y(double val): double +Sets/returns Y coordinate. + +### PolarPoint +Represents point with polar coordinates. +##### PolarPoint(double radius, double theta) +Constructor. +##### isEqual(PolarPoint p): bool +Determines whether the two points contain equivalent coordinates. +##### radius(double val): double +Sets/returns radius of point. +##### theta(double val): double +Sets/returns angle theta of point. +##### toPoint(): Point +Returns polar point as simple Cartesian (x,y) point. +##### toString(): string +Returns coordinates in string like: `(1 , 45°)`. + +### Rectangle +Represents a rectangle. +##### Rectangle(Point corner1, Point corner2) +Constructor. +##### bottom(): double +Returns bottom-most edge coordinate. +##### bottomRight(): Point +Returns bottom right corner point per natural axis orientation when X increases from left to right, and Y increases from top to bottom. +##### centerPoint(): Point +Returns center point. +##### contains(Point p): bool +Tests if point lies within this rectangle. +##### corner1(Point val): Point +Sets/returns top left corner of rectangle. +##### corner2(Point val): Point +Sets/returns bottom right corner of rectangle. +##### height(): double +Returns rectangle height. +##### left(): double +Returns left-most edge coordinate. +##### right(): double +Returns right-most edge coordinate. +##### square(): double +Returns rectangle square. +##### top(): double +Returns top-most edge coordinate. +##### topLeft(): Point +Returns top left corner point per natural axis orientation when X increases from left to right, and Y increases from top to bottom. +##### width(): double +Returns rectangle width. + + diff --git a/Guides/WAVE/WVJS/walkable.md b/Guides/WAVE/WVJS/walkable.md new file mode 100644 index 00000000..d9eee993 --- /dev/null +++ b/Guides/WAVE/WVJS/walkable.md @@ -0,0 +1,229 @@ +# WAVE.Walkable +Mixin that enables function chaining that facilitates lazy evaluation via lambda-functions. This is analogue of method-based LINQ queries in .NET. + +## Projection Operations +##### wSelect(transform) +Projects values that are based on a transform function. +```js +var a = [1, 2, 3]; +var aw = WAVE.arrayWalkable(a); +var wSelect = aw.wSelect(function(e) { return e * 10; }); +var result = wSelect.wToArray(); // [10, 20, 30] +``` + +##### wSelectMany(transform) +Projects sequences of values that are based on a transform function and then flattens them into one sequence. +```js +var a0 = [1, 2]; +var a1 = [3, 4]; + +var aa = [WAVE.arrayWalkable(a0), WAVE.arrayWalkable(a1)]; +var aw = WAVE.arrayWalkable(aa); +var result = aw.wSelectMany(function (e) { return e; }); + +// result.wAt(0) = 1 +// result.wAt(1) = 2 +// result.wAt(2) = 3 +// result.wAt(3) = 4 +``` + +## Filtering Data +##### wWhere(filter) +Selects values that are based on a predicate function `filter`. +```js +var a = [1, 2, 3, 4, 5]; +var aw = WAVE.arrayWalkable(a); +var whereWalkable = aw.wWhere(function(e) { return e > 3; }); +var resultArray = whereWalkable.wToArray(); // [4, 5] +``` + + +## Element Operations +##### wAt(int pos) +Returns the element at a specified index in a walkable collection. + +#### wEach(action) +Does `action` for each element in collection. + +##### wFirst(condition) +Returns the first element of a collection, or the first element that satisfies a condition. +```js +var a = [1, 2, 3]; +var aw = WAVE.arrayWalkable(a); +var first; + +first = aw.wFirst(); // 1 +first = aw.wFirst(function(e) { return e > 2; }); // 3 +first = aw.wFirst(function(e) { return e < 0; }); // null + +aw = WAVE.arrayWalkable([]); +var cnt = aw.wFirst(); // null +``` + +##### wFirstIdx(condition) +Returns an index of element that satisfies a condition. +```js +var a = [1, 2, 3]; +var aw = WAVE.arrayWalkable(a); +var idx; +idx = aw.wFirstIdx(function(e) { return e == 0; }); // -1 +idx = aw.wFirstIdx(function(e) { return e == 1; }); // 0 +``` + + +## Aggregation Operations +##### wAggregate(aggregate, initVal) +Performs a custom aggregation operation on the values of a collection. + +##### wCount(condition) +Counts the elements in a collection, optionally only those elements that satisfy a predicate function. + +##### wMax(greater) +Determines the maximum value in a collection. + +##### wMin(less) +Determines the minimum value in a collection. + +##### wSum(initVal) +Calculates the sum of the values in a collection. + + +## Set Operations +#### wConcat(other) +Concatenates two sequences to form one sequence. +```js +var aw = WAVE.arrayWalkable([1, 2, 3]); +var bw = WAVE.arrayWalkable([5, -4]); +var ct = aw.wConcat(bw).wToArray(); // [1, 2, 3, 5, -4] +``` + +##### wDistinct(equal) +Returns distinct elements from a sequence by using the default equality comparer or `equal` to compare values. +```js +var a = [1, 2, 2, 3, 5, 4, 2, 4, 3]; +var aw = WAVE.arrayWalkable(a); +var distinct = aw.wDistinct(); +var result = distinct.wToArray(); // [1, 2, 3, 5, 4] +``` +```js +var a = [{x: 0, y: 0}, {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 1}, {x: 4, y: 3}]; +var aw = WAVE.arrayWalkable(a); +var distinct = aw.wDistinct(function(a, b) { return a.y == b.y; }); +var result = distinct.wToArray(); // [{x: 0, y: 0}, {x: 1, y: 1}, {x: 4, y: 3}] +``` + +##### wExcept(other, equal) +Produces the set difference of two sequences by using the default equality comparer or `equal`. +```js +var a = [1, 2, 3]; +var b = [2]; +var aw = WAVE.arrayWalkable(a); +var bw = WAVE.arrayWalkable(b); +var except = aw.wExcept(bw).wToArray(); // [1, 3] +``` + +#### wEqual(other, equalFunc) +Determines whether two sequences are equal by comparing elements with `equalFunc`(optional). + +## Grouping Data +##### wGroup(keyer, valuer) +Groups elements that share a common attribute. Result has `k` (key) and `v` (values) properties. +```js +var a = [{x: 0, y: 0}, {x: 1, y: 1}, {x: 0, y: 33}, {x: 0, y: 34}, {x: 1, y: -5}, {x: 0, y: 127}]; + +var group = WAVE.arrayWalkable(a).wGroup(function(e) { return e.x; }, function(e) { return e.y; }).wGroupIntoArray(); +/* +group[0].k = 0 +group[0].v.length = 4 +group[0].v[0] = 0 +group[0].v[1] = 33 +group[0].v[2] = 34 +group[0].v[3] = 127 + +group[1].k = 1 +group[1].v.length = 2 +group[1].v[0] = 1 +group[1].v[1] = -5 +*/ +``` + +##### wGroupAggregate(aggregator, initVal) +Performs a custom aggregation operation on the elements in groups. +```js +var a = [{x: 0, y: 0}, {x: 1, y: 1}, {x: 0, y: 33}, {x: 0, y: 34}, {x: 1, y: -5}, {x: 0, y: 127}]; + +var group = WAVE.arrayWalkable(a).wGroup(function(e) { return e.x; }, function(e) { return e.y; }).wGroupAggregate(function(k, r, e) { return (r || 0) + e }); + +// group.wAt(0).v = 194 +// group.wAt(1).v = -4 +``` + +##### wGroupIntoArray() +Converts the result of grouping to array of objects like this: `{k: key, v: [values]}` + +##### wGroupIntoObject() +Converts the result of grouping to object like this: `obj[key] = [values]`. + +## Sorting Data +##### wOrder(order) +Sorts elements in according to `order`. +```js +var a = [1, -3, 2, 17, -9, 4, 5]; +var ordered = WAVE.arrayWalkable(a).wOrder(function(a, b) { return a < b ? 1 : a > b ? -1 : 0; }).wToArray(); +// ordered = [17, 5, 4, 2, 1, -3, -9] +``` + +## Partitioning Data +##### wTake(quantity) +Takes `quantity` elements from the head of collection. + +##### wTakeWhile(condition) +Takes elements from the head of collection while `condition` is true. + +##### wSkip(quantity) +Skips `quantity` elements from the head of collection. + +## Quantifier Operations +##### wAny(condition) +Determines whether any elements in a sequence satisfy a condition. + +##### wAll(condition) +Determines whether all the elements in a sequence satisfy a condition. + + +## Converting Data Types +#### wToArray() +Converts a collection to an array. + +## Special Operations +#### wHarmonicFrequencyFilter(m, k) +Frequency filter takes: +* "m" (f=ma Newtons law) - in virtual units of mass (i.e. kilograms) - the higher the number the more attenuation for high frequencies, +* "k" (f=-kx Hooks law) - in virtual units of spring membrane resistance, the higher the number the more attenuation for low frequencies. + +##### wConstLinearSampling(samplingStep) +Ensures that all {s, a} vectors in incoming walkable are equally spaced in time, so {a} component linearly interpolated between otherwise discrete points, i.e. [ {1, -47} , {10, 150}] => F(2) => yields vectors where respected components (0 -> 5, -47 -> 150) get linearly pro-rated. +```js +var w = WAVE.arrayWalkable([{s: 1, a: 10}, {s: 10, a: 700}]).wConstLinearSampling(2); +w.wAt(0).s = 0 +w.wAt(0).a = 10 +``` + +#### wSineGen / wSawGen / wSquareGen / wRandomGen(cfg) +Outputs {s,a} vectors per SINE/"Saw"/"Square"/Random function. + +#### wWMA(k) +"weight"-based moving average filter (k is kind of "weight" 0..1): +* if k == 0 - moving object has no weight (hence no momentum) and outbound signal is the same as inbound, +* if k == 1 - moving object has infinite weight (hence infinity momentum) and outbound signal will be permanent (equal to first sample amplitude). +```js +var aw = WAVE.arrayWalkable([{s: 0, a: 1}, {s: 1, a: 100}, {s: 2, a: -100}]); +var wma = aw.wWMA(.1); +// wma.wAt(0).a = 1 +// wma.wAt(1).a = 90.1 +// wma.wAt(2).a = -80.99 +``` + +##### WAVE.signalConstSrc(cfg) + Walkable source of constant signal: `WAVE.signalConstSrc({a: 17.75, qty: 2})`. + \ No newline at end of file