diff --git a/Readme.md b/Readme.md index 2c3b129f6..5128e4fff 100644 --- a/Readme.md +++ b/Readme.md @@ -11,6 +11,7 @@ UD-Viz is a 3-package JavaScript framework for creating web applications for vis [License](./LICENSE.md) — [Getting Started](#getting-started) + **Online demos**: * [Ud-Viz examples](https://ud-viz.vcityliris.data.alpha.grandlyon.com/) @@ -67,7 +68,7 @@ npm install # resolve dependencies based on the package.json (and package-lock.j ### Run an example urban data web application -To quickly build and locally host the examples landing page which links to several [UD-Viz example applications](./packages/browser/examples/). +To quickly build and locally host the examples landing page which links to several [UD-Viz example applications](./examples/). ```bash npm run start diff --git a/bin/remarkValidateLinks.js b/bin/remarkValidateLinks.js index ada4e0a0e..e89083eb3 100644 --- a/bin/remarkValidateLinks.js +++ b/bin/remarkValidateLinks.js @@ -1,6 +1,8 @@ const exec = require('child-process-promise').exec; +const fs = require('fs'); +const { Data } = require('@ud-viz/shared'); -const FAILURE_THRESHOLD = 74; // TODO this threshold should lower help please +const FAILURE_THRESHOLD = 0; // no warning should be found exec('npx remark -u validate-links .').then((result) => { console.log(result.stderr); @@ -15,4 +17,123 @@ exec('npx remark -u validate-links .').then((result) => { throw new Error('Too much warnings report to log above to fix them'); } } + + // DETECT ABSOLUTE PATH in Link + + /** + * directory to not parse + */ + const blackDirectoryList = ['node_modules']; + + /** + * + * @param {string} path - path to check + * @returns {boolean} - true if path is an absolute path + */ + const isAbsolutePath = (path) => { + const noAbsolutePathPrefix = ['https', 'http', '.', '#']; + let result = true; + for (let index = 0; index < noAbsolutePathPrefix.length; index++) { + const prefix = noAbsolutePathPrefix[index]; + if (path.startsWith(prefix)) { + result = false; + break; + } + } + return result; + }; + + /** + * Record log infos to display for absolute path check + */ + class LogInfosAbsolutePath { + constructor(filename) { + this.filename = filename; + this.absoluteLinks = []; + } + + record(link) { + this.absoluteLinks.push(link); + } + + log() { + console.log(this.filename); + console.log(this.absoluteLinks); + } + } + + const logInfos = []; + + const parseDirectory = (directoryPath) => { + const dirents = fs.readdirSync(directoryPath, { withFileTypes: true }); + dirents.forEach((dirent) => { + if (dirent.isFile() && Data.computeFileFormat(dirent.name) == 'md') { + const filePath = directoryPath + '/' + dirent.name; + let logInfo = null; + const contentMd = fs.readFileSync(filePath, { + encoding: 'utf-8', + }); + + const linkRegexResult = contentMd.match(/\[(.*?)\]\(.*?\)/gm); + + if (linkRegexResult) { + linkRegexResult.forEach((link) => { + // could be done with a regex but i didn't find one matching all cases + let lastCharacter = null; + let path = null; + for (let index = link.length - 1; index >= 0; index--) { + const character = link[index]; + if (index == link.length - 1 && character != ')') { + console.log(link); + throw new Error('wrong link format'); + } + + // detect first ]( path is between there and the end of link + if (lastCharacter == '(' && character == ']') { + path = link.slice(index + 2, link.length - 1); + break; + } + + lastCharacter = character; + } + + if (!path) throw new Error('cant find path in link'); + + if (isAbsolutePath(path)) { + if (!logInfo) { + logInfo = new LogInfosAbsolutePath(filePath); + logInfos.push(logInfo); + } + logInfo.record(link); + } + }); + } + + if (!logInfo) console.log(filePath + ': no issues found'); + } else if ( + dirent.isDirectory() && + !blackDirectoryList.includes(dirent.name) + ) { + parseDirectory(directoryPath + '/' + dirent.name); // recursive + } + }); + }; + + console.log('\nCheck Absolute path\n'); + parseDirectory('.'); + + if (logInfos.length) { + console.log('\nFound Absolute path\n'); + + let countAbsolutePath = 0; + logInfos.forEach((logInfo) => { + logInfo.log(); + countAbsolutePath += logInfo.absoluteLinks.length; + }); + throw new Error( + 'There is ' + + countAbsolutePath + + ' absolute path use relative path or URL instead' + ); + } }); diff --git a/docs/static/Devel/ArchitectureMVCTargetDesign.md b/docs/static/Devel/ArchitectureMVCTargetDesign.md index 0624d9b79..3f88accf1 100644 --- a/docs/static/Devel/ArchitectureMVCTargetDesign.md +++ b/docs/static/Devel/ArchitectureMVCTargetDesign.md @@ -73,11 +73,11 @@ We propose a nomenclature to use when working with classes in a module, so that ## Documents module -[[Detailed documentation](../../../packages/browser/src/Component/Widget/Server/Documents/README.md)] +[[Detailed documentation](./UD_Viz_Browser/Documents/README.md)] The documents module follows an MVVM architecture : -![](Pictures/DocumentsArchitecture.png) +![](./Pictures/DocumentsArchitecture.png) The model holds the documents and make requests to the server, the view model filter those documents and the view displays the filtered documents. @@ -104,7 +104,7 @@ The code is separated in two main parts : the view and the service. It ressemble * The service makes the appropriate request to the server, and processes the received data * It then notifies the listeners. The service follows a simple implementation of the [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern) where observers are just callbacks without arguments (called listeners). The view has subscribed to the service when it was created, so it received the notification of the service and can update itself. -![](Pictures/ViewServiceArchitecture.png) +![](./Pictures/ViewServiceArchitecture.png) ### Services diff --git a/docs/static/Devel/Configuring-the-Document-model-of-an-UDV-deployment.md b/docs/static/Devel/Configuring-the-Document-model-of-an-UDV-deployment.md deleted file mode 100644 index 43306e9e7..000000000 --- a/docs/static/Devel/Configuring-the-Document-model-of-an-UDV-deployment.md +++ /dev/null @@ -1,305 +0,0 @@ -# WARNING : Outdated document - -This document describes how the application was originally designed to handle the management of documents in a generic way. Although it is a good idea, we figured that it added too much complexity to the developement process, as more modules came to exist. - -However, hereas this document is outdated, we still think that the method it propose could be useful in the future. That's why we decide to keep it as it is for the moment, even if the described process is not actually implemented. - -# Motivations - -Providing UD-Viz with a customizable/parameterizable Document model came in response to the general need of having to provide an application while several unknown variables of this application are yet unknown or fuzzy. For example: - - the Document model is not fixed and even when some version is approved at some point, it is likely to evolve with upcoming needs - - the final end users (e.g. a scientific community) as well as their associated requirements are not yet defined - -Having at hand such a "generic/super" application, that can be customized to answer specific and evolving requirements coming from distinct user communities, allows to share/re-use a whole set of code. - -On the UD-Viz (frontend) side, the customization of an UD-Viz front end is done through the edition of a configuration file that is to be realized by the [Deployment Responsible Person](https://github.com/MEPP-team/RICT/blob/master/Doc/Devel/Needs/Roles.md#deployment-responsible-person). It provides a lightweight and convenient configuration of an UD-Viz frontend once the end user provides some version of what he/she needs. Such a configuration can thus be seen as a late statge of the development process. - - -# Configuring UD-Viz -Some modules/extensions of UD-Viz (e.g. [ConsultDoc](https://github.com/MEPP-team/UD-Viz/tree/master/UD-Viz-Core/src/Modules/ConsultDoc), [GuidedTour](https://github.com/MEPP-team/UD-Viz/tree/master/UD-Viz-Core/src/Modules/GuidedTour) or [Contribute](https://github.com/MEPP-team/UD-Viz/tree/master/UD-Viz-Core/src/Extensions/Contribute). -Depending on the UD-Viz deployment that is realized, the Document Data Structure (DDS) can be customized in order to answer the specific needs of the realized deployment. -The following documentation explains how to realize such a Document Data Structure (DDS) customization, and in particular how to - - customize the UD-Viz (frontend) with a given specific DDS - - customize the following views of UD-Viz that consume the DDS: - - Document browser view (of ConsultDoc module) - - Document research view (of ConsultDoc module) - - Document creation view (of Contribute extension) - - Document update (view of Contribute extension) - - GuidedTour view - - define the external data server (backend) that the considered UD-Viz deployment shall use - - customize the [backend deployment](https://github.com/MEPP-team/UD-Viz-server/tree/master/API_Extended_Document) to match the chosen DDS. - -This DDS customization thus concerns the whole UD-Viz system i.e. an UD-Viz front end and the associated backend. - - -### Frontend configuration file general structure -The [configuration file](../src/Modules/ConsultDoc/examples/consultDocConfig.json) holds two main attributes : server and properties. -* "server" holds the server-related information -* "properties" holds the document related information - -```` -{ - "type": "class", - "server":{ - }, - "properties": { - } -} -```` - -## I. Configure dependencies towards an external data server - -We need to configure the field 'server' by giving the routes to the controller. - - -## II. Configuring the document model and the views: document browser, document creation, document update and document research - -For this configuration, the field "properties" of the configuration file is used. -"Properties" holds the document attributes (e.g title, subject, referring date, date of publication...). -It defines : - - the document model = document's attributes - - actions / functionalities on document attributes (e.g if this attribute is optional, if this attribute can be updated...) - -There can be as many attributes as needed. They will be used to create* another json file holding the document model. The frame of this file looks as follows: - -```` -{ - "Document": { - "type": "class", - "properties": { - } - } -} -```` -In order to respect the [static document model](https://github.com/JorisMillot/APIExtendedDocument/wiki/Documentation-API), properties have to be set in two different categories: metadata and visualization. - -```` -{ - "type": "class", - "server":{ - }, - "properties": { - "metadata":{ - }, - "visualization":{ - } - } -} -```` - -An example of the file can be found [here](../src/Modules/ConsultDoc/examples/consultDocConfig.json) - -Each document attribute has properties that impact the different views of the system (Browser, Creation, Update, Research...). They have to be parametrized. - -###### How to parametrize the attributes' properties: - -| Property | Type | Authorized values | Required | Concerned view | Description | -|---------------|--------|------------------------------------------|-----------------------------|----------------|-----------------------------------------------------------------------------------| -| name | string | document's attribute (title, refDate...) | yes | all | | -| type | string | string date enum | yes | all | | -| optional | bool | true, false | yes | all | | -| creationID | string | create_[name] | yes if 'optional'=true | Creation | | -| labelCreation | string | everything | yes if 'optional'=true | Creation | gives information about the field to the user | -| displayable | bool | true, false | yes | Browser | | -| displayID | string | must be the same as 'name' | yes if 'displayable' = true | Browser | | -| label | string | false or everything | yes | Browser | If false, no label will be display. Otherwise, the chosen label will be displayed | -| updatable | bool | true false | yes | Update | | -| updateID | string | update_[name] | yes | Update | | -| labelUpdate | string | false or everything | no | Update | | -| queryable | bool | false, true, keyword | yes | Research | | -| queryID | string | query_[name] | yes if 'queryable'=true | Research | | -| labelQuery | string | false or everything | yes if 'queryable'=true | Research | | - - -Example: -```` -{ - "type": "class", - "server":{ - - ... - server config - ... - - }, - "properties": { - "metadata":{ - "description":{ - "name":"description", - "type": "string", - "optional": "false", - "creationID":"create_description", - "labelCreation":"Description: ", - "displayable":"true", - "displayID":"description", - "updatable":"true", - "label":"Description", - "updatable":"true", - "updateID":"update_description", - "labelUpdate":"Description: ", - "queryable":"keyword", - "queryID":"query_description', - "labelQuery":"false" - } - ... - other documents attributes and their properties - ... - }, - "visualization":{ - - ... - visualization attributes - ... - - } - } -} -```` - -What impacts the backend (database, mapping) are the attributes (fields of "properties" themselves (metadata (title, subject...), visualization...). See backend explanation later. - -### Document research view - -The research view is in form of a html formular. This formular is generated using js library alpaca. For this part, two files need to be created : schema.json and options.json. The files will be created depending on the configuration given in the [configuration file](../src/Modules/ConsultDoc/examples/consultDocConfig.json), that is to say by setting the attributes' properties related to the create view (see [table](Configuring-the-Document-model-of-an-UD-Viz-deployment.md#how-to-parametrize-the-attributes-properties)) - -We can allow or disallow the research on an attribute by setting its "queryable" property. - -We offer 3 research modes: - - research by attribute (type, subject..) - - research by keyword - - temporal research (from a date, until a date, in a time period) - -#### Research by attribute: - -The research by attribute can only happen on attributes which are not dates. - -How to set the configuration: - - * attribute.queryable = "false": research on attribute is disabled - * attribute.queryable = "true": standard attribute research - -Example: - -In the configuration file: -* subject.queryable = "true" -In the research form, the user will have the choice to enter a value in the field "subject" (example: urbanism). He will get all document whose subject matches the one he chose ( = all documents whose subject is urbanism). - -#### Temporal research - -How to set the configuration: - * attribute.type = "date" - * attribute.queryable = "true" - -Example: - * refDate.type = "date" - * refDate.queryable = "true" - * refDate.labelQuery = "referring date" -In the research view, two fields will be showed, called "Start referring date" (SRD) and "End referring date" (ERD). -The user can set both fields or only one one them. - * SRD only is provided: get all documents whose referring date >= given SRD - * ERB only is provided: get all documents whose referring date <= given ERD - * SRD and ERD provided: get all documents whose referring date is between the given SRD end ERD - -#### Keyword research - -The keyword research can only happen on attributes which are not dates. - -How to set the configuration: -* attribute.queryable = "keyword" - -Example: -In the configuration file: -* description.queryable = "keyword" -* title.queryable = "keyword" - -In the research form, a field "keyword" will be shown. The user writes "plan" in this field and launches the research. He will get all the documents where the word "plan" was found in the title or in the description. - -General example: -We want to give the user the possibility to launch: - - a temporal research on the date of publication and on the date of reference - - a keyword research in title and description - - a research by attribute on the type and on the subject - -We set the properties in the [configuration file](../src/Modules/ConsultDoc/examples/consultDocConfig.json) as explained previously. - -The following figure shows the research view generated by this example: - -![](Pictures/researchView.png) - -### Document browser - -The document browser only uses the properties.metadata. - -How to set the configuration: - * attribute.displaybable = true - * attribute.label = "false" or attribute.label = "whatever you want to write" - -Example: - * refDate.displayable = true - * refDate.label = "Referring date: " -In the browser, we will have for example (among with other metadata whose displayable property is set to true) - -Referring date: 1945-01-01 - -All the attributes (of metadata) that have the "displayable" property set to "true" will be displayed in the Document Browser. If refDate.label = "false", we have only "1940-01-01"/ - - -In this example, we want to display only the title of the document without writing that this is the title. So we set title.label = false. - -On the other hand, to differentiate the two dates, we set their label property. refDate.label = "Referring date", publicationDate.label = "Publication date" - -The order of the attributes in the document model also rules the order of display in the browser. - -In this example, the following browser has been generated: - -![](Pictures/ExampleBrowser.png) - -### Creation view - -The creation view is in form of a html formular. This formular is generated using [JS library Alpaca](http://www.alpacajs.org/). -To generate the creation form, two files are needed: schema.json and options.json. The files will be created depending on the configuration given in the [configuration file](../src/Modules/ConsultDoc/examples/consultDocConfig.json). - -See associated [design note] - -How to set the configuration: - * attribute.optional = true OR false - * attribute.creationID = create_[name] - * attribute.labelCreation = something you want to say - -Example: - * title.optional = false - * title.creationID = create_title - * title.labelCreation = Title: - -In this example, we set the configuration so that 'title', 'description', 'refDate', 'publicationDate', 'subject' and 'type' must be provided to create a new Document. - -The following figure shows the creation view generated by this example: - -![](Pictures/createView.png) - -We could add "rightsholder.optional = true" and in this way, the user would have the option to specify "rightsholder" or not. A field will be created in the creaton form but will not be mandatory. - -### BACKEND: - -Note: this part is immature - -A file "DocumentModel.json" is created based on the properties set in the configuration file. -The configuration file triggers (only one time) the generation of a "DocumentModel.json" file. -This JSON respects the model defined in the [document model](https://github.com/MEPP-team/UD-Viz-server/blob/master/API_Extended_Document/README.md). -This model is used to (re)create the entity class and (re)generate the DataBase, using this class directly, thanks to the ORM setting up. - -No changes in the back-end will be needed when the document model evolves, but, if the model changes, the DataBase is recreated and data already existing in the DB is lost. - -See [backend](https://github.com/MEPP-team/UD-Viz-server/tree/master/API_Extended_Document) - -### Things we need to be careful about (not exhaustive) - -- define the ID that need to be consistent (=the same) backend and frontend side -- this is great to have a super configurable application. What are the limit of the modularity? At one point, we may need to settle on some parameters. -- right very good documentation to explain how to write the file -- provide default configuration file - -### Perspectives of evolution - - - - use the file to configure "user mode" like: administrator, debug mode, contribute mode... diff --git a/docs/static/Devel/Contributing.md b/docs/static/Devel/Contributing.md index 88cf1e74b..0c0b1343a 100644 --- a/docs/static/Devel/Contributing.md +++ b/docs/static/Devel/Contributing.md @@ -9,7 +9,7 @@ ## Coding style (Linter) -The JavaScript files coding style is defined with [eslint](https://eslint.org/) through the [.eslintrc.js configuration file](/.eslintrc.js). +The JavaScript files coding style is defined with [eslint](https://eslint.org/) through the [.eslintrc.js configuration file](../../../.eslintrc.js). It can be checked (e.g. prior to a commit) with the `npm run eslint` command. Notice that UD-Viz coding style uses a unix `linebreak-style` (aka `LF` as newline character). @@ -32,12 +32,12 @@ Notice that UD-Viz coding style uses a unix `linebreak-style` (aka `LF` as newli ⚠️ When your PR is open each push on your branch will trigger Travis CI jobs. -> `npm run assert-code` will `npm run eslint` and `npm run test`. Also ran by CI. See [here](../../../Readme.md#npm-scripts) for more information. +> `npm run assert-code` will `npm run eslint` and `npm run test`. Also ran by CI. See [here](./Developers.md#npm-scripts) for more information. Before submitting a pull request, and because [UD-Viz still misses some tests](https://github.com/VCityTeam/UD-SV/issues/34), **non-regression testing must be done manually**. A developer must thus at least check that all the -[demo examples](/packages/browser/examples/) +[demo examples](../../../examples/) (they should function similar to [their online deployment](https://ud-viz.vcityliris.data.alpha.grandlyon.com/)) are still effective. > Note that you should interact with ui (user interface) for complete tests. diff --git a/docs/static/Devel/Definitions.md b/docs/static/Devel/Definitions.md index caf461df2..28849a176 100644 --- a/docs/static/Devel/Definitions.md +++ b/docs/static/Devel/Definitions.md @@ -1,7 +1,7 @@ ## Definitions - [Component](https://en.wikipedia.org/wiki/Component-based_software_engineering) everything thats is necessary to execute only one aspect of a desired functionality (see also [module](https://en.wikipedia.org/wiki/Modular_programming)). -- Extension: a component depending on a [web service](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Extensions/Geocoding/services/GeocodingService.js#L2) in order to be functionnal. -- Widget ([web widget](https://en.wikipedia.org/wiki/Web_widget)): an embedded element of a host web page but which is substantially independent of the host page (having limited or no interaction with the host). All the widget created in UD-Viz are explain [here](./src/Widget/Widget.md). +- Extension: a component depending on a [web service](https://github.com/VCityTeam/UD-Viz/blob/master/packages/browser/src/Component/Widget/Server/Geocoding/services/GeocodingService.js#L2) in order to be functionnal. +- Widget ([web widget](https://en.wikipedia.org/wiki/Web_widget)): an embedded element of a host web page but which is substantially independent of the host page (having limited or no interaction with the host). All the widget created in UD-Viz are explain [here](./UD_Viz_Browser/Widget/Widget.md). - [Template](https://en.wikipedia.org/wiki/Template_method_pattern): a class build on sibling sub-directories (Game, Widget, Views) components and proposing an application model - View: decorated/enhanced [iTowns Views](https://www.itowns-project.org/itowns/docs/#api/View/View) diff --git a/docs/static/Devel/Developers.md b/docs/static/Devel/Developers.md index a894a0d99..f392bedbd 100644 --- a/docs/static/Devel/Developers.md +++ b/docs/static/Devel/Developers.md @@ -6,7 +6,7 @@ Developing UD-Viz applications requires knowledge about : - [JavaScript](https://developer.mozilla.org/en-US/docs/Web/javascript) - [node.js](https://en.wikipedia.org/wiki/Node.js) -- [npm]() +- [npm](https://en.wikipedia.org/wiki/Npm_(software)) - [three.js](https://threejs.org/) - [iTowns](http://www.itowns-project.org) @@ -38,30 +38,31 @@ consists in ## Npm Scripts -| Script | Description | -| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `npm run clean` | Remove files and folders generated by `npm install` and the `npm run build-*` script such as `./node_modules`, `package-lock.json`, and `./dist` | +| Script | Description | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `npm run clean` | Remove files and folders generated by `npm install` and the `npm run build-*` script such as `./node_modules`, `package-lock.json`, and `./dist` | | `npm run clear-node` | ***Linux Command***: Kill all node process (this is a sudo script) | -| `npm run reset` | Reinstalls npm dependencies. This script runs `npm run clean` and `npm install` command | -| `npm run build-shared` | Call the build command of the [shared package](./packages/shared/Readme.md#npmscripttodo) | -| `npm run build-browser` | Call the build command of the [browser package](./packages/browser/Readme.md#npmscripttodo) | -| `npm run build-node` | Call the build command of the [node package](./packages/node/Readme.md#npmscripttodo) | -| `npm run debug-examples` | Launch a watcher and server for debugging the examples. See [here](#debugging-the-examples) for more information | -| `npm run eslint` | Run the linter. See [here](#coding-style-linter) for more information | -| `npm run eslint-quiet` | Run the linter without displaying warnings, only errors | -| `npm run eslint-fix` | Run the linter and attempt to fix errors and warning automatically | -| `npm run test` | Build the 3 packages and tests shared, browser scripts and examples html. Uses [this test script](./bin/test.js) | -| `npm run assert-code` | Run `npm run eslint` and `npm run test`. Also ran by CI. See [here](#continuous-integration-travis-ci) for more information | -| `npm run validate-links` | Run this [script](bin/../../../../bin/remarkValidateLinks.js) to detect dead links in markdown. Also ran by CI. See [here](#continuous-integration-travis-ci) for more information | -| `npm run pre-publish` | Change version in all package.json ( eg `npm run pre-publish x.x.x` ). See [this script](./bin/prePublish.js) | -| `npm run docs-shared` | Generate the [JSDOC shared package documentation](./docs/jsdocConfig/jsdoc.shared.json) | -| `npm run docs-browser` | Generate the [JSDOC browser package documentation](./docs/jsdocConfig/jsdoc.browser.json) | -| `npm run docs-node` | Generate the [JSDOC node package documentation](./docs/jsdocConfig/jsdoc.node.json) | -| `npm run docs-home` | Generate the [JSDOC documentation landing page](./docs/jsdocConfig/jsdoc.home.json) | -| `npm run docs` | Run `npm run docs-shared`, `npm run docs-browser`, `npm run docs-node`, and `npm run docs-home` | -| `npm run dev-docs` | Launch a watcher for generating and debugging the documentation. See [here](./docs/Readme.md) for more information | -| `npm run host` | host the bundle with an [ExpressAppWrapper](./bin/host.js).
http://locahost:8000/ | -| `npm run start` | Run `npm run build-browser` and `npm run host` | +| `npm run reset` | Reinstalls npm dependencies. This script runs `npm run clean` and `npm install` command | +| `npm run build-shared` | Call the build command of the [shared package](../../../packages/shared/Readme.md#npm-scripts) | +| `npm run build-browser` | Call the build command of the [browser package](../../../packages/browser/Readme.md#npm-scripts) | +| `npm run build-node` | Call the build command of the [node package](../../../packages/node/Readme.md#npm-scripts) | +| `npm run debug-examples` | Launch a watcher and server for debugging the examples. See [here](#debugging-the-examples) for more information | +| `npm run eslint` | Run the linter. See [here](./Contributing.md#coding-style-linter) for more information | +| `npm run eslint-quiet` | Run the linter without displaying warnings, only errors | +| `npm run eslint-fix` | Run the linter and attempt to fix errors and warning automatically | +| `npm run test` | Build the 3 packages and tests shared, browser scripts and examples html. Uses [this test script](../../../bin/test.js) | +| `npm run assert-code` | Run `npm run eslint` and `npm run test`. Also ran by CI. See [here](#continuous-integration-travis-ci) for more information | +| `npm run validate-links` | Run this [script](../../../bin/remarkValidateLinks.js) to detect dead links in markdown. Also ran by CI. See [here](#continuous-integration-travis-ci) for more information | +| `npm run local-ci` | Run CI on your local computer. See [here](#continuous-integration-travis-ci) for more information | +| `npm run pre-publish` | Change version in all package.json ( eg `npm run pre-publish x.x.x` ). See [this script](../../../bin//prePublish.js) | +| `npm run docs-shared` | Generate the [JSDOC shared package documentation](../../jsdocConfig/jsdoc.shared.json) | +| `npm run docs-browser` | Generate the [JSDOC browser package documentation](../../jsdocConfig/jsdoc.browser.json) | +| `npm run docs-node` | Generate the [JSDOC node package documentation](../../jsdocConfig/jsdoc.node.json) | +| `npm run docs-home` | Generate the [JSDOC documentation landing page](../../jsdocConfig/jsdoc.home.json) | +| `npm run docs` | Run `npm run docs-shared`, `npm run docs-browser`, `npm run docs-node`, and `npm run docs-home` | +| `npm run dev-docs` | Launch a watcher for generating and debugging the documentation. See [here](../../Readme.md) for more information | +| `npm run host` | host the bundle with an [ExpressAppWrapper](../../../bin/host.js) + a default game socket service.
http://locahost:8000/ | +| `npm run start` | Run `npm run build-browser` and `npm run host` | ## Debugging the examples @@ -71,20 +72,17 @@ The browser package contains several "example" applications that showcase differ npm run debug-examples ``` -It run [debugExamples.js](./bin/debugExamples.js): - -- Run an [ExpressAppWrapper](./packages/node/src/ExpressAppWrapper.js) -- Run a watched routine [buildDebugBrowser.js](./bin/buildDebugBrowser.js) with [nodemon](https://www.npmjs.com/package/nodemon). +- Run a watched routine [debugExamples.js](../../../bin/debugExamples.js) with [nodemon](https://www.npmjs.com/package/nodemon). ## Continuous Integration (Travis CI) -Each time origin/master branch is impacted by changes, Travis CI is triggered. It does a set of jobs describe in [travis.yml](./.travis.yml). +Each time origin/master branch is impacted by changes, Travis CI is triggered. It does a set of jobs describe in [travis.yml](../../../.travis.yml). Jobs list : - `npm run assert-code`: Run linter, build bundles and run tests - `npm audit --audit-level=moderate`: Npm native command ([npm-audit](https://docs.npmjs.com/cli/v6/commands/npm-audit)) which check packages dependencies vulnerabilities. -- `remark -u validate-links .`: Command of the package [remark-validate-links](https://www.npmjs.com/package/remark-validate-links) which check dead link in markdown. +- `npm run validate-links`: Run this [script](../../../bin/remarkValidateLinks.js) which check if links are not broken. ## Contributing @@ -97,4 +95,4 @@ For creating a new release see [ReleasePublish.md](./ReleasePublish.md) ## Generating the documentation The [Online documentation](https://vcityteam.github.io/UD-Viz/html/index.html) -can be re-generated by [following these instructions](./docs/Readme.md). +can be re-generated by [following these instructions](../../Readme.md). diff --git a/docs/static/Devel/LocalGameTutorial.md b/docs/static/Devel/LocalGameTutorial.md deleted file mode 100644 index 82a9a5f0e..000000000 --- a/docs/static/Devel/LocalGameTutorial.md +++ /dev/null @@ -1,828 +0,0 @@ - - -# Local Game tutorial :lion: - -Welcome in the first ud-viz game tutorial. We will proceed step by step, if you want to consult the complete project, you can find it in this [**folder**](../../examples). At the end of this tutorial you will fly with your zeppelin in the sky of Lyon, and collect some spheres! - -![Zeppelin](./Pictures/zeppelin.gif) - -# Create your game project :smile: - -- [Working environment](./LocalGameTutorial.md#working-environment) -- [Initialize your project](./LocalGameTutorial.md#initialize-your-project) -- [Importing ud-viz](./LocalGameTutorial.md#importing-ud-viz) -- [Create your game](./LocalGameTutorial.md#create-your-game) -- [Parameterize itowns layers](./LocalGameTutorial.md#parameterize-itowns-layers) - -## Working environment - -Steps : - -- Create an empty folder that you can call `My_UD-Viz_Game`. -- Create a html script in your folder that you call `index.html`([Check out the final version](../../examples/LocalGame.html)). - -> Open the folder in visual studio code or your favorite IDE :computer: - -## Initialize your project - -To begin with, here is the **base** of an html script, **copy it**: - -```html - - - - - My awesome game - - - - - - -``` - -Then you will need to host your game folder (`My_UD-Viz_Game`), to do so you can use your own local server otherwise follow these steps: - -> If you chose to host with this way npm and node must be installed. ([Doc link](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)) - -- Clone the `UD-SimpleServer` repo separately: - -```bash -git clone https://github.com/VCityTeam/UD-SimpleServer.git -``` - -- Open the SimpleServer repo in a terminal and install node packages: - -```bash -npm install -``` - -- And finally host `My_UD-Viz_Game` folder with this command line: - -```bash -node index.js PATH_TO_My_UD-Viz_Game 8000 - -# PATH_TO_My_UD-Viz_Game might be ../My_UD-Viz_Game if UD-SimpleServer is next to your game folder. -``` - -You can visit your page at http://localhost:8000/ but nothing is displayed (yet). - -## Importing ud-viz - -- Create a file `bootstrap.js` in a `src` folder - -- Install [npm / node](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - -- Create `package.json` file and fill with it : - -```json -{ - "name": "game", - "description": "My awesome game", - "main": "./src/bootstrap.js" -} -``` - -> You will need several node packages to run your application - -- To install `ud-viz` : - -`npm i ud-viz` - -> A line has been added to your `package.json`, a `package-lock.json` file and a `node_modules` folder have been created - -Now you will create a bundle of your application to be able to import it into your html file. - -- For this we will use webpack : - -`npm i -D webpack webpack-cli css-loader style-loader` - -Your `package.json` should look like this : - -```json -{ - "name": "game", - "description": "My awesome game", - "main": "./src/bootstrap.js", - "dependencies": { - "ud-viz": "^2.37.5" - }, - "devDependencies": { - "css-loader": "^6.7.1", - "style-loader": "^3.3.1", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0" - } -} -``` - -- Create a config for webpack in `webpack.config.js` - -```js -const path = require('path'); - -module.exports = { - context: path.resolve('src/'), - devtool: 'source-map', - - entry: { - main: path.resolve(__dirname, 'src/bootstrap.js'), - }, - module: { - rules: [ - { - test: /\.css$/, - use: ['style-loader', 'css-loader'], - }, - ], - }, - // Put the bundled code here: /dist/app.bundle.js - output: { - path: path.resolve(__dirname, 'dist/'), - filename: 'app.bundle.js', - libraryTarget: 'umd', - umdNamedDefine: true, - }, -}; -``` - -- Add `scripts` field in your `package.json` - -```json -{ - "name": "game", - "description": "My awesome game", - "main": "./src/bootstrap.js", - "scripts": { - "build": "webpack --mode production", - "build-debug": "webpack --mode development" - }, - "dependencies": { - "ud-viz": "^2.37.5" - }, - "devDependencies": { - "css-loader": "^6.7.1", - "style-loader": "^3.3.1", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0" - } -} -``` - -- Add this line your `src/bootstrap.js` for import ud-viz - -```js -import * as udviz from 'ud-viz'; -``` - -- You can now use the command `npm run build` & `npm run build-debug` (in our case, the advisor). It creates a `app.bundle.js` file in `dist` folder. - -- In your HTML file ([`index.html`](/examples/LocalGame.html)) add the following script tag in the **\**. - -```html - -``` - -Still nothing displayed but the library is now globally accessible. - -> You can also visit this [repository](https://github.com/VCityTeam/UD-Viz-Template) to see an example of a npm project using ud-viz as a package. - -## Create your game - -- Add the following code to start a new local game in `src/bootsrap.js`: - -```js -const myWorld = new udviz.Game.World({ - name: 'My World', - origin: { lat: 45.7530993, lng: 4.8452654, alt: 300 }, - gameObject: { - name: 'GameManager', - }, -}); - -const app = new udviz.Templates.LocalGame(); -app.start(myWorld, './assets/config/local_game_config.json'); -``` - -First a new world called `My World` is created, you have to specify at which 3D coordinates you want to create it. Here we take a random location in Lyon. We also specify our root game object which is here called `GameManager`. - -Then a [LocalGame](/src/Templates/LocalGame/LocalGame.js) is instanciated, to start it you need to pass a world and the path to a config file. - -- Create a new folder called `./assets/config/` and, in it, a new file called `local_game_config.json`([final version](/examples/assets/config/local_game_config.json)) composed of the following code: - -```json -{ - "worldStateInterpolator": { - "renderDelay": 150 - }, - "game": { - "fps": 30, - "shadowMapSize": 2046, - "radiusExtent": 1000, - "sky": { - "color": { - "r": 0.4, - "g": 0.6, - "b": 0.8 - }, - "sun_position": { - "phi": 1, - "theta": 0.3 - } - } - } -} -``` - -Parameters in `game` section are relative to your [GameView](/src/Views/GameView/GameView.js) (the framerate, the size of the shadow map and the sky color). The `itowns` parameter is used to crop the area around the location of your world. - -Ok, at this point, your **browser** should display something like the following, namely a light blue background and a dark blue slab. - -![1](./Pictures/1.png) - -## Parameterize itowns layers - -That's great, you don't know it yet but this is Lyon, ok let's make the city appeared ! - -- Let's add these lines in your [`local_game_config.json`](/examples/assets/config/local_game_config.json) file - -```json -"background_image_layer": { - "url": "https://download.data.grandlyon.com/wms/grandlyon", - "name": "Ortho2018_Dalle_unique_8cm_CC46", - "version": "1.3.0", - "format": "image/jpeg", - "layer_name": "Base_Map", - "transparent": true -}, -"elevation_layer": { - "url": "https://download.data.grandlyon.com/wms/grandlyon", - "name": "MNT2018_Altitude_2m", - "format": "image/jpeg", - "layer_name": "wms_elevation_test" -} -``` - -Here we are parameterized layers of the [itowns](http://www.itowns-project.org/itowns/docs/#home) framework on which `ud-viz` is builded. - -"background_image_layer" define where and how to query the background image of the ground ([ColorLayer](http://www.itowns-project.org/itowns/docs/#api/Layer/ColorLayer)). - -- Let's see how it looks like now: - -![2](./Pictures/2.png) - -- Okay we are close, add these lines in [`local_game_config.json`](/examples/assets/config/local_game_config.json): - -```json -"3DTilesLayers": [ - { - "id": "3d-tiles-layer-building", - "url": "./assets/3DTiles/buildings/tileset.json", - "color": "0xFFFFFF" - } -] -``` - -Here data (geometries of buildings) are not collected from a distant server but locally, you need to download the content [`buildings` folder](/examples/assets/3DTiles/buildings/) in `./assets/3DTiles`. - -with curl & tar : - -``` -curl https://codeload.github.com/VCityTeam/UD-Viz/tar.gz/master | tar -xz --strip=4 UD-Viz-master/examples/assets/3DTiles/buildings -``` - -with wget & tar: - -``` -wget -O - https://codeload.github.com/VCityTeam/UD-Viz/tar.gz/master | tar -xz --strip=4 "UD-Viz-master/examples/assets/3DTiles/buildings" -``` - -Here is what you should see now - -![3](./Pictures/3.png) - -That's it Lyon is here! Now we are going to add our zeppelin. - -## Create a worldscript - -First we are going to attach a [`WorldScript`](/src/Game/GameObject/Component/WorldScript.js) to our `GameManager` game object. A world script is used to customize the world simulation, you can put your code in different events called by the game engine. - -- In `bootstrap.js`, complete the declaration of the `myWorld` object as the following: - -```js -gameObject: { - name: 'GameManager', - static: true, - components: { - WorldScript: { - idScripts: ['worldGameManager'], - } - }, -}, -``` - -`static` set to `true` is used for internal optimization and is meaning that this gameobject is not moving into the 3D scene. - -Now our `GameManager` game object is linked to a world script named `worldGameManager`. We need to import that script in our game. - -- To do so add these lines to your [`local_game_config.json`](/examples/assets/config/local_game_config.json) file. - -```json -"assetsManager": { - "worldScripts": { - "worldGameManager": { - "path": "./assets/worldScripts/worldGameManager.js" - } - } -} -``` - -Now we need to create the `worldGameManager.js`([Check out the final version](/examples/assets/worldScripts/worldGameManager.js)) world script in the new folder `./assets/worldScripts/`. - -- Fill the script with the following skeleton: - -```js -let Game; - -module.exports = class WorldGameManager { - constructor(conf, GameModule) { - this.conf = conf; - Game = GameModule; - } - - init() {} - - tick() {} -}; -``` - -- `conf` is metadata that could be passed into the json file but here there is none. `GameModule` is the dynamic import of the [library](/src/Game/Game.js) which is used to code inside a worldscript context. -- `init` is called when the gameobject is added, and `tick` is called every world simulation step. - -## Add the zeppelin gameobject - -- Let's add the zeppelin, add these lines into `init` method of [`worldGameManager.js`](/examples/assets/worldScripts/worldGameManager.js). - -```js - init() { - //a context containing all references needed for scripting game - const worldContext = arguments[1]; - const world = worldContext.getWorld(); - - this.zeppelin = new Game.GameObject({ - name: 'zeppelin', - components: { - Render: { idRenderData: 'zeppelin' }, - }, - }); - - world.addGameObject(this.zeppelin, worldContext, world.getGameObject()); - } -``` - -We create a new gameobject called zeppelin and a [Render](/src/Game/GameObject/Component/Render.js) component is added with an id of the 3D model. - -As always when we point to assets with an id, we need to import that asset (here a 3D model). We gonna to use this [one](/examples/assets/models/Zeppelin_Labex_IMU.glb). - -- Like the worldscript add these lines in your [`local_game_config.json`](/examples/assets/config/local_game_config.json) file : - -```json -"assetsManager": { - "renderData": { - "zeppelin": { - "path": "./assets/models/Zeppelin_Labex_IMU.glb", - "anchor": "center_min", - "rotation": { - "x": 0, - "y": 0, - "z": 1.57 - } - } - }, - "worldScripts": { - "worldGameManager": { - "path": "./assets/worldScripts/worldGameManager.js" - } - } - } -``` - -`path` point to your .glb -`anchor` means where the origin of the object is taken here at the bottom centered of the 3D model -`rotation` tweak a custom rotation in your 3D model - -Ok let's see what's happen on screen - -![4](./Pictures/4.png) - -Yes a zeppelin appears on the middle of the scene ! trust me... - -## Create a localscript - -Ok let's add a [LocalScript](/src/Game/GameObject/Component/LocalScript.js) now to focus this zeppelin with the camera. These scripts are used to customize client-side game. - -- GameManager in `bootstrap.js` becomes: - -```js -gameObject: { - name: 'GameManager', - static: true, - components: { - WorldScript: { - idScripts: ['worldGameManager'], - }, - LocalScript: { - conf: { - nameGO2Focus: 'zeppelin', - cameraAngle: 0.51, - offsetZ: 10, - minDist: 50, - maxDist: 1000, - }, - idScripts: ['focus'], - }, - }, -} -``` - -- Import it the same way that the worldscript with these lines in your [`local_game_config.json`](/examples/assets/config/local_game_config.json) file. - -```json -"localScripts": { - "focus": { - "path": "./assets/localScripts/focus.js" - } -} -``` - -A localscript skeleton is like so: - -```js - - -let udviz; - -module.exports = class MyClass { - constructor(conf, udvizBundle) { - this.conf = conf; - udviz = udvizBundle; - } - - init() {} - - tick() {} -}; -``` - -`conf` is metadata that could be passed into the json file but here there is none. `udvizBundle` is the dynamic import of the ud-viz framework which is used to code inside a localscript context. - -- And here is the [focus.js](/examples/assets/localScripts/focus.js) script, copy it in the folder `./assets/localScripts` - -Ok here is what the game looks like now, you should also be able to zoom in/out with the wheel ! - -![5](./Pictures/5.png) - -## Inputs - -Ok in the next steps we are gonna to move the zeppelin above the city. - -- Let's add a new `commands.js` local script. Complete the declaration of the GameManager game object in `bootstrap.js` like below: - -```js -gameObject: { - name: 'GameManager', - static: true, - components: { - WorldScript: { - idScripts: ['worldGameManager'], - }, - LocalScript: { - idScripts: ['focus', 'commands'], - }, - }, -} -``` - -- Modify [`local_game_config.json`](/examples/assets/config/local_game_config.json) to import it - -```json -"localScripts": { - "focus": { - "path": "./assets/localScripts/focus.js" - }, - "commands": { - "path": "./assets/localScripts/commands.js" - } - } -``` - -- Then copy this [commands.js](/examples/assets/localScripts/commands.js) local scrip in the folder `./assets/localScripts`. - -Now commands are send to world simulation but the world simulation don't know what to do with them. - -- In the [`worldGameManager.js`](/examples/assets/worldScripts/worldGameManager.js) add these lines in the `tick` function - -```js -tick() { - const worldContext = arguments[1]; - const dt = worldContext.getDt(); - const commands = worldContext.getCommands(); - const speedTranslate = 0.05; - const speedRotate = 0.0003; - const zeppelin = this.zeppelin; - - commands.forEach(function (cmd) { - switch (cmd.getType()) { - case Game.Command.TYPE.MOVE_FORWARD: - zeppelin.move( - zeppelin.computeForward().setLength(dt * speedTranslate) - ); - break; - case Game.Command.TYPE.MOVE_BACKWARD: - zeppelin.move( - zeppelin.computeBackwardVector().setLength(dt * speedTranslate) - ); - break; - case Game.Command.TYPE.MOVE_LEFT: - zeppelin.rotate(new Game.THREE.Vector3(0, 0, speedRotate * dt)); - break; - case Game.Command.TYPE.MOVE_RIGHT: - zeppelin.rotate(new Game.THREE.Vector3(0, 0, -speedRotate * dt)); - break; - default: - throw new Error('command not handle ', cmd.getType()); - } - }); - } -``` - -- You can now pilot the zeppelin! Try it with the Z,Q,S,D or the arrows keys. - -## Add collisions - -Now we are going to add some collectable spheres. - -- In [`worldGameManager.js`](/examples/assets/worldScripts/worldGameManager.js) add the method `createCollectableSphere` - -```js -createCollectableSphere(x, y) { - const size = 10; - - const result = new Game.GameObject({ - name: 'collectable_sphere', - static: true, - components: { - Render: { - idRenderData: 'sphere', - color: [Math.random(), Math.random(), Math.random()], - }, - }, - transform: { - position: [x, y, size], - scale: [size, size, size], - }, - }); - - return result; -} -``` - -- and then inside the `init` method - -```js -//add collectable sphere at random position -const range = 400; -const minRange = 50; -for (let i = 0; i < 10; i++) { - let x = (Math.random() - 0.5) * range; - let y = (Math.random() - 0.5) * range; - - if (x > 0) { - x += minRange; - } else { - x -= minRange; - } - - if (y > 0) { - y += minRange; - } else { - y -= minRange; - } - - const s = this.createCollectableSphere(x, y); - world.addGameObject(s, worldContext, world.getGameObject()); -} -``` - -- You should see spheres around your zeppelin (**zoom out** :smile:) - -![6](./Pictures/6.png) - -ok that's nice, now let handle the collision with these objects. - -- First add a [Collider](/src/Game/GameObject/Component/Collider.js) component to these spheres in [`worldGameManager.js`](/examples/assets/worldScripts/worldGameManager.js) - -```js - createCollectableSphere(x, y) { - const size = 10; - - const result = new Game.GameObject({ - name: 'collectable_sphere', - static: true, - components: { - Render: { - idRenderData: 'sphere', - color: [Math.random(), Math.random(), Math.random()], - }, - Collider: { - shapes: [ - { - type: 'Circle', - center: { x: 0, y: 0 }, - radius: size / 2, - }, - ], - }, - }, - transform: { - position: [x, y, size], - scale: [size, size, size], - }, - }); - - return result; - } -``` - -- Then add a [Collider](/src/Game/GameObject/Component/Collider.js) component to the zeppelin in the `init` method inside `this.zeppelin` declaration: - -```js -this.zeppelin = new Game.GameObject({ - name: 'zeppelin', - components: { - Render: { idRenderData: 'zeppelin' }, - Collider: { - shapes: [ - { - type: 'Circle', - center: { x: 0, y: 0 }, - radius: 10, - }, - ], - }, - }, -}); -``` - -Ok now let's add a worldscript to the zeppelin to handle collision. - -Create a new worldscript import it with the config files and create it in the assets. - -```js - - -let Game; - -module.exports = class Zeppelin { - constructor(conf, GameModule) { - this.conf = conf; - Game = GameModule; - } - - //called when this gameobject collider components collides with another one collider components - onEnterCollision() { - const go = arguments[0]; - const result = arguments[1]; - const worldContext = arguments[2]; - - const goCollided = result.b.getGameObject(); - worldContext.getWorld().removeGameObject(goCollided.getUUID()); - } -}; -``` - -Check out [zeppelin.js](/examples/assets/worldScripts/zeppelin.js) - -When you touch spheres with the zeppelin they are disapearing !! - -## Add some UI - -We are going to display the count of spheres collected. - -The collision with spheres is detected inside a **WorldScript**, and the rendering of game (where to add UI for example) is handle by the **LocalScript**. We need to transfer this data from [`zeppelin.js`](/examples/assets/worldScripts/zeppelin.js) (worldScript) to a [`zeppelin.js`](/examples/assets/localScripts/zeppelin.js) (localScript). - -- First add the _localscript_ [`zeppelin.js`](/examples/assets/localScripts/zeppelin.js) to your zeppelin gameobject in your [`worldGameManager.js`](/examples/assets/worldScripts/worldGameManager.js). - -```js -LocalScript: { - idScripts: ['zeppelin'], - conf: { sphereCount: 0 }, -} -``` - -Here we are going to use the conf attribute of LocalScript. - -- Inside [`zeppelin.js`](/examples/assets/worldScripts/zeppelin.js) (_worldscript_) the `onEnterCollision()` becomes: - -```js -onEnterCollision() { - const go = arguments[0]; - const result = arguments[1]; - const worldContext = arguments[2]; - - const goCollided = result.b.getGameObject(); - worldContext.getWorld().removeGameObject(goCollided.getUUID()); - - const zeppelinLocalScript = go.fetchLocalScripts()['zeppelin']; - zeppelinLocalScript.conf.sphereCount++; -} -``` - -Here the conf of the _localscript_ is modified, this will trigger a update event on the _localscript_. - -- The [`zeppelin.js`](/examples/assets/localScripts/zeppelin.js) (_localscript_) looks like this: - -```js - - -let udviz; - -module.exports = class Zeppelin { - constructor(conf, udvizBundle) { - this.conf = conf; - udviz = udvizBundle; - this.labelSphereCount = null; - } - - init() { - const localContext = arguments[1]; - - const l = document.createElement('div'); - this.labelSphereCount = l; - localContext.getGameView().appendToUI(l); - this.updateUI(); - } - - updateUI() { - this.labelSphereCount.innerHTML = 'Sphere count: ' + this.conf.sphereCount; - } - - update() { - this.updateUI(); - } -}; -``` - -Now when a sphere is collected the ui update the sphere count ! - -## Audio - -Let's play a sound when a sphere is collected. First add this [wav file](/examples/assets/sounds/ballon_pop.wav) in `./assets/sounds/`. Then import it with the assetsManager. - -- Add these lines in [`local_game_config.json`](/examples/assets/config/local_game_config.json) in the _assetsManager_ Object: - -```json -"sounds": { - "ballon_pop": { - "path": "./assets/sounds/ballon_pop.wav" - } -} -``` - -- Then add an _Audio_ component in your zeppelin gameobject in [`worldGameManager`](/examples/assets/worldScripts/worldGameManager.js). - -```js -Audio: { - sounds: ['ballon_pop'], -} -``` - -Okay everything is setup to play a sound ! - -- In [`zeppelin.js`](/examples/assets/localScripts/zeppelin.js) (_localscript_) the update function becomes: - -```js -update() { - const go = arguments[0]; - const s = go.getComponent(udviz.Game.Audio.TYPE).getSounds()[ - 'ballon_pop' - ]; - s.play(); - - this.updateUI(); -} -``` - -That's it a sound will be played when the sphere is collected ! - -## Conclusion - -Congrats you have finished this tutorial, you are now able to : - -- Create a project from scratch -- Importing assets in a ud-viz game -- Parameterized itowns layers -- Manipulating components of gameobjects -- Using user inputs -- Pass data from WorldScript to LocalScript -- Play audio diff --git a/packages/browser/src/Component/Itowns/3DTiles/Docs/3DTilesInteraction.md b/docs/static/Devel/UD_Viz_Browser/3DTiles/3DTilesInteraction.md similarity index 90% rename from packages/browser/src/Component/Itowns/3DTiles/Docs/3DTilesInteraction.md rename to docs/static/Devel/UD_Viz_Browser/3DTiles/3DTilesInteraction.md index a55adc641..444e130d8 100644 --- a/packages/browser/src/Component/Itowns/3DTiles/Docs/3DTilesInteraction.md +++ b/docs/static/Devel/UD_Viz_Browser/3DTiles/3DTilesInteraction.md @@ -9,20 +9,22 @@ The `TilesManager` utility class, located in `TilesManager.js` is a useful tool ## Summary -1. [Code examples](#code-examples) - 1. [Create and update the manager](#Create-and-update-the-manager) - 2. [Pick a city object](#Pick-a-city-object) - 3. [Set the style for one or many city objects](#Set-the-style-for-one-or-many-city-objects) - 4. [Define named styles](#Define-named-styles) - 5. [Remove styles](#Remove-styles) -2. [Model](#Model) - 1. [Tile](#Tile) - 2. [City object](#city-object) - 1. [City object identifier](#City-object-identifier) - 3. [City object style](#city-object-style) -3. [Logic](#Logic) - 1. [Tiles management](#Tiles-management) - 1. [Style management](#Style-management) +- [3DTiles interaction : model, tiles manager \& style manager](#3dtiles-interaction--model-tiles-manager--style-manager) + - [Summary](#summary) + - [Code examples](#code-examples) + - [Create and update the manager](#create-and-update-the-manager) + - [Pick a city object](#pick-a-city-object) + - [Set the style for one or many city objects](#set-the-style-for-one-or-many-city-objects) + - [Define named styles](#define-named-styles) + - [Remove styles](#remove-styles) + - [Model](#model) + - [Tile](#tile) + - [City object](#city-object) + - [City object identifier](#city-object-identifier) + - [City object style](#city-object-style) + - [Logic](#logic) + - [Tiles management](#tiles-management) + - [Style management](#style-management) ## Code examples @@ -118,7 +120,7 @@ There are two main object representing the 3DTiles hierarchy : `Tile` and `CityO ### Tile -[Model/Tile.js](../Model/Tile.js) +[Model/Tile.js](../../../../../packages/browser/src/Component/Itowns/3DTiles/Model/Tile.js) The `Tile` object represents a tile. It contains the batch table and the reference to its city objects. @@ -151,7 +153,7 @@ constructor(layer, tileId) ### City object -[Model/CityObject.js](../Model/CityObject.js) +[Model/CityObject.js](../../../../../packages/browser/src/Component/Itowns/3DTiles/Model/CityObject.js) The `CityObject` class represents a city object. It contains useful geometry properties, such as the vertex indexes or the centroid. It also contains the properties of the batch table. @@ -211,7 +213,7 @@ let cityObjectId = createCityObjectID({tileId: 6, batchId: 64}); ### City object style -[Model/CityObjectStyle.js](../Model/CityObjectStyle.js) +[Model/CityObjectStyle.js](../../../../../packages/browser/src/Component/Itowns/3DTiles/Model/CityObjectStyle.js) The `CityObjectStyle` object represents a style that can be applied to a city object. For the moment, the only option available is to change the material. In order to to that, the `materialProps` property stores THREE.js material parameters, as defined in [the THREE.js documentation](https://threejs.org/docs/index.html#api/en/materials/MeshLambertMaterial). diff --git a/packages/browser/src/Component/Itowns/3DTiles/Docs/3DTilesUtils.md b/docs/static/Devel/UD_Viz_Browser/3DTiles/3DTilesUtils.md similarity index 98% rename from packages/browser/src/Component/Itowns/3DTiles/Docs/3DTilesUtils.md rename to docs/static/Devel/UD_Viz_Browser/3DTiles/3DTilesUtils.md index 5f74e81f8..b09499757 100644 --- a/packages/browser/src/Component/Itowns/3DTiles/Docs/3DTilesUtils.md +++ b/docs/static/Devel/UD_Viz_Browser/3DTiles/3DTilesUtils.md @@ -2,7 +2,7 @@ This document is about the following file : -- [3DTilesUtils](../3DTilesUtils.js) +- [3DTilesUtils](../../../../../packages/browser/src/Component/Itowns/3DTiles/3DTilesUtils.js) ## Helper functions for 3DTiles @@ -60,7 +60,7 @@ The batch table objects represent a 3DTiles batch table. It has two attributes : Below is an example batch table with one attribute, called "cityobject.database_id". -![Batch table example](batch_table_example.png) +![Batch table example](./batch_table_example.png) ### Geometry attributes diff --git a/packages/browser/src/Component/Itowns/3DTiles/Docs/StyleManager.md b/docs/static/Devel/UD_Viz_Browser/3DTiles/StyleManager.md similarity index 100% rename from packages/browser/src/Component/Itowns/3DTiles/Docs/StyleManager.md rename to docs/static/Devel/UD_Viz_Browser/3DTiles/StyleManager.md diff --git a/packages/browser/src/Component/Itowns/3DTiles/Docs/TilesManager.md b/docs/static/Devel/UD_Viz_Browser/3DTiles/TilesManager.md similarity index 100% rename from packages/browser/src/Component/Itowns/3DTiles/Docs/TilesManager.md rename to docs/static/Devel/UD_Viz_Browser/3DTiles/TilesManager.md diff --git a/packages/browser/src/Component/Itowns/3DTiles/Docs/batch_table_example.png b/docs/static/Devel/UD_Viz_Browser/3DTiles/batch_table_example.png similarity index 100% rename from packages/browser/src/Component/Itowns/3DTiles/Docs/batch_table_example.png rename to docs/static/Devel/UD_Viz_Browser/3DTiles/batch_table_example.png diff --git a/packages/browser/src/Component/Widget/3DTilesDebug/docs/3DTilesDebug.md b/docs/static/Devel/UD_Viz_Browser/3DTilesDebug/3DTilesDebug.md similarity index 73% rename from packages/browser/src/Component/Widget/3DTilesDebug/docs/3DTilesDebug.md rename to docs/static/Devel/UD_Viz_Browser/3DTilesDebug/3DTilesDebug.md index 1ed01d49b..e89780645 100644 --- a/packages/browser/src/Component/Widget/3DTilesDebug/docs/3DTilesDebug.md +++ b/docs/static/Devel/UD_Viz_Browser/3DTilesDebug/3DTilesDebug.md @@ -8,4 +8,4 @@ Capabilities : - Get information about a specific building by clicking on it. Also change its style. - Apply color and opacity to city objects in a tile. -This tool also serves as a demonstration for 3DTiles utility classes and functions. You can find their documentation [here](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Itowns/3DTiles/Docs/3DTilesInteraction.md). +This tool also serves as a demonstration for 3DTiles utility classes and functions. You can find their documentation [here](../3DTiles/3DTilesInteraction.md). diff --git a/packages/browser/src/Component/Widget/Server/Contribute/ReadMe.md b/docs/static/Devel/UD_Viz_Browser/Contribute/ReadMe.md similarity index 100% rename from packages/browser/src/Component/Widget/Server/Contribute/ReadMe.md rename to docs/static/Devel/UD_Viz_Browser/Contribute/ReadMe.md diff --git a/packages/browser/src/Component/Widget/Server/Documents/Doc/Pictures/dependencies.png b/docs/static/Devel/UD_Viz_Browser/Documents/Pictures/dependencies.png similarity index 100% rename from packages/browser/src/Component/Widget/Server/Documents/Doc/Pictures/dependencies.png rename to docs/static/Devel/UD_Viz_Browser/Documents/Pictures/dependencies.png diff --git a/packages/browser/src/Component/Widget/Server/Documents/Doc/Pictures/view.png b/docs/static/Devel/UD_Viz_Browser/Documents/Pictures/view.png similarity index 100% rename from packages/browser/src/Component/Widget/Server/Documents/Doc/Pictures/view.png rename to docs/static/Devel/UD_Viz_Browser/Documents/Pictures/view.png diff --git a/packages/browser/src/Component/Widget/Server/Documents/README.md b/docs/static/Devel/UD_Viz_Browser/Documents/README.md similarity index 98% rename from packages/browser/src/Component/Widget/Server/Documents/README.md rename to docs/static/Devel/UD_Viz_Browser/Documents/README.md index 01b22594a..b4752adf4 100644 --- a/packages/browser/src/Component/Widget/Server/Documents/README.md +++ b/docs/static/Devel/UD_Viz_Browser/Documents/README.md @@ -11,12 +11,12 @@ The module is also extensible, which means that other modules can serve as plug- ## Basic functionalities -In the [example](/examples/DocumentWidget), you can view how to implement this modules. It can: +In the [example](../../../../../examples/DocumentWidget.html), you can view how to implement this modules. It can: - Fetch all documents from the server. It's actually the default comportement (and may change in the future for scaling purpose). The user can filter the retrieved list according to some filters: keywords in the title/description, subject, publication or refering date. - Display the details of one particular documents, and navigate through the documents list. The navigation can be done either by selecting a document in the document list, or by using navigation arrows in the document inspector. -![The look of the documents module](./Doc/Pictures/view.png) +![The look of the documents module](./Pictures/view.png) The demo also includes the `DocumentVisualizer` module, that adds an "Orient" button in the document inspector. When pressed, the button moves the camera to the "visualization" position specified in the document, and the image of the document is displayed in superposition to the scene. @@ -58,7 +58,7 @@ The documents module depends on the utility `RequestService` to perform HTTP req The document visualizer depends on the documents module, and the iTowns view and camera controls from the demo. -![Dependencies graph](./Doc/Pictures/dependencies.png) +![Dependencies graph](./Pictures/dependencies.png) ## Code architecture diff --git a/packages/browser/src/Component/Widget/Server/Geocoding/doc/Geocoding.md b/docs/static/Devel/UD_Viz_Browser/Geocoding/Geocoding.md similarity index 100% rename from packages/browser/src/Component/Widget/Server/Geocoding/doc/Geocoding.md rename to docs/static/Devel/UD_Viz_Browser/Geocoding/Geocoding.md diff --git a/packages/browser/src/Component/Widget/LayerChoice/docs/LayerChoice.md b/docs/static/Devel/UD_Viz_Browser/LayerChoice/LayerChoice.md similarity index 100% rename from packages/browser/src/Component/Widget/LayerChoice/docs/LayerChoice.md rename to docs/static/Devel/UD_Viz_Browser/LayerChoice/LayerChoice.md diff --git a/packages/browser/src/Component/Itowns/LayerManager/Docs/layerManager.md b/docs/static/Devel/UD_Viz_Browser/LayerManager/layerManager.md similarity index 100% rename from packages/browser/src/Component/Itowns/LayerManager/Docs/layerManager.md rename to docs/static/Devel/UD_Viz_Browser/LayerManager/layerManager.md diff --git a/docs/static/Widget/Extensions/SPARQL/Pictures/interface.png b/docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/interface.png similarity index 100% rename from docs/static/Widget/Extensions/SPARQL/Pictures/interface.png rename to docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/interface.png diff --git a/docs/static/Widget/Extensions/SPARQL/Pictures/pickcityobjectfromgraph.gif b/docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/pickcityobjectfromgraph.gif similarity index 100% rename from docs/static/Widget/Extensions/SPARQL/Pictures/pickcityobjectfromgraph.gif rename to docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/pickcityobjectfromgraph.gif diff --git a/docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-demo.gif b/docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/sparql-widget-demo.gif similarity index 100% rename from docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-demo.gif rename to docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/sparql-widget-demo.gif diff --git a/docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-json-demo.gif b/docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/sparql-widget-json-demo.gif similarity index 100% rename from docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-json-demo.gif rename to docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/sparql-widget-json-demo.gif diff --git a/docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-table-demo.gif b/docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/sparql-widget-table-demo.gif similarity index 100% rename from docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-table-demo.gif rename to docs/static/Devel/UD_Viz_Browser/SPARQL/Pictures/sparql-widget-table-demo.gif diff --git a/packages/browser/src/Component/Widget/Server/SPARQL/Readme.md b/docs/static/Devel/UD_Viz_Browser/SPARQL/Readme.md similarity index 91% rename from packages/browser/src/Component/Widget/Server/SPARQL/Readme.md rename to docs/static/Devel/UD_Viz_Browser/SPARQL/Readme.md index fa7d5f2ce..63d63ab93 100644 --- a/packages/browser/src/Component/Widget/Server/SPARQL/Readme.md +++ b/docs/static/Devel/UD_Viz_Browser/SPARQL/Readme.md @@ -11,23 +11,23 @@ The basic functionalities of the SPARQL module include: ## Usage -For an example of how to the SPARQL Widget to a UD-Viz web application see the [SPARQLWidget example](https://github.com/VCityTeam/UD-Viz/blob/master/packages/browser/examples/SPARQLWidget.html) +For an example of how to the SPARQL Widget to a UD-Viz web application see the [SPARQLWidget example](https://github.com/VCityTeam/UD-Viz/blob/master/examples/SPARQLWidget.html) ### User Interface The Interface is composed of a **SPARQL Query** window containing a text box for composing queries to send to a [SPARQL Endpoint](https://github.com/VCityTeam/UD-SV/blob/master/Vocabulary/Readme.md#SPARQL-Endpoint). -![SPARQL widget interface](/docs/static/Widget/Extensions/SPARQL/Pictures/interface.png) +![SPARQL widget interface](./Pictures/interface.png) The *Results Format* dropdown menu can be used to select how the query results will be visualised. Currently 3 formats are supported: -- [Graph](#Graph) -- [Table](#Table) -- [JSON](#JSON) +- [Graph](#graph-view) +- [Table](#table) +- [JSON](#json) #### Graph View A displayed graph can be zoomed in and out using the mouse wheel and panned by clicking and dragging the background of the graph. In addition, nodes can be moved by clicking and dragging them. -![Vizualize SPARQL query result in D3](/docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-demo.gif) +![Vizualize SPARQL query result in D3](./Pictures/sparql-widget-demo.gif) In order to propery colorize the nodes of a graph a SPARQL query must be formulated following a simple subject-predicate-object [RDF triple](https://github.com/VCityTeam/UD-SV/blob/master/Vocabulary/Readme.md#triple) structure. Colors will be assigned as a function each node's `rdf:type`. Thus 4 data must be selected: - ?subject @@ -67,17 +67,17 @@ WHERE { If the URIs of nodes in the graph correspond with identifiers of objects in the tileset batch table, they can be selected as shown below. -![Pick City Object from Graph](/docs/static/Widget/Extensions/SPARQL/Pictures/pickcityobjectfromgraph.gif) +![Pick City Object from Graph](./Pictures/pickcityobjectfromgraph.gif) #### Table The table view features a filter for searching for data within a column. In addition rows can be sorted in ascending or descending order by column. -![Table view demonstraction](/docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-table-demo.gif) +![Table view demonstraction](./Pictures/sparql-widget-table-demo.gif) #### JSON The JSON view returns a collapsible representation of the query reponse. -![JSON view demonstraction](/docs/static/Widget/Extensions/SPARQL/Pictures/sparql-widget-json-demo.gif) +![JSON view demonstraction](./Pictures/sparql-widget-json-demo.gif) ## Code architecture diff --git a/packages/browser/src/Component/Widget/Temporal/Docs/Readme.md b/docs/static/Devel/UD_Viz_Browser/Temporal/Readme.md similarity index 64% rename from packages/browser/src/Component/Widget/Temporal/Docs/Readme.md rename to docs/static/Devel/UD_Viz_Browser/Temporal/Readme.md index 8910f8579..afcd837d7 100644 --- a/packages/browser/src/Component/Widget/Temporal/Docs/Readme.md +++ b/docs/static/Devel/UD_Viz_Browser/Temporal/Readme.md @@ -12,21 +12,21 @@ the [documention can be found here](https://github.com/VCityTeam/UD-SV/3DTilesTe ## Design of the temporal module -The entrypoint of the temporal module is [TemporalModule.js](../TemporalModule.js). +The entrypoint of the temporal module is [TemporalModule.js](../../../../../packages/browser/src/Component/Widget/Temporal/TemporalModule.js). The module is designed following the MVVM pattern which is one of the preffered -patterns to design UD-Viz modules (see [UD-Viz architecture notes](../../../../Doc/Devel/ArchitectureMVCTargetDesign.md)). +patterns to design UD-Viz modules (see [UD-Viz architecture notes](../../ArchitectureMVCTargetDesign.md)). ### The model -The entrypoint of the model is[3DTemporalExtension](../Model/3DTemporalExtension.js). +The entrypoint of the model is[3DTemporalExtension](../../../../../packages/browser/src/Component/Widget/Temporal/Model/3DTemporalExtension.js). The other classes of the model parse the content of the 3DTILES_temporal extensions pieces scattered in the 3D Tiles classes (e.g. in the bounding volume or in the batch table). ### The view model -[TemporalProvider.js](../ViewModel/TemporalProvider.js) holds the view model of +[TemporalProvider.js](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js) holds the view model of this module. It maintains a structure describing city objects display states: whether they should be displayed or not depending on the date and if yes with which style: e.g. color, opacity, etc. The style is for instance useful to @@ -48,7 +48,7 @@ The temporal provider also manages updates of the model. ### The view -The entrypoint of the view is [TemporalView.js](../View/TemporalView.js). +The entrypoint of the view is [TemporalView.js](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalView.js). It declares the windows and associates events between windows and the view model. The view is composed of two windows: the `SLIDERWINDOW` and the `GRAPHWINDOW`. @@ -228,36 +228,36 @@ The code for parsing and storing the temporal tileset can be found in the [model ### Concerning the relationship between the slider position and the data update -A [TemporalView calls](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/View/TemporalView.js#L46) a [refreshCallback](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/View/TemporalView.js#L31) function every time the slider is moved. -* The refreshCallback is defined as the [TemporalView::currentTimeUpdated(...)](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/View/TemporalView.js#L25) function. -* The TemporalView passes this refreshCallback to the [TemporalSliderWindow constructor](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/View/TemporalView.js#L46) . -* Eventually the callback is [invoked by the TemporalSliderWindow](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/View/TemporalSliderWindow.js#L88) when e.g. the slider is acted upon the user. +A [TemporalView calls](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalView.js#L46) a [refreshCallback](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalView.js#L31) function every time the slider is moved. +* The refreshCallback is defined as the [TemporalView::currentTimeUpdated(...)](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalView.js#L25) function. +* The TemporalView passes this refreshCallback to the [TemporalSliderWindow constructor](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalView.js#L46) . +* Eventually the callback is [invoked by the TemporalSliderWindow](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalSliderWindow.js#L88) when e.g. the slider is acted upon the user. -In order to get the proper slide-bar refresh, the [TemporalView::currentTimeUpdated(...)](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/View/TemporalView.js#L25) callback function uses a [provider](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/View/TemporalView.js#L18) (that is [handled over to the constructor](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/TemporalModule.js#L29)) that triggers a [provider.changeVisibleTilesStates()](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/View/TemporalView.js#L29). -* In turn the [TemporalProvider::changeVisibleTilesStates() function](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L333) uses - * a [TileManager](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L334) ([provided to the constructor](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L29)) to retrieve the visible tiles, - * a [`$3DTemporalExtension` model](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/TemporalModule.js#L21) (also [provided to the constructor](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L27)) -* Both those `TileManager` and `model` are [provided to the TemporalProvider at instantiation](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/TemporalModule.js#L24) and it is this instantiantion context that instantiates the [`$3DTemporalExtension` model](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/TemporalModule.js#L21) +In order to get the proper slide-bar refresh, the [TemporalView::currentTimeUpdated(...)](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalView.js#L25) callback function uses a [provider](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalView.js#L18) (that is [handled over to the constructor](../../../../../packages/browser/src/Component/Widget/Temporal/TemporalModule.js#L29)) that triggers a [provider.changeVisibleTilesStates()](../../../../../packages/browser/src/Component/Widget/Temporal/View/TemporalView.js#L29). +* In turn the [TemporalProvider::changeVisibleTilesStates() function](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L333) uses + * a [TileManager](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L334) ([provided to the constructor](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L29)) to retrieve the visible tiles, + * a [`$3DTemporalExtension` model](../../../../../packages/browser/src/Component/Widget/Temporal/TemporalModule.js#L21) (also [provided to the constructor](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L27)) +* Both those `TileManager` and `model` are [provided to the TemporalProvider at instantiation](../../../../../packages/browser/src/Component/Widget/Temporal/TemporalModule.js#L24) and it is this instantiantion context that instantiates the [`$3DTemporalExtension` model](../../../../../packages/browser/src/Component/Widget/Temporal/TemporalModule.js#L21) -Now, [TemporalProvider::changeVisibleTilesStates() function](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L333) calls [TemporalProvider::computeTileState()](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L336) for each `tiles[i].tileId` that [is visible](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L334) -[TemporalProvider::computeTileState()](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L336) - uses the [`TemporalProvider.COStyles`](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L39) +Now, [TemporalProvider::changeVisibleTilesStates() function](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L333) calls [TemporalProvider::computeTileState()](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L336) for each `tiles[i].tileId` that [is visible](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L334) +[TemporalProvider::computeTileState()](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L336) + uses the [`TemporalProvider.COStyles`](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L39) optimization data structure that `computeTileState()` -* [initializes on first traversal](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L296) -* updates/set the [features rendering style on further traveral](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L287) +* [initializes on first traversal](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L296) +* updates/set the [features rendering style on further traveral](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L287) -In order to [set the rendering mode (display styles)](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L336) of the features of tile (for a given currentTime), `TemporalProvider::computeTileState()` calls [TemporalProvider::culling()](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L178) that -* If the feature exists at the currentTime, [displays it in gray](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L188), +In order to [set the rendering mode (display styles)](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L336) of the features of tile (for a given currentTime), `TemporalProvider::computeTileState()` calls [TemporalProvider::culling()](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L178) that +* If the feature exists at the currentTime, [displays it in gray](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L188), * If there is a transaction between the feature and another feature at the currentTime AND - * if the currentTime lies within the first half duration of the transaction THEN [displayed geometry is the one of the old feature](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L211) and [set the color](https://github.com/VCityTeam/UD-Viz/blob/86ff907a5d00b944de895a735fe4c42162d2251c/src/Widget/Temporal/ViewModel/TemporalProvider.js#L211) - * if the currentTime lies within the second half of the duration THEN [the displayed geometry is the one of the new feature](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L229) and [set the color](https://github.com/VCityTeam/UD-Viz/blob/86ff907a5d00b944de895a735fe4c42162d2251c/src/Widget/Temporal/ViewModel/TemporalProvider.js#L229) + * if the currentTime lies within the first half duration of the transaction THEN [displayed geometry is the one of the old feature](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L211) and [set the color](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L211) + * if the currentTime lies within the second half of the duration THEN [the displayed geometry is the one of the new feature](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L229) and [set the color](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L229) * If there is no existing feature or transaction at the currentTime : - * If there a feature that exists in the next vintage, [display it as green (construction)](https://github.com/VCityTeam/UD-Viz/blob/86ff907a5d00b944de895a735fe4c42162d2251c/src/Widget/Temporal/ViewModel/TemporalProvider.js#L253) - * If there a feature that exists in the previous vintage, [display it as red (destruction)](https://github.com/VCityTeam/UD-Viz/blob/86ff907a5d00b944de895a735fe4c42162d2251c/src/Widget/Temporal/ViewModel/TemporalProvider.js#L253) - * Otherwise [hide the feature](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L264) + * If there a feature that exists in the next vintage, [display it as green (construction)](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L253) + * If there a feature that exists in the previous vintage, [display it as red (destruction)](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L253) + * Otherwise [hide the feature](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L264) Hence, all the features for all the vintages are always present, but their rendering mode depends on the `currentTime` value. ### Concerning the client side color rendering -The rendering style is hardcoded in the [TemporalProvider:: initCOStyles()](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Temporal/ViewModel/TemporalProvider.js#L67) function. +The rendering style is hardcoded in the [TemporalProvider:: initCOStyles()](../../../../../packages/browser/src/Component/Widget/Temporal/ViewModel/TemporalProvider.js#L67) function. diff --git a/packages/browser/src/Component/Widget/Temporal/Docs/graphwindow.png b/docs/static/Devel/UD_Viz_Browser/Temporal/graphwindow.png similarity index 100% rename from packages/browser/src/Component/Widget/Temporal/Docs/graphwindow.png rename to docs/static/Devel/UD_Viz_Browser/Temporal/graphwindow.png diff --git a/packages/browser/src/Component/Widget/Temporal/Docs/sliderwindow.png b/docs/static/Devel/UD_Viz_Browser/Temporal/sliderwindow.png similarity index 100% rename from packages/browser/src/Component/Widget/Temporal/Docs/sliderwindow.png rename to docs/static/Devel/UD_Viz_Browser/Temporal/sliderwindow.png diff --git a/packages/browser/src/Component/Widget/Temporal/Docs/visu-2013-2014.png b/docs/static/Devel/UD_Viz_Browser/Temporal/visu-2013-2014.png similarity index 100% rename from packages/browser/src/Component/Widget/Temporal/Docs/visu-2013-2014.png rename to docs/static/Devel/UD_Viz_Browser/Temporal/visu-2013-2014.png diff --git a/packages/browser/src/Component/Widget/Temporal/Docs/visu-transactions.png b/docs/static/Devel/UD_Viz_Browser/Temporal/visu-transactions.png similarity index 100% rename from packages/browser/src/Component/Widget/Temporal/Docs/visu-transactions.png rename to docs/static/Devel/UD_Viz_Browser/Temporal/visu-transactions.png diff --git a/packages/browser/src/Component/Widget/Widget.md b/docs/static/Devel/UD_Viz_Browser/Widget/Widget.md similarity index 96% rename from packages/browser/src/Component/Widget/Widget.md rename to docs/static/Devel/UD_Viz_Browser/Widget/Widget.md index e15a1a21c..0fada839b 100644 --- a/packages/browser/src/Component/Widget/Widget.md +++ b/docs/static/Devel/UD_Viz_Browser/Widget/Widget.md @@ -28,7 +28,7 @@ Each module adds new functionnalities to the application. You can find the code - Filtered research (research by keyword, attribute and/or temporal research) - All documents are loaded from an external data server and can be accessed using the **Document Inspector** window. -![](https://github.com/VCityTeam/UD-Viz/blob/master/src/Widget/Documents/Doc/Pictures/view.png) +![documents_view](../Documents/Pictures/view.png) This module has several extensions that add functionalities : diff --git a/docs/static/User/ContributeData.md b/docs/static/User/ContributeData.md index 6cb04bb8d..215477942 100644 --- a/docs/static/User/ContributeData.md +++ b/docs/static/User/ContributeData.md @@ -15,7 +15,7 @@ contributions are possible. As a first step, you can try to navigate in the 3D scene with the following controls: -![](Pictures/UserDoc/controls.PNG) +![](./Pictures/UserDoc/controls.PNG) ## Creating an account @@ -23,18 +23,18 @@ Before starting contributing, you need to create an account. To do so, you must click on the _Sign in_ button on the upper-left corner of [the application](http://rict.liris.cnrs.fr/UDVDemo/UDV/UDV-Core/examples/DemoStable/Demo.html): -![](Pictures/UserDoc/UDVHome.png) +![](./Pictures/UserDoc/UDVHome.png) Then, you need to fill the _Registration form_ and click on _Register_: -![](Pictures/UserDoc/registration.png) +![](./Pictures/UserDoc/registration.png) You're account is now created! You can now log in with the _Login_ form on the right. Once you're logged in, you should see your name on the upper-left corner of the application: -![](Pictures/UserDoc/loggedIn.png) +![](./Pictures/UserDoc/loggedIn.png) **Note**: Your account gives you **contributor** rights, meaning that when you [add a document](#adding-a-document), it is not published right away. @@ -50,12 +50,12 @@ are images (jpeg or png). You can see existing documents by opening the **Document** module from the left side menu: -![](Pictures/UserDoc/documentsMenu.png) +![](./Pictures/UserDoc/documentsMenu.png) Clicking on this menu opens the **Document Navigator** and the **Document Inspector**. -![](Pictures/UserDoc/documentsModule.png) +![](./Pictures/UserDoc/documentsModule.png) These two windows allow to consult the documentation that has already been added by contributors and validated by administrators. @@ -81,7 +81,7 @@ The **Document Inspector** (window on the right) allows to: To add a document, click on **Create a new document** in the **Document Navigator**. The **Document creation window** opens: -![](Pictures/UserDoc/docCreation.png) +![](./Pictures/UserDoc/docCreation.png) To add your document, you need to: @@ -111,30 +111,30 @@ To add your document, you need to: Before placing your document, you might want to go to a specific address where you will place it. This is possible using the **address search module**: -![](Pictures/UserDoc/addressSearchMenu.png) +![](./Pictures/UserDoc/addressSearchMenu.png) By clicking on the magnifying glass on the menu, a search bar will open in the top-center of the screen: -![](Pictures/UserDoc/addressSearchModule.png) +![](./Pictures/UserDoc/addressSearchModule.png) Type in the address you're looking for and hit enter. This will initiate a travel to the address and will identify the result in the 3D scene with a red pin: -![](Pictures/UserDoc/addressSearchExample.png) +![](./Pictures/UserDoc/addressSearchExample.png) You can now close the **address search** module by clicking on the loop in the left-side menu and start placing your document by clicking on **Set position** in the **Document Creation** window. This will display your document in overlay to the 3D scene: -![](Pictures/UserDoc/docSetPosition.png) +![](./Pictures/UserDoc/docSetPosition.png) To place your document, you can play with its opacity and move in the scene to be rightly placed above the 3D geometry. For instance: -![](Pictures/UserDoc/docPositionSet.png) +![](./Pictures/UserDoc/docPositionSet.png) Once you've found the right position, click on Validate in the **Camera Positioner** window situated on the left side of the screen. diff --git a/package.json b/package.json index 0f87be582..d025fbe23 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "test": "cross-env NODE_ENV=production node ./bin/test.js", "assert-code": "npm run eslint && npm run test", "validate-links": "node ./bin/remarkValidateLinks.js", + "local-ci": "npm run assert-code && npm audit --audit-level=low && npm run validate-links", "pre-publish": "node ./bin/prePublish.js", "docs-shared": "cross-env PACKAGE=shared jsdoc -c ./docs/jsdocConfig/jsdoc.js", "docs-browser": "cross-env PACKAGE=browser jsdoc -c ./docs/jsdocConfig/jsdoc.js", diff --git a/packages/browser/Readme.md b/packages/browser/Readme.md index 755fc08f6..57a4c7c2c 100644 --- a/packages/browser/Readme.md +++ b/packages/browser/Readme.md @@ -45,7 +45,7 @@ See [here](https://github.com/VCityTeam/UD-Viz/blob/master/Readme.md#getting-sta ## Developers -For pre-requisites see [here](https://github.com/VCityTeam/UD-Viz/blob/master/Readme.md#pre-requisites). +For pre-requisites see [here](https://github.com/VCityTeam/UD-Viz/blob/master/docs/static/Devel/Developers.md#pre-requisites). ### Npm scripts diff --git a/packages/node/Readme.md b/packages/node/Readme.md index 2aeb6a53d..1c2e7f6bf 100644 --- a/packages/node/Readme.md +++ b/packages/node/Readme.md @@ -31,7 +31,7 @@ See [here](https://github.com/VCityTeam/UD-Viz/blob/master/Readme.md#getting-sta ## Developers -For pre-requisites see [here](https://github.com/VCityTeam/UD-Viz/blob/master/Readme.md#pre-requisites). +For pre-requisites see [here](https://github.com/VCityTeam/UD-Viz/blob/master/docs/static/Devel/Developers.md#pre-requisites). ### Npm scripts @@ -44,4 +44,4 @@ For pre-requisites see [here](https://github.com/VCityTeam/UD-Viz/blob/master/Re ### Debugging -To debug the [ExpressAppWrapper](./src/ExpressAppWrapper.js) back-end see [here](../../docs/static/Devel/Developers.md#debugging-the-examples) +To debug the [ExpressAppWrapper](../node/src/ExpressAppWrapper.js) back-end see [here](../../docs/static/Devel/Developers.md#debugging-the-examples) diff --git a/packages/node/src/Test.js b/packages/node/src/Test.js index c9b873a99..052779ff6 100644 --- a/packages/node/src/Test.js +++ b/packages/node/src/Test.js @@ -1,6 +1,7 @@ const puppeteer = require('puppeteer'); const fs = require('fs'); const spawn = require('child_process').spawn; +const { Data } = require('@ud-viz/shared'); /** * `MODULE` Test @@ -117,9 +118,8 @@ const scripts = function (folderPath) { const html = function (folderPath, port) { return folderInBrowserPage(folderPath, (page, currentFile) => { // check if file is an html file - const indexLastPoint = currentFile.name.lastIndexOf('.'); - const fileFormat = currentFile.name.slice(indexLastPoint + 1); - if (fileFormat != 'html') return Promise.resolve(); + if (Data.computeFileFormat(currentFile.name) != 'html') + return Promise.resolve(); return new Promise((resolve) => { console.log('\n\nstart testing html ', currentFile.name); diff --git a/packages/shared/src/Data.js b/packages/shared/src/Data.js index 0a2146d0a..c5e6f7489 100644 --- a/packages/shared/src/Data.js +++ b/packages/shared/src/Data.js @@ -533,6 +533,17 @@ function arrayEquals(a1, a2) { return true; } +/** + * Compute the last string after the . in the filename + * + * @param {string} filename - file name + * @returns {string} - file format + */ +function computeFileFormat(filename) { + const indexLastPoint = filename.lastIndexOf('.'); + return filename.slice(indexLastPoint + 1); +} + module.exports = { PartialString: PartialString, StringComposer: StringComposer, @@ -551,4 +562,5 @@ module.exports = { objectOverWrite: objectOverWrite, objectParse: objectParse, objectParseNumeric: objectParseNumeric, + computeFileFormat: computeFileFormat, };