diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 301d634..0000000 --- a/.babelrc +++ /dev/null @@ -1,65 +0,0 @@ -{ - "presets": [ - "@babel/preset-react", - [ - "@babel/preset-env", - { - "targets": { - "browsers": ["last 2 versions", "IE >= 8"], - "node": "current" - }, - "useBuiltIns": "usage", - "corejs": { - "version": 3, - "proposals": true - } - } - ] - ], - "plugins": [ - [ - "@babel/plugin-transform-runtime", - { - "corejs": { - "version": 3, - "proposals": true - } - } - ], - [ - "@babel/plugin-proposal-decorators", - { - "legacy": true - } - ], - "react-loadable/babel", - "react-hot-loader/babel", - "@babel/plugin-syntax-dynamic-import", - "@babel/plugin-syntax-import-meta", - "@babel/plugin-proposal-class-properties", - "@babel/plugin-proposal-json-strings", - "@babel/plugin-proposal-function-sent", - "@babel/plugin-proposal-export-namespace-from", - "@babel/plugin-proposal-numeric-separator", - "@babel/plugin-proposal-throw-expressions", - "@babel/plugin-proposal-export-default-from", - "@babel/plugin-proposal-logical-assignment-operators", - "@babel/plugin-proposal-optional-chaining", - [ - "@babel/plugin-proposal-pipeline-operator", - { - "proposal": "minimal" - } - ], - "@babel/plugin-proposal-nullish-coalescing-operator", - "@babel/plugin-proposal-do-expressions", - "@babel/plugin-proposal-function-bind" - ], - "env": { - "development": { - "plugins": [ - "@babel/plugin-transform-react-jsx-source" - ] - } - } -} diff --git a/.bootstraprc b/.bootstraprc deleted file mode 100644 index e9f7d1c..0000000 --- a/.bootstraprc +++ /dev/null @@ -1,79 +0,0 @@ -{ - "bootstrapVersion": 3, - "preBootstrapCustomizations": "./src/theme/variables.scss", - "appStyles": "./src/theme/app.scss", - "loglevel": "disabled", - "env": { - "development": { - "styleLoaders": [ - "style-loader?sourceMap", - "css-loader?sourceMap&importLoaders=2", - "resolve-url-loader", - "sass-loader?sourceMap" - ], - "extractStyles": false - }, - "production": { - "styleLoaders": [ - "style-loader", - "css-loader?importLoaders=1", - "sass-loader?sourceMap" - ], - "extractStyles": true - } - }, - "scripts": { - "transition": false, - "alert": false, - "button": false, - "carousel": false, - "collapse": false, - "dropdown": false, - "modal": false, - "tooltip": false, - "popover": false, - "scrollspy": false, - "tab": false, - "affix": false - }, - "styles": { - "mixins": true, - "normalize": true, - "print": true, - "glyphicons": true, - "scaffolding": true, - "type": true, - "code": true, - "grid": true, - "tables": true, - "forms": true, - "buttons": true, - "component-animations": true, - "dropdowns": true, - "button-groups": true, - "input-groups": true, - "navs": true, - "navbar": true, - "breadcrumbs": true, - "pagination": true, - "pager": true, - "labels": true, - "badges": true, - "jumbotron": true, - "thumbnails": true, - "alerts": true, - "progress-bars": true, - "media": true, - "list-group": true, - "panels": true, - "wells": true, - "responsive-embed": true, - "close": true, - "modals": true, - "tooltip": true, - "popovers": true, - "carousel": true, - "utilities": true, - "responsive-utilities": true - } -} diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index e9bb5c3..0000000 --- a/.dockerignore +++ /dev/null @@ -1,13 +0,0 @@ -.git/ -.idea/ -node_modules/ -package-lock.json -npm-debug.log -yarn-error.log -static/dist/ -*.iml -webpack-assets.json -webpack-stats.json -# api/**/*.nedb -*.report.html -coverage/ diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 9e00e99..0000000 --- a/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -[*] -indent_style = space -end_of_line = lf -indent_size = 2 -charset = utf-8 -trim_trailing_whitespace = true - -[*.md] -max_line_length = 0 -trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index c71f8e9..0000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -static/dist/ diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index b23126d..0000000 --- a/.eslintrc +++ /dev/null @@ -1,71 +0,0 @@ -{ - "extends": "airbnb", - "env": { - "browser": true, - "node": true, - "jest": true, - "es6": true - }, - "rules": { - "arrow-parens": ["error", "as-needed"], - "comma-dangle": ["error", "only-multiline"], - "consistent-return": "off", - "global-require": "off", - "indent": ["error", 2, {"SwitchCase": 1}], - "max-len": ["warn", 180], - "no-alert": "off", - "no-confusing-arrow": "off", - "no-console": "off", - "no-param-reassign": "off", - "no-underscore-dangle": "off", - "prefer-promise-reject-errors": "warn", - "prefer-template": "warn", - "react/forbid-prop-types": "warn", - "react/jsx-closing-tag-location": "off", - "react/jsx-filename-extension": "off", - "react/jsx-no-target-blank": "warn", - "react/jsx-one-expression-per-line": "off", - "react/no-multi-comp": ["error", {"ignoreStateless": true}], - "react/no-unescaped-entities": "off", - "react/prefer-stateless-function": "warn", - "jsx-a11y/label-has-for": ["error", {"allowChildren": true}], - "jsx-a11y/anchor-is-valid": [ - "error", - { - "components": ["Link"], - "specialLink": ["to"], - "aspects": ["noHref", "invalidHref", "preferButton"] - } - ], - "import/default": "off", - "import/extensions": "off", - "import/no-extraneous-dependencies": "off", - "import/no-named-as-default": "error", - "import/no-unresolved": "off" - }, - "plugins": [ - "react", - "import" - ], - "settings": { - "import/resolve": { - "moduleDirectory": [ - "node_modules", - "src", - "api" - ] - } - }, - "parser": "babel-eslint", - "parserOptions": { - "sourceType": "module" - }, - "globals": { - "__DEVELOPMENT__": true, - "__CLIENT__": true, - "__SERVER__": true, - "__DISABLE_SSR__": true, - "__DEVTOOLS__": true, - "webpackIsomorphicTools": true - } -} diff --git a/.gitignore b/.gitignore index 4e15a7a..46aa385 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,7 @@ -.idea/ -node_modules/ -package-lock.json -npm-debug.log -yarn-error.log -static/dist/ -static/packages/ -static/files/ -static/min/ -api/static/samples/ -api/static/reactsamples/ -api/static/apireference/ -api/static/changelog.md -*.iml -webpack-assets.json -webpack-stats.json -api/**/*.nedb -*.report.html -coverage/ +server/node_modules/ +server/api/**/*.nedb +server/static/javascript +server/static/react +client/node_modules/ .vscode -.vs + diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index def4337..0000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -dist: trusty - -language: node_js - -node_js: - - '10' - - '8' - -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-4.8 - - g++-4.8 - -sudo: required - -before_install: - - sudo apt-get -qq update - - curl -o- -L https://yarnpkg.com/install.sh | bash - - export PATH="$HOME/.yarn/bin:$PATH" - -install: - - yarn - -before_script: - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - - export NODE_ENV=development - -cache: - yarn: true - directories: - - node_modules - -script: - - yarn lint - - yarn test - -env: - - TRAVIS=travis CXX=g++-4.8 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index d3d04f7..0000000 --- a/Dockerfile +++ /dev/null @@ -1,51 +0,0 @@ -FROM mhart/alpine-node:14 - -# Install required dependencies (Alpine Linux packages) -RUN apk update && \ - apk add --no-cache \ - sudo \ - g++ \ - gcc \ - git \ - libev-dev \ - libevent-dev \ - libuv-dev \ - make \ - openssl-dev \ - perl \ - python - -# Add user and make it sudoer -ARG uid=1000 -ARG user=username -RUN set -x ; \ - addgroup -g $uid -S $user ; \ - adduser -u $uid -D -S -G $user $user \ - && exit 0 ; exit 1 -RUN echo $user' ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers - -# Install (global) Yarn packages/dependencies -RUN yarn global add node-gyp -RUN git clone --recursive https://github.com/sass/node-sass.git \ - && cd node-sass \ - && yarn \ - && node scripts/build -f - -# Make project directory with permissions -RUN mkdir /project - -# Switch to project directory -WORKDIR /project - -# Copy required stuff -COPY . . - -# Give owner rights to the current user -RUN chown -Rh $user:$user /project - -# Install (local) Yarn packages and build -RUN yarn - -USER $user - -CMD [ "yarn", "start" ] diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 60a5f89..0000000 --- a/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2013 - 2018 Basic Primitives Inc - -Licenses - -Non-commercial - Free -http://creativecommons.org/licenses/by-nc/3.0/ -Do you want to use Basic Primitives Diagram for a personal or non-profit project? -Then you can use Basic Primitives Diagram for free under the Creative Commons Attribution-NonCommercial 3.0 License. - -Commercial and government licenses -http://www.basicprimitives.com/pdf/license.pdf -The Basic Primitives Diagram Standard Terms and Conditions are appropriate if you run a commercial website or project, -a corporate intranet or a government agency project. diff --git a/README.md b/README.md index 34ff241..513e945 100644 --- a/README.md +++ b/README.md @@ -8,16 +8,35 @@ This project is created for validation of effortless integration of Basic Primit * [Basic Primitives for React Live Demos](https://basicprimitives.github.io/react/) - github live site * [Basic Primitives for JavaScript, jQUery and PDFkit Live Demos & Samples](https://basicprimitives.github.io/javascript/) - github live site -### Running Dev Server +### Basics + +* [Create React App](https://create-react-app.dev/) +* [Material-UI](https://material-ui.com/) +* [Hooks](https://reactjs.org/docs/hooks-intro.html) +* [Redux](https://redux.js.org/) +* [Reach Router](https://reach.tech/router/) +* [React Final Form](https://github.com/final-form/react-final-form) +* [React DnD](https://react-dnd.github.io/react-dnd/about) + +### Setup ```bash -yarn dev +git clone https://github.com/BasicPrimitives/react-demo.git +cd react-demo/server/src/static +git clone https://github.com/BasicPrimitives/javascript.git +git clone https://github.com/BasicPrimitives/react.git ``` -### Building and Running Production Server +### Running API server ```bash -yarn build +cd server +yarn start +``` +### Running client server + +```bash +cd client yarn start ``` @@ -26,4 +45,3 @@ yarn start Copyright (c) 2013 - 2020 Basic Primitives Inc * [Non-commercial - Free](http://creativecommons.org/licenses/by-nc/3.0/) * [Commercial and government licenses](http://www.basicprimitives.com/license.pdf) - diff --git a/api/hooks/index.js b/api/hooks/index.js deleted file mode 100644 index 43123f6..0000000 --- a/api/hooks/index.js +++ /dev/null @@ -1 +0,0 @@ -export validateHook from './validateHook'; diff --git a/api/services/demofamilycharts/data/famdataLoopsTest.js b/api/services/demofamilycharts/data/famdataLoopsTest.js deleted file mode 100644 index f65893e..0000000 --- a/api/services/demofamilycharts/data/famdataLoopsTest.js +++ /dev/null @@ -1,65 +0,0 @@ -const primitives = require('basicprimitives'); - -export default { - cursorItem: 2, - annotations: [ - // { - // annotationType: primitives.common.AnnotationType.Connector, - // connectorPlacementType: primitives.common.ConnectorPlacementType.Offbeat, - // labelPlacementType: primitives.common.ConnectorLabelPlacementType.Between, - // zOrderType: primitives.common.ZOrderType.Foreground, - // fromItem: 3, - // toItem: 4, - // label: {color:"red", badge: "1", title: ""}, - // labelSize: { width: 30, height: 30 }, //new primitives.common.Size(80, 30) - // connectorShapeType: primitives.common.ConnectorShapeType.OneWay, - // color: primitives.common.Colors.Red, - // offset: 5, - // lineWidth: 2, - // lineType: primitives.common.LineType.Dashed - // }, - { - annotationType: primitives.common.AnnotationType.Label, - fromItem: 2, - toItems: [1], - title: '2->1' - }, - { - annotationType: primitives.common.AnnotationType.Label, - fromItem: 1, - toItems: [2], - title: '1->2' - } - // { annotationType: primitives.common.AnnotationType.Label, fromItem: 1, toItems: [6], title: "1->6" }, - // { annotationType: primitives.common.AnnotationType.Label, fromItem: 1, toItems: [2, 6], title: "1->2,6" }, - - // { annotationType: primitives.common.AnnotationType.Label, fromItem: 5, toItems: [2], title: "5->2" }, - // { annotationType: primitives.common.AnnotationType.Label, fromItem: 2, toItems: [1,5], title: "2->1,5" }, - // { annotationType: primitives.common.AnnotationType.Label, fromItem: 7, toItems: [8], title: "7->8" }, - // { annotationType: primitives.common.AnnotationType.Label, fromItem: 8, toItems: [7], title: "8->7" } - ], - items: [ - { - id: 1, - parents: [2], - title: '1', - label: '1', - description: '1', - image: '/photos/j.png', - itemTitleColor: '#ff0000' - }, - { - id: 2, - parents: [1], - title: '2', - label: '2', - description: '2', - image: '/photos/b.png', - itemTitleColor: '#4b0082' - } - // { id: 5, parents: [7], title: "5", label: "5", description: "5", image: "/photos/j.png", itemTitleColor: "#ff0000" }, - // { id: 6, parents: [], title: "6", label: "6", description: "6", image: "/photos/b.png", itemTitleColor: "#4b0082" }, - // { id: 7, parents: [8], title: "7", label: "7", description: "7", image: "/photos/b.png", itemTitleColor: "#4b0082" }, - // { id: 8, title: "8", label: "8", description: "8", image: "/photos/j.png", itemTitleColor: "#ff0000" } - ] -}; diff --git a/api/services/howtouse/index.js b/api/services/howtouse/index.js deleted file mode 100644 index b23a775..0000000 --- a/api/services/howtouse/index.js +++ /dev/null @@ -1,40 +0,0 @@ -import _ from 'lodash'; -import express from 'express'; -import path from 'path'; -import cache from 'memory-cache'; -import uuid from 'uuid'; -import { loadMarkdown, getSampleFileContent } from './markdown'; - -export default function customService(app) { - app.use(express.static(path.join(__dirname, '..', '..', 'static'))); - - app.use('/load-markdown', async (req, res, next) => { - try { - var markdown = await loadMarkdown(req.query.name); - return res.json(markdown); - } catch (e) { - next(e) - } - }); - - app.use('/get-sample', async (req, res) => { - const fileContent = await getSampleFileContent(req.query.name); - return res.send(fileContent); - }); - - app.use('/get-saved-sample', (req, res) => { - let fileContent = cache.get(req.query.name); - if (fileContent == null) { - fileContent = '

Sample expired in cache. Click Try button again.

'; - } - return res.send(fileContent); - }); - - app.use('/save-code', (req, res) => { - const id = uuid.v1(); - cache.put(id, req.body.content, 60000); - return res.json({ - url: `/api/get-saved-sample?name=${id}` - }); - }); -} diff --git a/api/services/index.js b/api/services/index.js deleted file mode 100644 index 5ad3738..0000000 --- a/api/services/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import authentication from './authentication'; -import demoorganizationalcharts from './demoorganizationalcharts'; -import demofamilycharts from './demofamilycharts'; -import howtouse from './howtouse'; -import users from './users'; - -export default function services(app) { - app.configure(authentication); - app.configure(demoorganizationalcharts); - app.configure(demofamilycharts); - app.configure(users); - app.configure(howtouse); -} diff --git a/api/static/changelog.md b/api/static/changelog.md deleted file mode 100644 index 608e735..0000000 --- a/api/static/changelog.md +++ /dev/null @@ -1,396 +0,0 @@ -#### Version 5.5.0 -* Added IntelliSense API annotations to code -* Added API annotations conversion into markdown -#### Version 5.4.15 -* Fixed minimised items highlight alignment in React -#### Version 5.4.14 -* Fixed objects comparison for React JSX -#### Version 5.4.12 -* Removed CSS file from React component -#### Version 5.4.0 -* Added OrgDiagram & FamDiagram React components and samples. -* Extracted platform specific functionality out of core. -* Added onButtonsRender event to TemplateConfig. -* Added support of cycles in objects defenitions of labels. -* Fixed CSS scale bugs. -* Removed jQuery UI Widget Organizational Chart Editor. -* Removed PHP samples. -#### Version 5.3.1 -* Fixed performance issue in react demo. -#### Version 5.3.0 -* Added `relativeItem`, `placementType` and `position` properties to `primitives.famdiagram.ItemConfig`. Properties define user preferences for items order in Family Diagram. See "Family Members Order" data set in Family Chart & Annotations Demo. -#### Version 5.2.4 -* Merged fix for straight connector annotations labels. -#### Version 5.2.2 -* Fixed `update` method. In case when only nodes content properties changed like title, description, context, etc, chart will render only them. See Cursor item properties editor panel in Organizational Chart Editor Demo in React Demos. -* Fixed elbows of connection lines. -#### Version 5.2.1 -* Fixed performance bug. JSONML Templates triggered layout on every update. See Dependencies Chart Demo in React Demos. -#### Version 5.2.0 -* Added optional center on cursor parameter to update method. See React Demos for usage. -#### Version 5.1.1 -* Fixed document undefined bug in NodeJS environment. -* Published React Demo & Tutorial to Github -#### Version 5.1.0 - -**Warning**: Extracted jQuery UI Widgets into separate `file primitives.jquery.latest.js` ! -* Added npm package header and published library to [www.npmjs.com](https://www.npmjs.com/package/basicprimitives) -* Added pagination for nodes in page fit mode set to None. -#### Version 5.0.4 -* Fixed cursor neighbours selection over template inactive items. -#### Version 5.0.3 -* Fixed call out placement in auto size mode when control is placed in document layout and scrolled. -#### Version 5.0.2 -* Fixed highlight path annotation tracing when famDiagram option hiding direct connections to grandparents is enabled. -* Fixed false layout invalidation on highlight changed event -#### Version 5.0.1 -* Fixed fit to page mode in primitives.famdigram.Control. -#### Version 5.0.0 -**Warning**: Non-backward compatible API changes! -* Removed dependency on jQuery. -* Added pure JavaScript Controls `primitives.orgdiagram.Control` and `primitives.famdiagram.Control` -* Added JSON ML support for HTML templates -* Removed support of VML and IE8 -* Reworked Drag & Scroll to use native JavaScript draggable object -* Fixed highlight call-out placement in CSS Zoom scale mode. -* Fixed selection check-boxes to ignore mouse double click event -* Fixed controls rendering inside divs having computed width and height - -*Version 4.3.0 archived. See primitives430.zip in downloads. Archive contains demos, "how to use" examples & reference. It is available only for registered users.* - -#### Version 4.3.0 -* Added option groupTitlePlacementType to primitives.famdiagram.Config and primitives.orgdiagram.Config. Property swaps positions of group title and buttons. -#### Version 4.2.3 -* Reorganized samples. -#### Version 4.2.2 -* Fixed selection/pin checkbox label click in IE -#### Version 4.2.1 -* Updated demos and samples to use jQuery 3.3.1 & jQuery UI 1.12.1 libraries. -* Fixed bug in jQuery UI Layout library used in demos. -#### Version 4.2.0 -* Added option enableMatrixLayout, minimumMatrixSize and maximumColumnsInMatrix to primitives.famdiagram.Config. See Family Chart & Annotations demo for usage. -* Reworked background annotations merge. Items backgrounds don't grow beyond padding area anymore. -* Reworked keyboard navigation. So it respects nodes crossing multiple layers of nodes. -* Reworked mouse highlight gravity. Nodes are no longer highlighted when cursor is out of nodes bounds. -* Removed PhantomJS support and page split rendering mode. Use PDFkit plugin for PDF generation and printing. -* Reworked labels conflicts resolution in labels visibility auto mode. -* Fixed inactive items usage in Family diagram. -* Improved layout update and rendering triggered by cursor change event. -#### Version 4.1.0 -* Added option hideGrandParentsConnectors for primitives.famdiagram.Config. See patents demo for usage. -#### Version 4.0.0 -* Reworked horizontal alignment algorithm for Family chart -#### Version 3.7.10 -* Fixed option showCallout for primitives.famdiagram.ItemConfig and primitives.orgdiagram.ItemConfig -#### Version 3.7.9 -* Added option calloutMaximumVisibility to primitives.famdiagram.Config and primitives.orgdiagram.Config -#### Version 3.7.8 -* Fixed panning in IE10 in Windows 7 -#### Version 3.7.7 -* Added group title font size option -#### Version 3.7.6 -* Fixed refresh dependency on items order in items collection -#### Version 3.7.5 -* Added extra horizontal arrows over connection lines with following options showExtraArrows and extraArrowsMinimumSpace to primitives.famdiagram.Config and primitives.orgdiagram.Config. -#### Version 3.7.4 -* Added options highlightGravityRadius and calloutPlacementOffset to primitives.famdiagram.Config and primitives.orgdiagram.Config -* Improved call-out placement, so it is placed across connectors and does not block neighbors of highlighted item anymore. -#### Version 3.7.3 -* Named layers with CSS classes -#### Version 3.7.2 -* Added alignByLevels options to primitives.famdiagram.Config, see Family Demo -#### Version 3.7.1 -* Fixed highlighted item callout placement -* Fixed bugs in famDiagram layout algorithms -#### Version 3.7.0 -* Improved highlight connection path annotations rendering time -* Added multiple rendering styles support for highlight connection path annotation -* Improved famDiagram horizontal alignment -#### Version 3.6.6 -* Fixed straight line annotation rendering -#### Version 3.6.5 -* Fixed organizational chart horizontal alignment -#### Version 3.6.4 -* Fixed connection lines of children having vertical layout -#### Version 3.6.3 -* Eliminated recursive calls. -#### Version 3.6.2 -* Fixed exception on null image reference in default PDF item template. -#### Version 3.6.1 -* Fixed user templates support in PDF plugins. See User Item template sample in Client Side PDF Generation Demo. -#### Version 3.6.0 -* Added PDF generation support with PDFkit library for Node and in the browser. See Client Side PDF Generation Demo. -#### Version 3.5.0 -* Added resolution of straight collinear connectors overlapping. See "Highlight Movement & Annotations" demo. -* Optimized connector annotations rendering. -* Improved cross diagram connection lines stacking. -* Disabled refresh on event handlers binding. -#### Version 3.4.1 -* Fixed layout update on widget placeholder resize and forced update in refresh mode. -#### Version 3.4.0 -* Added primitives.common.ConnectorShapeType.BothWay option to enumeration. See Connector and Family Chart Demos for Connector Annotation options. -#### Version 3.3.1 -* Fixed options updates within onCursorChanging and onHighlightChanging event handlers. -#### Version 3.3.0 -* Added primitives.common.ConnectorPlacementType enumerations, having following options: Offbeat & Straight. -* Added connectorPlacementType option to primitives.orgdiagram.Config & primitives.famdiagram.Config -#### Version 3.2.0 -* Added primitives.common.NavigationMode.HighlightOnly option to navigationMode option. -* Fixed item position in mouse events. -* Changed order of event handler invocation and cursor/highlight option assignment. -#### Version 3.1.2 -* Fixed PositonHighlight update mode -#### Version 3.1.1 -* Fixed enablePanning option. -#### Version 3.1.0 -* Added enumeration `primitives.common.NavigationMode` and `navigationMode` option disabling control's highlight and cursor interactivity when needed. See Interactivity options for Large Hierarchy & Family Demos. -#### Version 3.0.0 -* Optimized data processing and rendering. See Controls Processing Diagrams. -* Fixed CSS scale. See primitives.famdiagram.Config.scale and primitives.orgdiagram.Config.scale options -* Added `neighboursSelectionMode` option to `primitives.famdiagram.Config`. See `primitives.common.NeighboursSelectionMode` enumeration for ParentsAndChildren & ParentsChildrenSiblingsAndSpouses options of cursor related nodes selection. -*Version 2.1.10 archived. See primitives2110.zip in downloads. Archive contains demos, "how to use" examples & reference. It is available only for registered users.* - -#### Version 2.1.10 -* Fixed label annotations placement on loop connections in famDiagram. -#### Version 2.1.9 -* Fixed label annotations placement on loop connections in famDiagram. -* Changed arrow size of 2 & 3 pixel wide lines. -#### Version 2.1.8 -* Added PageFitMode.AutoSize, autoSizeMaximum and autoSizeMinimum options to Configs of orgDiagram & famDiagram widgets. -* Changed PageFitMode.PrintPreview mode to auto size widget to show all nodes of diagram. -#### Version 2.1.7 -* Fixed multiple spouses connection lines. -#### Version 2.1.6 -* Added minimizedItemShapeType to Config, ItemConfig & TemplateConfig of orgDigram & famDiagram widgets. -* Added minimizedItemLineWidth, minimizedItemBorderColor, minimizedItemLineType, minimizedItemFillColor and minimizedItemOpacity to TemplateConfig of orgDigram & famDiagram widgets. -* Fixed spouses connection lines. -* Fixed spouses navigation. -* Fixed annotation labels navigation. -#### Version 2.1.5 -* Fixed exception on orphan invisible item. -* Enforced side alignment for SubAdviser and SubAssistant item types in orgDiagram. -#### Version 2.1.4 -* Fixed keyboard navigation with arrow keys. -#### Version 2.1.3 -* Fixed horizontal connector lines for vertically aligned items to the top or bottom. -#### Version 2.1.2 -* Improved family diagram layout. -#### Version 2.1.1 -* Fixed loops visualization in family diagram. -#### Version 2.1.0 -* Added support of loops in family diagram. The item defined first in users items collection stays at the top of diagram. -* Added nodes grouping to children/parents. See groupByType option of primitives.famdiagram.Config -* Fixed disconnected family fragments alignment to the top. -#### Version 2.0.24 -* Added onItemDblClick event to famDiagram and orgDiagram widget configs. -#### Version 2.0.23 -* Added elbowDotSize option to famDiagram and orgDiagram widget configs. -#### Version 2.0.22 -* Added BackgroundAnnotationConfig to famDiagram and orgDiagram widgets. See Partners & Annotations Demo. -* Added includeChildren option to primitives.orgdiagram.BackgroundAnnotationConfig selecting all descendants of annotated items. -#### Version 2.0.21 -* Added arrowsDirection option to primitives.orgdiagram.Config, primitives.famdiagram. Config. See "Arrows Direction" options in "Organizational Chart Navigation" demo. -#### Version 2.0.20 -* Fixed connectors rendering. -* Fixed HighlightPathAnnotationConfig tracing. See financial ownership diagram demo. -#### Version 2.0.19 -* Added spouses option to primitives.famdiagram.ItemConfig. See first family chart use case. -* Fixed group title alignment. -#### Version 2.0.18 -* Added LabelAnotationConfig option class and defaulLabelAnnotationTemplate to primitives.famdiagram.Config. See financial ownership diagram demo. -* Fixed context buttons usage in templates. -#### Version 2.0.17 -* Added isActive option to primitives.orgdiagram.ItemConfig, primitives.famdiagram.ItemConfig, primitives.orgdiagram.TemplateConfig and primitives.famdiagram.TemplateConfig. See inactive items example. -#### Version 2.0.16 -* Fixed minor data validation bug. Ignores orphan parent references. -#### Version 2.0.15 -* Added PrintPreview option to primitives.common.PageFitMode and printPreviewPageSize option to primitives.orgdiagram.Config and primitives.famdiagram.Config. See print preview example. -#### Version 2.0.14 -* Added highlight path annotation support to famDiagram. See primitives.famdiagram.HighlightPathAnnotationConfig usage in PERT Chart & Critical Path visualization example. -#### Version 2.0.13 -* Disabled labels for regular items. Option primitives.orgdiagram.showLabels is only valid for minimized items now. For regular items see labels in item template example. -#### Version 2.0.12 -* Added buttons option to primitives.orgdiagram.TemplateConfig and primitives.famdiagram.TemplateConfig. -* Fixed mouse events arguments. -#### Version 2.0.11 -* Hid connectors for skipped/invisible root items. -#### Version 2.0.10 -* Added elbowType option of type primitives.common.ElboyType to style squared connector lines. -#### Version 2.0.9 -* Improved famDiagram layout. Added bundles for children and parents. Cross chart connectors length reduced by 20%. -#### Version 2.0.8 -* Fixed primitives.common.luminosity. -* Removed overflow hidden from item style. -#### Version 2.0.7 -* Added keyboard navigation with arrow keys and "Enter". -#### Version 2.0.6 -* Added partners placement to Left/Right in famDigram Widget depending on cross hierarchy connections. -#### Version 2.0.5 -* Added bp-highlight-dot-frame class to css. -* Fixed Bootstrap compatibility bug related to box-styling. -* Added labelPlacementType to Connector Annotation Config and to Connector helper Widget Config. See Family Chart & Connector Widget demos. -* Added minimizedItemCornerRadius to TemplateConfig. See Organizational Chart Navigation demo. -#### Version 2.0.4 -* Improved famDiagram layout. Cross chart connectors length reduced by 5%. -#### Version 2.0.3 -* Improved famDiagram layout. -#### Version 2.0.2 -* Improved famDiagram layout. -#### Version 2.0.1 -* Added support of orphan families and groups of families to famDigram Widget. -#### Version 2.0.0 -* Added famDiagram Widget - Multi-parent hierarchical chart. It has similar API to orgDiagram widget except it supports multiple parents for items instead of one. Chart does not support loops in hierarchy and does not check for them. It has following set of configuration classes in primitives.famdiagram: Config, ItemConfig, ButtonConfig, TemplateConfig, PaletteItemConfig, ConnectorAnnotationConfig & ShapeAnnotationConfig. -* Fixed dashed line style for Canvas in IE11 -* Fixed partners alignment in organizational chart. -#### Version 1.1.1 -* Added extra constructors to HighlightPathAnnotationConfig, ShapeAnnotationConfig and ConnectorAnnotationConfig. -#### Version 1.1.0 -**Warning**: **Non-backward compatible API changes!** -* Added Shape & Connector helper widgets: bpShape & bpConnector. -* Added Shape, Connector & Highlight path annotations to orgDiagram. Added ConnectorAnnotationConfig, ShapeAnnotationConfig & HighlightPathAnnotationConfig classes to orgDiagram. Added annotations collection property to orgdiagram.Config. -* Added connection lines styling options: linesType, highlightLinesColor, highlightLinesWidth, highlightLinesType to orgdiagram.Config. -* Changed API from hierarchical structure defined by rootItem to flat list of ItemConfig objects defined in items collection property. Added id & parent properties to ItemConfig. Changed type of cursorItem, highlightItem & selectedItems properties from object references to ItemConfig id-s. Now, in order to define root item, root item in items collection should have its parent property set to null. Chart supports multiple root items. Chart does not search for orphans and ignores looped items. It is Applications responsibility to provide consistent collection of items. -#### Version 1.0.39 -* Fixed SVG blurred lines in IE for charts layouted without absolute positioning. -* Added tooltip option to ButtonConfig. -#### Version 1.0.38 -* Added new ItemType options: GeneralPartner & LimitedPartner & AdviserPartner -#### Version 1.0.37 -* Added enablePanning option to Config. -* ASP.NET 3.5: Added ShowButtons & Buttons properties to control. -* ASP.NET 3.5: Added ShowButtons property to Item class. -#### Version 1.0.36 -* Added showCallout to Config & ItemConfig. -* Added defaultCalloutTemplateName to Config. -* Added calloutTemplateName to ItemConfig. -#### Version 1.0.35 -* Fixed invisible cursor item bug. -#### Version 1.0.34 -* Added showLabels, labelSize, labelOffset, labelOrientation, labelPlacement, labelFontSize, labelFontFamily, labelColor, labelFontWeight, labelFontStyle options to Config. -* Added label, showLabel, labelSize, labelOrientation, labelPlacement to ItemConfig. -* Fixed graphics & non-graphics elements alignment -* Improved curved connectors -#### Version 1.0.33 -* Enabled native scroll for Mobile Safari. -* Made selection checkbox label clickable. -#### Version 1.0.32 -* Added cousinsIntervalMultiplier option to Config options class. -#### Version 1.0.31 -* Added CSS3 scale transform on zoom gesture for Mobile Safari. Added minimumScale & maximumScale options to primitives.orgdiagram.Config. -* Enabled annotation for highlight items outside of widget boundaries. -#### Version 1.0.30 -* Added: Mouse panning/scrolling for desktop browsers. -* Changed siblings visibility for cursor item. -* ASP.NET 3.5: Updated to jQuery 1.9.1 -* Joomla 1.5 & 2.5: Updated to jQuery 1.9.1 -#### Version 1.0.29 -* Added new ItemType options: SubAdviser & SubAssistant. Deprecated Invisible item type. -* Added isVisible option to ItemConfig. -* Joomla 1.5 & 2.5: Added Invisible template and ported new item types. -* ASP.NET 3.5 Moved templates customization from C# code to JavaScript. -* ASP.NET 3.5 Removed dependency on jquery.json-2.3.min.js and added json3.min.js instead. -* ASP.NET 3.5 Added HorizontalAlignmentType, ChildrenPlacementType, OrientationType to control options. -* ASP.NET 3.5 Added SubAssistant & SubAdviser to available item types. -* ASP.NET 3.5 Added IsVisible & ChildrenPlacementType options to Item class. - -#### Version 1.0.28 -* Disabled highlight for touch devices. -* Fixed rotated text in pure IE8. IE9's IE8 compatibility mode is not compatible with IE8. -* Joomla 2.5: plg_bporgdiagram plug-in added, {bporgdiagarm #} where # is chart id in management panel. Provides optimized support of multiple charts in one article. -* Joomla 1.5 & 2.5. Added chart orientationType option: Left, Right, Top, Bottom -#### Version 1.0.27 -* Fixed performance issues. -#### Version 1.0.26 -* Fixed visibility of hierarchy of invisible items. -#### Version 1.0.25 -* Added chart orientationType option: Left, Right, Top, Bottom -#### Version 1.0.24 -* Added ALT attribute to image of default template. -* Fixed blurred dots in VML mode. -#### Version 1.0.23 -* Fixed performance issues. -#### Version 1.0.22 -* Fixed selection check box functionality for diagram inside jQuery UI Dialog. -#### Version 1.0.21 -* Added defaultTemplateName to Config options class. -* Added templateName to RenderEventArgs parameter class. -* Joomla 1.5, 2.5: com_bporgdiagram added, organizational charts management component wrapping BP jQuery orgEditor widget. -* Joomla 2.5: mod_bp_orgdiagram_editor added, places organizational charts created in management panel in module position, it is compatible with {module [#]} plugin. -* Joomla 1.5, 2.5: com_bpwidgets added, rendering widgets component distributed under its own license. -* Joomla 1.5: plg_bporgdiagram plug-in added, {bporgdiagarm #} where # is chart id in management panel. Provides optimized support of multiple charts in one article. -#### Version 1.0.20 -* Fixed connectors drawing for items having assistants, but no children. -* Fixed group title update for different heights. -#### Version 1.0.19 -* Added childrenPlacementType to Config & ItemConfig options classes. -* Added horizontalAlignment in Config. -#### Version 1.0.18 -* Fixed layout performance bug. -#### Version 1.0.17 -* Added primitives.min.js. -* Added primitives.latest.css -* Fixed large canvas issue. When chart width is over 6000px it uses pure HTML graphics now. -* Fixed user jQuery UI buttons initialization. -#### Version 1.0.16 -* Fixed Bootstrap compatibility bugs. http://twitter.github.com/bootstrap/ Added Bootstrap demo for registered users. -* Added onMouseClick event to Config. -#### Version 1.0.15 -* Fixed narrow tree alignment to center instead of stretching it to available view port width. -* Fixed Assistants & Advisers children placement. Parent's regular children are shifted down in order to provide space for them inside of parent's hierarchy. -* Added maximumColumnsInMatrix option to org chart Config. -* ASP.NET 3.5 Fixed IE8 related bugs. -* ASP.NET 3.5 Fixed JSON serialization in IE6-IE7. Added dependency on jquery.json-2.3.min.js. http://code.google.com/p/jquery-json/ -* ASP.NET 3.5 Added LeavesPlacementType & MaximumColumnsInMatrix properties to Control class. -* ASP.NET 3.5 Added GroupTitle, GroupTitleColor, ItemType, AdviserPlacementType properties to Item class. -#### Version 1.0.14 -* Added leavesPlacementType option to Config. Vertical, Horizontal & Matrix layouts. -* Added adviserPlacementType option to ItemConfig. Left, Right placement. -* Added Adviser and Assistant item types to ItemType. -#### Version 1.0.13 -* Added explicit hasButtons option to orgDiagram Config. -* Added onSelectionChanging Event to orgDiagram Config. -* Added groupTitle, groupTitleColor, hasSelectorCheckbox and hasButtons to orgDiagram ItemConfig. -* Added isCursor & isSelected options to RenderEventArgs indicating current state of rendered item. -* ASP.NET 3.5 Custom control: Fixed Item's ShowCheckBox property. -#### Version 1.0.12 -* Added call out shape to annotation. -* Joomla 152-256 menu module: Added verticalAlignment & connectorType properties. -* ASP.NET 3.5 Custom control: Added verticalAlignment & connectorType properties. -#### Version 1.0.11 -* Fixed annotation placement. -#### Version 1.0.10 -* Improved tree balancing. -#### Version 1.0.9 -* Added bpText widget. Displays vertical text using VML or CSS3. -* Added bpCallout widget. Draws call-out geometry in VML, SVG or Canvas formats. -* Added narrow hierarchy auto stretching up to available view port width. -* Added items verticalAlignment property. It defines relative items alignment within one row: Top, Middle, Bottom. It only affects rows containing items of different heights. -* Added connectorType options: Squared, Angular and Curved connector lines style for dots. -#### Version 1.0.8 -* Fixed widget placement inside divs having non-absolute position. -* Joomla 152-256 menu module: Suppressed layout update before sending server post back. -* ASP.NET 3.5 Custom control: Fixed custom control placement inside panels having non-absolute position. -#### Version 1.0.7 -* Added parentItem to EventArgs class. (See use case: "Adding new items at run time") -#### Version 1.0.6 -* Added itemTitleFirstFontColor & itemTitleSecondFontColor options to orgDiagram Config class. -* Added common functions: highestContrast, luminosity, beforeOpacity, getColorHexValue, getRed, getBlue, getGreen. -* Fixed itemTitleColor option. -* ASP.NET custom control: Added TitleColor property to Item class. -* Removed BOM marks from file. -#### Version 1.0.5 -* Added onHighlightChanging & onCursorChanging events to orgDiagram Config class. -* Named noname event arguments to named classes: primitives.orgdiagram.EventArgs & primitives.common.RenderEventArgs. -* Published ASP.NET 3.5 custom control BPOrgDiagram & Demo. -#### Version 1.0.4 -* Fixed bugs blocking jQuery 1.6.2 compatibility. -#### Version 1.0.3 -* Fixed bugs in page auto layout. -#### Version 1.0.2 -* Joomla 1.5.2 and 2.5.6 compliant menu modules added. -* Added minimalVisibility option to Config options class. -* Fixed page sizing in PageFitMode.None mode. -#### Version 1.0.1 -* Fixed mootools compatibility bug. -#### Version 1.0.0 -* Initial check-in. \ No newline at end of file diff --git a/api/static/introduction.md b/api/static/introduction.md deleted file mode 100644 index 4a912b7..0000000 --- a/api/static/introduction.md +++ /dev/null @@ -1,98 +0,0 @@ -## Supported Diagrams: -* Organizational Chart -* Family tree & Inheritance Chart -* Multi-parent hierarchical chart -* Dependencies Visualization -* PERT - Program Evaluation and Review Technique Diagram -* DAG - Directed Acyclic Graph visualization -* Business Ownership Diagram - -## Products: -### Basic Primitives Diagrams for [React:](https://reactjs.org/) -* [create-react-app](https://github.com/facebook/create-react-app#readme) compatible -* [react-dnd](http://react-dnd.github.io/react-dnd/about) compatible -* [JSX](https://reactjs.org/docs/introducing-jsx.html) templates -* 100% [Virtual DOM](https://reactjs.org/docs/faq-internals.html) rendering cycle, i.e. no direct DOM rendering - -### Basic Primitives Diagrams for JavaScript: -* 100% client side JavaScript layout and rendering. -* No dependencies on 3rd party libraries. -* Works in all major modern browsers: Internet Explorer, Edge, Chrome, Firefox, Safari and mobile browsers. -* Rendering in [SVG](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) and [Canvas](https://en.wikipedia.org/wiki/Canvas_element) modes depending on user options. - -### Basic Primitives [PDFkit plugin:](http://pdfkit.org/) -* Browser based or NodeJS based PDF rendering - -## Open Source: -One of the key features of our product is that under any of the licenses, free or not, you are allowed to download the source code and make your own edits to it. This allows for personal modifications and security for your product. Additionally the library's source code can be validated and easily tested through the use of our samples, demos and unit tests. -The samples, demos and unit tests can be found online and are also provided within the product packages. - -## Product for visual data analysis of diagrams: -Business intelligence systems and applications are designed for two major areas: reporting and analytics. Reporting based applications display the original data as is, so reported data should be 100% complete, no data should have any discrepancies or be omitted in the form of improperly rounded values or excessive abbreviations. On the other side, there are applications that are designed for data analytics and are focused on the most valuable and user relevant data. Going as far as removing data that is deemed irrelevant by the end user depending on what they are interested in analyzing. Our components provide various API options to the developers, so they can configurate our diagrams and use them for both of the mentioned above scenarios. - -#### Auto layout and fititing the diagram into a single screen space: -When using a graphics editor to manually draw your diagrams, it is common place to have large gaps between the nodes. This can make the diagram/chart unreadable, hard to edit and navigate. On top of that, on a large scale the diagram could have screen size intervals between items. Admittedly the computer UI does allow the user to scale and fit the diagram in order to visualize it on a single screen. But in that case, the items become small and unreadable as there is no scaling priority and the items are just too small to be readable [Here is PDF example demonstrating the problem.](images/sparse_data_problem.pdf) The primary goal of our approach to organizational charts and other diagrams visualization is to resolve these issues. Our product component specializes in displaying large diagrams in a single screen or nearly removing all scrolling while at the same time not affecting the diagram's usability. This is only possible when the diagramming component is in control of the auto layout for the nodes. - -* Minimizing nodes into markers and labels: Our component provides a special mode that renders the diagram nodes in the form of markers. This is a highly scalable form that is capable of rendering large numbers of nodes while not affecting the rendering performance. With this, huge diagrams can be fit into avaialable screen space. -* The user has focused navigation as they go node by node. The key nodes are kept full size as the less relevant nodes in the user view are minimized. The user also has the option to customize which nodes are relevant via selection, annotations and navigation options. By default the chart displays the cursor selected item and its neighbors in full size and minimizes all other less relevant nodes. By clicking on neighboring nodes the user will move the focus of interest to the newly selected part of the diagram. Local zoom around the cursor item works for all available diagrams. -* Pinning of items in diagram. All selected/checked items are always displayed full size. All other items stay minimized. This allows to pin/select items in different branches of the diagram and show them side by side within available screen space for comparison. -* Diagram autolayout consistency. Our auto layout provides visual consistency across all diagramming documents. The user can customize the visual appearance for any diagrams that they wish manually. All users have various skills and preferences, so auto layout provides consistent default diagram viewing throughout the organization. -* Always up to date. Your application's diagrams will not be effected by changes in the component's layout algorithms and application data. Your visualizations will always be up to date and in sync with your data. - -#### Stable rules based auto layout of multi parent hierarchies -The core problem of dependency diagrams layout is the endless number of permutations. As a result every time we make any changes to the diagram's relations, we get a new "optimal" layout. However that "optimal" layout can be so different from the previous "optimal" layout that the end user needs to relearn the diagram again and again. This becomes worse the more nodes you have. Analysis takes so much time, that it makes the automatic diagram layout useless. So it is very important that diagram does not change much between user edits. -So in order to overcome that problem we added support of user rules that the auto layout algorithm follows. The problem is that "hard" rules are equivalent to manual layout if we start to define the placement of every node manually. Which destroys the whole point of even having auto layout for the nodes. So we introduced "soft" rules, which our control follows as long as they don't contradict to the purpose. Our control does ignore them when they are not applicable. -* Moderate layout changes between edits. Multi parent hierarchy diagram does not change much when we add or remove nodes. Developer is encouraged to add order of nodes relative to each other, but that order does not enforce layout, control still has flexibility to choose optimal layout itself. - -#### Auto sorting the diagram nodes into levels -It is not obvious, but by default we distribute all nodes in the diagram into distinct levels. This gives the end user a clear indication about a node's relations. For any given node, all nodes that are below it in the diagram, are either it's dependents or minors. On the contrary any nodes found above the node are either its parents or superiors. This is a simple and straightforward visual sorting method that helps when analyzing and viewing large diagrams. - -#### Auto alignment of nodes relative to each other -Our auto layout that is responsible for our diagrams, focuses a lot of effort on the alignment of the nodes when visualizing them. This is very important because when the end user is analyzing the diagram it is easier to identify their dependencies by looking at their alignment and positions rather then tracing lines between nodes. For example if a set of nodes are organized into a pyramid formation, the pyramid shape itself gives a clear indication about the mutual relation or the group structure of the nodes. In such an ideal case,minimal to no connection lines should be needed. This is the ultimate goal when visualizing diagrams, that in an ideal case every node should be placed in such way that no connection lines are neccessary in order to show the node's relations within the diagram. - -#### Customizable Placement of children -By default all direct children that belong to a parent node are of the same rank and status between each other and due to that, are always aligned below the parent and are organized in the same way. However for special cases were the end user wishes to have a child that is seperate from the rest of it's siblings, we provide custom child types that the end user can use to place diffrent ranking nodes anywhere around the parent node. These placement options give a lot of space for the creation of roles such as an Assitant, Adviser, various Partners and co-heads that may be in the organization. Additionally, by default a node's children are always placed in a horizontal line below the parent node. On a large scale this may result in the end user having to scroll screens in order to view all of the nodes. To compensate for this, we provide the option of placing all of the children of a parent node in a sqaure/matrix formation. This will reduce sideways screen scrolling by compacting the child nodes into a much smaller area on the screen. - -#### Automatic transformation of connection lines between nodes -A diagram can have multiple parent and child nodes all be part of one large relationship with each other. This type of relationship results in an excessive number of connections between the nodes and creates a visual clutter in the diagram. In extreme cases this makes the diagram unreadable. - -The following is an example of a complete bipartite graph. As visable every parent node is connected with every child node. - -![Complete Bipartite Graph](images/cbp88.png) - -This is definitely an extreme example of family relations, but it could happen and the component automatically groups connectors into bundles so it produces the following optimized set of relations: - -![Complete Bipartite Graph Bundled](images/cbp88bundled.png) - -This connector bundling method is actively used throughout the product in order to increase the readability of the diagrams. - -#### Automatic elimination of redundant relations between nodes -Another typical problem with visualizing connections is the possible excessive amount of connections that can take place between multiple gradnchild and grandparent nodes. Usually when we draw family diagrams we are more interested to see the overall order of dependencies over the more direct and specific node relations. In a family tree we know that all the nodes are directly linked to one another via their immediate parent. Because of this, we can remove the direct connections between non-immediate parents, reducing the amount of visual clutter on the screen and still get the same order of dependencies. By doing this the diagram becomes a lot easier to analyze, view and navigate. - -![Excessive amount of connections](images/cbp88everyparent.png) - -### Annotating diagram nodes -Every time we make changes to our diagrams, we need to visualize the performed modifications otherwise it is hard to trace the changes before and after the modification occured. So in order to visualize the diagram's transition from one state to another, the control provides various annotations to the end user. Annotations are API elements that are attached to the diagram nodes. We draw our annotations either in front of the nodes or in the background. The annotations don't affect the nodes placement in any way. As a result the control redraws them instantaneously without rerendering or recalculating the actual diagram layout. The general logic of annotations is that they are not supposed to be displayed for every node in the diagram. The application is supposed to create them and add them to the diagram depending on the context of the current user cursor or operation that the user is performing with the data. It should be noted that annotations have minimal mutual conflict resolution. As a result it is very easy to clutter the diagram with an excessive number of annotations. But they are nevertheless very useful when describing or giving node specific context or details to the diagram. - -* Connector lines - Direct lines between nodes across the diagram. -* Background - It is an equivalent to highlighting text with a marker. The component merges overlapping background annotations into one if they overlap each other. -* Highlight path - A highlighter styled line that highlights the connections between directly connected nodes and helps the end user navigate the diagram. -* Shape annotations - Similar to background annotations, but are drawn in front of nodes in the form of custom shapes. -* In-layout labels - Are annotations that are drawn over connector lines but are also taken into consideration when calculating and rendering the layout of the diagram. Because of this, they do not cross any nodes, however can effect loading times as the entire diagram is rerendered. - -## First time user expereince with our product -Visualizing diagrams is a complex task which requires a lot of tuning. So long before we get something visible on the screen, we need to set and configurate a lot of diagram options. In order to make the starting experience simple, our component provides default functionality for almost everything: -* Default node template - You just need to provide your data and the first diagram will be rendered. -* Standard collection control features - Our product follows the standard behaivour for regular list and tree collection controls available in many other frameworks. -* User buttons panel - A custom in layout context panel with buttons. The diagram needs maximum screen space, so cutting screen real estate on the sides of the diagram for the buttons panel takes valuable space out of diagram. Placing the buttons in pop-up context menus or panels is also not ideal since it decreases UI discoverability and first time user expereince. So our component reserves space right inside of the diagram layout for the buttons panel. -* Basic visual categories - Our data visualization component has various ways to display basic data categories: titles, vertical titles, title colors and photos. - -## Free for Non-commercial: -Do you want to use a Basic Primitives diagram for a personal website, a school site or a non-profit organization? Then you don't need the author's permission. Just go on and use the Basic Primitives diagram. However for commercial website and project uses, see our License and Pricing. - -## Compatibility: -* Works in AngularJS directive -* Works in jQuery UI widgets - -## Performance: -Through a full API you can add, remove and modify individual items and their properties. The component will only update visual elements affected by the API changes. We put in a lot of effort in order to make it happen! diff --git a/api/static/readme.md b/api/static/readme.md deleted file mode 100644 index bc6f24f..0000000 --- a/api/static/readme.md +++ /dev/null @@ -1,12 +0,0 @@ -# Markdown file not found -The content of this page is rendered by `MDReactComponent`, in order to make it render the same content as you see at [Basic Primitives](https://www.basicprimitives.com/) you have to copy following GitHub folders: - -## 1 Copy following [BasicPrimitives/javascript](https://github.com/BasicPrimitives/javascript) repository folders: -* `https://github.com/BasicPrimitives/javascript/samples` => `/api/static/samples` -* `https://github.com/BasicPrimitives/javascript/min` => `/static/min` -* `https://github.com/BasicPrimitives/javascript/images` => `/static/images` -* `https://github.com/BasicPrimitives/javascript/packages` => `/static/packages` - -## 2 Copy following [BasicPrimitives/react](https://github.com/BasicPrimitives/react) repository folders: -* `https://github.com/BasicPrimitives/react/docs` => `/api/static/reactsamples/docs` -* `https://github.com/BasicPrimitives/react/src` => `/api/static/reactsamples/src` \ No newline at end of file diff --git a/app.json b/app.json deleted file mode 100644 index 2de7831..0000000 --- a/app.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "basic-primitives-react-integration-demo", - "description": "Basic Primitives React Demo. JavaScript components visualize hierarchical and DAG structures in form of organizational and dependency diagrams using default or user defined JSX templates.", - "repository": "https://github.com/BasicPrimitives/react-demo", - "logo": "https://www.basicprimitives.com/images/stories/logo.png", - "keywords": [ - "basicprimitives", - "diagrams", - "Hierarchy Visualization", - "Organizational Chart", - "Multi-parent hierarchical chart", - "Family Tree", - "Dependencies Diagram", - "PERT chart", - "Financial Ownership Diagram", - "react", - "isomorphic", - "universal", - "webpack", - "express", - "hot reloading", - "react-hot-reloader", - "redux", - "starter", - "boilerplate", - "babel" - ] -} diff --git a/bin/api.js b/bin/api.js deleted file mode 100644 index 4036677..0000000 --- a/bin/api.js +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env node -if (process.env.NODE_ENV !== 'production') { - if ( - !require('piping')({ - hook: true, - ignore: /(\/\.|~$|\.json$)/i - }) - ) { - return; - } -} -require('../server.babel'); // babel registration (runtime transpilation for node) -require('../api/api'); diff --git a/bin/server.js b/bin/server.js deleted file mode 100644 index 1b8635d..0000000 --- a/bin/server.js +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env node -require('../server.babel'); // babel registration (runtime transpilation for node) -const path = require('path'); - -const rootDir = path.resolve(__dirname, '..'); -/** - * Define isomorphic constants. - */ -global.__CLIENT__ = false; -global.__SERVER__ = true; -global.__DISABLE_SSR__ = false; // <----- DISABLES SERVER SIDE RENDERING FOR ERROR DEBUGGING -global.__DEVELOPMENT__ = process.env.NODE_ENV !== 'production'; - -if (__DEVELOPMENT__) { - if ( - !require('piping')({ - hook: true, - ignore: /(\/\.|~$|\.json|\.scss$)/i - }) - ) { - return; - } -} - -// https://github.com/halt-hammerzeit/webpack-isomorphic-tools -const WebpackIsomorphicTools = require('webpack-isomorphic-tools'); -global.webpackIsomorphicTools = new WebpackIsomorphicTools(require('../webpack/webpack-isomorphic-tools')).server( - rootDir, - () => { - require('../src/server'); - } -); diff --git a/circle.yml b/circle.yml deleted file mode 100644 index dcd7c9b..0000000 --- a/circle.yml +++ /dev/null @@ -1,16 +0,0 @@ -machine: - node: - version: 6.0 - environment: - CONTINUOUS_INTEGRATION: true - -dependencies: - cache_directories: - - node_modules - override: - - npm prune && npm install - -test: - override: - - npm run lint - - npm test diff --git a/client/.env b/client/.env new file mode 100644 index 0000000..0e8b188 --- /dev/null +++ b/client/.env @@ -0,0 +1 @@ +REACT_APP_PORT=3000 diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..4d29575 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/client/README.md b/client/README.md new file mode 100644 index 0000000..02aac3f --- /dev/null +++ b/client/README.md @@ -0,0 +1,70 @@ +# Getting Started with Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Available Scripts + +In the project directory, you can run: + +### `yarn start` + +Runs the app in the development mode.\ +Open [http://localhost:3000](http://localhost:3000) to view it in the browser. + +The page will reload if you make edits.\ +You will also see any lint errors in the console. + +### `yarn test` + +Launches the test runner in the interactive watch mode.\ +See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. + +### `yarn build` + +Builds the app for production to the `build` folder.\ +It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.\ +Your app is ready to be deployed! + +See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. + +### `yarn eject` + +**Note: this is a one-way operation. Once you `eject`, you can’t go back!** + +If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. + +You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) + +### Analyzing the Bundle Size + +This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) + +### Making a Progressive Web App + +This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) + +### Advanced Configuration + +This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) + +### Deployment + +This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) + +### `yarn build` fails to minify + +This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/client/jsconfig.json b/client/jsconfig.json new file mode 100644 index 0000000..35c31a7 --- /dev/null +++ b/client/jsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "baseUrl": "src" + }, + "include": ["src"] +} \ No newline at end of file diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..32eb938 --- /dev/null +++ b/client/package.json @@ -0,0 +1,76 @@ +{ + "name": "react-demo", + "version": "0.1.0", + "private": true, + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.32", + "@fortawesome/free-solid-svg-icons": "^5.15.1", + "@fortawesome/react-fontawesome": "^0.1.12", + "@material-ui/core": "^4.11.0", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.56", + "@material-ui/styles": "^4.10.0", + "@reach/router": "^1.3.4", + "@testing-library/jest-dom": "^5.11.4", + "@testing-library/react": "^11.1.0", + "@testing-library/user-event": "^12.1.10", + "axios": "^0.21.0", + "basicprimitives": "^5.9.2", + "basicprimitivesreact": "^5.9.3", + "blob-stream": "^0.1.3", + "clsx": "^1.1.1", + "codemirror": "^5.58.2", + "final-form": "^4.20.1", + "lodash": "^4.17.20", + "markdown-react-js": "^1.0.2", + "node-sass": "^4.0.0", + "pdfkit-nodejs-webpack": "^0.0.2", + "prop-types": "^15.7.2", + "react": "^17.0.1", + "react-codemirror2": "^7.2.1", + "react-dnd": "^11.1.3", + "react-dnd-html5-backend": "^11.1.3", + "react-dom": "^17.0.1", + "react-final-form": "^6.5.2", + "react-ga": "^3.2.0", + "react-helmet": "^6.1.0", + "react-live": "^2.2.3", + "react-redux": "^7.2.2", + "react-scripts": "4.0.0", + "react-sortable-hoc": "^1.11.0", + "react-syntax-highlighter": "^15.3.0", + "react-youtube": "^7.13.0", + "redial": "^0.5.0", + "redux": "^4.0.5", + "redux-logger": "^3.0.6", + "web-vitals": "^0.2.4" + }, + "devDependencies": { + "http-proxy-middleware": "^1.0.6" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "proxy": "http://localhost:3030" +} diff --git a/static/favicon.ico b/client/public/favicon.ico similarity index 100% rename from static/favicon.ico rename to client/public/favicon.ico diff --git a/client/public/index.html b/client/public/index.html new file mode 100644 index 0000000..aa069f2 --- /dev/null +++ b/client/public/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + React App + + + +
+ + + diff --git a/client/public/logo192.png b/client/public/logo192.png new file mode 100644 index 0000000..fc44b0a Binary files /dev/null and b/client/public/logo192.png differ diff --git a/client/public/logo512.png b/client/public/logo512.png new file mode 100644 index 0000000..a4e47a6 Binary files /dev/null and b/client/public/logo512.png differ diff --git a/client/public/manifest.json b/client/public/manifest.json new file mode 100644 index 0000000..080d6c7 --- /dev/null +++ b/client/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/client/public/robots.txt b/client/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/client/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/src/components/OptionsPanels/Components/CheckboxOption.js b/client/src/components/Options/CheckboxOption.js similarity index 59% rename from src/components/OptionsPanels/Components/CheckboxOption.js rename to client/src/components/Options/CheckboxOption.js index 3da2e94..f853b21 100644 --- a/src/components/OptionsPanels/Components/CheckboxOption.js +++ b/client/src/components/Options/CheckboxOption.js @@ -1,7 +1,9 @@ import React, { Component } from 'react'; import _ from 'lodash'; import PropTypes from 'prop-types'; -import { Checkbox } from 'react-bootstrap'; +import Checkbox from '@material-ui/core/Checkbox'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Tooltip from '@material-ui/core/Tooltip'; class CheckboxOption extends Component { // eslint-disable-line react/prefer-stateless-function static propTypes = { @@ -28,15 +30,21 @@ class CheckboxOption extends Component { // eslint-disable-line react/prefer-sta } render() { - const { - caption, propertyName, onChange, value - } = this.props; + const { caption, propertyName, onChange, value } = this.props; return ( -
- onChange(!value)}> - {caption} - -
+ + onChange(!value)} + name={propertyName} + color="primary" + /> + } + label={caption} + /> + ); } } diff --git a/src/components/OptionsPanels/Components/ComboBoxOption.js b/client/src/components/Options/ComboBoxOption.js similarity index 52% rename from src/components/OptionsPanels/Components/ComboBoxOption.js rename to client/src/components/Options/ComboBoxOption.js index 83969b5..5a0c5d8 100644 --- a/src/components/OptionsPanels/Components/ComboBoxOption.js +++ b/client/src/components/Options/ComboBoxOption.js @@ -1,7 +1,11 @@ import React, { Component } from 'react'; import _ from 'lodash'; import PropTypes from 'prop-types'; -import { FormGroup, FormControl, ControlLabel } from 'react-bootstrap'; +import FormLabel from '@material-ui/core/FormLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; +import Tooltip from '@material-ui/core/Tooltip'; class ComboBoxOption extends Component { static propTypes = { @@ -34,18 +38,22 @@ class ComboBoxOption extends Component { } getValue(value) { - const { valueType } = this.props; + const { valueType, isNullable } = this.props; let floatValue = null; let intValue = null; - switch (valueType) { - case 'number': - floatValue = parseFloat(value, 10); - intValue = parseInt(value, 10); - return floatValue !== intValue ? floatValue : intValue; - case 'boolean': - return value === 'true' || value === true; - default: - return value; + if(isNullable && value === "NULL") { + return null; + } else { + switch (valueType) { + case 'number': + floatValue = parseFloat(value, 10); + intValue = parseInt(value, 10); + return floatValue !== intValue ? floatValue : intValue; + case 'boolean': + return value === 'true' || value === true; + default: + return value; + } } } @@ -72,30 +80,32 @@ class ComboBoxOption extends Component { return result; }, {}) : items; + if(!Object.keys(properties).some( property => properties[property] === value)) { + properties[value] = value; + } return ( -
- - {caption} - onChange(this.getValue(event.target.value))} - > - {isNullable ? ( - - ) : ('')} - {Object.keys(properties).map(property => ( - - ))} - - -
+ + + {caption} + + + ); } } diff --git a/src/components/OptionsPanels/ItemsOrderPanel.js b/client/src/components/Options/ItemsOrderOption.js similarity index 58% rename from src/components/OptionsPanels/ItemsOrderPanel.js rename to client/src/components/Options/ItemsOrderOption.js index 76dcbc5..4929cde 100644 --- a/src/components/OptionsPanels/ItemsOrderPanel.js +++ b/client/src/components/Options/ItemsOrderOption.js @@ -2,25 +2,37 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import _ from 'lodash'; import { SortableContainer, SortableElement, arrayMove } from 'react-sortable-hoc'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import PersonIcon from '@material-ui/icons/Person'; +import ListItemText from '@material-ui/core/ListItemText'; -const SortableItem = SortableElement(({ value }) =>
  • {value}
  • ); +const SortableItem = SortableElement(({ value }) => + + + + + +); const SortableList = SortableContainer(({ items }) => ( - + )); -class ItemsOrderPanel extends Component { +class ItemsOrderOption extends Component { static propTypes = { - setItemsOrder: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, + propertyName: PropTypes.string.isRequired, items: PropTypes.arrayOf(PropTypes.any.isRequired).isRequired // eslint-disable-line react/forbid-prop-types }; - constructor(props, context) { - super(props, context); + constructor(props) { + super(props); this.onSortEnd = this.onSortEnd.bind(this); @@ -49,23 +61,20 @@ class ItemsOrderPanel extends Component { onSortEnd({ oldIndex, newIndex }) { const { items } = this.state; - const { setItemsOrder } = this.props; + const { onChange } = this.props; const newItems = arrayMove(items, oldIndex, newIndex); this.setState({ items: newItems }); - setItemsOrder(newItems); + onChange(newItems); } render() { - const { items } = this.state; + const { items, propertyName } = this.state; return ( - <> -

    Drag to order children

    - - + ); } } -export default ItemsOrderPanel; +export default ItemsOrderOption; diff --git a/client/src/components/Options/OptionsPanel.js b/client/src/components/Options/OptionsPanel.js new file mode 100644 index 0000000..b4b263b --- /dev/null +++ b/client/src/components/Options/OptionsPanel.js @@ -0,0 +1,147 @@ +import React from 'react'; +import Accordion from '@material-ui/core/Accordion'; +import FormGroup from '@material-ui/core/FormGroup'; +import AccordionSummary from '@material-ui/core/AccordionSummary'; +import AccordionDetails from '@material-ui/core/AccordionDetails'; +import Typography from '@material-ui/core/Typography'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { RadioGroupOption } from 'components'; +import { CheckboxOption } from 'components'; +import { ComboBoxOption } from 'components'; +import { SizeOption } from 'components'; +import { ThicknessOption } from 'components'; +import { TextOption } from 'components'; +import { ItemsOrderOption } from 'components'; +import { makeStyles } from "@material-ui/core/styles"; + +const useStyles = makeStyles(theme => { + return ({ + accrodionRoot: { + width: '100%', + }, + accordionHeading: { + fontSize: theme.typography.pxToRem(15), + fontWeight: theme.typography.fontWeightRegular, + }, + formGroupRoot: { + '& .option-panel-item': { + margin: theme.spacing(2, 0, 0), + minWidth: "25ch" + } + } + }) +}); + +function OptionsPanel(props) { + const {optionsPanelConfig, onChange} = props; + + const styles = useStyles(); + + const [expanded, setExpanded] = React.useState('panel0'); + + const handleChange = (panel) => (event, newExpanded) => { + setExpanded(newExpanded ? panel : false); + }; + + return <> + { optionsPanelConfig.map( ({title, options, namespace}, index) => { + const config = props[namespace]; + return + } + aria-controls={`panel${index}-content`} + id={`panel${index}-header`} + > + {title} + + {expanded === `panel${index}` && + + + {options.map( ({optionType, caption, name, valueType, options, isNullable, widths, heights, onValidate, placeholder}, index) => { + switch(optionType) { + case "CaptionConfig": + return {caption}; + case "RadioBoxConfig": + return onChange(namespace, name, value)} + />; + case "CheckBoxConfig": + return onChange(namespace, name, value)} + />; + case "DropDownBoxConfig": + return onChange(namespace, name, value)} + />; + case "SizeConfig": + return onChange(namespace, name, value)} + />; + case "ThicknessConfig": + return onChange(namespace, name, value)} + />; + case "TextConfig": + return onChange(namespace, name, value)} + />; + case "ItemsOrderConfig": + return onChange(namespace, name, value)} + /> + default: + return
  • {optionType}:{caption}
  • ; + } + } + )} +
    +
    + } +
    + }) + } + +} + +export default OptionsPanel; \ No newline at end of file diff --git a/src/components/OptionsPanels/Components/RadioGroupOption.js b/client/src/components/Options/RadioGroupOption.js similarity index 64% rename from src/components/OptionsPanels/Components/RadioGroupOption.js rename to client/src/components/Options/RadioGroupOption.js index c690d4e..fc78634 100644 --- a/src/components/OptionsPanels/Components/RadioGroupOption.js +++ b/client/src/components/Options/RadioGroupOption.js @@ -1,7 +1,12 @@ import React, { Component } from 'react'; import _ from 'lodash'; import PropTypes from 'prop-types'; -import { FormGroup, Radio, ControlLabel } from 'react-bootstrap'; +import Radio from '@material-ui/core/Radio'; +import RadioGroup from '@material-ui/core/RadioGroup'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormControl from '@material-ui/core/FormControl'; +import FormLabel from '@material-ui/core/FormLabel'; +import Tooltip from '@material-ui/core/Tooltip'; class RadioGroupOption extends Component { static propTypes = { @@ -62,22 +67,21 @@ class RadioGroupOption extends Component { }, {}) : items; return ( -
    - - {caption} - {Object.keys(properties).map(property => ( - onChange(this.getValue(event.target.value))} - > - {property} - - ))} - -
    + + + {caption} + + onChange(this.getValue(event.target.value))}> + {Object.keys(properties).map(property => ( + } + label={property} + key={properties[property]} + value={properties[property]} + /> + ))} + + ); } } diff --git a/client/src/components/Options/SizeOption.js b/client/src/components/Options/SizeOption.js new file mode 100644 index 0000000..1602461 --- /dev/null +++ b/client/src/components/Options/SizeOption.js @@ -0,0 +1,98 @@ +import React, { Component } from 'react'; +import _ from 'lodash'; +import PropTypes from 'prop-types'; +import FormLabel from '@material-ui/core/FormLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; +import primitives from 'basicprimitives'; +import Tooltip from '@material-ui/core/Tooltip'; + +class SizeOption extends Component { + static propTypes = { + caption: PropTypes.string.isRequired, + widths: PropTypes.arrayOf(PropTypes.number).isRequired, + heights: PropTypes.arrayOf(PropTypes.number).isRequired, + onChange: PropTypes.func.isRequired, + propertyName: PropTypes.string.isRequired, + value: PropTypes.shape({ + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired + }).isRequired + }; + + shouldComponentUpdate(nextProps, nextState) { // eslint-disable-line no-unused-vars + const nextOptions = this.getUsedOptions(nextProps); + const currentOptions = this.getUsedOptions(this.props); + + return !_.isEqual(currentOptions, nextOptions); + } + + onWidthChange(width) { + const { onChange, value } = this.props; + onChange(new primitives.common.Size(width, value.height)); + } + + onHeightChange(height) { + const { onChange, value } = this.props; + onChange(new primitives.common.Size(value.width, height)); + } + + getUsedOptions(props) { // eslint-disable-line class-methods-use-this + const { + caption, widths, heights, propertyName, value + } = props; + return { + caption, + widths, + heights, + propertyName, + value + }; + } + + render() { + const { caption, widths, heights, propertyName, value } = this.props; + return ( + <> + + + {caption} + + Width + + + + Height + + + + ); + } +} + +export default SizeOption; diff --git a/src/components/OptionsPanels/Components/TextOption.js b/client/src/components/Options/TextOption.js similarity index 83% rename from src/components/OptionsPanels/Components/TextOption.js rename to client/src/components/Options/TextOption.js index 5a54b45..b2cfb07 100644 --- a/src/components/OptionsPanels/Components/TextOption.js +++ b/client/src/components/Options/TextOption.js @@ -1,14 +1,12 @@ import React, { Component } from 'react'; import _ from 'lodash'; import PropTypes from 'prop-types'; -import { - FormGroup, ControlLabel, FormControl, HelpBlock -} from 'react-bootstrap'; +import TextField from '@material-ui/core/TextField'; class TextOption extends Component { // eslint-disable-line react/prefer-stateless-function static propTypes = { caption: PropTypes.string.isRequired, - placeholder: PropTypes.string.isRequired, + placeholder: PropTypes.string, propertyName: PropTypes.string.isRequired, onValidate: PropTypes.func, onChange: PropTypes.func.isRequired, @@ -25,8 +23,8 @@ class TextOption extends Component { // eslint-disable-line react/prefer-statele debounce: 1000 }; - constructor(props, context) { - super(props, context); + constructor(props) { + super(props); this.onHandleChange = this.onHandleChange.bind(this); this.onTimer = this.onTimer.bind(this); @@ -119,21 +117,26 @@ class TextOption extends Component { // eslint-disable-line react/prefer-statele static getValidationState(value) { const isEmpty = value === undefined || value === null || value === ''; if (!isEmpty) { - return 'error'; + return true; } - return null; + return false; } render() { - const { caption, propertyName, placeholder } = this.props; + const { caption, propertyName, placeholder, isNullable } = this.props; const { value, message } = this.state; return ( - - {caption} - - - {message} - +
    + + ); } } diff --git a/client/src/components/Options/ThicknessOption.js b/client/src/components/Options/ThicknessOption.js new file mode 100644 index 0000000..65cce43 --- /dev/null +++ b/client/src/components/Options/ThicknessOption.js @@ -0,0 +1,82 @@ +import React, { Component } from 'react'; +import _ from 'lodash'; +import PropTypes from 'prop-types'; +import FormLabel from '@material-ui/core/FormLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; +import Tooltip from '@material-ui/core/Tooltip'; +import primitives from 'basicprimitives'; + +class ThicknessOption extends Component { + static propTypes = { + caption: PropTypes.string.isRequired, + items: PropTypes.arrayOf(PropTypes.number).isRequired, + onChange: PropTypes.func.isRequired, + propertyName: PropTypes.string.isRequired, + value: PropTypes.shape({ + left: PropTypes.number.isRequired, + top: PropTypes.number.isRequired, + right: PropTypes.number.isRequired, + bottom: PropTypes.number.isRequired + }).isRequired + }; + + shouldComponentUpdate(nextProps, nextState) { // eslint-disable-line no-unused-vars + const nextOptions = this.getUsedOptions(nextProps); + const currentOptions = this.getUsedOptions(this.props); + + return !_.isEqual(currentOptions, nextOptions); + } + + onPropertyChange(propertyName, propertyValue) { + const { onChange, value } = this.props; + const result = new primitives.common.Thickness(value); + result[propertyName] = propertyValue; + onChange(result); + } + + getUsedOptions(props) { // eslint-disable-line class-methods-use-this + const { + caption, items, propertyName, value + } = props; + return { + caption, + items, + propertyName, + value + }; + } + + render() { + const { caption, items, propertyName, value } = this.props; + const names = ["left", "top", "right", "bottom"]; + return ( + <> + + {caption} + + {names.map(name => { + return + {_.startCase(_.camelCase(name))} + + + })} + + ); + } +} + +export default ThicknessOption; diff --git a/client/src/components/Options/options.js b/client/src/components/Options/options.js new file mode 100644 index 0000000..a9a6bbc --- /dev/null +++ b/client/src/components/Options/options.js @@ -0,0 +1,283 @@ +import primitives from 'basicprimitives'; +import { phone, email } from 'utils/validation'; + +const images = 'abcdefghijklmnopqrstuvwxyz'.split('').reduce((agg, imageChar) => { + agg[imageChar.toUpperCase()] = `/api/images/photos/${imageChar}.png`; + return agg; + }, {}); + +const AutoLayoutOptions = { + title: "Auto Layout", + namespace: "config", + options: [ + { optionType: "CaptionConfig", caption: "Page Fit Mode defines rule of fitting chart into available screen space. Set it to None if you want to disable it." }, + { optionType: "RadioBoxConfig", name: "pageFitMode", caption: "Page Fit Mode", options: { None: 0, PageWidth: 1, PageHeight: 2, FitToPage: 3, SelectionOnly: 6 }, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "orientationType", caption: "Orientation Type", options: primitives.common.OrientationType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "verticalAlignment", caption: "Items Vertical Alignment", options: primitives.common.VerticalAlignmentType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "horizontalAlignment", caption: "Items Horizontal Alignment", options: primitives.common.HorizontalAlignmentType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "childrenPlacementType", caption: "Children placement", options: primitives.common.ChildrenPlacementType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "leavesPlacementType", caption: "Leaves placement defines layout shape for items having no children", options: primitives.common.ChildrenPlacementType, valueType: "number" }, + { optionType: "CheckBoxConfig", name: "placeAdvisersAboveChildren", caption: "Place children of advisers above their parent node children" }, + { optionType: "CheckBoxConfig", name: "placeAssistantsAboveChildren", caption: "Place children of assistants above their parent node children" }, + { optionType: "DropDownBoxConfig", name: "maximumColumnsInMatrix", caption: "Maximum columns number in matrix children layout", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20], valueType: "number" }, + { optionType: "RadioBoxConfig", name: "minimalVisibility", caption: "Minimal nodes visibility", options: primitives.common.Visibility, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "selectionPathMode", caption: "Selection Path Mode sets visibility of items between cursor item and root", options: primitives.common.SelectionPathMode, valueType: "number" } + ] +}; + +const FamilyLayoutOptions = { + title: "Auto Layout", + namespace: "config", + options: [ + { optionType: "CaptionConfig", caption: "Page Fit Mode defines rule of fitting chart into available screen space. Set it to None if you want to disable it." }, + { optionType: "RadioBoxConfig", name: "pageFitMode", caption: "Page Fit Mode", options: { None: 0, PageWidth: 1, PageHeight: 2, FitToPage: 3, SelectionOnly: 6 }, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "orientationType", caption: "Orientation Type", options: primitives.common.OrientationType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "verticalAlignment", caption: "Items Vertical Alignment", options: primitives.common.VerticalAlignmentType, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "maximumColumnsInMatrix", caption: "Maximum columns number in matrix children layout", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20], valueType: "number" }, + { optionType: "RadioBoxConfig", name: "minimalVisibility", caption: "Minimal nodes visibility", options: primitives.common.Visibility, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "neighboursSelectionMode", caption: "Neighbours Selection Mode", options: primitives.common.NeighboursSelectionMode, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "selectionPathMode", caption: "Selection Path Mode sets visibility of items between cursor item and root", options: primitives.common.SelectionPathMode, valueType: "number" }, + { optionType: "CaptionConfig", caption: "Group by option defines node placement in layout close to its parents or children when node is linked across multiple levels in hierarchy. See `alignment` data set." }, + { optionType: "RadioBoxConfig", name: "groupByType", caption: "Group By", options: { Children: 2, Parents: 1 }, valueType: "number" }, + { optionType: "CaptionConfig", caption: "The following option keeps items at the same levels after connections bundling." }, + { optionType: "CheckBoxConfig", name: "alignBylevels", caption: "Align by levels" }, + { optionType: "CaptionConfig", caption: "The following option hides direct connectors to grand parents. It helps reduce diagrams connectors layout complexity. This option should be used together with dynamic highlighting of connectors to grandparents via immidiate parents, so information is not lost." }, + { optionType: "CheckBoxConfig", name: "hideGrandParentsConnectors", caption: "Hides grand parents connectors" }, + { optionType: "CaptionConfig", caption: "Chart optimizes items placement into layers, so the final diagram has minimal number of feedback loops between them. Use following option to disable that behaviour and place items in the same sequence as in source items collection." }, + { optionType: "RadioBoxConfig", name: "loopsLayoutMode", caption: "Loops Layout Mode", options: primitives.common.LoopsLayoutMode, valueType: "number" }, + { optionType: "CaptionConfig", caption: "The following option enables natrix layout in family diagram. Nodes having the same set of parents and children are grouped into square shaped matrix in order to keep them visualy together." }, + { optionType: "CheckBoxConfig", name: "enableMatrixLayout", caption: "Enable Matrix Layout" }, + { optionType: "DropDownBoxConfig", name: "minimumMatrixSize", caption: "Minimum number of nodes needed in order to be formed into matrix layout", options: [2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "number", isNullable: true }, + { optionType: "DropDownBoxConfig", name: "maximumColumnsInMatrix", caption: "Maximum columns number in matrix nodes layout", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20], valueType: "number", isNullable: true } + ] +}; + +const DefaultTemplateOptions = { + title: "Default Template", + namespace: "config", + options: [ + { optionType: "RadioBoxConfig", name: "hasButtons", caption: "Show user buttons", options: primitives.common.Enabled, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "hasSelectorCheckbox", caption: "Show selection check box", options: primitives.common.Enabled, valueType: "number" }, + { optionType: "TextConfig", name: "selectCheckBoxLabel", caption: "Selection checkbox label", valueType: "string", isNullable: false }, + { optionType: "CaptionConfig", name: "Default chart item template tries to select the best matching font color for current title background." }, + { optionType: "DropDownBoxConfig", name: "itemTitleFirstFontColor", caption: "Title first font color", options: primitives.common.Colors, valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "itemTitleSecondFontColor", caption: "Title second font color", options: primitives.common.Colors, valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "buttonsPanelSize", caption: "Buttons panel size", options: [28, 56, 84], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "checkBoxPanelSize", caption: "Checkbox panel size", options: [24, 48, 72], valueType: "number" } + ] +}; +const GroupTitlesOptions = { + title: "Group Titles", + namespace: "config", + options: [ + { optionType: "RadioBoxConfig", name: "groupTitlePlacementType", caption: "Placement", options: primitives.common.AdviserPlacementType, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "groupTitlePanelSize", caption: "Group title panel width", options: [24, 48, 72], valueType: "number" }, + { optionType: "RadioBoxConfig", name: "groupTitleOrientation", caption: "Orientation", options: primitives.text.TextOrientationType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "groupTitleVerticalAlignment", caption: "Vertical Alignment", options: primitives.common.VerticalAlignmentType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "groupTitleHorizontalAlignment", caption: "Horizontal Alignment", options: primitives.common.HorizontalAlignmentType, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "groupTitleColor", caption: "Background Color", options: primitives.common.Colors, valueType: "string" }, + { optionType: "CaptionConfig", caption: "For group title color, see title first and second font colors in default template options." }, + { optionType: "DropDownBoxConfig", name: "groupTitleFontSize", caption: "Font size", options: ["8px", "10px", "12px", "14px", "16px", "18px", "20px"], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "groupTitleFontWeight", caption: "Font Weight", options: ["normal", "bold"], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "groupTitleFontStyle", caption: "Font Style", options: ["normal", "italic"], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "groupTitleFontFamily", caption: "Font Style", options: ["Arial", "Verdana", "Times New Roman", "Serif", "Courier"], valueType: "string" }, + ] +}; +const MarkersOptions = { + title: "Markers", + namespace: "defaultTemplate", + options: [ + { optionType: "CaptionConfig", caption: "These options are defined per item template. So if you need to show individual markers per item, you have to define template for every marker type and assign it to items. Template is some sort of named property bag." }, + { optionType: "CaptionConfig", caption: "By default marker has color of itemTitleColor property, download demos and check samples source data. If item has no title color set, then be sure that you set border line width and color for markers having no fill, othewise you are not going to see them." }, + { optionType: "SizeConfig", name: "minimizedItemSize", caption: "Marker size", widths: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40], heights: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40] }, + { optionType: "DropDownBoxConfig", name: "minimizedItemCornerRadius", caption: "Corner Radius", options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20], valueType: "number", isNullable: true }, + { optionType: "ThicknessConfig", name: "highlightPadding", caption: "Highlight border padding around marker", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, + { optionType: "RadioBoxConfig", name: "minimizedItemShapeType", caption: "Marker Shape", options: primitives.common.ShapeType, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "minimizedItemLineWidth", caption: "Marker border line width", options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "number" }, + { optionType: "RadioBoxConfig", name: "minimizedItemLineType", caption: "Marker border line type", options: primitives.common.LineType, valueType: "number" }, + { optionType: "CaptionConfig", caption: "Following Border and Fill colors properties work only for items having no title color property set. See Parners & Annotations Demo to try them." }, + { optionType: "DropDownBoxConfig", name: "minimizedItemBorderColor", caption: "Marker border line color", options: primitives.common.Colors, valueType: "string", isNullable: true }, + { optionType: "DropDownBoxConfig", name: "minimizedItemFillColor", caption: "Marker fill color", options: primitives.common.Colors, valueType: "string", isNullable: true }, + { optionType: "DropDownBoxConfig", name: "minimizedItemOpacity", caption: "Opacity", options: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], valueType: "number" } + ] +}; +const IntervalsOptions = { + title: "Intervals", + namespace: "config", + options: [ + { optionType: "CaptionConfig", caption: "Vertical Intervals Between Rows" }, + { optionType: "DropDownBoxConfig", name: "normalLevelShift", caption: "Normal", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40], valueType: "number" }, + { optionType: "CaptionConfig", caption: "If you enable labels for dots, use the following interval to fit them between levels." }, + { optionType: "DropDownBoxConfig", name: "dotLevelShift", caption: "Dotted", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40, 80, 160, 240, 320], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "lineLevelShift", caption: "Lined", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40, 80, 160, 240, 320], valueType: "number" }, + + { optionType: "CaptionConfig", caption: "Horizontal Intervals Between Items in Row" }, + { optionType: "DropDownBoxConfig", name: "normalItemsInterval", caption: "Normal", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "dotItemsInterval", caption: "Dotted", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "lineItemsInterval", caption: "Lined", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "cousinsIntervalMultiplier", caption: "Additional interval multiplier between cousins, it creates extra space between hierarchies", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 30, 40], valueType: "number" } + ] +}; +const ConnectorsOptions = { + title: "Connectors", + namespace: "config", + options: [ + { optionType: "RadioBoxConfig", name: "arrowsDirection", caption: "Arrows Direction", options: primitives.common.GroupByType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "connectorType", caption: "Connectors", options: primitives.common.ConnectorType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "elbowType", caption: "Elbows Type", options: primitives.common.ElbowType, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "bevelSize", caption: "Bevel Size", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "elbowDotSize", caption: "Elbow dot Size", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "number" }, + { optionType: "RadioBoxConfig", name: "linesType", caption: "Line type", options: primitives.common.LineType, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "linesColor", caption: "Color", options: primitives.common.Colors, valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "linesWidth", caption: "Line width", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "number" }, + { optionType: "CheckBoxConfig", name: "showExtraArrows", caption: "Show extra horizontal arrows on top of connectors, for easy navigation between parents and children through connector lines" }, + { optionType: "DropDownBoxConfig", name: "extraArrowsMinimumSpace", caption: "Available minimum space to show horizontal arrow", options: [0, 5, 10, 20, 30, 40, 50, 100, 200, 1000], valueType: "number" } + ] +}; +const LabelsOptions = { + title: "Labels", + namespace: "config", + options: [ + { optionType: "CaptionConfig", caption: "Label property should be defined for every item first, otherwise chart has nothiong to show. Labels are visible only for markers. If you need to add labels to normal size items you have to modify default item template and place text outside item boundaries." }, + { optionType: "RadioBoxConfig", name: "showLabels", caption: "Show labels", options: primitives.common.Enabled, valueType: "number" }, + { optionType: "SizeConfig", name: "labelSize", caption: "Size: Use this property to define labels bounding rectangle. Labels placed relative to markers(dots), so if they overlap each other in auto show mode, one of them would be hidden. Set appropriate intervals between levels of markers in order to fit and make all labels visible.", widths: [80, 160, 240, 320], heights: [8, 16, 24, 32, 40, 48, 56] }, + { optionType: "DropDownBoxConfig", name: "labelOffset", caption: "Offset", options: [0, 1, 2, 3, 4, 5, 10, 20, 30], valueType: "number" }, + { optionType: "RadioBoxConfig", name: "labelOrientation", caption: "Label Orientation", options: primitives.text.TextOrientationType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "labelPlacement", caption: "Label Placement", options: primitives.common.PlacementType, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "labelFontSize", caption: "Font size", options: ["8px", "10px", "12px", "14px", "16px", "18px", "20px"], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "labelFontFamily", caption: "Font Style", options: ["Arial", "Verdana", "Times New Roman", "Serif", "Courier"], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "labelColor", caption: "Font Color", options: primitives.common.Colors, valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "labelFontWeight", caption: "Font Weight", options: ["normal", "bold"], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "labelFontStyle", caption: "Font Style", options: ["normal", "italic"], valueType: "string" }, + ] +}; +const CalloutOptions = { + title: "Callout", + namespace: "config", + options: [ + { optionType: "CaptionConfig", caption: "By default callout displays item content, but it can be redefined with custom callout template." }, + { optionType: "CheckBoxConfig", name: "showCallout", caption: "Show callout" }, + { optionType: "RadioBoxConfig", name: "calloutMaximumVisibility", caption: "Maximum node type visibility", options: { Normal: 1, Dot: 2, Line: 3 }, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "calloutPlacementOffset", caption: "Call out placement offset", options: [10, 20, 30, 40, 50, 100, 200, 300], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "calloutfillColor", caption: "Fill color", options: primitives.common.Colors, valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "calloutBorderColor", caption: "Border line color", options: primitives.common.Colors, valueType: "string", isNullable: true }, + { optionType: "DropDownBoxConfig", name: "calloutOffset", caption: "Offset", options: [0, 1, 2, 3, 4, 5, 10, 20, 30], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "calloutCornerRadius", caption: "Corner Radius", options: ["0%", "5%", "10%", "20%", 0, 1, 2, 3, 4, 5, 10, 20, 30], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "calloutPointerWidth", caption: "Pointer Base Width", options: ["0%", "5%", "10%", "20%", 0, 5, 10, 20, 50], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "calloutLineWidth", caption: "Line width", options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "calloutOpacity", caption: "Opacity", options: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], valueType: "number" } + ] +}; +const InteractivityOptions = { + title: "Interactivity", + namespace: "config", + options: [ + { optionType: "CaptionConfig", caption: "Use this option to disable mouse highlight on touch devices." }, + { optionType: "RadioBoxConfig", name: "navigationMode", caption: "Navigation mode", options: primitives.common.NavigationMode, valueType: "number" }, + { optionType: "CaptionConfig", caption: "This option defines highlight gravity radius, so minimized item gets highlighted when mouse pointer does not overlap marker but it is within gravity radius of its boundaries." }, + { optionType: "DropDownBoxConfig", name: "highlightGravityRadius", caption: "Normal", options: [0, 5, 10, 20, 30, 40, 50, 100, 200, 1000], valueType: "number" }, + { optionType: "CheckBoxConfig", name: "enablePanning", caption: "Enable Panning" } + ] +}; +const RenderingOptions = { + title: "Rendering", + namespace: "config", + options: [ + { optionType: "CaptionConfig", caption: "By default widget preferes SVG graphics mode. Use this property to enforce graphics mode programmatically." }, + { optionType: "RadioBoxConfig", name: "graphicsType", caption: "Graphics", options: primitives.common.GraphicsType, valueType: "number" }, + { optionType: "CaptionConfig", caption: "In order to achive better greacefull degradation of your diagram use item templates of various sizes instead of CSS scale." }, + { optionType: "DropDownBoxConfig", name: "scale", caption: "CSS Scale", options: { "50%": 0.5, "60%": 0.6, "70%": 0.7, "80%": 0.8, "90%": 0.9, "100%": 1.0, "110%": 1.1, "120%": 1.2, "130%": 1.3, "140%": 1.4, "150%": 1.5, "160%": 1.6, "170%": 1.7, "180%": 1.8, "190%": 1.9, "200%": 2.0 }, valueType: "number" }, + ] +}; +const FrameOptions = { + title: "Frame", + namespace: "config", + options: [ + { optionType: "CaptionConfig", caption: "Displays selected items outside view port area." }, + { optionType: "CheckBoxConfig", name: "showFrame", caption: "Show Frame" }, + { optionType: "ThicknessConfig", name: "frameInnerPadding", caption: "Frame inner padding", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "number" }, + { optionType: "ThicknessConfig", name: "frameOuterPadding", caption: "Frame outer padding", options: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "number" } + ] +}; + +const ItemOptions = { + title: "Properties", + namespace: "config", + options: [ + { optionType: "TextConfig", name: "title", caption: "Title", valueType: "string", isNullable: false }, + { optionType: "TextConfig", name: "description", caption: "Description", valueType: "string", isNullable: false }, + { optionType: "TextConfig", name: "groupTitle", caption: "Group Title", valueType: "string", isNullable: true }, + { optionType: "TextConfig", name: "phone", caption: "Phone", placeholder: "(123) 123-12-12", onValidate: (value) => phone(value), valueType: "string", isNullable: true }, + { optionType: "TextConfig", name: "email", caption: "E-mail", placeholder: "name@server.com", onValidate: (value) => email(value), valueType: "string", isNullable: true }, + { optionType: "TextConfig", name: "label", caption: "Marker Label", isNullable: true, valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "itemTitleColor", caption: "Title Color", options: primitives.common.Colors, valueType: "string", isNullable: true }, + { optionType: "DropDownBoxConfig", name: "groupTitleColor", caption: "Group Title Color", options: primitives.common.Colors, valueType: "string", isNullable: true }, + { optionType: "DropDownBoxConfig", name: "image", caption: "Image", options: images, valueType: "string", isNullable: true }, + { optionType: "DropDownBoxConfig", name: "minimizedItemShapeType", caption: "Marker Shape", options: primitives.common.ShapeType, valueType: "string", isNullable: true }, + ] +}; + +const ConnectorAnnotationOptions = { + title: "Connector Annotation", + namespace: "annotation", + options: [ + { optionType: "RadioBoxConfig", name: "connectorPlacementType", caption: "Placement", options: primitives.common.ConnectorPlacementType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "connectorShapeType", caption: "Shape", options: primitives.common.ConnectorShapeType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "labelPlacementType", caption: "Label Placement", options: primitives.common.ConnectorLabelPlacementType, valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "lineWidth", caption: "Line width", options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "lineType", caption: "Line type", options: primitives.common.LineType, valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "color", caption: "Color", options: primitives.common.Colors, valueType: "string" }, + { optionType: "DropDownBoxConfig", name: "offset", caption: "Offset", options: [-50, -20, -10, -5, 0, 5, 10, 20, 50], valueType: "number" }, + { optionType: "DropDownBoxConfig", name: "zOrderType", caption: "Connector Z order type", options: primitives.common.ZOrderType, valueType: "number" } + ] +}; + +const ItemLayoutOptions = { + title: "Layout", + namespace: "config", + options: [ + { optionType: "RadioBoxConfig", name: "itemType", caption: "Item Type", options: { + Regular: 0, + Assistant: 1, + SubAssistant: 4, + SubAdviser: 5, + Adviser: 2, + GeneralPartner: 6, + LimitedPartner: 7, + AdviserPartner: 8 + }, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "adviserPlacementType", caption: "Placement", options: primitives.common.AdviserPlacementType, valueType: "number" }, + { optionType: "RadioBoxConfig", name: "childrenPlacementType", caption: "Children Layout", options: primitives.common.ChildrenPlacementType, valueType: "number" } + // { optionType: "CheckBoxConfig", name: "placeAdvisersAboveChildren", caption: "Place advisers above children" }, + // { optionType: "CheckBoxConfig", name: "placeAssistantsAboveChildren", caption: "Place assistants above children" } + ] +}; + +const ChildrenOrderOptions = { + title: "Children", + namespace: "children", + options: [ + { optionType: "CaptionConfig", caption: "Drag to order children." }, + { optionType: "ItemsOrderConfig", name: "children", caption: "Drag to order children" } + ] +}; + +const Options = { + AutoLayoutOptions, + FamilyLayoutOptions, + DefaultTemplateOptions, + ConnectorAnnotationOptions, + GroupTitlesOptions, + MarkersOptions, + IntervalsOptions, + ConnectorsOptions, + LabelsOptions, + CalloutOptions, + InteractivityOptions, + RenderingOptions, + FrameOptions, + ItemOptions, + ItemLayoutOptions, + ChildrenOrderOptions +}; +export default Options; \ No newline at end of file diff --git a/client/src/components/PdfViewDialog/PdfViewDialog.js b/client/src/components/PdfViewDialog/PdfViewDialog.js new file mode 100644 index 0000000..e5b3a52 --- /dev/null +++ b/client/src/components/PdfViewDialog/PdfViewDialog.js @@ -0,0 +1,113 @@ +import React, { useEffect } from 'react'; +import primitives from 'basicprimitives'; +import ReactGA from "react-ga"; +import PDFDocument from 'pdfkit-nodejs-webpack'; +import blobStream from 'blob-stream'; +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import IconButton from '@material-ui/core/IconButton'; +import CloseIcon from '@material-ui/icons/Close'; +import Photos from './Photos'; + +function PdfViewDialog(props) { + const { isVisible, onClose, config, fileName, caption, templates, onItemRender, plugin } = props; + + const [url, setUrl] = React.useState(null); + + useEffect(() => { + ReactGA.event({ + category: 'PDF Download', + action: 'Click', + label: fileName + }); + + let { items } = config; + + items = items.map(item => { + var imageName = "a"; + if (item.image != null) { + [, imageName] = item.image.match(/.*(.+?)\.png/m) || []; + } + return { + ...item, + image: Photos[imageName] + } + }); + + const orgDiagramPlugin = plugin({ + ...config, + items, + cursorItem: null, + hasSelectorCheckbox: primitives.common.Enabled.False, + templates: (templates || []), + onItemRender + }); + + var diagramSize = orgDiagramPlugin.getSize(); + + var doc = new PDFDocument({ size: [diagramSize.width + 100, diagramSize.height + 150] }); + var stream = doc.pipe(blobStream()); + + doc.save(); + + doc.fontSize(25) + .text(caption, 50, 50); + + orgDiagramPlugin.draw(doc, 50, 100); + + doc.restore(); + + doc.end(); + + stream.on('finish', function () { + const blob = stream.toBlobURL('application/pdf'); + setUrl(blob); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + isVisible && ( + + + + + + + + {caption} + + + + +
    +