├── 101.txt ├── API_Management.txt ├── API_Management_OpenAPI_Code_Generator.txt ├── API_Management_TOP_APIS.txt ├── API_Management_swagger_autodoc.md ├── CSS.txt ├── JSON_LD.md ├── SEO_positioning_and_monetization.txt ├── W3C_Identity.dia ├── W3C_Identity.svg ├── angular.txt ├── angular01_architecture.txt ├── angular02_development_cycle.txt ├── angular03_responsive_app.txt ├── angular04_recipes.txt ├── angular_ALL.payload ├── angular_TODO.txt ├── angular_plus_keycloak_example_integration.txt ├── angular_whats_new.txt ├── cookies_state_management.txt ├── data_visualization.txt ├── gRPC.txt ├── javascript.payload ├── javascript.txt ├── javascript_PWA.txt ├── javascript_alternatives.txt ├── javascript_binary_data.txt ├── javascript_testing.txt ├── nativescript.txt ├── nodejs_101.txt ├── nodejs_bundlers.txt ├── notes.txt ├── preact.txt ├── react.txt └── typescript.txt /101.txt: -------------------------------------------------------------------------------- 1 | ... (2017) Big data: According to IBM5, 2.5 trillion6 data bytes are 2 | generated every day, and 90% of the global data was created during 3 | the past 2 years. These data come from sensors, messages posted on 4 | social networks, pictures and videos published on the Internet, from 5 | geolocation (for example, GPS or NFC) from mobile devices 6 | (smartphones, tablets, smart watches), traceability logs for online 7 | payments (for example from e-payments or m-payments), keywords 8 | entered in search engines and, more generally, any digital 9 | information that can be used for interpretation (scientific data, 10 | fraud detection, medical, personal, behavioral data, etc.). Big data 11 | can be defined by “3V”: volume (“data tsunami”: 20 petabytes7 of data 12 | are processed every day by Google, and this has been the case since 13 | 2010, 1.88 zettabytes were produced in 2011, meaning a 50% increase 14 | per year), variety (web data from social networks, linked data from 15 | semantic web, public data, open data and mobiquitous data coming from 16 | tagged objects and sensor networks, etc.) and velocity (data flow 17 | from sensors and social networks, real-time “on the fly”), to which 18 | we add a fourth “V”: variability (evolution), and a fifth “V”: 19 | valorization (improvement and enrichment). 20 | -------------------------------------------------------------------------------- /API_Management_OpenAPI_Code_Generator.txt: -------------------------------------------------------------------------------- 1 | 5 | [openapi-generator](https://openapi-generator.tech) 6 | 7 | |OpenAPI.json| ··> openapi-generator ¹ ··> go/python/... client/server SDK 8 | ^ 9 | · 10 | Golang/Python/.. ·····┘ 11 | Mustache template/s 12 | 13 | 14 | ¹: docker run -v ${PWD}/:/local \ 15 | openapitools/openapi-generator-cli:v5.1.1 \ 16 | generate -i https://api.merge.dev/api/ats/v1/schema \ 17 | -g python \ 18 | -o ./local/python-sdk 19 | 20 | ## Template Basic: 21 | Tipical worklfow: 22 | - override default Mustache template files with custom configuration 23 | by simply creating a new file locally that has the same name! 24 | 25 | -t ./local/REPLACE-WITH-YOUR-TEMPLATES-FOLDER 26 | 27 | 28 | JSON ················> MUSTACHE ······> OUTPUT 29 | ---- ---------- ------- 30 | OpenAPI spec test.mustache 31 | { {{#list1}} item1 32 | "list1": [ {{{.}}} 33 | "item1", {{/list1}} item2 34 | "item2" 35 | ... 36 | ], 37 | "existingName": "foo" 38 | } ^^^^^^^^^^ 39 | Similar to HTML 40 | with {{}} vs <> 41 | 42 | 43 | 44 | The (tests) SDK is going to contain: 45 | - Client code wraping http connections and auth configuration 46 | - API methods matching our OpenAPI spec. 47 | - Model classes matching request+response payloads 48 | basic test: 49 | - deserializing a model class from (example) json payload. 50 | 51 | ## Modifying `model_test.mustache` Golang/Python/... Template 52 | 53 | 54 | def test{{classname}}(self): 55 | """Test {{classname}}""" 56 | # FIXME: construct object with mandatory 57 | # attributes with example values 58 | # model = {{classname}}() # noqa: E501 59 | # Add this 60 | {{{.}}} <·· Mustache debug: see raw json payload 61 | 62 | 63 | {{#vendorExtensions}} 64 | {{#x-merge-sample-json}} <··· custom property manually added to OpenAPI 3.0 65 | raw_json = """ 66 | {{{.}}} 67 | {{/x-merge-sample-json}} 68 | {{^x-merge-sample-json}} <··· we lack "if-conditionals". {{^...}} for "branching" 69 | """ common pattern all over default templates 70 | No test json responses defined for {{classname}} 71 | """ 72 | raw_json = None 73 | {{/x-merge-sample-json}} 74 | {{/vendorExtensions}} 75 | 76 | 77 | Final generated code will be something like: 78 | 79 | model_sync_status_test.go: 80 | 81 | /* ... */ 82 | package merge_hris_client 83 | 84 | import "testing" 85 | 86 | func TestDeserializeSyncStatus(t *testing.T) { 87 | var rawJson = []byte( 88 | `{"model_name": "Candidate", "model_id": "ats.Candidate", ...}`) 89 | var result01 SyncStatus 90 | 91 | err := NewAPIClient(NewConfiguration()).decode( 92 | &result01, rawJson, "application/json") 93 | if err != nil { ... } 94 | } 95 | 96 | 97 | ### Generating custom Output Files: 98 | { 99 | "templateDir": "/local", 100 | "files": { 101 | "PATH_TO_YOUR_TEMPLATES/go_test.mustache": { 102 | "templateType": "Model", 103 | "destinationFilename": "_test.go" 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /API_Management_TOP_APIS.txt: -------------------------------------------------------------------------------- 1 | # TOP Open APIs 2 | * REF: 3 | ## Account Management API 4 | standardized mechanism for management of billing and settlement 5 | accounts, as well as for financial accounting (account receivable) 6 | either in B2B or B2B2C contexts. 7 | ## Appointment API 8 | standardized APIs to book appointment, including: 9 | ✓ parameterized searching for free slots 10 | ✓ nature and place of appointment. 11 | ✓ ... 12 | 13 | ## Customer Management API 14 | standardized API for customer and customer account management 15 | (creation, update, retrieval, deletion and notification of events). 16 | 17 | ## Partnership Type Management API 18 | Standardized API for CRUD operations on partnership types. 19 | It is one of the APIs involved in an onboarding process . 20 | ✓ Identifies type of partnership among parties 21 | (allowed role types list, e.g: [ Buyer, Seller, Developer]. 22 | ## Party Management API : 23 | 24 | Standardized API for CRUD party management. 25 | Party := individual | organization 26 | 27 | ## Party Role Management API 28 | standardized API for general CRUD party roles and notification of events. 29 | 30 | ## Product Catalog Management API 31 | standardized API for adding partners' products to existing Catalog. 32 | It brings the capability for Service Providers to directly 33 | feed partners systems with the technical description of the products they 34 | propose to them. 35 | 36 | ## Product Inventory Management API 37 | standardized API for CRUD (representation of)product inventory management 38 | and product lifecycle event notification. 39 | 40 | ## Product Offering Qualification API : 41 | One of Pre-Ordering Management API Family. 42 | 43 | ## Product Ordering API : 44 | standardized API for placing a product order. 45 | simple set of operations to interact with CRM/Order negotiation systems 46 | in a consistent manner. 47 | 48 | ## Quote Management API : 49 | one of the Pre-Ordering Management APIs. 50 | 51 | ## Shopping Cart API : 52 | standardized API for shopping-carts CRUD and events management. 53 | used for the temporary selection and reservation of product 54 | offerings in e-commerce and retail purchase. 55 | 56 | ## Trouble Ticket API : 57 | standardized API to Trouble Ticket Management Systems CRUD among 58 | partners as result of an issue or problem identified by a customer 59 | or another system. 60 | Examples of Trouble Ticket API clients include CRM applications, 61 | network management or fault management systems, or other trouble 62 | ticket management systems (e.g. B2B). 63 | 64 | ## Agreement Management API : 65 | standardized API for managing agreements, especially in the context 66 | of partnerships between partners. 67 | 68 | ## Communication API : 69 | create+send communications, notifications, and instructions to 70 | Parties, Individuals, Organizations or Users. 71 | 72 | ## Entity Catalog Management API : 73 | The entity catalog is intended to provide any SID entity to consumers via a 74 | catalog, with its specification and policy providing governance over its 75 | content. The API provides management of the entity specifications and their 76 | associations thru CRUD operations. 77 | 78 | ## Federated Identity API : [aaa] 79 | management of principals of any kind (persons, objects, …) and their 80 | access to resources in an open environment which can span across different 81 | enterprise boundaries. It relies on authentication, authorization and consent 82 | mechanisms to protect privacy with a simple and easy user experience. 83 | Different parties can provide identity services 84 | (operators, social networks, GSMA, …). 85 | 86 | ## Geographic Address Management API : 87 | Standardized client interface to an (worldwide) Address management system, 88 | validating and searching for geographic address data: 89 | 1) searching an area as a start (city, town ...) 90 | 2) zooming on the streets of this area 91 | 3) listing all the street segments (numbers) in a street. 92 | 93 | ## Geographic Location Management API : 94 | Provides the information of a geographic region of the entity (customer, 95 | equipment, address). 96 | 97 | ## Geographic Site Management API : 98 | CRUD ops to manage sites that can be associated with customers, accounts, 99 | service delivery or other entities. 100 | 101 | ## Loyalty Management API : [monetization] 102 | Supports the management of loyalty program specifications, loyalty program 103 | members, their associated products and loyalty accounts with loyalty balances 104 | https://www.tmforum.org/resources/specification/tmf658-loyalty-management-api-rest-specification-r17-0-1/ 105 | 106 | ## Partnership Type Management API : 107 | Standardized mechanisms for creating partnership types. It is one of the APIs 108 | involved in an onboarding process. 109 | 110 | ## Party Interaction Management API : 111 | A User Interaction captures information about past interactions in order to 112 | reuse it in future ones. This allows agents to serve users better by knowing 113 | the steps they went through. It also allows customers to see better the 114 | actions they have performed and how they interacted with us. 115 | 116 | ## Party Management API : 117 | Provides a standardized API for party CRUD management. 118 | 119 | ## Party Role Management API 120 | Provides a standardized API for general party roles CRUD management. 121 | 122 | ## Payment Management API : [payments] 123 | standardized client interface to Payment Systems for notifying about 124 | performed payments or refunds. 125 | Examples of Payment API originators (clients) include: 126 | Web servers, mobile app servers, Contact center dashboards or retail 127 | store systems. 128 | 129 | ## Payment Methods API : [payments] 130 | This API supports the frequently-used payment methods for the customer to 131 | choose and pay the usage, including voucher card, coupon, and money transfer. 132 | 133 | ## Prepay Balance Management API [payments] 134 | REST API for Balance Management. It includes the model definition as well as 135 | all available operations for prepay balance management. Prepaid subscribers 136 | pay fees before using services. Therefore, the subscribers must have 137 | sufficient balances. Operators can provide multiple recharge channels for 138 | subscribers. Subscribers can pass credit between different subscriptions, 139 | therefore transferring the balance from one account to another. 140 | 141 | ## Privacy Management API : [privacy] 142 | The Privacy management API provides standardized mechanisms for privacy 143 | profile types, privacy profiles and privacy agreements such as creation, 144 | update, retrieval, deletion and notification of events.. 145 | 146 | ## Product Catalog Management API : 147 | standardized API for rapidly adding partners' products to an existing 148 | Catalog. It brings the capability for Service Providers to directly 149 | feed partners systems with the technical description of the products they 150 | propose to them. 151 | 152 | ## Product Inventory Management API : 153 | standardized API for CRUD of representation-of-product in inventory. 154 | 155 | ## Product Offering Qualification API : 156 | One of Pre-Ordering Management API Family, providing Product Offering 157 | commercial eligibility. 158 | 159 | ## Product Ordering API : 160 | standardized API for placing a product order interacting with CRM/ 161 | Order negotiation systems in a consistent manner. 162 | 163 | ## Quote Management API : [payments] 164 | One of the Pre-Ordering Management APIs allowing to place a customer 165 | quote with all of the necessary quote parameters. 166 | 167 | ## Resource Catalog Management API : 168 | API spec allowing the management of the entire lifecycle of the 169 | Resource Catalog elements and the consultation of resource catalog 170 | elements during several processes such as ordering process. 171 | 172 | ## Resource Function Activation and Configuration API : 173 | This API introduces Resource Function which is used to represent a Network 174 | Service as well as a Network Function. The Network Service and Network 175 | Function class definitions and associations in TR244 (which, in turn, builds 176 | on concepts from the SID addenda on Logical Resource and Service) are 177 | utilized to define the Resource Function 178 | 179 | ## Trouble Ticket API : 180 | standardized client interface to Trouble Ticket Management Systems 181 | for creating, tracking and managing trouble tickets among partners as a 182 | result of an issue or problem identified by a customer or another system. 183 | API clients include CRM applications, network management or fault 184 | management systems, or other trouble ticket management systems (e.g. B2B). 185 | 186 | ## Usage Consumption Management API : [monetization] 187 | API allowing real-time view of the balance of the various buckets 188 | (SMS, Voice, Data for example) that a user consumes with each of his devices 189 | and the usages done out of the bucket. Usage report retrieves the data 190 | related to these balances. 191 | This API should also allow performing a direct top-up on the balance of 192 | a prepaid bucket with voucher references or with a given credit value after 193 | a payment done by a credit card or with a credit value transfer. 194 | 195 | ## Usage Management API : 196 | Provides standardized mechanism for collection-of-usages CRUD management. 197 | E.g: It allows a service provider to 198 | 1) retrieve usage generated by a partner service platform in order to rate it 199 | 2) provide rated usage to a partner for consumption follow up purposes. 200 | 201 | ## User Roles&Permissions API : 202 | user role : entity that defines a set of privileges covering various functions 203 | and/or manageable assets. 204 | (session) User are assigned a given role then it is actually allocated 205 | all the privileges defined for that role type and the corresponding 206 | permissions are created for that user. 207 | 208 | 209 | -------------------------------------------------------------------------------- /API_Management_swagger_autodoc.md: -------------------------------------------------------------------------------- 1 | [[{API_MANAGEMENT,20_QA.DOCUMENTATION,STACK.NODEJS]] 2 | # swagger-autogen API Documentation 3 | 4 | ## PRESETUP: 5 | 6 | ``` 7 | $ npm install --save-dev swagger-autogen 8 | ``` 9 | 10 | https://medium.com/swlh/automatic-api-documentation-in-node-js-using-swagger-dd1ab3c78284 11 | 12 | swagger-autogen input: 13 | - output path for .json Swagger. 14 | - files containing the endpoints (files containing get(), post(), functions) 15 | - object containing documentation details: (optional) 16 | - version, title, description, schemes, etc., 17 | 18 | Example: https://github.com/davibaltar/example-swagger-autogen. 19 | 20 | 21 | project structure: 22 | |-- ... 23 | |-- swagger.js <··· Script in charge of calling swagger-autogen 24 | similar to: 25 | const swaggerAutogen = require('swagger-autogen')() 26 | const outputFile = './swagger_output.json' // <··· Generated Output (save to Git) 27 | const endpointsFiles = [ 28 | './endpoints.js' 29 | ] 30 | 31 | const doc = { 32 | info: { 33 | version: "1.0.0", 34 | title: "My API", 35 | description: "Documentation ..." 36 | }, 37 | host: "api.bla.ble", 38 | basePath: "/", 39 | schemes: ['http', 'https'], 40 | consumes: ['application/json'], // 41 | produces: ['application/json'], 42 | tags: [ 43 | { "tag_key1": "...", 44 | "tag_key2": "..." } 45 | ], 46 | securityDefinitions: { 47 | api_key: { 48 | type: "apiKey", name: "api_key", in: "header" }, 49 | petstore_auth: { 50 | type: "oauth2", 51 | authorizationUrl: "https://petstore.swagger.io/oauth/authorize", 52 | flow: "implicit", 53 | scopes: { 54 | read_pets: "read your pets", 55 | write_pets: "modify pets in your account" 56 | } 57 | } 58 | }, 59 | definitions: { // <·· INPUT and Output data schemas 60 | User: { 61 | $id: "myUser01", // '$' indicates attribute is mandatory 62 | $prop01: 10, 63 | $prop02: { ... }, 64 | $prop03: [ ... ] 65 | }, 66 | ... 67 | } 68 | } 69 | 70 | // swaggerAutogen(outputFile, endpointsFiles, doc) // alt 1. Just generate code 71 | swaggerAutogen(outputFile, endpointsFiles, doc) // alt 2. Auto gen code, 72 | .then(() => { then launch server 73 | require('./index.js') 74 | }) 75 | |-- endpoints.js <··· file containing .get()/post()/... functions. 76 | Something similar to: 77 | module.exports = function (app) { 78 | app.get('/users/:id', (req, res) => { 79 | /* 80 | * #swagger.tags = ['User'] 81 | * #swagger.description = 'Endpoint para obter um usuário.' 82 | * ^^^^^^^^ 83 | * This is the way to communicate wit swagger-autogen 84 | * WARN: Commment must be inside the function. 85 | */ 86 | ... 87 | return res.status(404).send(false) 88 | }) 89 | } 90 | └─────────────────┬───────────────────┘ 91 | TIP: With Express.js (or similar) swagger-autogen 92 | automatically recognizes the 93 | methods/path/status-of-responses and 94 | content-type of Header! 95 | |-- package.json 96 | { 97 | "main": "index.js", 98 | "scripts": { 99 | "start": "node swagger.js", <···· Autogen doc and start server 100 | "swagger-autogen": "node swagger.js" <···· npm run swagger-autogen 101 | }, to generate the info 102 | "dependencies": { 103 | "express": "^4.17.1", 104 | "swagger-autogen": "^2.23.1", 105 | "swagger-ui-express": "^4.1.4" 106 | } 107 | } 108 | 109 | TIP: every time the project is started, new documentation is generated. 110 | making it always updated. 111 | 112 | TIPS: #swagger.ignore = true <··· Ignore this endpoint 113 | 114 | If the framework is NOT automatically recognised by swagger, do it manually like: 115 | function myFunction(params) { 116 | // #swagger.path = '/forcedEndpoint/{id}' 117 | // #swagger.method = 'put' 118 | // #swagger.description = 'Endpoint forçado' 119 | // #swagger.produces = ["application/json"] 120 | // #swagger.tags = ['User'] 121 | } 122 | 123 | https://github.com/davibaltar/example-swagger-autogen-with-router 124 | https://github.com/davibaltar/example-swagger-autogen. 125 | 126 | Note: We can also expose the API directly to our micro using swagger-ui-express 127 | 128 | [[}]] 129 | -------------------------------------------------------------------------------- /JSON_LD.md: -------------------------------------------------------------------------------- 1 | [[{standards.data_mng,01_PM.TODO]] 2 | # JSON-LD #[json-ld_summary] 3 | @[https://json-ld.org/] [TODO] 4 | * JSON-based format used to serialize Linked Data primarily targeting 5 | Web environments in order to build interoperable Web services, and 6 | to store Linked Data in JSON-based storage engines. 7 | * Provides smooth upgrade path from JSON to JSON-LD. 8 | 9 | ## Linked Data Proofs 1.0 10 | @[https://w3c-ccg.github.io/ld-proofs/] 11 | This specification describes a mechanism for ensuring the 12 | authenticity and integrity of Linked Data documents using 13 | mathematical proofs. 14 | 15 | [[}]] 16 | -------------------------------------------------------------------------------- /W3C_Identity.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/earizon/WebTechnologies/8299bb7f36da1e73306e5343d27c4c4dfe7cd49c/W3C_Identity.dia -------------------------------------------------------------------------------- /W3C_Identity.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Verifiable 31 | Crendential 32 | (Claim "proof") 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Verifiable 42 | Crendential 43 | (Claim "proof") 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Verifiable 53 | Crendential 54 | (Claim "proof") 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Verifiable 64 | Crendential 65 | (Claim "proof") 66 | 67 | 68 | 69 | REFs: 70 | - https://w3c.github.io/did-core/ 71 | - https://www.w3.org/TR/vc-data-model/ 72 | - https://w3c.github.io/vc-use-cases/ 73 | 74 | 75 | Identity of a subject ("DID") will be the sum of all the claims "pointing" to the DID. 76 | 77 | Verifiable credentials will contain all the needed information to allow a DID owner to 78 | retrieve all the information. 79 | - This information can be public, un-encrypted on the Verifiable Crendential, in which 80 | case it can be interpreted as a claim from pointing node to pointed DID. 81 | Ussually the Verifiable Crendital will not contain the un-encrypted information but: 82 | - some cryptographic material (public key) 83 | - a suite of cryptographic methods supported by the cryptographic material, and 84 | - an external URL pointing to the service that can provide the Claim payload 85 | (using the associated private key owned by the (pointed-to) DID. 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | W3C Identity Model 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | DID 113 | URL 114 | 115 | 116 | 117 | 118 | 119 | 120 | DID 121 | Document 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | DID 131 | URL 132 | 133 | 134 | 135 | 136 | 137 | 138 | DID 139 | Document 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | DID 149 | URL 150 | 151 | 152 | 153 | 154 | 155 | 156 | DID 157 | Document 158 | 159 | 160 | 161 | 162 | Document: 163 | - Info used by DID controllers: 164 | - cryptographic material. 165 | - verification methods 166 | - service endpoints 167 | - (Opt) DID subject data (model). 168 | 169 | 170 | 171 | 172 | 173 | 174 | DID 175 | URL 176 | 177 | 178 | 179 | 180 | 181 | 182 | DID 183 | Document 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /angular.txt: -------------------------------------------------------------------------------- 1 | # ANGULAR 2 | * Official Doc: 3 | 4 | ## Ext.Links 5 | * Angular API: 6 | * Github Repo: 7 | 8 | 9 | -------------------------------------------------------------------------------- /angular01_architecture.txt: -------------------------------------------------------------------------------- 1 | # Angular Architecture [[{angular.101]] 2 | * REF: 3 | 4 | * VIEW: "screen element" on browser, mobile, ... 5 | * COMPOMENT: 6 | * Typescript Class with ng-decorator. 7 | * Defines N views, arranged hierarchically. 8 | The (optional) Router service defines navigation paths 9 | among them. 10 | * At least one root component is needed by App, connecting a 11 | component hierarchy with the page document object model (DOM). 12 | * Service (providers) are injected (@Injectable() decorator) to provide 13 | needed non-visual functionality. 14 | * When a component is instantiated, it's associated directly with 15 | the (root) host view. 16 | * Generate with cli like: 17 | ``` 18 | | $ ng generate component "compName" 19 | * ``` 20 | 21 | ``` 22 | | DATA 23 | | TEMPLATE == HTML + BINDING + DIRECTIVES 24 | | MARKUP 25 | | └─┬──┘ └───┬────┘ 26 | | ┌────────────┘ └ There can be: 27 | | FRONTEND │ ANGULAR ├─ Component directives (the most common) 28 | | DOM │ COMPONENT │ 29 | | └┬┘ ┌──────┴─────────────────┐ └───┬───┘ ├─ Attribute Directives: 30 | | │ │ │ - [ngClass]="JS expression" 31 | | ←················ {{value}} ···· ←┤ │ - [ngStyle]="JS expression" 32 | | │ │ │ - NgModel two way data binding: 33 | | │ │ │ 34 | | ←······· [property]="value" ···· ←┤ │ PRE-SETUP: add FormsModule to @"X".module.ts 35 | | │ │ │ imports:[...,FormsModule] 36 | | │ │ │ 37 | | ├─··→· (click)="handler" ·········→ │ 38 | | │ │ │ 39 | | │ │ │ 40 | | ←···· [(ng-model)]=comp.varName ··→ └─ Structural directives: add/remove elements 41 | | │ │ 42 | | ----------------------- NgIf, NgFor, NgSwitch: 43 | | Two way binding (forms mainly). Ex: 44 | | 45 | |
{{I.name}}
46 | | ☞ All data bindings are processed once 47 | | for each JS event cycle from app
48 | | root component through tree children. 49 | | ... 50 | | 51 | |
52 | 53 | e.g.: 54 | 55 | TEMPLATE : template ·> evaluate ·> resolve ·> modify 56 | EVALUATION input directives binding HTML DOM 57 | syntax 58 | ``` 59 | 60 | * TEMPLATE PIPES (data transformation) 61 | * Ex: date data → pipe → locale-date 62 | * Predefined Pipes ():
63 | Async , Currency , Date , Decimal, I18n(Plural|Select), JSON, 64 | KeyValue, (Lower|Upper)Case , Percent , Slice , TitleCase 65 | ``` 66 | | User click → (intercepted by) → Router → (reacts by) → showing/hiding view hierarchies. 67 | | ( lazy load └───────┬──────┘ 68 | | of related modules) │ 69 | | ┌···································· hierarchical structure is key ···┘ 70 | | │ to how Angular detects/reacts 71 | | │ to changes in the DOM|app data. 72 | | ┌───┴─────┐ 73 | | ┌→ view root ←→ NgModule1.rootComponent ┐ ← boostrapping module (ex. app.module.ts) 74 | | · └- view1 ←→ NgModule1.component1 ├ A view hierarchy can include 75 | | · └- view2 ←→ NgModule2.rootComponent │ views from components in the 76 | | · └- view3 ←→ NgModule2.component3 ┘ same or different NgModule 77 | | · └───┬───┘ └───┬───┘ 78 | | · | 79 | | · | - (typescript) app logic controling a view 80 | | · | through an properties+methods API. 81 | | · | - 82 | | · 83 | | · - container|scope for a set of (component list, Service list, ...) 84 | | · - compilation context for components: 85 | | · - orthogonal app-domain|workflow|capabilities set. 86 | | · - can depend on other (imported) NgModules 87 | | · 88 | | └→ Ex Module: app.module.ts: 89 | | import { NgModule } from '@angular/core'; ← JS input 90 | | import { BrowserModule } from '@angular/platform-browser'; ← JS input 91 | | @NgModule ({ ← Decorator function. 92 | | imports : [ BrowserModule ], 93 | | providers : [ Logger ], ← Creators of services that this NgModule 94 | | contributes to. (providers at component 95 | | level can also be specified , which is 96 | | often preferred). 97 | | A service declared here also ensures that it 98 | | will be available as a singleton instance to 99 | | any other component/service. 100 | | 101 | | declarations: [ AppComponent ], ← components|directives|pipes declared 102 | | 103 | | exports: [ AppComponent ], ← (opt) Subset of declarations accesible 104 | | by templates in other NgModules 105 | | 106 | | bootstrap: [ AppComponent ] ← (Only root module): main app view 107 | | }) 108 | | export class AppModule { } ← JS export (vs NgModule export) 109 | ``` 110 | * Component Example: 111 | ``` 112 | | file: src/app/hero-list.component.ts 113 | | @Component ({ 114 | | selector : 'app-hero-list', ← associated html tag name 115 | |┌→ templateUrl: './hero-list.component.html', ← seteable property programatically 116 | |·┌ providers: [HeroService] ← required Service prov. array 117 | |·· }) Size must match constructor arg. size 118 | |·· 119 | |·· export class HeroListComponent implements OnInit { 120 | |·· heroes : Hero[]; ← data app property. Note: Many components wrap all 121 | |·· selectedHero: Hero; ← data app property data in a model dict to make code 122 | |·· more readable. 123 | |·└ constructor (private service:HeroService) ← service will be injected 124 | |· { ...} Must match @Component.providers 125 | |· 126 | |· @Input() hero : Hero; // ← @Input() marks field as input, bounding it 127 | |· @Input() power: string; // to template DOM prop. Used to comunicate data 128 | |· // among parent←→children components. 129 | |· 130 | |· ... 131 | |· ngOnChanges(change_map: SimpleChanges) { // 132 | |· └───────────┬───────────┘ 133 | |· /* lifecycle hook called when data-bound properties change. 134 | |· * Implemented by NgModel, FormControl*, Max/MinLenghtValidator, ... 135 | |· * maps each changed property to a SimpleChange 136 | |· * instance with (current,previous) values. */ 137 | |· for (let key in change_map) { 138 | |· let chng = change_map[key]; 139 | |· let cur = JSON.stringify(chng. currentValue); 140 | |· let prev = JSON.stringify(chng.previousValue); 141 | |· .log('PropName: ${key}: Val: ${cur}, previous ${prev}'); 142 | |· } 143 | |· } 144 | |· 145 | |· 146 | |· ngOnInit() { ←·lifeCycle hook 147 | |· this. heroes = this.service.getHeroes(); See also detailed examples at: 148 | |· } 149 | |· selectHero(hero: Hero) { this.selectedHero = hero; } │ 150 | |· } └─────────┬──────────┘ │ 151 | |· └─────────────────────────────────────────┐ │ 152 | |· │ │ 153 | |└→ Ex template: src/app/hero─list.component.html │ │ 154 | |

Hero List

│ │ 155 | | Pick a hero from list: │ │ 156 | |
    ┌───────┴──────┐ │ 157 | |
  • │ 158 | | {{hero.name | UpperCase}} │ 159 | |
  • │ 160 | |
│ 161 | | │ 162 | | │ 165 | | │ 166 | | │ 167 | | │ 168 | | ┌───────────────────────────────────────────────────────────┘ 169 | | ┌───────┴───────────┐ 170 | | Main Life-cycle Hooks for Component(or Directive in general): 171 | | HOOK PURPOSE AND TIMING 172 | | ──── ────────────────── 173 | | ngOnChanges(changes: SimpleChanges) (re)sets data-bound input properties. 174 | | ngOnInit() Initialize component after first display 175 | | with data-bound properties and sets the 176 | | directive/component's input properties. 177 | | ngDoCheck() Detect and act upon changes that Angular 178 | | can't or won't detect on its own. 179 | | ngAfterContentInit() Respond after Angular projects external content 180 | | into the component's view 181 | | ngAfterContentChecked() ... 182 | | ngAfterViewInit() ... 183 | | ngAfterViewChecked() ... 184 | | ngOnDestroy() tap into Cleanup just before Angular destroy 185 | | Use it to Unsubscribe Observables and detach 186 | | Other hooks: event handlers to avoid memory leaks. 187 | | - Angular sub-systems 188 | | - 3rd party libraries may add new hooks. 189 | ``` 190 | 191 | * Service Example: 192 | ``` 193 | | file: src/app/logger.service.ts 194 | | $ $ ng generate service ... 195 | | Service: "Do one thing and do it right" (root/module/component)singleton . 196 | | - Injected in components through constructors. 197 | | @Injectable() 198 | | export class Logger { 199 | | log (msg: any) { console.log (msg); } 200 | | error(msg: any) { console.error(msg); } 201 | | warn (msg: any) { console.warn (msg); } 202 | | } 203 | ``` 204 | * Note on Services injection procedure: 205 | * Angular will create 1+providers for each service(or function|value). 206 | * The provider can be part of the service's own metadata, to make 207 | it available everywhere, or it can be registered with an specific 208 | module|component using the respective decorator 209 | `(@Injectable(), @NgModule() or @Component())` 210 | * NOTE: If the providers is in @Injectable() decorator, Angular 211 | will optimize the app by removing it, if it's not used. 212 | 213 | * Service SCOPE: 214 | ``` 215 | | ┌──────────┬─────────────────────────────────┬────────────────────────────── 216 | | │ LEVEL │ Scope │ Declaration 217 | | ├──────────┼─────────────────────────────────┼────────────────────────────── 218 | | │ ROOT │ single instance injected in all │ @Injectable( 219 | | │ (app) │ app─components (Default) │ {providedIn: 'root'}) 220 | | │ │ │ (@ service01.service.ts) 221 | | ├──────────┼─────────────────────────────────┼────────────────────────────── 222 | | │ NgModule │ single instance injected in all │ @NgModule( ... 223 | | │ │ module─components │ { providers: 224 | | │ │ │ [ service01, service02 ] 225 | | │ │ │ }) 226 | | ├──────────┼─────────────────────────────────┼────────────────────────────── 227 | | │ Component│ new service instance created for│ @Component({ 228 | | │ │ each new component │ selector : '...' 229 | | │ │ │ ,templateUrl: '...component.html' 230 | | │ │ │ ,providers : [ service01 ] 231 | | │ │ │ }) 232 | | └──────────┴─────────────────────────────────┴────────────────────────────── 233 | ``` 234 | [[}]] 235 | -------------------------------------------------------------------------------- /angular02_development_cycle.txt: -------------------------------------------------------------------------------- 1 | [[{angular.101]] 2 | # Angular Development cycle 3 | (Setup, build, deploy config) 4 | 5 | ## ng CLI reference 6 | 7 | * Used to: 8 | * create projects, 9 | * generate app. and library code. 10 | * testing, bundling, deployment. 11 | * ... 12 | 13 | * PRE-SETUP: 14 | ``` 15 | $ npm install -g @angular/cli 16 | ``` 17 | * BASIC WORKFLOW 18 | ``` 19 | | $ ng new my-first-project\ ← create, build, and serve (Wait ~ 1 minute to complete) 20 | | --strict ← Opt. Forbids "any" type 21 | | CREATE ... ← initial app created goes to root project folder 22 | | CREATE ... ← Additional apps/library go to ./projects/ 23 | | 24 | | $ cd my-first-project new, basic project 25 | | $ ng serve ← Automatic rebuilds on edit!!! 26 | | Test server listening at: 27 | | http://localhost:4200/ 28 | ``` 29 | 30 | * App Layout : 31 | * A new app contains: 32 | ``` 33 | | - source files for root module 34 | | - root component + root template. 35 | | - /src folder: contains 36 | | - logic 37 | | - data 38 | | - assets. 39 | ``` 40 | within a project folder, use a command similar to the next one 41 | to components,services, pipe code, directives, ... (or do it manually) 42 | ``` 43 | | $ ng generate ... to add new 44 | ``` 45 | 46 | * Workspace and project configuration 47 | ``` 48 | | WORKSPACE 1 <··> 1+ Project 49 | | └──┬──┘ 50 | | application or 51 | | shareable lib 52 | | ${WORKSPACE} 53 | | └ ./angular.json ← workspace per-project defaults for "ng" command 54 | | like custorm target defaults, ... 55 | | Edit it manually or through $ $ng config ... 56 | ``` 57 | 58 | * ng syntax: 59 | ``` 60 | | $ ng commandNameOrAlias requiredArg --opt1 --boolOpt2 --noBoolOpt3 61 | | └─────────────┬──────────────┘ 62 | | NOTE: opt.names in angular.json are "camelCase". 63 | | opt.names in ng command are "camelCase" or 64 | | "dash-case". 65 | | 66 | | $ ng generate "artifact or library to be generated" 67 | | $ ng add "artifact or library to be added" 68 | | └──┬───┘ └──────────────────────────────────┘ 69 | | │ each artifact/library defines its 70 | | │ own options in a schematic. 71 | | ┌────┴─────────────────────────────────────────────────────────┐ 72 | | - add 73 | | - analytics https://angular.io/cli/usage-analytics-gathering. 74 | | - build output to dist/ 75 | | - config 76 | | - deploy 77 | | - doc Opens Official Angular documentation in browser, 78 | | and searches for a given keyword. 79 | | - e2e Builds and serves an Angular app, then runs 80 | | end-to-end tests using Protractor 81 | | - generate Generates/modifies files based on a schematic. 82 | | - help 83 | | - new 84 | | - run Runs an Architect target with an optional custom builder 85 | | configuration defined in your project. 86 | | - serve 87 | | - test 88 | | - update Updates app and dependencies. 89 | | See 90 | | - version 91 | | 92 | | - xi18n Extracts i18n messages from source code. 93 | | Ex: 94 | | $ ng build my-app -c production 95 | | ^^^^^^ 96 | | generated artifact can also be 97 | | indicated with --name "my-app" 98 | ``` 99 | 100 | * Workspace, Project Layout 101 | * REF: 102 | ``` 103 | | ${WORKSPACE}/ 104 | | .editorconfig 105 | | .gitignore 106 | | README.md 107 | | angular.json 108 | | package.json (npm package dependencies) 109 | | package-lock.json (version information for all npm packages installed) 110 | | (yarn.lock in case o using yarn) 111 | | src/ src for root-level main application project ¹ 112 | | node_modules/ 113 | | tsconfig.json "Solution Style" TypeScript config file. Used by 114 | | code editors and TS's language server to inprove dev. experience. 115 | | NOT used by compilers . See detailied info about "noImplicitAny", 116 | | "suppressImplicitAnyIndexErrors", ... at 117 | | 118 | | tsconfig.base.json base TypeScript config for all (sub)projects in W.S. 119 | | tslint.json Default TSLint config for all (sub)projects in W.S. 120 | | ./projects/ ← Only for (git SCM) monorepo . Recommended for: 121 | | └ my-lib01/src - shareable libraries 122 | | └ src/lib library project's logic and data(components,services, 123 | | · modules, directives and pipes) 124 | | └ src/test.ts main unit-test entry point (normally defaults are OK) 125 | | └ src/public-api.ts Specifies all files exported from library. 126 | | └ karma.conf.js 127 | | └ ng-package.json Config file used by ng-packagr at build time. 128 | | └ package.json npm package dependencies required by library. 129 | | └ tsconfig.lib.json Lib-custom TypeScript configuration. 130 | | └ tsconfig.spec.json TypeScript configuration for the tests. 131 | | └ tslint.json 132 | | 133 | | └ py-app02/src - enterprises using "monorepo" approach. 134 | | └ ... In monorepos all developers in all dev.groups 135 | | └ e2e/ can see all changes from other devs./dev.groups 136 | | ... Git becomes the "source-of-true" . 137 | | All projects will share similar parent config. 138 | | Add new one as: 139 | | $ $ ng generate application projectXX (--strict) 140 | | e2e/ End-to-end test files corresponding to root-level 141 | | · app, along with test-specific configuration files. 142 | | · protractor.conf.js (test-tool config) 143 | | · tsconfig.json (extends tsconfig.json from workspace) 144 | | · src/ 145 | | · app.e2e-spec.ts (end-to-end tests for my-app) 146 | | · app.po.ts 147 | | 148 | | 149 | |¹ src/ Directory Layout: 150 | | 151 | | app/ Angular components, templates, styles, logic and data 152 | | · app.component.ts : app root component logic ("AppComponent"). 153 | | · Its view becomes root of view-hierarchy 154 | | · └──┬───┘ 155 | | · app.component.html : ←──┘ 156 | | · app.component.css : 157 | | · app.component.spec.ts: unit test for root AppComponent. 158 | | · app.module.ts : Defines the root module named "AppModule", 159 | | telling Angular how to assemble the whole app. 160 | | As you add more components to the app, they must 161 | | be declared here. 162 | | 163 | | assets/ images, ... to be copied as-is 164 | | environments/ build config options for a given target 165 | | By default: 166 | | - unnamed standard development 167 | | - production ("prod") 168 | | - (custom ones can be defined, like acceptance, ...) 169 | | favicon.ico 170 | | index.html CLI automatically adds all JavaScript and CSS files 171 | | when building your app, so you typically there is no 172 | | need to add any script/link tags manually. 173 | | main.ts App entry point 174 | | Compiles the application with the JIT compiler and 175 | | bootstraps the application's root module (AppModule) to 176 | | run in the browser. 177 | | - AOT compiler can also be used by appending by using 178 | | $ $ ng build|serve .... --aot 179 | | polyfills.ts Polyfill scripts for browser support. 180 | | styles.sass Lists CSS files supplying styles for a project. 181 | | (sass extension can vary depending on defaults for project) 182 | | WARN:!!! sass is in deprecated state. It requires npm packages 183 | | with lot of dependencies (including gcc/python2/...) when 184 | | "npm" installing. 185 | | Don't use it unless you need to maintain a old software. 186 | | test.ts main entry point for unit tests . 187 | | package.json (strict mode only) 188 | | Not used by package managers, it tell tools&bundlers whether 189 | | the code under this directory is free of non-local side-effects. 190 | | 191 | | APPLICATION-SPECIFIC CONFIG FILES 192 | | .browserslistrc : Config sharing of target browsers and Node.js versions 193 | | among various front-end tools. More info at: 194 | | 195 | | karma.conf.js : App-specific Karma configuration. 196 | | tsconfig.app.json : App-specific TypeScript configuration, 197 | | (TypeScript, ng template compiler options, ...) [[{01_PM.TODO}]] 198 | | 202 | | tsconfig.spec.json: TypeScript config. for the app. tests. 203 | | tslint.json : App-specific TSLint config. 204 | ``` 205 | [[angular.101}]] 206 | -------------------------------------------------------------------------------- /angular03_responsive_app.txt: -------------------------------------------------------------------------------- 1 | ## Angular Responsive App [[{angular.101,01_PM.WiP]] 2 | 3 | * Observables and event processing REF: 4 | 5 | 6 | * similar (but not identical) to the publish/subscribe design pattern. 7 | * In the observer pattern:
8 | * "subject" object maintains a list o its dependents (observers) 9 | * "subject" automatically notifies dependent observers of state changes. 10 | 11 | ``` 12 | | Component01 ·> +Observable: Observable is a function that 13 | | function executes only when a consumer subscribes 14 | | 15 | | Component02 ·> Component02 : create Component02.Observer01 16 | | Component02 ·> Obs.funct : subscribe (Component02.Observer01) 17 | | └───┬───┘ 18 | | ┌─────────────────┬─┘ 19 | | Observable function execution "loop": 20 | | Observable ·> Observer01: event (keystroke, HTTP response, 21 | | function timer, ...) 22 | ``` 23 | * Setup and teardown logic is handled by the observable function . 24 | application code in Component02 only needs to worry about 25 | subscribing to consume values, and when done, unsubscribing 26 | It doesn't change whether the code was sync or async. 27 | 28 | * Unicast example: 29 | ``` 30 | | const observable01 = 31 | | new Observable( 32 | | /* 33 | | * This code creates a new independent execution for each 34 | | * subscribed observer creating a relation 35 | | * Execution 1 ←→ 1 Subscriber 36 | | * (vs) Execution 1 ←→ N Subscriber ("Multicast") 37 | | */ 38 | | (observer) { ← function to execute at ".subscribe(...) 39 | | const {nextCallback, errorCallback} = observer; 40 | | let watchId = navigator.geolocation 41 | | .watchPosition(nextCallback, errorCallback); 42 | | return { 43 | | unsubscribe() { // ← ☞ Freing resources is 44 | | navigator.geolocation. responsability of Observable 45 | | clearWatch(watchId); 46 | | } 47 | | }; 48 | | } ); 49 | | 50 | | const subscription01 = O observable01 .subscribe( 51 | | { 52 | | next(position) { console.log(position); }, 53 | | error(msg) { console.log('Error: ', msg); }, 54 | | }); 55 | | ... 56 | | setTimeout(() => { observable01.unsubscribe(); }, 10000); 57 | ``` 58 | 59 | * Multicast example:
60 | **TIP**: multicasting tools simplify next code by allowing 61 | to convert any existing observable to "multicast". 62 | 63 | ``` 64 | | // Emit one value/second until end-of-array. 65 | |┌·→ function executor(observer, arr, idx) { ←┐ 66 | || return setTimeout(() => { | 67 | || observer.next(arr[idx]); | 68 | || if (idx === arr.length - 1) { | 69 | || observer.complete(); | 70 | || } else { | 71 | || executor(observer, arr, ++idx); ···┘ 72 | || } 73 | || }, 1000); 74 | || } 75 | || 76 | || /* 77 | || * multicastSequenceSubscriber wraps the executor 78 | || * keeping state of subcribers. 79 | || */ 80 | || function multicastSequenceSubscriber() { 81 | || const seq = [1, 2, 3]; 82 | || const observers = []; // ← Keep track o subscribers 83 | || // Still a single timeoutId because there will only ever be one 84 | || // set of values being generated, multicasted to each subscriber 85 | || let timeoutId; 86 | || 87 | || // Return the subscriber function (runs when subscribe() 88 | || // function is invoked) 89 | || return (observer) => { 90 | || observers .push(observer); 91 | || if ( observers .length === 1) { 92 | || // ^^^^^^^^^^^^^^^^^^^^^^ 93 | || // start executor at 1st subcription only 94 | |└·· timeoutId = executor({ 95 | | next(val) { 96 | | observers .forEach(obs => obs.next(val)); 97 | | }, 98 | | complete() { 99 | | observers .forEach(obs => obs.complete()); 100 | | } 101 | | }, seq, 0); 102 | | } 103 | | 104 | | return { 105 | | unsubscribe() { 106 | | observers.splice(observers.indexOf(observer), 1); 107 | | if (observers.length === 0) { 108 | | clearTimeout(timeoutId); 109 | | } 110 | | } 111 | | }; 112 | | }; 113 | | } 114 | | 115 | | const mcastObservble01 = new Observable(multicastSequenceSubscriber()); 116 | | 117 | | setTimeout(() => { 118 | | multicastSequence .subscribe ({ 119 | | next (num) { console.log('1st subscribe: ' + num); }, 120 | | complete() { console.log('1st sequence finished.'); } 121 | | }); 122 | | }, 0 /*← Subscribe "now"*/ ); 123 | | 124 | | setTimeout(() => { 125 | | multicastSequence .subscribe ({ 126 | | next (num) { console.log('2nd subscribe: ' + num); }, 127 | | complete() { console.log('2nd sequence finished.'); } 128 | | }); 129 | | }, 1500 /*← Subscribe after 1st event */ ); 130 | | 131 | | Console will show: 132 | | (second 1) → 1st subscribe: 1 133 | | (second 2) → 1st subscribe: 2 134 | | " → 2nd subscribe: 2 135 | | (second 3) → 1st subscribe: 3 136 | | " → 1st sequence finished 137 | | " → 2nd subscribe: 3 138 | | " → 2nd sequence finished 139 | ``` 140 | 141 | * EX USING REACTIVE RX.JS: 142 | 143 | ``` 144 | | ┌─ Observable Service (EVENT EMITTER) ──── ┌─ Observer Component (EVENT CONSUMER) ───── 145 | | │ import {Subject} from 'rxjs'; │ import { Component } from '@angular/core'; 146 | | │ // npm i -s rxjs@v6.5.3 │ import { ServiceX} from ... 147 | | │ │ 148 | | │ @Injectable() │ @Component({ 149 | | │ export class ServiceX { │ selector: ... 150 | | │ ... │ templateUrl: ... 151 | | │ public infoObservable = │ providers: ... 152 | | │ new Subject(); │ styleUrls: ... 153 | | │ │ }) 154 | | │ private async refreshInfo() { │ export class Comp01 implements OnInit { 155 | | │ ... │ 156 | | │ const info = await getRemoteInfo() │ constructor( 157 | | │ this.infoObservable .next(info); │ private myService : ServiceX ) { 158 | | │ } │ ... 159 | | │ } │ } 160 | | └───────────────────────────────────────── │ 161 | | │ ngOnInit() { 162 | | │ this.myService. 163 | | │ .infoObservable.subscribe( 164 | | │ ( info ) => { /* "consume info */ } 165 | | │ ) 166 | | │ } 167 | | └─────────────────────────────────────────── 168 | ``` 169 | [[}]] 170 | 171 | ## PrimeNG Library [[{angular.PrimeNG]] 172 | * 173 | * See also other "top" Frameworks: 174 | 175 | 176 | * PRE-SETUP 177 | ``` 178 | | $ npm install primeng --save 179 | | $ npm install primeicons --save 180 | | $ npm install @angular/animations --save (opt) 181 | | ^ 182 | | Or manually add dependencies to package.json add like : 183 | | ... 184 | | "dependencies": { 185 | | ... 186 | |+ "primeng": "^10.0.0", 187 | |+ "primeicons": "^4.0.0" 188 | | ... 189 | | } 190 | ``` 191 | * 95% of code is native with no 3rd party dependencies 192 | * UI component library configured as ng-modules. e.g: 193 | import {AccordionModule} from 'primeng/accordion'; //accordion and accordion tab 194 | import {MenuItem} from 'primeng/api'; //api 195 | * Lot of free themes out-of-the-box. 196 | * Ex. config. for required styles: 197 | ``` 198 | | "styles": [ 199 | | "node_modules/primeng/resources/themes/saga-blue/theme.css", 200 | | "node_modules/primeng/resources/primeng.min.css", 201 | | "node_modules/primeicons/primeicons.css", 202 | | ... 203 | | ], 204 | | ... 205 | ``` 206 | * See also: PrimeNG Video Tutorial: 207 | 208 | [[}]] 209 | 210 | 211 | [[{angular.101,mobile.pwa,arch.async,data_mng.cache,02_doc_has.comparative,performance.cache,01_PM.TODO.NOW]] 212 | ## Service Workers #[angular_service_worker] 213 | * 214 | * See general introduction to Service workers at #[service_workers_summary] 215 | * The Angular service worker's (v5.0+) design goal: 216 | * Caching app as one unit. The running app will use the 217 | same version of all files (vs randomnly receiving cached 218 | files from a newer incompatible version). [[{angular.Devops}]]] 219 | * Refreshing will show latest fully cached version. 220 | with updates executing in background. [[{angular.Devops}]]] 221 | * NG service will load the PWA manifest file from the server 222 | describing the resource to cache. When an update to the 223 | PWA is deployed, manifest data changes triggering the 224 | background update. 225 | * TheB manifest is generated from "ngsw-config.json". [[{angular.Devops}]]] 226 | 227 | ## NG Service how-to: 228 | * Include NgModule ???? [TODO]. 229 | * Registering NG Service Worker with the browser: 230 | * WARN: PWApp must be accessed over HTTPS, not HTTP. 231 | Otherwise, registration will fail to avoid 232 | tampering. (security meassure since Service Workers 233 | are "quite powerful").
234 | Exception: localhost is allowed for developers. 235 | * See Service Worker config at: 236 | [TODO] 237 | * See Service Worker production ready at: [[{angular.DevOps}]] 238 | 239 | [[}]] 240 | 241 | [[{angular.forms,mobile.pwa,20_qa.error_control,01_PM.low_code,01_PM.BACKLOG]] 242 | ## Interactive Angular Forms 243 | 244 | * 245 | * Support complex data entry scenarios with HTML-based validation and dirty checking. 246 | * template-driven interactive form how-to 247 | * Requested features: 248 | * from with control elements bound to data properties 249 | * input data integrity validation with two-way data binding. 250 | 251 | 252 | ### design approaches. 253 | * Alt 1: write templates using: 254 | ``` 255 | | NG template syntax 256 | | + form-specific directives 257 | | + "best-pattern". 258 | ``` 259 | Suitable for small or simple forms. 260 | 261 | * Alt 2: Use reactive(==model-driven) approach 262 | 1. lay out the controls creatively, binding to the data in your object model. 263 | 1. Set input validation rules and output display validation errors. 264 | 1. conditionally enable controls. 265 | 1. trigger built-in visual feedback, 266 | 1. ... 267 | 268 | #### Alt 1: template-driven form:; 269 | * Next directives defined in FormsModule are used:. 270 | * NgModel : reconcilites 271 | ``` 272 | "form element" <··> data model value changes 273 | ``` 274 | * used also to respond to user input (input validation, error handling). 275 | * NgForm : 276 | * creates top-level FormGroup instance bined to
DOM. 277 | * track aggregated form value and validation status. 278 | * active by default on all tags at "FormsModule" import 279 | (it has a selector matching the element). 280 | * NgModelGroup : create+bind FormGroup instance ←→ DOM element. 281 | * STEPS: 282 | 1. Define a sample data model. 283 | 1. Include FormsModule,... "stuff". 284 | 1. Bind form-controls ←→ data properties with ngModel 285 | * Examine how ngModel reports control states using CSS classes. 286 | * Name controls to make them accessible to ngModel. 287 | 1. Track input validity/control status with ngModel 288 | * Add custom CSS to provide visual feedback on the status. 289 | * Show and hide validation-error messages. 290 | 1. Respond to a native HTML button-click event by adding to the model data. 291 | 1. Handle form submission using form ngSubmit output property. 292 | * Disable the Submit button until the form is valid. 293 | * After submit, swap out the finished form for different content on the page. 294 | * Ex: two required fields (css:left border when OK, red otherwise) with 295 | initial default values. 296 | ``` 297 | | file: src/app/hero.ts: (Model) 298 | | 299 | | export class Hero { 300 | | constructor( 301 | | public id: number, 302 | | public name: string, 303 | | public power: string, 304 | | public alterEgo?: string 305 | | ) { } 306 | | } 307 | ``` 308 | 309 | ``` 310 | | file: src/app/hero-form/hero-form.component.ts: (v1) (layout, details) 311 | | 312 | | import { Component } from '@angular/core'; 313 | | import { Hero } from '../hero'; 314 | | 315 | | @Component({ 316 | | selector: 'app-hero-form', ·············· ← drop form in parent template using 317 | | templateUrl: './hero-form.component.html', 318 | | styleUrls: ['./hero-form.component.css'] 319 | | }) 320 | | export class HeroFormComponent { 321 | | 322 | | powers = ['Really Smart', 'Super Flexible', 323 | | 'Super Hot', 'Weather Changer']; 324 | | 325 | | model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet'); 326 | | 327 | | submitted = false; 328 | | 329 | | onSubmit() { this.submitted = true; } 330 | | 331 | | // TODO: Remove this when we're done 332 | | get diagnostic() { return JSON.stringify(this.model); } 333 | | } 334 | ``` 335 | 336 | ``` 337 | | file: src/app/app.module.ts: 338 | | import { NgModule } from '@angular/core'; 339 | | import { BrowserModule } from '@angular/platform-browser'; 340 | | import { FormsModule } from '@angular/forms'; ← enable Forms feature 341 | | 342 | | import { AppComponent } from './app.component'; 343 | | import { HeroFormComponent } from './hero-form/hero-form.component'; 344 | | 345 | | @NgModule({ 346 | | imports : [ BrowserModule, FormsModule ], 347 | | declarations: [ AppComponent, HeroFormComponent ], 348 | | providers : [], 349 | | bootstrap : [ AppComponent ] 350 | | }) 351 | | export class AppModule { } 352 | ``` 353 | 354 | ``` 355 | | file: src/app/app.component.html: 356 | | ← display at root component's template. 357 | ``` 358 | 359 | ``` 360 | | file: src/styles.css: 361 | | (Twitter Bootstrap style classes: container/form-group/form-control/btn) 362 | | @import url('https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css'); 363 | ``` 364 | 365 | ``` 366 | | file: src/app/hero-form/hero-form.component.html 367 | | 368 | | 369 | |
370 | |
← main form visible by default since submitted init to false 371 | | 372 | | 373 | | └───┬────────────┘ 374 | | └──── Access overall form status 375 | | #heroForm : tpl ref.var is now a ref. to 376 | | NgForm directive inst.governing form 377 | | as a whole. 378 | |
379 | | 380 | | to match 383 | | required 384 | | [(ngModel)]="model.name" 385 | | └──────────┬───────────┘ 386 | | └──────────── two-way data binding. model.name server to display and debug that 387 | | model is really being updated when user changes input. 388 | | NG sets special CSS classes on (NgModel) control elements to 389 | | reflect the state. 390 | | ┌─────────────────────────────────┬────────────┬─────────────┐ 391 | | │State │ Class │ Class │ 392 | | │ │ if true │ if false │ 393 | | ├─────────────────────────────────┼────────────┼─────────────┤ 394 | | │The control has been visited. │ ng─touched │ ng─untouched│ 395 | | ├─────────────────────────────────┼────────────┼─────────────┤ 396 | | │The control's value has changed │ ng─dirty │ ng─pristine │ 397 | | ├─────────────────────────────────┼────────────┼─────────────┤ 398 | | │The control's value is valid. │ ng─valid │ ng─invalid │ 399 | | └─────────────────────────────────┴────────────┴─────────────┘ 400 | | 401 | | name="name" 402 | | └───┬─────┘ 403 | | └──────────── [(ngModel)] on an element requires also the name attribute for that element, used by NG 404 | | to register such element with the NgForm directive attached to parent form element. 405 | | 406 | | #name="ngModel"> 407 | | └───┬─────┘ 408 | | └──────────── tpl reference variable that you can use to access the input 409 | | box's Angular control from within the template. 410 | | It is set to "ngModel" because that is the value of the NgModel.exportAs property. 411 | | This property tells Angular how to link a reference variable to a directive. 412 | | 413 | | ┌─────────── Show or hide the error message by binding properties 414 | | │ of the name control to the message
element's hidden property 415 | | ┌──────┴─────────────────────────────┐ 416 | |
Name is required
417 | |
└──┬───┘ 418 | | └── pristine == user hasn't changed the value since it was displayed. 419 | | 420 | |
421 | | 422 | | 424 | |
425 | | 426 | |
427 | | 428 | | 434 | |
435 | | Power is required 436 | |
437 | |
438 | | 439 | | 440 | | └─ automatically hiddes if ─────┘ 441 | | form is invalid 442 | | 443 | | 444 | | with reset 445 | | 446 | |    447 | | 448 | | without reset 449 | | 450 | | 451 | |
452 | |
453 | | Name via form.controls = {{showFormControls(heroForm)}} 454 | |
455 | | 456 | | 457 | |
458 | | 459 | |
460 | |
Name
{{ model.name }}
461 | |
Alter Ego
{{ model.alterEgo }}
462 | |
Power
{{ model.power }}
463 | | 464 | |
465 | |
466 | ``` 467 | * customizing CSS : 468 | ``` 469 | | file: src/assets/forms.css: 470 | | .ng-valid[required], .ng-valid.required { 471 | | border-left: 5px solid #42A948; /* green */ 472 | | } 473 | | 474 | | .ng-invalid:not(form) { 475 | | border-left: 5px solid #a94442; /* red */ 476 | | } 477 | ``` 478 | 479 | ``` 480 | | file: src/index.html (styles) 481 | | 482 | | ... 483 | | 484 | ``` 485 | but it does trigger a form-submit event because of its type (type="submit"). 486 | [[angular.forms}]] 487 | -------------------------------------------------------------------------------- /angular04_recipes.txt: -------------------------------------------------------------------------------- 1 | # Angular Recipes 2 | 3 | * Init service on page load: 4 | 5 | ``` 6 | | let window: any; 7 | | @Injectable() 8 | | export class MyService01 { 9 | | constructor() { 10 | | window.addEventListener('load' , function (event) { ... }); 11 | | } 12 | | } 13 | | 14 | | RX Observables: (TODO:Explain) 15 | | import {Subject} from 'rxjs'; 16 | | @Injectable() 17 | | export class MyService01 { 18 | | public accountsObservable = new Subject 5 | * Angular provides just-in-time (JIT) compilation for the 6 | development environment, and ahead-of-time (AOT) compilation 7 | for the production environment. 8 | 9 | ## Testing platform 10 | * 11 | Run unit tests on your application parts as they interact with the Angular framework. 12 | 13 | ## Internationalization: 14 | * 15 | 16 | ## Security guidelines 17 | * 18 | Learn about Angular's built-in protections against common 19 | web-app vulnerabilities and attacks such as cross-site scripting attacks. 20 | 21 | 22 | ## Reactive Angular Library NgRx v10 23 | * Adds Component Local State Management Package 24 | 25 | 26 | ## ng-select native angular Select: 27 | * Gallery: 28 | * Github: 29 | 30 | ## ng-zorro: component lib (8.5K likes) 31 | * 32 | * Gallery: 33 | 34 | ## Angular Best Patterns [[{qa.best_patterns]] 35 | 36 | * 37 | * Don’t use nested subscriptions:
38 | There may be situations where you need to consume data from 39 | multiple observable streams. In those cases, you should generally try 40 | to avoid socalled nested subscriptions. Nested subscriptions becomes 41 | hard to understand and may introduce unexpected side effects. We 42 | should instead use chainable methods like switchMap, forkJoin and 43 | combineLatest to condense our code.This will help us avoid writing 44 | code like this: 45 | ``` 46 | | this.returnsObservable1(...) 47 | | .subscribe( 48 | | success => { 49 | | this.returnsObservable2(...) 50 | | .subscribe( 51 | | success => { 52 | | this.returnsObservable3(...) 53 | | .subscribe( 54 | | success => { ... } 55 | | }) 56 | | ) 57 | | }, 58 | ``` 59 | And hopefully more like this: 60 | ``` 61 | | this.returnsObservable1(...) 62 | | .pipe( 63 | | flatMap(success => this.returnObservable2(...), 64 | | flatMap(success => this.returnObservable3(...) 65 | | ) 66 | | .subscribe(success => {...});+Quick tip! 67 | ``` 68 | * There may be confusion around when to use the appropriate operators 69 | when dealing with multiple streams. I recommend checking out this 70 | article for some clarity on this topic. 71 | [[}]] 72 | 73 | ## DevTools Released with Component Explorer and Profiler [[{]] 74 | * 75 | [[}]] 76 | -------------------------------------------------------------------------------- /angular_plus_keycloak_example_integration.txt: -------------------------------------------------------------------------------- 1 | [[{stack.angular,security.aaa,use_case.identity.openid,standards.identity]] 2 | 3 | ## Angular/Keycloak Integration 4 | * 5 | 6 | * Core principle behind OpenID-Connect: 7 | Delegation complex authentication/authorization of remote users (and hackers 8 | trying to impersonate as users) to some central authentication and authorization 9 | server. 10 | * Complex in practice means seting up multifactor authentication, onboarding 11 | of users, onboaring of trusted apps, mapping of users to roles (that can be 12 | different in different apps). 13 | 14 | ``` 15 | ┌─────┐ ┌───────┐ ┌────────┐ 16 | │Alice│ │NG-App │ │Keycloak│ 17 | └──┬──┘ └───┬───┘ └───┬────┘ 18 | │ Can I see │ │ 19 | │ this page? │ Can Alice see │ 20 | │────────────────>│ that page? │ 21 | │ │─────────────────>│ 22 | │ Please, enter (login) credentials? │ 23 | │<───────────────────────────────────│ 24 | │ crendentials (password, token, ...)│ 25 | │───────────────────────────────────>│ 26 | │ │ OK, Alice │ 27 | │ │ can see it │ 28 | │ page content │<─────────────────│ 29 | │<────────────────│ │ 30 | ┌──┴──┐ ┌───┴───┐ ┌───┴────┐ 31 | │Alice│ │NG-App │ │Keycloak│ 32 | └─────┘ └───────┘ └────────┘ 33 | ``` 34 | 35 | ### PRESETUP 36 | 1. ``` 37 | | → Keycloak 38 | | → Client Config 39 | | → Add Client : 40 | | Client ID : angular-test-app 41 | | Client protocol: openid-connect 42 | | Root URL : https://myapp.mydomain.com ← or dev URL 43 | | (http://localhost:4200) 44 | ``` 45 | 2. Create new angular app if needed: 46 | ``` 47 | | $ ng new angular-keycloak 48 | ``` 49 | 3. Adding official keycloak js adapter 50 | ``` 51 | | $ npm i keycloak-js --save 52 | ``` 53 | 54 | ### Use: 55 | 1. Modify Angular app and next code to main.ts 56 | ``` 57 | | let initOptions = { //keycloak init options 58 | | url : 'https://0.0.0.0:8445/auth', 59 | | realm : 'keycloak-demo', 60 | | clientId: 'angular-test-app' 61 | | } 62 | | let keycloak = Keycloak(initOptions); 63 | | 64 | | keycloak 65 | | .init({ onLoad: "login-required" }) //← page load will redirect to 66 | | .success((auth) => { // keycloak Auth. page 67 | | if (!auth) { 68 | | window.location.reload(); 69 | | return 70 | | } 71 | | console.log("successful authentication. Bootstrapping now"); 72 | | 73 | | platformBrowserDynamic() 74 | | .bootstrapModule(AppModule) // ← boostrap module 75 | | .catch(err => console.error(err)); 76 | | 77 | | localStorage.setItem 78 | | ( "ang-token" , keycloak .token); // Access token 79 | | localStorage.setItem 80 | | ( "ang-refresh-token", keycloak .refreshToken) // Refresh token 81 | | 82 | | setTimeout( refreshToken, 60000 /* 1 min*/ ) // May just each hour/day 83 | | }) 84 | | .error(() => { console.error("Authenticated Failed"); }); 85 | | 86 | | function refreshToken = () => { 87 | | keycloak .updateToken(70) 88 | | .success( (bRefreshed) => { 89 | | if (bRefreshed) { /* OK */ return ; } 90 | | console.warn('Token not refreshed, valid for ' 91 | | + Math.round( 92 | | keycloak .tokenParsed.exp 93 | | + keycloak .timeSkew 94 | | - new Date().getTime() / 1000) + ' seconds'); 95 | | }) 96 | | .error(() => { console.error('Failed token refresh'); }); 97 | | } 98 | ``` 99 | 100 | [[}]] 101 | 102 | -------------------------------------------------------------------------------- /angular_whats_new.txt: -------------------------------------------------------------------------------- 1 | ## Angular What's new 2 | 3 | ### Angular 13 4 | * 5 | 6 | ### Angular v12 7 | * Transitions to Ivy Rendering Engine 8 | * 9 | * ...The Protractor end-to-end test framework will no longer be 10 | included in new projects. The team reports working with alternative 11 | popular solutions (e.g., Cypress, WebdriverIO, TestCafe)... 12 | 13 | ### Angular 11 14 | * 15 | * 16 | * Hot Module Replacement implementation: 17 | ``` 18 | $ ng serve --hmr ← It can be initialized with --hmr flag. 19 | NG app will not need full page refresh on code changes: 20 | Instead, latest changes to code/style/templates will be 21 | updated directly while preserving the current state of 22 | the application. 23 | ``` 24 | 25 | * Build process speed boost by upgrading to TypeScript 4.0 26 | and through improving the ngcc update process. 27 | 28 | * developers can now opt-in to the experimental Webpack 5 support 29 | (faster builds with persistent disk caching and smaller bundle sizes 30 | using improved tree-shaking). To enable it: 31 | "resolutions": { "webpack": "5.4.0" } ← Add to package.json 32 | 33 | * NG language service (popular add-on offers autocomplete, type checking, etc...) 34 | is being transitioned to the new Ivy engine, offering improved support for 35 | generic types. 36 | 37 | * For simple upgrade of projects: 38 | ``` 39 | $ ng update @angular/cli @angular/core 40 | ``` 41 | WARN : for more complex updates, use the interactive update guide 42 | provided by the Angular team. 43 | 44 | ## Angular 9 45 | * 46 | * Ivy Compiler: 47 | Smaller bundle sizes, improved build times, and better debugging 48 | thanks to the release of the much anticipated Ivy rendering engine 49 | that has been in development by Google since 2018. 50 | Ivy uses tree shaking, allowing it to include only the parts of 51 | Angular needed for the current application. 52 | 53 | ## Angular 5 54 | Service worker implementation shipping by default. 55 | [[}]] 56 | 57 | -------------------------------------------------------------------------------- /cookies_state_management.txt: -------------------------------------------------------------------------------- 1 | [[{data_mng.session,arch.async,]] 2 | 3 | # HTTP State Management Mechanism ("Cookies") 4 | * 5 | * (Obsoletes: 2965) 6 | * KEY-POINT: Do not store information in cookies, but only a "session identifier". [[{SECURITY.101}]] 7 | 8 | * ``` 9 | |Server as S 10 | |UserAgent as C (client) 11 | | 12 | |C -> S: HTTP GET/POST/... request 13 | |S -> C: HTTP Response, with Set-Cookie's headers 14 | | Set-Cookie: SID=31d4d96e407aad42; 15 | | └──────────┬───────┘ 16 | | Cookie (name,value) pairs 17 | | (returned back by the user agent) 18 | | ┌────┴────┐ 19 | | Set-Cookie: lang=en-US; Path=/; scope=... ; 20 | | Set-Cookie: ... └───────┬───────┘ 21 | | ... · Cookie attributes 22 | | · (not returned back by user-agent) 23 | | ┌───────────┴───────────────────┘ 24 | | Cookie attributes include: 25 | | Domain=example.com; <·· (Sub)domain list to send cookies back 26 | | Secure; <·· Limit to secure channels (as seen by 27 | | the user-agent) 28 | | HttpOnly <·· Limit to HTTP request 29 | | scope=..., 30 | | Expires=Wed, 09 Jun 2021 10:18:14 GMT 31 | | └──┬──┘ 32 | | if not set cookie expires after 33 | | user-agent("browser") restart. 34 | | It is also used with a date in the past to reset the cookie. 35 | | Max-Age=... (Similar to expire, it represent a timeout in secs) 36 | | 37 | | expected servers to return the cookie to, URI schemes 38 | | where it is applicable) 39 | | allow to pass (name,value) to a user agent. 40 | |C -> C: Stores/updates the cookie (with its attributes) 41 | | l The user agent stores the following fields about each cookie: 42 | | (name,value), expiry-time, domain, path, creation-time, 43 | | last-access-time, persistent-flag, host-only-flag, 44 | | secure-only-flag, and http-only-flag. 45 | | General-use user agents SHOULD provide: 46 | | - 4096+bytes per cookie (sum of name+value+attributes). 47 | | - At least 50 cookies per domain. 48 | | - At least 3000 cookies total. 49 | |C -> C: Ignore cookies? 50 | |alt no: 51 | |C -> S: Cookie: SID=31d4d96e407aad42; lang=en-US 52 | | └──────────┬───────┘ └───┬────┘ 53 | | Cookie (name,value) pairs 54 | | Authorization: Bearer ... 55 | | └─────┬─────┘ 56 | | HTTP Header 57 | |alt yes: do nothing 58 | ``` 59 | [[data_mng.session}]] 60 | -------------------------------------------------------------------------------- /data_visualization.txt: -------------------------------------------------------------------------------- 1 | # Data Visualization 2 | [[{data_mng.visualization.real_time,]] 3 | # SVG Summary #[svg_summary] 4 | ← Make y coordinate work bottom-to-top. 13 | 14 | ┌ 17 | │ 18 | │ 20 | │ (avoid pointy triangle) 31 | │ 32 | │ ← Polygon (triagle in this case) 33 | │ ← create dashed lines for strokes 35 | │ 4,6: "4-pixel-dash then 6-pixel-space" 36 | │ ← multipoint x1/y1 x2/y2 x3/y3 ... line. 37 | │ ← multiple anchors with handles. 38 | └ Generally written by a program (vs by hand) 39 | 40 | 45 | dx="5" dy="-3"> 46 | ... some text ... 47 | 48 | 49 | 50 | ← Add hyperlink 51 | Dinosaurs! 52 | 53 | 54 | 55 | ← defining Reusable symbol 56 | 57 | 58 | ← Using it later on. 59 | 60 | ┌ ← section to create shapes that won't be 61 | │ visible until used in other places like 62 | │ gradients, paths for text, masks, etc. 63 | │ 64 | │ ← GRADIENTS 65 | │ 66 | │ 67 | │ 68 | │ MASKING 69 | │ (black:transparent, white: show) 71 | │ 72 | │ 73 | │ 76 | │ 77 | │ 78 | │ FILTER 79 | │ 82 | │ 83 | └ 84 | 85 | {"rule"}) ← operator acting on selection and 177 | .attr("x2",160) wrapping W3C DOM API, 178 | .attr("y1", y) := .attr(...) | .style(...) | .property(...) 179 | .attr("y2", y) .html(...) | .text(...) | 180 | .each(...) (general extension point operator) 181 | and expressed either as constants or functions. 182 | 183 | g.append("svg:text") ← (g) Add reference labels. 184 | .attr("x",164) 185 | .attr("y",y) 186 | .attr("dy", ".3em") 187 | .text(d3.format(",.1")) 188 | 189 | * ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐ NOTE: Data is sticky: Once bound 190 | e e e e e e │u││u││u││u││u││ ││ ││ ││ ││ │ to nodes, it is available 191 | └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘ in next re-selection with 192 | └───────┬──────┘ └──────┬──────┘└──────┬──────┘ no need for .data(...) operator 193 | entering data updated data exit nodes with 194 | data with no bounded to no matching data 195 | matching nodes. matching nodes allowed to be 196 | insert will bind removed. 197 | new nodes to the 198 | data. 199 | 200 | 201 | * used as "kernel" library for other high level ones 202 | e.g.: <#vega_lite_summary> 203 | 204 | * Extracted from 205 | • D3 stands for "Data Driven Documents". 206 | • D3 allows to bind arbitrary data to a Document Object Model (DOM), 207 | and then apply data-driven transformations to the document. 208 | e.g: 209 | INPUT BIND TO 210 | ======== ======= 211 | number[] --→ D3.js ─┬→ Interactive SVG chart 212 | ├→ HTML table 213 | ├·····→ 214 | 215 | • Step learning path : 30+ modules , 1000s of methods. 216 | [[}]] 217 | 218 | [[{data_mng.visualization.real_time,data_mng.visualization,01_PM.TODO]] 219 | # https://mafs.dev/ 220 | Math components for React apps. 221 | 222 | # Vega Lite!!! @ma #[vega_lite_summary] 223 | 224 | 225 | * HIGH-LEVEL GRAMMAR OF INTERACTIVE GRAPHICS with declarative JSON syntax. 226 | by University of Washington Interactive Data Lab 227 | * visualizations for data analysis and presentation. 228 | * Used by: 229 | Tableau , Google, Microsoft, Airbnb, Los Angeles Times, CERN, 230 | Carnegie Mellon University, Berkeley University, ... 231 | * Extracted from: https://vega.github.io/vega/about/vega-and-d3/ 232 | ... D3 is intentionally a lower-level library (than Vega) ... 233 | a "visualization kernel" rather than a "toolkit" or "framework" 234 | ... intended as a supporting layer for higher-level visualization 235 | tools. Vega is one such tool, and Vega uses D3 heavily within its 236 | implementation: vega lite → vega → d3.js 237 | 238 | * HOWTO: STEP 1) HTML SETUP 239 | 240 | ┌──────────────────────────────────────────────────────────────────────────┐ 241 | │ │ 242 | │ │ 243 | │ │ 244 | │ ... │ 245 | │ │ 246 | │ │ 247 | │ │ 248 | │ │ 249 | │ │ 254 | │ │ 255 | │ │ 256 | │ ... │ 257 | │
│ 258 | │ │ 259 | │ │ 269 | │ │ 270 | │ │ 271 | └──────────────────────────────────────────────────────────────────────────┘ 272 | 273 | * HOWTO: STEP 2) DATA and Visualization SETUP 274 | 275 | TABULAR DATA SET │ EQUIVALENT VEGA-LITE 276 | │ JSON ARRAY + RENDER PROP 277 | ================ │ ======================== 278 | var. a var. b │ { 279 | cate- vs nume- │ "data" : { ← "data" prop defines data source for chart 280 | gorical rical │ "values" : [ Other data sources type supported 281 | C ←→ 2 · · ·│· · · {"a": "C", "b": 2}, ┐ e.g: "data": {"url": ".../data/myData.csv"} 282 | C ←→ 7 · · ·│· · · {"a": "C", "b": 7}, ┤ ← each value (row) will be rendered 283 | C ←→ 4 · · ·│· · · {"a": "C", "b": 4}, ┤ as a1visual mark 284 | D ←→ 1 · · ·│· · · {"a": "D", "b": 1}, ┤ 285 | ... 286 | E ←→ 7 · · ·│· · · {"a": "E", "b": 7} ┘ 287 | │ ] 288 | │ }, 289 | vega-lite ┌ → "mark": "point", ← mark key indicates how to render data 290 | chart │ │ mark properties := position, size, color 291 | visualization ─┤ │ vega-lite will render one point per "data" object 292 | properties │ │ 293 | └ → "encoding": { ← Without encoding output marks will overlap. 294 | │ "x": { ← encode "x-channel" to ("row") data fields. 295 | vega-lite │ "field": "a", ("a" in this case) 296 | chart │ "type" : "nominal" := "quantitative" | "temporal" | "ordinal" | "nominal" * 297 | visualization │ }, 298 | │ "y": { ← "x" alone will already render "a" distribution. 299 | │ "field": "b", "y" to compare "var a" vs "var b" 300 | │ "type" : "quantitative" 301 | │ "title": "b's average" ← optional. 302 | │ "aggregate": "average" ← optional := "aggregate" | "average" 303 | │ } ^ 304 | │ } "mark" : "bar" 305 | │ } 306 | * 307 | TIP: Vega-Lite will auto. add axis-with-labels for different-categories + axis title. 308 | 309 | * EXPLORING DATA EXAMPLES 310 | 311 | 312 | QUANTITATIVE CONTINUOUS SAME QUANTITATIVE VAR DISCRETIZED 313 | VAR DISTRIBUTION ALONG X AXIS AS BAR HISTOGRAM ALONG X/Y AXES 314 | ============================= =============================== 315 | 316 | { { 317 | "data": ... "data": ... 318 | "mark": "tick", "mark": "bar", 319 | "encoding": { "encoding": { 320 | "x": { "x": { 321 | "field": "precipitation", "field": "precipitation" 322 | "type" : "quantitative" "bin" : true, ← bin == discretize cont.var. 323 | } }, (bin quantitative by default) 324 | "y": { 325 | "aggregate": "count" 326 | } 327 | } } 328 | } } 329 | 330 | MEAN PRECIPITATION VS (month) DATE 331 | ================================== 332 | { 333 | "data": ... 334 | "mark": "line", 335 | "encoding": { 336 | "x": { 337 | "field" : "date" 338 | "timeUnit" : "month", ← : yearmonth will compare same month 339 | }, in different years 340 | "y": { 341 | "field" : "precipitation" 342 | "aggregate": "mean", 343 | } 344 | } 345 | } 346 | 347 | WEATHER TYPE OVER MONTH STACKED (aggregate) BAR 348 | ============================================== 349 | { 350 | "data": ... 351 | "mark": "bar" , 352 | "encoding": { 353 | "x": { 354 | "timeUnit" : "month", 355 | "field" : "date", 356 | "type" : "ordinal" 357 | }, 358 | "y": { 359 | "aggregate": "count", ←···· we need to add "color" prop. 360 | "type" : "quantitative" to indicate stack visualization 361 | }, · 362 | "color": { · 363 | "field": "weather", ←······─┘ 364 | "type": "nominal", 365 | "scale": { ← Optional. Customize default category colors 366 | "domain": ["sun", "fog" , "drizzle", "rain", "snow"], 367 | "range": ["#ea2","#c77", "#aec7e8", "#1b4", "#946"] 368 | } 369 | } 370 | } 371 | } 372 | 373 | 374 | * CALCULATED FIELD HOW-TO 375 | ======================= 376 | { 377 | "data": ... 378 | "transform": [ 379 | { 380 | "calculate" : "datum.temp_max - datum.temp_min", 381 | "as" : "temp_range" 382 | } 383 | ], 384 | "mark": ... 385 | "encoding": { 386 | ... 387 | "y": { 388 | "field": "temp_range" 389 | ... 390 | } 391 | } 392 | } 393 | [[}]] 394 | 395 | 396 | [[{data_mng.visualization,data_mng.visualization,]] 397 | # JointJS #[jointjs_summary] 398 | 399 | 400 | * JointJS 401 | 402 | INPUT PROCESSING OUTPUT 403 | ===== ========== ====== 404 | GRAPH MODEL: ···→ attach graph to ···→ rendered view 405 | · N joint.dia.Element's joint.dia.Paper 406 | (or descendants) 407 | · M joint.dia.Link's 408 | ^^^^^^^^^^^^^^^^ 409 | cell := Element or Link 410 | 411 | - Joint.JS "Hello World!: 412 | 413 |