Merge branch '157-replace-pintura-files-by-npm-package' into develop
|
@ -1,9 +1,11 @@
|
|||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: normal
|
||||
DOCKER_TAG: ${CI_COMMIT_REF_NAME}
|
||||
DOCKER_IMAGE_DEV: villas/web-dev:${CI_COMMIT_REF_NAME}
|
||||
|
||||
cache:
|
||||
untracked: true
|
||||
key: "$CI_PROJECT_ID"
|
||||
key: ${CI_PROJECT_ID}
|
||||
paths:
|
||||
- node_modules/
|
||||
- _site/vendor/
|
||||
|
@ -14,11 +16,12 @@ stages:
|
|||
- prepare
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
prepare:
|
||||
stage: prepare
|
||||
script:
|
||||
- docker build -t villas/web-dev .
|
||||
- docker build -t ${DOCKER_IMAGE_DEV} -f packaging/docker/Dockerfile.dev .
|
||||
tags:
|
||||
- linux
|
||||
- shell
|
||||
|
@ -30,7 +33,7 @@ build_job:
|
|||
script:
|
||||
- npm install
|
||||
- npm run build
|
||||
image: villas/web-dev
|
||||
image: ${DOCKER_IMAGE_DEV}
|
||||
artifacts:
|
||||
paths:
|
||||
- build/
|
||||
|
@ -42,8 +45,22 @@ test_job:
|
|||
stage: test
|
||||
script:
|
||||
- npm test
|
||||
image: villas/web-dev
|
||||
image: ${DOCKER_IMAGE_DEV}
|
||||
dependencies:
|
||||
- build_job
|
||||
tags:
|
||||
- docker
|
||||
|
||||
deploy:docker:
|
||||
stage: deploy
|
||||
script:
|
||||
- docker build -t ${DOCKER_IMAGE} -f packaging/docker/Dockerfile .
|
||||
- docker tag villas/web:${DOCKER_TAG} villas/web:latest
|
||||
- docker push villas/web:${DOCKER_TAG}
|
||||
- docker push villas/web:latest
|
||||
tags:
|
||||
- shell
|
||||
- linux
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
|
|
20
Dockerfile
|
@ -1,20 +0,0 @@
|
|||
FROM node:8.2
|
||||
|
||||
# Create app directory
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# use changes to package.json to force Docker not to use the cache
|
||||
# when we change our application's nodejs dependencies:
|
||||
ADD package.json /usr/src/app
|
||||
RUN npm install
|
||||
|
||||
# Install app dependencies
|
||||
COPY . /usr/src/app
|
||||
RUN npm run build
|
||||
|
||||
# Run the app in a local webserver
|
||||
RUN npm install -g serve
|
||||
EXPOSE 5000
|
||||
|
||||
CMD [ "serve", "-s", "build" ]
|
1
Dockerfile
Symbolic link
|
@ -0,0 +1 @@
|
|||
packaging/docker/Dockerfile
|
15785
package-lock.json
generated
19
package.json
|
@ -19,7 +19,10 @@
|
|||
"file-saver": "^1.3.8",
|
||||
"flux": "^3.1.2",
|
||||
"gaugeJS": "^1.3.2",
|
||||
"handlebars": "^4.1.1",
|
||||
"immutable": "^3.8.1",
|
||||
"jszip": "^3.2.0",
|
||||
"libcimsvg": "git+https://git.rwth-aachen.de/acs/public/cim/pintura-npm-package.git",
|
||||
"lodash": "^4.17.11",
|
||||
"prop-types": "^15.6.2",
|
||||
"rc-slider": "^8.6.3",
|
||||
|
@ -36,7 +39,7 @@
|
|||
"react-rnd": "^7.4.3",
|
||||
"react-router": "^4.3.1",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"react-scripts": "^1.1.5",
|
||||
"react-scripts": "^3.0.1",
|
||||
"react-sortable-tree": "^0.1.19",
|
||||
"react-svg-pan-zoom": "^2.18.0",
|
||||
"superagent": "^3.8.3",
|
||||
|
@ -51,5 +54,17 @@
|
|||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"proxy": "http://localhost:4000"
|
||||
"proxy": "http://localhost:4000",
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
21
packaging/docker/Dockerfile
Normal file
|
@ -0,0 +1,21 @@
|
|||
FROM node:12.2 AS builder
|
||||
|
||||
RUN apt-get install -y \
|
||||
git
|
||||
|
||||
# Create app directory
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# use changes to package.json to force Docker not to use the cache
|
||||
# when we change our application's nodejs dependencies:
|
||||
ADD package.json /usr/src/app
|
||||
RUN npm install
|
||||
|
||||
# Install app dependencies
|
||||
COPY . /usr/src/app
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx
|
||||
|
||||
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
|
4
packaging/docker/Dockerfile.dev
Normal file
|
@ -0,0 +1,4 @@
|
|||
FROM node:12.2
|
||||
|
||||
RUN apt-get install -y \
|
||||
git
|
|
@ -1,61 +0,0 @@
|
|||
#menu {
|
||||
color:#fff!important;
|
||||
background-color:#000!important
|
||||
}
|
||||
.dark-grey-background {
|
||||
color:black;
|
||||
background:#aaa;
|
||||
}
|
||||
.light-grey-background {
|
||||
color:black;
|
||||
background:#ddd;
|
||||
}
|
||||
.blue-grey-background {
|
||||
color:white;
|
||||
background:#607d8b;
|
||||
}
|
||||
.floating-panel-item {
|
||||
font-size:12px;
|
||||
}
|
||||
#floating-panel-list-div {
|
||||
background:#aaa;
|
||||
}
|
||||
.floating-panel-list {
|
||||
background:grey;
|
||||
border:none;
|
||||
}
|
||||
.w3-ul li {
|
||||
border-bottom:0px;
|
||||
}
|
||||
#sidebar {
|
||||
background:#607d8b;
|
||||
border-right:thick solid white;
|
||||
}
|
||||
.component-type-name {
|
||||
color:black;
|
||||
font-size:12px;
|
||||
}
|
||||
.floating-panel-name {
|
||||
font-size:12px;
|
||||
}
|
||||
.dark-font {
|
||||
color:black;
|
||||
}
|
||||
.dropdown-menu {
|
||||
border:medium solid black;
|
||||
background:#607d8b;
|
||||
border:medium solid black;
|
||||
border-width: 1px 1px 1px 1px;
|
||||
}
|
||||
.dropdown-menu h4 {
|
||||
color:white;
|
||||
}
|
||||
.dropdown-menu a {
|
||||
color: black;
|
||||
background:#ddd;
|
||||
font-size:14px;
|
||||
}
|
||||
.dropdown-menu a:hover {
|
||||
background:#bbb;
|
||||
color: white;
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
.bar {
|
||||
stroke: #000;
|
||||
stroke-width: 3px;
|
||||
}
|
||||
|
||||
.highlighted-node:hover {
|
||||
stroke: #ff0;
|
||||
}
|
||||
|
||||
line {
|
||||
stroke: #000;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.line {
|
||||
stroke: #000;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
.terminal-connnode {
|
||||
stroke: #000;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
.terminal-toponode {
|
||||
stroke: #000;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
.conduct {
|
||||
stroke: #000;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
.unknown {
|
||||
stroke: #f0f;
|
||||
stroke-width: 1px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
.acline {
|
||||
stroke: #000;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
#backing {
|
||||
fill: whitesmoke;
|
||||
}
|
||||
|
||||
/* Below here are SVG elements that we don't want the user to interact with
|
||||
therefore we disable pointer events */
|
||||
|
||||
.svglabel {
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
-webkit-user-select: none; /* Chrome all / Safari all */
|
||||
-moz-user-select: none; /* Firefox all */
|
||||
-ms-user-select: none; /* IE 10+ */
|
||||
}
|
||||
.svglabel-high {
|
||||
visibility: visible;
|
||||
font-size: 12px;
|
||||
font-family: "sans-serif";
|
||||
text-anchor: right;
|
||||
fill: black;
|
||||
stroke-width: 1px;
|
||||
pointer-events: none;
|
||||
-webkit-user-select: none; /* Chrome all / Safari all */
|
||||
-moz-user-select: none; /* Firefox all */
|
||||
-ms-user-select: none; /* IE 10+ */
|
||||
}
|
||||
.gridLine {
|
||||
stroke: #aaa;
|
||||
stroke-width: 1px;
|
||||
pointer-events: none;
|
||||
-webkit-user-select: none; /* Chrome all / Safari all */
|
||||
-moz-user-select: none; /* Firefox all */
|
||||
-ms-user-select: none; /* IE 10+ */
|
||||
}
|
||||
.gridLabel {
|
||||
font-size: 8px;
|
||||
font-family: "sans-serif";
|
||||
fill: grey;
|
||||
stroke-width: 0px;
|
||||
pointer-events: none;
|
||||
-webkit-user-select: none; /* Chrome all / Safari all */
|
||||
-moz-user-select: none; /* Firefox all */
|
||||
-ms-user-select: none; /* IE 10+ */
|
||||
}
|
Before Width: | Height: | Size: 65 KiB |
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="4" y="4" height="16" width="16" fill-opacity="0" stroke="black" stroke-width="1" />
|
||||
<line x1="4" y1="12" x2="8" y2="12" fill-opacity="0" stroke="black" stroke-width="1" />
|
||||
<line x1="8" y1="12" x2="14" y2="8" fill-opacity="0" stroke="black" stroke-width="1" />
|
||||
<line x1="15" y1="12" x2="20" y2="12" fill-opacity="0" stroke="black" stroke-width="1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="27" width="27" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle id="circle" cx="13" cy="14" r="6" fill-opacity="1" stroke="black" stroke-width="1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 909 B |
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="7,10 17,10 12,24" style="fill:black;stroke:black;stroke-width:1" />
|
||||
<line x1="12" y1="3" x2="12" y2="22" style="fill:black;stroke:black;stroke-width:1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 991 B |
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="36" width="36" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="diagonalHatch" width="8" height="8" patternUnits="userSpaceOnUse">
|
||||
<line x1="0" y1="0" x2="8" y2="8" style="stroke:black; stroke-width:1" />
|
||||
<line x1="8" y1="0" x2="0" y2="8" style="stroke:black; stroke-width:1" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect x="6" y="6" width="24" height="24" style="fill:url(#diagonalHatch);stroke:black;stroke-width:1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="36" width="36" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
|
||||
<path d="M0,2 L0,4 L2,3 z" fill="#000" />
|
||||
</marker>
|
||||
<pattern id="diagonalHatch" width="8" height="8" patternUnits="userSpaceOnUse">
|
||||
<line x1="8" y1="0" x2="0" y2="8" style="stroke:black; stroke-width:1" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<line x1="8" y1="8" x2="12" y2="12" stroke="#000" stroke-width="3" marker-end="url(#arrow)" />
|
||||
<line x1="16" y1="8" x2="20" y2="12" stroke="#000" stroke-width="3" marker-end="url(#arrow)" />
|
||||
<rect x="6" y="18" width="24" height="12" style="fill:url(#diagonalHatch);stroke:black;stroke-width:1" />
|
||||
<rect x="6" y="6" width="24" height="24" style="fill:none;stroke:black;stroke-width:1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.6 KiB |
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle id="circle" cx="12" cy="12" r="10" fill-opacity="0" stroke="black" stroke-width="1" />
|
||||
<path d="M4 12 C 6 5, 10 5, 12 12 S 19 19, 20 12" stroke="black" fill="transparent"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1,000 B |
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="8" y="8" width="8" height="8" style="fill:black;stroke:black;stroke-width:1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 904 B |
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="12" width="12" xmlns="http://www.w3.org/2000/svg" stroke-width="1">
|
||||
<circle cx="6" cy="6" r="1" fill-opacity="1" stroke="black" stroke-width="1" />
|
||||
<rect x="0" y="0" height="12" width="12" fill-opacity="0" stroke="black" stroke-width="1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1,009 B |
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2016-2017, RWTH Aachen University
|
||||
Authors: Richard Marston
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
A copy of the GNU General Public License is in the LICENSE file
|
||||
in the top level directory of this source tree.
|
||||
-->
|
||||
<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle id="leftcircle" cx="13" cy="10" r="7" fill-opacity="0" stroke="black" stroke-width="1" />
|
||||
<circle id="rightcircle" cx="13" cy="14" r="7" fill-opacity="0" stroke="black" stroke-width="1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1,016 B |
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2016-2017, RWTH Aachen University
|
||||
* Authors: Richard Marston
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU General Public License is in the LICENSE file
|
||||
* in the top level directory of this source tree.
|
||||
*/
|
||||
|
||||
var cimjson = cimjson || (function() {
|
||||
|
||||
var pathBase = '';
|
||||
const imageNames = {
|
||||
"cim:ACLineSegment": "images/term.svg",
|
||||
"cim:Terminal": "images/term.svg",
|
||||
"cim:Breaker": "images/brea.svg",
|
||||
"cim:ConnectivityNode": "images/conn.svg",
|
||||
"cim:EnergyConsumer": "images/cons.svg",
|
||||
"cim:EquivalentInjection": "images/cons.svg",
|
||||
"cim:ExternalNetworkInjection": "images/net.svg",
|
||||
"cim:PowerTransformer": "images/trans.svg",
|
||||
"cim:SolarGeneratingUnit": "images/solar.svg",
|
||||
"cim:SynchronousMachine": "images/sync.svg",
|
||||
"cim:TopologicalNode": "images/topo.svg",
|
||||
"cim:TransformerWinding": "images/trans.svg",
|
||||
};
|
||||
|
||||
const PinturaDiagramObjectPoints = "Pintura:DiagramObjectPoints";
|
||||
|
||||
var getImageName = function(type) {
|
||||
return pathBase + imageNames[type];
|
||||
}
|
||||
|
||||
var convertDiagramObjectToTemplateFormat = function(diagramObject, graph, categoryGraphName, diagramList) {
|
||||
|
||||
let originalPoints = diagramObject[PinturaDiagramObjectPoints];
|
||||
let preOffsetPoints = [];
|
||||
let imagePoints = [];
|
||||
let labelPoint;
|
||||
let object;
|
||||
let categoryGraph = graph[categoryGraphName];
|
||||
const imageHeight = 12;
|
||||
const imageWidth = 12;
|
||||
if (diagramObject["cim:DiagramObject.IdentifiedObject"] != undefined) {
|
||||
let rdfId = diagramObject["cim:DiagramObject.IdentifiedObject"]["rdf:resource"].substring(1);
|
||||
for (let index in originalPoints) {
|
||||
let point = originalPoints[index];
|
||||
preOffsetPoints.push(
|
||||
{
|
||||
"x": parseInt(point["cim:DiagramObjectPoint.xPosition"]).toString(),
|
||||
"y": parseInt(point["cim:DiagramObjectPoint.yPosition"]).toString()
|
||||
});
|
||||
imagePoints.push(
|
||||
{
|
||||
"imageHeight" : imageHeight.toString(),
|
||||
"imageWidth" : imageWidth.toString(),
|
||||
"x" : (parseInt(point["cim:DiagramObjectPoint.xPosition"]) - (imageWidth/2)).toString(),
|
||||
"y" : (parseInt(point["cim:DiagramObjectPoint.yPosition"]) - (imageHeight/2)).toString()
|
||||
});
|
||||
};
|
||||
labelPoint = {
|
||||
"x": (parseInt(preOffsetPoints[0].x) + (imageWidth/2)).toString(),
|
||||
"y": (parseInt(preOffsetPoints[0].y) - (imageHeight/2)).toString()
|
||||
};
|
||||
object =
|
||||
{
|
||||
"pintura:image" : getImageName(categoryGraphName),
|
||||
"pintura:rdfId" : rdfId,
|
||||
"pintura:points" : imagePoints,
|
||||
"pintura:label" : {
|
||||
"text": categoryGraph[rdfId]["cim:IdentifiedObject.name"],
|
||||
"x" : labelPoint.x,
|
||||
"y" : labelPoint.y
|
||||
}
|
||||
}
|
||||
while (preOffsetPoints.length > 1) {
|
||||
if (object["pintura:line"] == null) {
|
||||
object["pintura:line"] = [];
|
||||
}
|
||||
let line = {
|
||||
"x1": preOffsetPoints[0].x,
|
||||
"y1": preOffsetPoints[0].y,
|
||||
"x2": preOffsetPoints[1].x,
|
||||
"y2": preOffsetPoints[1].y
|
||||
};
|
||||
object["pintura:line"].push(line);
|
||||
preOffsetPoints.shift()
|
||||
}
|
||||
}
|
||||
let diagram = diagramObject["cim:DiagramObject.Diagram"]["rdf:resource"].substring(1);
|
||||
if (diagramList[diagram] === undefined){
|
||||
diagramList[diagram] = { "pintura:name" : graph["cim:Diagram"][diagram]["cim:IdentifiedObject.name"] };
|
||||
}
|
||||
if (diagramObject["cim:DiagramObject.IdentifiedObject"]) {
|
||||
let identifiedObject = diagramObject["cim:DiagramObject.IdentifiedObject"]["rdf:resource"].substring(1);
|
||||
if (diagramList[diagram]["components"] === undefined){
|
||||
diagramList[diagram]["components"] = {};
|
||||
}
|
||||
if (diagramList[diagram]["components"][categoryGraphName] === undefined){
|
||||
diagramList[diagram]["components"][categoryGraphName] = {};
|
||||
}
|
||||
diagramList[diagram]["components"][categoryGraphName][identifiedObject] = object;
|
||||
}
|
||||
};
|
||||
|
||||
var convertToTemplatableFormat = function(diagramObjects, graph) {
|
||||
|
||||
let output = { 'Diagram' : {} };
|
||||
let diagramList = output['Diagram'];
|
||||
|
||||
for (categoryGraphName in imageNames) {
|
||||
|
||||
let categoryGraph = graph[categoryGraphName];
|
||||
for (let key in categoryGraph) {
|
||||
let diagramObject = diagramObjects[key];
|
||||
if (diagramObject != undefined) {
|
||||
convertDiagramObjectToTemplateFormat(diagramObject, graph, categoryGraphName, diagramList);
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
var indexDiagramGraphByComponentType = function(input) {
|
||||
/*
|
||||
* Index the diagram object graph by the identified object's id so we don't
|
||||
* have to go hunting for the referenced object inside the diagram objects.
|
||||
*/
|
||||
let graph = {};
|
||||
for (let key in input) {
|
||||
let diagramObject = input[key];
|
||||
let diagram = diagramObject["cim:DiagramObject.Diagram"]["rdf:resource"].substring(1);
|
||||
if (diagramObject["cim:DiagramObject.IdentifiedObject"]) {
|
||||
let identifiedObject = input[key]["cim:DiagramObject.IdentifiedObject"]["rdf:resource"].substring(1);
|
||||
graph[identifiedObject] = input[key];
|
||||
}
|
||||
}
|
||||
return graph;
|
||||
};
|
||||
|
||||
var addDiagramObjectPointsToDiagramObjects = function(diagramObjectPointGraph, diagramObjectGraph){
|
||||
for (let key in diagramObjectPointGraph) {
|
||||
mergeMatchingDataIntoParentNodeArray(diagramObjectPointGraph[key], "cim:DiagramObjectPoint.DiagramObject", diagramObjectGraph, PinturaDiagramObjectPoints);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Create link to a member of an array of e.g. points
|
||||
*/
|
||||
var mergeMatchingDataIntoParentNodeArray = function(node, matchingElement, destinationGraph, destinationElement) {
|
||||
if (node[matchingElement]) {
|
||||
let id = node[matchingElement]["rdf:resource"].substr(1);
|
||||
if (destinationGraph[id]) {
|
||||
if (destinationGraph[id][destinationElement] === undefined) {
|
||||
destinationGraph[id][destinationElement] = [];
|
||||
}
|
||||
destinationGraph[id][destinationElement].push(node);
|
||||
}
|
||||
else {
|
||||
console.log("Could not find destination "+matchingElement+" to merge into "+destinationElement+".");
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log("Could not find matching element "+matchingElement+" to merge "+destinationElement+" into .");
|
||||
}
|
||||
};
|
||||
|
||||
var getTemplateJson = function(graph) {
|
||||
let updatedDiagramObjects = JSON.parse(JSON.stringify(graph['cim:DiagramObject']));
|
||||
let diagramObjectPoints = graph['cim:DiagramObjectPoint'];
|
||||
addDiagramObjectPointsToDiagramObjects(diagramObjectPoints, updatedDiagramObjects);
|
||||
|
||||
let diagramObjectsByIdentifiedObjects = indexDiagramGraphByComponentType(updatedDiagramObjects);
|
||||
|
||||
templateReadyFormat = convertToTemplatableFormat(diagramObjectsByIdentifiedObjects, graph);
|
||||
|
||||
return templateReadyFormat;
|
||||
};
|
||||
|
||||
return {
|
||||
setImagePathBase : function(path) {
|
||||
pathBase = path;
|
||||
},
|
||||
getTemplateJson,
|
||||
};
|
||||
}());
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = {
|
||||
cimjson
|
||||
};
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2016-2017, RWTH Aachen University
|
||||
* Authors: Richard Marston
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU General Public License is in the LICENSE file
|
||||
* in the top level directory of this source tree.
|
||||
*/
|
||||
|
||||
var cimsvg = cimsvg || (function() {
|
||||
|
||||
var svgNode = null;
|
||||
var xmlNode = null;
|
||||
var pinturaNode = null;
|
||||
var sidebarNode = null;
|
||||
|
||||
function handler() {
|
||||
//console.log(this.getResponseHeader('content-type'));
|
||||
}
|
||||
|
||||
var includeFile = function(fileName, callback) {
|
||||
let dom = svgNode.ownerDocument;
|
||||
let newTag = dom.createElement("script");
|
||||
newTag.type = "text/javascript";
|
||||
newTag.src=fileName;
|
||||
if ( callback != undefined ) {
|
||||
newTag.onload=function() {
|
||||
callback();
|
||||
};
|
||||
}
|
||||
svgNode.parentElement.appendChild(newTag);
|
||||
};
|
||||
|
||||
var applyTemplate = function(data) {
|
||||
var template = Handlebars.templates['cim2svg'];
|
||||
return template(data);
|
||||
};
|
||||
|
||||
var loadFile = function(fileContents) {
|
||||
if (cimxml.moreXmlData(fileContents)) {
|
||||
baseJson = cimxml.getBaseJson();
|
||||
templateJson = cimjson.getTemplateJson(baseJson);
|
||||
svgNode.ownerDocument.getElementById('diagrams').innerHTML = applyTemplate(templateJson);
|
||||
if(sidebarNode != null) {
|
||||
cimmenu.populateSidebar(sidebarNode, templateJson);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var setFileCount = function(count) {
|
||||
cimxml.setRdfFileCount(count);
|
||||
};
|
||||
|
||||
var isNode = false;
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
isNode = true;
|
||||
}
|
||||
|
||||
var updateComponent = function(type, id, attribute, value) {
|
||||
cimxml.updateComponentInBaseJson(type, id, attribute, value)
|
||||
baseJson = cimxml.getBaseJson();
|
||||
templateJson = cimjson.getTemplateJson(baseJson);
|
||||
if (attribute === "cim:IdentifiedObject.name") {
|
||||
buttonId = '#' + id + "-sidebar-button"
|
||||
button = sidebarNode.querySelector(buttonId)
|
||||
button.innerHTML = value;
|
||||
}
|
||||
};
|
||||
|
||||
var loadXml = function(fileName, callback) {
|
||||
// Create a connection to the file.
|
||||
var Connect = new XMLHttpRequest();
|
||||
// Define which file to open and
|
||||
Connect.open("GET", fileName, true);
|
||||
Connect.setRequestHeader("Content-Type", "text/xml");
|
||||
Connect.onreadystatechange = handler;
|
||||
Connect.onload = function (e) {
|
||||
if(Connect.readyState === 4) {
|
||||
if(Connect.status === 200) {
|
||||
callback(Connect.responseXML);
|
||||
}
|
||||
else {
|
||||
console.log(Connect.statusText);
|
||||
}
|
||||
}
|
||||
};
|
||||
// send the request.
|
||||
Connect.send(null);
|
||||
};
|
||||
|
||||
return {
|
||||
init : function(svg, sidebar, componentAttributes, componentCreation) {
|
||||
svgNode = svg;
|
||||
sidebarNode = sidebar;
|
||||
includeFile("handlebars.runtime.js", function() {
|
||||
includeFile("src/cimview.js", function() {
|
||||
cimview.init(svgNode);
|
||||
if(sidebarNode != undefined) {
|
||||
includeFile("src/cimmenu.js", function() {
|
||||
cimmenu.init(componentAttributes)
|
||||
});
|
||||
}
|
||||
includeFile("templates/template.js", function(){
|
||||
includeFile("src/cimxml.js", function(){
|
||||
includeFile("src/cimjson.js", function(){});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
loadXml("templates/generated_add_components/menu.xml", function(xml){
|
||||
if(componentCreation != undefined) {
|
||||
accordion = componentCreation.querySelector('#component-creation-list-div')
|
||||
accordion.innerHTML = xml.documentElement.innerHTML;
|
||||
}
|
||||
});
|
||||
},
|
||||
setSVG : function(svg) {
|
||||
svgNode = svg;
|
||||
},
|
||||
loadFile,
|
||||
setFileCount,
|
||||
updateComponent,
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
if (cimsvg.isNode) {
|
||||
module.exports = {
|
||||
cimsvg
|
||||
}
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2016-2017, RWTH Aachen University
|
||||
* Authors: Richard Marston
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU General Public License is in the LICENSE file
|
||||
* in the top level directory of this source tree.
|
||||
*/
|
||||
|
||||
var cimview = cimview || (function() {
|
||||
|
||||
var svgNode = null;
|
||||
|
||||
var zoomSizes = [
|
||||
{ width: 1024, height: 768 },
|
||||
{ width: 920, height: 690 },
|
||||
{ width: 816, height: 612 },
|
||||
{ width: 712, height: 532 },
|
||||
{ width: 608, height: 456 },
|
||||
{ width: 504, height: 378 },
|
||||
{ width: 400, height: 300 },
|
||||
];
|
||||
|
||||
var zoomLevel = 0;
|
||||
|
||||
var zoomToLevel = function(level) {
|
||||
zoomLevel = level;
|
||||
let rect = getViewBox();
|
||||
centreOfGrid = { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };
|
||||
rect.width = zoomSizes[level].width;
|
||||
rect.height = zoomSizes[level].height;
|
||||
rect.x = centreOfGrid.x - (rect.width / 2);
|
||||
rect.y = centreOfGrid.y - (rect.height / 2);
|
||||
setViewBox(rect);
|
||||
};
|
||||
|
||||
var zoomOut = function() {
|
||||
let level = zoomLevel-1;
|
||||
if (level < 0) {
|
||||
level = 0;
|
||||
}
|
||||
zoomToLevel(level);
|
||||
//document.getElementById("zoomer").value=level;
|
||||
};
|
||||
|
||||
var zoomIn = function() {
|
||||
let level = zoomLevel+1;
|
||||
let lastIndex = zoomSizes.length-1;
|
||||
if (level > lastIndex) {
|
||||
level = lastIndex;
|
||||
}
|
||||
zoomToLevel(level);
|
||||
//document.getElementById("zoomer").value=level;
|
||||
};
|
||||
|
||||
var pan = function(point) {
|
||||
let rect = getViewBox();
|
||||
rect.x += point.x;
|
||||
rect.y += point.y;
|
||||
setViewBox(rect);
|
||||
};
|
||||
|
||||
var clearGrid = function() {
|
||||
let oldLines = Array.from(svgNode.getElementsByClassName("gridLine"));
|
||||
oldLines.forEach(function(key) {
|
||||
key.remove();
|
||||
});
|
||||
let oldLabels = Array.from(svgNode.getElementsByClassName("gridLabel"));
|
||||
oldLabels.forEach(function(key) {
|
||||
key.remove();
|
||||
});
|
||||
};
|
||||
|
||||
var createLocationMarker = function(id, loc, x, y) {
|
||||
let grid = svgNode.ownerDocument.getElementById("grid");
|
||||
let textAttributes = {
|
||||
"x": x,
|
||||
"y": y,
|
||||
"class": "gridLabel",
|
||||
"id": id,
|
||||
};
|
||||
let text = createSvgTag("text", textAttributes);
|
||||
text.innerHTML = loc;
|
||||
grid.appendChild(text);
|
||||
};
|
||||
|
||||
var createGridLine = function(x1, y1, x2, y2) {
|
||||
let grid = svgNode.ownerDocument.getElementById("grid");
|
||||
let lineAttributes = {
|
||||
"x1": x1,
|
||||
"x2": x2,
|
||||
"y1": y1,
|
||||
"y2": y2,
|
||||
"class": "gridLine",
|
||||
};
|
||||
let line = createSvgTag("line", lineAttributes);
|
||||
grid.appendChild(line);
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a tag in the svg namespace
|
||||
*/
|
||||
const createSvgTag = function(tagname, attributes) {
|
||||
let xmlns="http://www.w3.org/2000/svg";
|
||||
let newTag = svgNode.ownerDocument.createElementNS(xmlns, tagname);
|
||||
for (let key in attributes) {
|
||||
newTag.setAttribute(key, attributes[key]);
|
||||
}
|
||||
return newTag;
|
||||
};
|
||||
|
||||
var calculateStartOffset = function(distanceFromOrigin, gridSize) {
|
||||
let offset;
|
||||
if (distanceFromOrigin < 0) {
|
||||
offset = distanceFromOrigin - ( distanceFromOrigin % gridSize );
|
||||
}
|
||||
else {
|
||||
offset = distanceFromOrigin + gridSize - ( distanceFromOrigin % gridSize );
|
||||
}
|
||||
return offset;
|
||||
};
|
||||
|
||||
var createGrid = function() {
|
||||
clearGrid();
|
||||
let gridSize = 100;
|
||||
let viewBoxRect = getViewBox();
|
||||
/* horizontal lines */
|
||||
let startOffsetY = calculateStartOffset(viewBoxRect.y, gridSize);
|
||||
let startOffsetX = calculateStartOffset(viewBoxRect.x, gridSize);
|
||||
for (let i=0; i<(viewBoxRect.height/gridSize); i++) {
|
||||
let yval = i*gridSize+startOffsetY;
|
||||
createGridLine(viewBoxRect.x, yval, viewBoxRect.width+viewBoxRect.x, yval);
|
||||
createLocationMarker(yval+"y", yval.toString(), viewBoxRect.x+10, yval+20);
|
||||
}
|
||||
/* vertical lines */
|
||||
for (let i=0; i<(viewBoxRect.width/gridSize); i++) {
|
||||
let xval = i*gridSize+startOffsetX;
|
||||
createGridLine(xval, viewBoxRect.y, xval, viewBoxRect.height+viewBoxRect.y);
|
||||
createLocationMarker(xval+"x", xval.toString(), xval+10, viewBoxRect.y+20);
|
||||
}
|
||||
};
|
||||
|
||||
var fit = function() {
|
||||
setViewBox(svgNode.getElementById('diagrams').getBBox());
|
||||
};
|
||||
|
||||
var getViewBox = function() {
|
||||
let rect = {};
|
||||
viewBoxString = svgNode.getAttribute("viewBox");
|
||||
viewBoxElements = viewBoxString.split(" ");
|
||||
rect.x = parseInt(viewBoxElements[0]);
|
||||
rect.y = parseInt(viewBoxElements[1]);
|
||||
rect.width = parseInt(viewBoxElements[2]);
|
||||
rect.height = parseInt(viewBoxElements[3]);
|
||||
return rect;
|
||||
};
|
||||
|
||||
var setViewBox = function(rect) {
|
||||
let viewBoxString = rect.x+" "+rect.y+" "+rect.width+" "+rect.height;
|
||||
svgNode.setAttribute("viewBox", viewBoxString);
|
||||
let bg = svgNode.ownerDocument.getElementById("backing");
|
||||
bg.setAttribute("x", rect.x);
|
||||
bg.setAttribute("y", rect.y);
|
||||
bg.setAttribute("width", "100%");
|
||||
bg.setAttribute("height", "100%");
|
||||
createGrid();
|
||||
};
|
||||
|
||||
var clearDisplay = function() {
|
||||
while (svgNode.firstChild) {
|
||||
svgNode.removeChild(svgNode.firstChild);
|
||||
}
|
||||
};
|
||||
|
||||
var hideAllLabels = function() {
|
||||
Array.from(svgNode.getElementsByClassName("svglabel")).forEach(function (label) {
|
||||
label.setAttributeNS(null, "visibility", "hidden");
|
||||
});
|
||||
};
|
||||
|
||||
var init = function(svg) {
|
||||
svgNode = svg;
|
||||
let rect = { x: "-100", y: "-100", width: "1024", height: "768" };
|
||||
setViewBox(rect);
|
||||
};
|
||||
|
||||
var setSVG = function(svg) {
|
||||
svgNode = svg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify the functions that this module exports
|
||||
*/
|
||||
return {
|
||||
init,
|
||||
pan,
|
||||
fit,
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
setSVG
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = {
|
||||
cimview
|
||||
}
|
||||
}
|
|
@ -1,253 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2016-2017, RWTH Aachen University
|
||||
* Authors: Richard Marston
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU General Public License is in the LICENSE file
|
||||
* in the top level directory of this source tree.
|
||||
*/
|
||||
|
||||
var cimxml = cimxml || (function() {
|
||||
|
||||
var xmlDoc;
|
||||
var rdfFileCount = 0;
|
||||
var rdfFileReceived = 0;
|
||||
var jsonBaseData = null;
|
||||
const xmlnsString = "xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:cim='http://iec.ch/TC57/2012/CIM-schema-cim16#' xmlns:md='http://iec.ch/TC57/61970-552/ModelDescription/1#' xmlns:entsoe='http://entsoe.eu/Secretariat/ProfileExtension/2#'";
|
||||
|
||||
var getRawXML = function() {
|
||||
return xmlDoc;
|
||||
};
|
||||
|
||||
var getBaseJson = function() {
|
||||
return jsonBaseData;
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert a small data item into XML and add it to a node
|
||||
*/
|
||||
var addChild = function(object, name, doc, owner) {
|
||||
|
||||
let child;
|
||||
if (typeof object == "object") {
|
||||
child = doc.createElement(name);
|
||||
child.setAttribute("rdf:resource", object["rdf:resource"]);
|
||||
}
|
||||
else {
|
||||
child = doc.createElement(name);
|
||||
child.innerHTML = object;
|
||||
}
|
||||
owner.appendChild(child);
|
||||
};
|
||||
|
||||
var copyXmlDataIntoObject = function(object, node) {
|
||||
|
||||
let childNodes = node.children;
|
||||
for (let childIndex = 0; childIndex < childNodes.length; childIndex++) {
|
||||
let thisChild = childNodes[childIndex];
|
||||
if (thisChild.nodeType == Node.ELEMENT_NODE) {
|
||||
if (thisChild.attributes.length > 0) {
|
||||
object[thisChild.nodeName] = { "rdf:resource": thisChild.getAttribute("rdf:resource")};
|
||||
}
|
||||
else {
|
||||
object[thisChild.nodeName] = thisChild.innerHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var importXmlNodeIntoGraph = function(graph, nodeCategory, node, id) {
|
||||
|
||||
let thisObject = { };
|
||||
|
||||
thisObject['rdfid'] = id
|
||||
|
||||
copyXmlDataIntoObject(thisObject, node);
|
||||
|
||||
if (!graph[nodeCategory]) {
|
||||
graph[nodeCategory] = {};
|
||||
}
|
||||
|
||||
/* add the new object to the graph */
|
||||
let categoryGraph = graph[nodeCategory];
|
||||
categoryGraph[id] = thisObject;
|
||||
};
|
||||
|
||||
var importAboutDataIntoGraph = function(graph, nodeCategory, thisNode, id) {
|
||||
|
||||
if (graph[nodeCategory] && graph[nodeCategory][id]) {
|
||||
let thisObject = graph[nodeCategory][id].about = [];
|
||||
copyXmlDataIntoObject(thisObject, thisNode);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* What is the rdf:ID attribute for this node
|
||||
*/
|
||||
var getRdfId = function(node) {
|
||||
|
||||
let rdfId = node.getAttribute("rdf:ID");
|
||||
return rdfId;
|
||||
};
|
||||
|
||||
/*
|
||||
* What is the rdf:about attribute for this node
|
||||
*/
|
||||
var getRdfAbout = function(node) {
|
||||
|
||||
let rdfAbout = node.getAttribute("rdf:about");
|
||||
return rdfAbout;
|
||||
};
|
||||
|
||||
/*
|
||||
* Clear the buffer of XML data that we use to handle multiple file imports
|
||||
*/
|
||||
var clearXmlData = function() {
|
||||
|
||||
xmlDoc = null;
|
||||
};
|
||||
|
||||
var xmlns = function(){
|
||||
|
||||
return xmlnsString;
|
||||
};
|
||||
|
||||
/*
|
||||
* Function to create a JSON document from an RDF (XML) DOM.
|
||||
* RDF is a shallow xml format so we don"t have to dig too
|
||||
* deep, a node will only ever have children or attributes.
|
||||
*/
|
||||
var createObjectGraphFromXml = function( xmlData ) {
|
||||
|
||||
let graph = {};
|
||||
let topLevelNodes = xmlData.documentElement.childNodes;
|
||||
|
||||
/* loop through all of the top level nodes */
|
||||
for (let topLevelIndex=0; topLevelIndex<topLevelNodes.length; topLevelIndex++) {
|
||||
let thisNode = topLevelNodes[topLevelIndex];
|
||||
if (thisNode.nodeType == Node.ELEMENT_NODE)
|
||||
{
|
||||
/* find out what type of node we are reading */
|
||||
let nodeCategory = thisNode.nodeName;
|
||||
let id = getRdfId(thisNode);
|
||||
if (id) {
|
||||
importXmlNodeIntoGraph(graph, nodeCategory, thisNode, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we need all of the rdf:id nodes before importing the rdf:about nodes */
|
||||
for (let topLevelIndex=0; topLevelIndex<topLevelNodes.length; topLevelIndex++) {
|
||||
let thisNode = topLevelNodes[topLevelIndex];
|
||||
if (thisNode.nodeType == Node.ELEMENT_NODE)
|
||||
{
|
||||
/* find out what type of node we are reading */
|
||||
let nodeCategory = thisNode.nodeName;
|
||||
let id = getRdfAbout(thisNode);
|
||||
if (id) {
|
||||
importAboutDataIntoGraph(graph, nodeCategory, thisNode, id.substr(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return graph;
|
||||
};
|
||||
|
||||
/*
|
||||
* Tell this module how many pieces the data will be arriving in
|
||||
*/
|
||||
var setRdfFileCount = function(count) {
|
||||
|
||||
rdfFileCount = count;
|
||||
};
|
||||
|
||||
/*
|
||||
* Have we received all the data files yet?
|
||||
*/
|
||||
var checkIfParseReady = function() {
|
||||
|
||||
if (rdfFileReceived > 0) {
|
||||
if (rdfFileCount == rdfFileReceived) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Here comes some more data
|
||||
*/
|
||||
var moreXmlData = function(text, draw=true) {
|
||||
|
||||
if (!xmlDoc) {
|
||||
xmlDoc = getDOM("<rdf:RDF "+xmlns()+"/>");
|
||||
}
|
||||
|
||||
let newDoc = getDOM(text);
|
||||
let nodes = newDoc.documentElement.childNodes;
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
if (nodes[i].nodeType == Node.ELEMENT_NODE) {
|
||||
if (nodes[i].nodeName != "md:FullModel") {
|
||||
xmlDoc.documentElement.appendChild(nodes[i].cloneNode(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rdfFileReceived++;
|
||||
if (checkIfParseReady()) {
|
||||
jsonBaseData = createObjectGraphFromXml(xmlDoc);
|
||||
rdfFileReceived = 0;
|
||||
rdfFileCount = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/*
|
||||
* Different method of getting DOM required for some platforms
|
||||
*/
|
||||
var getDOM = function(text) {
|
||||
|
||||
let newDoc;
|
||||
if ( window.DOMParser ) {
|
||||
newDoc = ( new DOMParser() ).parseFromString( text, "application/xml" );
|
||||
}
|
||||
else if( window.ActiveXObject ) {
|
||||
let xmlObject = new ActiveXObject( "Microsoft.XMLDOM" );
|
||||
xmlObject.async = false;
|
||||
xmlObject.loadXML( text );
|
||||
newDoc = xmlObject;
|
||||
xmlObject = undefined;
|
||||
}
|
||||
else {
|
||||
throw new Error( "Cannot find an XML parser!" );
|
||||
}
|
||||
return newDoc;
|
||||
};
|
||||
|
||||
var updateComponentInBaseJson = function(type, id, attribute, value) {
|
||||
jsonBaseData[type][id][attribute] = value
|
||||
};
|
||||
|
||||
return {
|
||||
getBaseJson,
|
||||
setRdfFileCount,
|
||||
clearXmlData,
|
||||
moreXmlData,
|
||||
getRawXML,
|
||||
updateComponentInBaseJson,
|
||||
};
|
||||
}());
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = {
|
||||
cimxml
|
||||
};
|
||||
}
|
|
@ -27,12 +27,5 @@
|
|||
To begin the development, run `npm start`.
|
||||
To create a production bundle, use `npm run build`.
|
||||
-->
|
||||
<link rel="stylesheet" href="%PUBLIC_URL%/Pintura/css/svg.css"/>
|
||||
<script type="text/javascript" src="%PUBLIC_URL%/Pintura/js/cimsvg.js"></script>
|
||||
<script type="text/javascript" src="%PUBLIC_URL%/Pintura/js/cimview.js"></script>
|
||||
<script type="text/javascript" src="%PUBLIC_URL%/Pintura/js/cimxml.js"></script>
|
||||
<script type="text/javascript" src="%PUBLIC_URL%/Pintura/js/cimjson.js"></script>
|
||||
<script type="text/javascript" src="%PUBLIC_URL%/Pintura/js/handlebars.runtime.js"></script>
|
||||
<script type="text/javascript" src="%PUBLIC_URL%/Pintura/templates/template.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -85,8 +85,8 @@ class EditableHeader extends React.Component {
|
|||
<FormControl type='text' bsSize='large' value={this.state.title} onChange={this.onChange} style={editStyle} autoFocus />
|
||||
</form>
|
||||
|
||||
<a onClick={this.save}><Icon icon='check' style={iconStyle} /></a>
|
||||
<a onClick={this.cancel}><Icon icon='times' style={iconStyle} /></a>
|
||||
<a href={'#'} onClick={this.save}><Icon icon='check' style={iconStyle} /></a>
|
||||
<a href={'#'} onClick={this.cancel}><Icon icon='times' style={iconStyle} /></a>
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
@ -95,12 +95,12 @@ class EditableHeader extends React.Component {
|
|||
{this.state.title}
|
||||
</h1>
|
||||
|
||||
<a onClick={this.edit}><Icon icon='edit' style={iconStyle} /></a>
|
||||
<a href={'#'} onClick={this.edit}><Icon icon='edit' style={iconStyle} /></a>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
EditableHeader.PropTypes = {
|
||||
EditableHeader.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func
|
||||
};
|
||||
|
|
|
@ -74,7 +74,7 @@ class CustomTable extends Component {
|
|||
if (linkKey && data[linkKey] != null) {
|
||||
cell.push(<Link to={child.props.link + data[linkKey]}>{content}</Link>);
|
||||
} else if (child.props.clickable) {
|
||||
cell.push(<a onClick={() => child.props.onClick(index)}>{content}</a>);
|
||||
cell.push(<a href={'#'} onClick={() => child.props.onClick(index)}>{content}</a>);
|
||||
} else {
|
||||
cell.push(content);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import React from 'react';
|
|||
import {ReactSVGPanZoom} from 'react-svg-pan-zoom';
|
||||
import config from '../../config';
|
||||
import '../../styles/simple-spinner.css';
|
||||
|
||||
import { cimsvg } from 'libcimsvg';
|
||||
|
||||
// Do not show Pintura's grid
|
||||
const pinturaGridStyle = {
|
||||
|
@ -82,7 +82,7 @@ function detachComponentEvents() {
|
|||
class WidgetTopology extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.svgElem = null;
|
||||
this.svgElem = React.createRef();
|
||||
this.Viewer = null;
|
||||
|
||||
this.state = {
|
||||
|
@ -90,15 +90,8 @@ class WidgetTopology extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
setSVG(svg) {
|
||||
this.svgElem = svg;
|
||||
window.cimsvg.setSVG(svg); // function not available in upstream source
|
||||
window.cimview.setSVG(svg); // function not available in upstream source
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.svgElem) {
|
||||
window.cimjson.setImagePathBase(process.env.PUBLIC_URL + '/Pintura/');
|
||||
window.onMouseLeave = function() {};
|
||||
window.onMouseOver = function() {};
|
||||
window.onMouseLeave = function() {};
|
||||
|
@ -122,18 +115,25 @@ class WidgetTopology extends React.Component {
|
|||
.then( response => {
|
||||
if (response.status === 200) {
|
||||
this.setState({'visualizationState': 'ready' });
|
||||
window.cimxml.clearXmlData()
|
||||
window.cimsvg.setFileCount(1);
|
||||
return response.text().then( contents => {
|
||||
window.cimsvg.loadFile(contents);
|
||||
window.cimview.fit();
|
||||
attachComponentEvents();
|
||||
if (this.svgElem) {
|
||||
let cimsvgInstance = new cimsvg(this.svgElem.current);
|
||||
cimsvg.setCimsvg(cimsvgInstance);
|
||||
cimsvgInstance.setFileCount(1);
|
||||
cimsvgInstance.loadFile(contents);
|
||||
//cimsvgInstance.fit();
|
||||
attachComponentEvents();
|
||||
}
|
||||
else {
|
||||
console.error("The svgElem variable is not initialized before the attempt to create the cimsvg instance.");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new Error('Request failed');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
this.setState({
|
||||
'visualizationState': 'show_message',
|
||||
'message': 'Topology could not be loaded.'});
|
||||
|
@ -169,10 +169,10 @@ class WidgetTopology extends React.Component {
|
|||
tool="pan"
|
||||
width={this.props.widget.width-2} height={this.props.widget.height-2} >
|
||||
<svg width={this.props.widget.width} height={this.props.widget.height}>
|
||||
<svg ref={ c => this.setSVG(c) } width={this.props.widget.width} height={this.props.widget.height}>
|
||||
<rect id="backing" style={pinturaBackingStyle} />
|
||||
<g id="grid" style={pinturaGridStyle} />
|
||||
<g id="diagrams"/>
|
||||
<svg ref={ this.svgElem } width={this.props.widget.width} height={this.props.widget.height}>
|
||||
<rect className="backing" style={pinturaBackingStyle} />
|
||||
<g className="grid" style={pinturaGridStyle} />
|
||||
<g className="diagrams"/>
|
||||
</svg>
|
||||
</svg>
|
||||
</ReactSVGPanZoom>
|
||||
|
|
|
@ -30,7 +30,6 @@ class FilesDataManager extends RestDataManager {
|
|||
|
||||
upload(file, token = null, progressCallback = null, finishedCallback = null) {
|
||||
RestAPI.upload(this.makeURL('/upload'), file, token, progressCallback).then(response => {
|
||||
console.log(response);
|
||||
|
||||
AppDispatcher.dispatch({
|
||||
type: 'files/uploaded',
|
||||
|
|