Compare commits

...

12 Commits

Author SHA1 Message Date
rui hildt cb2caffe82 Remove extra space 2020-10-12 17:47:02 +02:00
rui hildt a7ea07eb85 Delete old map svg file 2020-10-12 17:46:09 +02:00
rui hildt 401076d222 Add description of the app 2020-10-12 17:27:39 +02:00
rui hildt e8a3eb6fef Update Backend deployed url & homepage 2020-10-12 11:42:04 +02:00
rui hildt 877b54f6aa Improve map and layout 2020-10-08 16:02:30 +02:00
rui hildt 7bdaf1f619 Replace graph with an svg path 2020-10-07 23:27:30 +02:00
ruihildt 60bbf7a890 Update source link 2020-09-28 16:15:03 +00:00
rui hildt c62106f2c1 Improve styling 2020-08-16 20:45:15 +02:00
rui hildt 121f5c6e92 Change git repo url 2020-08-16 19:28:35 +02:00
rui hildt 4d1984444a Update package versions 2020-08-16 19:26:20 +02:00
rui hildt 97e5dc6aff Update homepage description and title 2020-08-16 19:21:28 +02:00
Rui Hildt 906ba408d9 Update Backend Git link 2020-03-20 13:19:28 +00:00
10 changed files with 3755 additions and 4362 deletions

25
.gitignore vendored
View File

@ -1,23 +1,2 @@
# 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*
node_modules
build

View File

@ -4,6 +4,6 @@ Find the the shortest path between different cities in Belgium with Dijkstra alg
- Frontend: https://dijkstra.ruihildt.xyz/
- Backend: https://dijkstra-backend.herokuapp.com/
- Backend: https://dijkstra-backend.ruihildt.xyz/
- Backend Source: https://github.com/ruihildt/dijkstra/
- Backend Source: https://git.ruihildt.xyz/ruihildt/dijkstra-backend

7443
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,21 @@
{
"name": "dijkstra-frontend",
"homepage": "http://dijkstra.ruihildt.xyz",
"version": "0.1.0",
"private": true,
"dependencies": {
"@ant-design/icons": "^4.2.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"antd": "^3.26.9",
"antd": "^4.6.6",
"axios": "^0.19.2",
"react": "^16.12.0",
"react": "^16.13.1",
"react-dom": "^16.12.0",
"react-graph-vis": "^1.0.5",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.1",
"react-scripts": "^3.4.3",
"react-sigma": "^1.2.34",
"react-svgmt": "^1.1.11",
"styled-components": "^5.0.1"
},
"scripts": {

124
public/belgium-map.svg Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1"
id="svg116" inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)" sodipodi:docname="belgium-map.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 951 770.6"
style="enable-background:new 0 0 951 770.6;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:#FDC646;}
.st2{fill:none;stroke:#00856E;stroke-width:4;stroke-miterlimit:10;}
.st3{fill:none;stroke:#00856E;stroke-width:4;}
.st4{fill:none;stroke:#00856E;stroke-width:4;}
.st5{fill:none;stroke:#00856E;stroke-width:4;}
.st6{fill:none;stroke:#00856E;stroke-width:4;}
.st7{fill:none;stroke:#00856E;stroke-width:4;}
.st9{font-size:25px;}
.st10{fill:#00856E;}
.st11{fill:#FFC408;}
</style>
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview118" inkscape:current-layer="g10" inkscape:cx="294.90731" inkscape:cy="463.42751" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="976" inkscape:window-maximized="1" inkscape:window-width="1920" inkscape:window-x="1920" inkscape:window-y="26" inkscape:zoom="0.80364372" objecttolerance="10" pagecolor="#ffffff" showgrid="false">
</sodipodi:namedview>
<path id="path2" class="st0" d="M0,0h951v770.6H0V0z"/>
<g id="g10">
<path id="path6" class="st1" d="M420.8,63.6l-12,14l-18,18l-9,4l0,0l-3,2l-3,2h-6l0,0l-8,3l-2,3l-4,4l-6,2h-2l-2-2h-2l-2,4l-4,1h-3
l-1-2l2-2v-2l-1-2l-2,1l-2,3l-1,2l-5,1l-9-1h-1l-1-1l0,0l-2-1v-12l1-3l-1-2l-3-1l-2,1l-3-3l0,0l-4-1h-6l0,0l-6-3l-8-1l-1-1h-3l-2-1
l-7-5l-2-1h-1l0,0h-1v5l-1,1l-1-1l-3-2l0,0l-3,2l-3,1l-4-2l0,0h-1l0,0v1l2,16h-3l-4,1l-2,1h-11l0,0l-2-1h-1l-2-4l-2-1l-4-4l-5-5v-1
l-4-4v-2h2v-1l-1-3l-1-2l5-5l1-3l-1-2l-2-4l-2-7h-2l-2,2l-7,2l-10,3l-5,3l-3,1h-4l-2,2l-2,1v-3h-2l-2,3h-1l2-5h-1l-2,2l-1,4l-2,1
l-8,3l-4,2l-3,1l-9,4l-7,7l-14,8l-5,3l-5,4l-3,1l-3,1l2,4v2l-1-1l-1-1l-1-1l0,0l-2-1l-1,2l-1,1l0,0l-9,7l-11,7l-4,2l-7,5l-8,4l-4,3
l0,0l-6,4l-7,3l-7,4h-1l-7,4l-1,1l-3,2l-2,1l-8,4l-1,1l1,3v2l1,2l1,2l0,0l1,3l2,14l-1,4l2,5h1l1,1l5,2l1,1v2l1,4v1l2,2l2,5l-3,3v2
l-5,6l-2,2l1,1h3v3l2,3l-1,5l1,2l-1,2l1,4l-3,5l3,1h1l1,4l2,3l1,6h5l1-1l2-3l1,1h1l1,1l1,2h8l1,1l0,0l1,2v4l1,2l1,2l4,3l3,3l1,4
l-1,1l5,2l1,3v3l2,4l5,3h2l5-3l2,2l1,3l2,2l1,1h4l1,2h3l1-1h2l2-1v-3l1-4v-2h2l1-2l-1-3l3-3h6l2-2l1-2l3-1l2-2l1-1h4l0,0l5-2l0,0
l2-1l1,1l4,1h2l6-5h3l2-1h2l3,1v3l4,7l2,3l1,1v2l1,2l3,2l1,2l-1,2l2,2l2,2l4,1h3l3,5v3l3,4l-1,1l-5,3l-1,1v3l1,3l1,2l-1,2l1,2l1,4
l2,2l3,3v5l1,1l-1,4l2,4l-1,2v1l1,3l-1,1l1,1l-1,2v5l2,3l2,2l10,6l5,1l5,5h1l1-1l2-3h5l2-1h1l1-1h5l1-4l3-5l6,1l4,2l2,2l-4,5l-1,1
l-1,2l1,4l4-1l5-2h4l3-1l2,1l3,2h1l4-3l1,1l5,6l1,2v1l3,3l2,1l1,2v5l2,1l1,2v4l1,4v7l-3,6l-1,4l1,2l1,1v4l2,3l1,4l2,3v2l2,2l3,1h1
l-1-3l1-1l4,3l1-2l-1-4l2-5l2-3l2-1l2,1l3-3l6,2l3-1v1l2,2h1v-2l6-1l5,5l2,1l2-1l1,1v2l4,1l7-2l4-3l2-1h1l1,1l3-1l2,1l2-1l2-2h3
l1-2l1-1l1,1l1,3l1,1l2,1l2,1l1,4h2l2,2l2,5l2-2l2,1l3,3l1,1l1,1l1,3v7h2l1,1v3l1,2h3l4-2v-2l-4-3v-2l2-2l1-1l2,1l1,3l2,1h3l2,1
l1,2l1,3v3l-1,2l-8,6v2l-2,3l-3,1l-1,1l2,6v3l-2,2l-1,3v1l1,1v3l-4,4v3l-2,4l2,2h2l2-1l3-2h4l3,1h2l-1,3l0,0l1,3l-1,3l1,1l1,1l-1,1
v1l2,2l3,3l2,3v2l-1,2l-7,4l-2,2l-1,1l-3-1l-3,1l-1,1l-3,6l-1,1v6l1,3h2l2,2l-1,2l-3,5l1,1l1,1l4-1h2v2h2l2,1v4l1,1l2-1h6l4-2h8
l2-1l3-1h1l4,2h2l2,3l2,1h7l2,2l2,1l2-1l7,2h2l1,2l3-1l6-2h1l6-1l4-3l1-3l1-1l2-1h3l3-1l2-4l3-1l7-1l2-1h5l1-1h1l1-1l5-1l1-2l1-5
l2-7l1-7v-2l-5-1v-2l2-3v-2l1-2l2-3l1-2l7-3l2-1l2-1l1-3l1-3l2-3l1-1l6-4l1-1h2l2-3v-2l2-1l2,2l1,2l5,2l5-1l1,1v2l3,3l-2,2l-1,1
l-3,2v9l1,1v3h-1l-2-3h-4l-1,3l1,2l-1,1v5l-4,1l1,4l-1,1l4,3v2l-5,4l-1,5l1,2l-1,2l1,3l0,0l-1,2l-2,4h-2l-1,2l-1,6l2,2l1,1l7,1h2
l2,2l2,4l2,2l3,2v3l2,6l-1,2l-3,4v2l-1,3l-1,2l-1,1l-1,1v1l1,6l3,1v3l1,5v1l-2,2l-2,6l-1,1l1,1l3,1l1-2h1l4,2l3,1l3-1l6-2v-2l3-1h1
l1,1l1-1h2l3,1l2,1v1l3,5l3,2l4,2l2,1l3-1l1,1l1,3l0,0h2l3-1l2,1l7,12l-1,4l1,2l3-1l1,2h1l1-3h2l1,3v3l0,0v3h4l4,1l1-1h2l1,2l1,1
l2-1l5,1l3-3l3,1l4,3l5,4l1,2l2,1l3,5l-3,3l-2,4l-1,3l2,6v-1l2-2l5-1v-3l2-1l3,3h1l2,1l3,1v1l10,8v3l2,7l4,1l-3,6l4,2l2,3v2l-2,2
l-2,2h-2l-2,1l7,4v3l3,3v-4l2-3l6,1l3-2l4-1l3-5h5l5,3l1,1l2,4h2l1-2l1-2l-1-4l1-2l2-2l1-2l4-2h1l5,1l7,2h5v-1h2l1,1l1,1l2-1v-1
l1-2v-2l1-2l3-1l3,1l1,1l1,2h3l1,1l1,1h1l2-1l3-3l1-1h1l5-4l2-2l-2-2l2-3h-5l-1-3l1-1l5-3v-5l2-3l1-1v-2l0,0h3l1-2v-6l1-2v-1l-2-1
l-10-4l0,0l1-3l1-4l5-5l-4-6l-1-1h-2l-3,2l-4-2v-8l-1-1l-1-1l-2-3l-6-14l-2,1h-2l-4,1l-1-8l-1-1l1-5l-2-2l-1-1l2-2l1-2v-3l2-1l-1-4
l1-1l0,0h1l2,1h1l0,0l1-1h1v-2l0,0l-3-3l-2-2h-3l-4-3l3-4l3-2l1-1v-5l2-1l1-3l-1-3l2-4l1-1l3-1l3,1l1-2v-2l2-1l3-1v-1l1-3l-2-2l0,0
l-1-2l0,0l-1-1v-4l1-1l6-3l2-4v-1l3-4l-1-1l-2-4l-1-1l1-2l3-3h3l1-1l1-2l-1-3l1-2l1-3v-3l2-3l3-1l10-4l1-7l1-2v-1l-1-4l3-2h5l6-3
l0,0h2v1l1,4l1,2l4,1l0,0l2,2h2l2-1l1-2v-3l7,1l0,0l3,2l-2,2l2,2l-2,4l2,3l4,2v-2l1-1h2l1-2l-1-4h-3l2-2l0,0l-1-4l2-4l0,0l2,1l1-1
l2-1l4,1l1-2l-2-4l1-3l-1-4l-1-1l-2-1l-1-2h1l1-1v-2l0,0v-2h4l1-1l2-2v-3h1l3-2l2-1l5-1l2-1h4l5-4l-2-3v-3l2-2l1-4l1-1l1-1l1-2h2
l1-1h2l2,1l2,1l2,2l7-4h3l0,0l1-1l-1-7l-7-6l-1-2l-1-1l-5-4l1-3l5-8v-7l3-4l-1-5l-6-4l-1-1l-1-1v-3l1-2v-3l-3-3l-5-1h-5l-2-2h-3
l-2,1l-1-1h-3l-3,3l-2-1l-2-5h-1l-1-1l-1-3l-3-3l1-1v-4l-2,1l-1-1l-1-1v-4l-1-1l6-5l2-2l4-3l1-3h1l2,2l2-1v-3l1-3l2-2l2-3v-3l-6,1
l-2-1h-1l-4-2h-4l-2,1l-2,1l-1-1l1-1l-2-2l-1-2l3-3l1-2h-1l-2-1l-1-2l-2-4h-1l-1-2l-8-10l-1-3l-2-4h-10l-2-1l-1,1l-2,1h-2l-1-2v-1
l2-5l-1-2l-4-3h-12l-1-3h-3l-3,1l-2,1h-2l-2,1h-5v1h-1l-1-1l-1-2v-2l-1-2l-2,2h-2l-1,1l-2,2l-1-3l-1-1l-7,4h-2l-4-5l-2,1l-2-5l-1-1
h-1l-4,3l-2,3l-1,3h-3l-1-2l0,0l-1,1l-2,1h-1v-1l-2,2h-1l-2-1l0,0l4-7v-2l-2-5l1-3v-1l0,0l-1-1l-1-1l-4-6l-4-3l-1-1l-1-8v-5l1-1
l3-2l0,0h2l0,0l1-1l1-1l1-1v-1l1-1v-1l1-2v-2h2l3-1l2-1l2-7l4-4l1-4l1-1l0,0l-1-3h-1l-5,2v-1l-1-1l3-5v-1l6-5l1-3l1-2l1-3l1-6l-4-2
v-2l3-4l1-3v-2l0,0l2-1l0,0l2,2l1-1l1-2v-3l1-2l-1-3v-2l0,0l1-1h4l0,0l3-1v-3l0,0l-5-2l0,0v-3l0,0l1-3h2l3-1l1-2l2-3l0,0v-3l-3-2
h-2l-1-1h-3l-2,1v-4h-2l1-1l-2-2v-1l-10-4l-6,1l-4,1h-3l-5-1h-1l-1-2l-15-3l-3-4l-3-3l0,0l-2-1l-3-3l-1-7v-8l-5-4l-12-9l-4,5v1
l-6,3h-4l-2,5l-5-1v-1l-12-2l-2,5l-4-1l-16,1l-3,1h-2l-1-1l-2-3l0,0l4-13l-5-4l-2-1l-1-1l-10,2h-7v-5l-2-9l0,0l-7-9l-1-1l-5-5l5-12
l-2-11l-2-6h-7v-1l-1-1l-1-5h-1l-2,2l-4,4l1,5v1l-1,3l-4,3l-15,15l-2,1l-1,1l-5-7h-1l-2-1l-6,1h-3l-12,1l-4-1l-3-1l-1-6l3-1l11,4
v-4h-1v-1l-2-4v-4l3-1v-4l1-3v-1l-2-1l-2-4l-7-2l-1-2l0,0l-5,2l-3,4l-1,1l-2,2h-1l-1,2v2l-3,5l-1,3l-2,3l-1,2l-4,4l-7,1h-3l-5-1
l-8-2l-3-1l-4,2l-1,1l-2-5l-2-8l1-5l-1-3l-13,2l-1-1h-1l-2,4h-4l-3,1l-4,2l-11,6l2,3v6l3,6l8,11v4l-4,2h-5l-1,1l-2-1h-4l-3-2l-2-4
l-1-1l-15,1h-7 M420.8,63.6l2-2l-1-2l-4-3v-2h5"/>
</g>
<path id="path12" class="st2" d="M564.7,371.1L748,321"/>
<path id="path14" class="st3" d="M458,257.9L748,321"/>
<path id="path16" class="st3" d="M359,402l99-141"/>
<path id="path18" class="st4" d="M786,687L564.7,371.1"/>
<path id="path20" class="st3" d="M458,257.9l14.7-79.7"/>
<path id="path22" class="st3" d="M474.4,173.1l-19.1-82.7"/>
<path id="path24" class="st5" d="M290.1,153.2l165.2-65"/>
<path id="path26" class="st6" d="M189.1,112.6l101,40.6"/>
<path id="path28" class="st3" d="M290.1,153.2L231,344"/>
<path id="path30" class="st3" d="M231,344l128,58"/>
<path id="path32" class="st3" d="M359,398l205.3-24.9"/>
<path id="path34" class="st3" d="M231,344l225-86.1"/>
<path id="path36" class="st7" d="M297.8,157.5L456,257.9"/>
<ellipse fill="#00856E" class="antwerp" id="ellipse40" cx="454.5" cy="88.2" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="brussels" id="ellipse38" cx="458.2" cy="257.9" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="ghent" id="ellipse42" cx="291.3" cy="154.3" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="bruges" id="ellipse44" cx="188.8" cy="112.6" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="mechelen" id="ellipse46" cx="473.7" cy="173.8" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="mons" id="ellipse48" cx="358.8" cy="400.3" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="namur" id="ellipse50" cx="564.3" cy="372.9" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="liege" id="ellipse52" cx="747.6" cy="320.6" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="tournai" id="ellipse54" cx="229.5" cy="345.1" rx="12.2" ry="11.9"/>
<ellipse fill="#00856E" class="arlon" id="ellipse56" cx="788.4" cy="689" rx="12.2" ry="11.9"/>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 491.0674 183.1056)" class="mechelen st9">MECHELEN</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 472.4283 98.463)" class="antwerp st9">ANTWERP</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 594.7698 393.9895)" class="namur st9">NAMUR</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 768.0781 330.6074)" class="liege st9">LIEGE</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 673.7654 698.2338)" class="arlon st9">ARLON</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 321.4514 437.0341)" class="mons st9">MONS</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 50.2342 124.5001)" class="bruges st9">BRUGES</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 182.6856 183.1054)" class="ghent st9">GHENT</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 477.7684 257.9001)" class="brussels st9">BRUSSELS</text>
<text font-weight="bold" fill="#00856E" transform="matrix(1 0 0 1 85.914 355.1399)" class="tournai st9">TOURNAI</text>
<rect id="rect1175" x="219.8" y="121.2" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 225.1011 143.3633)" class="st11 st9">40</text>
<rect id="rect1175-3" x="244.8" y="228.7" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 250.1353 250.8834)" class="st11 st9">60</text>
<rect id="rect1175-9" x="357.1" y="194.2" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 362.4669 216.3563)" class="st11 st9">50</text>
<rect id="rect1175-8" x="443.9" y="119.4" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 449.1873 141.542)" class="st11 st9">20</text>
<rect id="rect1175-9-3" x="367" y="107" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 372.3274 129.1829)" class="st11 st9">50</text>
<rect id="rect1175-9-3-2" x="328.7" y="287.4" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 334.0247 309.6705)" class="st11 st9">70</text>
<rect id="rect1175-9-3-2-1" x="275" y="362.4" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 280.3274 384.6232)" class="st11 st9">40</text>
<rect id="rect1175-9-3-2-7" x="393.2" y="313.4" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 398.4906 335.614)" class="st11 st9">50</text>
<rect id="rect1175-9-3-2-0" x="447.4" y="371.5" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 452.7662 393.6427)" class="st11 st9">60</text>
<rect id="rect1175-9-3-2-10" x="643.3" y="501.5" class="st10" width="46.5" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 645.0945 523.7145)" class="st11 st9">110</text>
<rect id="rect1175-9-3-2-2" x="568.4" y="275.3" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 573.7507 297.4456)" class="st11 st9">90</text>
<rect id="rect1175-9-3-2-5" x="448.1" y="199.9" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 453.4424 222.1189)" class="st11 st9">20</text>
<rect id="rect1175-9-3-2-0_1_" x="636.4" y="333" class="st10" width="40.7" height="25.6"/>
<text font-weight="bold" transform="matrix(1 0 0 1 641.7466 355.1396)" class="st11 st9">50</text>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -7,7 +7,7 @@
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
content="Find the shortest path between belgian cities"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Dijkstra</title>
<title>Dijkstra App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

View File

@ -1,239 +1,301 @@
import React, { useState ,useEffect } from 'react';
import { fetchRoads, fetchCities, getShortestPath } from './requests';
import { Select, Button, Icon } from 'antd';
import Graph from 'react-graph-vis';
import React, { useState, useEffect } from 'react';
import { Layout, Select, Button } from 'antd';
import styled from 'styled-components';
import { fetchRoads, fetchCities, getShortestPath } from '../utils/requests';
import Map from './Map';
import 'antd/dist/antd.css';
import arrow from '../assets/arrow-right.png';
const { Header, Content } = Layout;
const { Option } = Select;
let highlightInitial = {
bruges: '#00856E',
ghent: '#00856E',
antwerp: '#00856E',
mechelen: '#00856E',
tournai: '#00856E',
brussels: '#00856E',
mons: '#00856E',
namur: '#00856E',
liege: '#00856E',
arlon: '#00856E',
};
function HomeView() {
const [startingPoint, setStartingPoint] = useState(1);
const [destination, setDestination] = useState(9);
const [errorSelect, setError] = useState({ message: '', flag: false });
const [shortestPath, setShortestPath] = useState();
const [cities, setCities] = useState([]);
useEffect(() => {
fetchCities()
.then(data => setCities(data))
.catch(error => console.log(error))
}, []);
const [roads, setRoads] = useState([]);
useEffect(() => {
fetchRoads()
.then(data => setRoads(data))
.catch(error => console.log(error));
}, []);
const [startingPoint, setStartingPoint] = useState(1);
const [destination, setDestination] = useState(9);
const [errorSelect, setError] = useState({ message: '', flag: false });
const [shortestPath, setShortestPath] = useState();
const [cities, setCities] = useState([]);
const [highlighted, setHighlighted] = useState(highlightInitial);
const [graph, setGraph] = useState({nodes: [], edges: []});
useEffect(() => {
fetchCities()
.then((data) => setCities(data))
.catch((error) => console.log(error));
}, []);
useEffect(() => {
let nodes = cities.map(node => (
{ id: node.id, label: node.name, title: node.name}
));
const [roads, setRoads] = useState([]);
useEffect(() => {
fetchRoads()
.then((data) => setRoads(data))
.catch((error) => console.log(error));
}, []);
let edges = roads.map(edge => (
{ from: edge.start_city_id, to: edge.end_city_id, length: edge.distance * 2 }
))
const [graph, setGraph] = useState({ nodes: [], edges: [] });
setGraph({nodes, edges})
}, [cities, roads, shortestPath])
useEffect(() => {
let nodes = cities.map((node) => ({
id: node.id,
label: node.name,
title: node.name,
}));
function handleStart(city_id) {
// eslint-disable-next-line
let [ startingPoint ] = cities.filter(city => city.id == city_id);
setStartingPoint(startingPoint);
// Check if start and destination are the same
if (startingPoint === destination) {
setError({ message: 'The start and destination must be different.', flag: true });
return
}
// Will reset the error message and shown path
setShortestPath();
setError({ flag: false });
}
let edges = roads.map((edge) => ({
from: edge.start_city_id,
to: edge.end_city_id,
length: edge.distance * 2,
}));
function handleDestination(city_id) {
// eslint-disable-next-line
let [ destination ] = cities.filter(city => city.id == city_id);
setDestination(destination);
// Check if start and destination are the same
if (startingPoint === destination) {
setError({ message: 'The start and destination must be different.', flag: true });
return
}
// Will reset the error message and shown path
setShortestPath();
setError({ flag: false });
}
setGraph({ nodes, edges });
}, [cities, roads, shortestPath]);
function handleSubmit() {
if (startingPoint === destination) {
setError({ message: 'Please select a start and a destination', flag: true});
return
} else
if (startingPoint && destination) {
getShortestPath(startingPoint.id, destination.id)
.then(data => setShortestPath(data))
.catch(error => console.log(error));
setError({ flag: false });
} else {
setError({ message: 'Please select a start and a destination', flag: true});
}
}
function handleStart(city_id) {
// eslint-disable-next-line
let [startingPoint] = cities.filter((city) => city.id == city_id);
setStartingPoint(startingPoint);
// Check if start and destination are the same
if (startingPoint === destination) {
setError({
message: 'The start and destination must be different.',
flag: true,
});
return;
}
// Reset the error message and shown path
setHighlighted(highlightInitial);
setShortestPath();
setError({ flag: false });
}
// Graph visualization settings
const options = {
layout: {
hierarchical: false
},
edges: {
color: "#000000"
},
height: "500px"
};
const events = {
select: function(event) {
let { nodes, edges } = event;
}
}
function handleDestination(city_id) {
// eslint-disable-next-line
let [destination] = cities.filter((city) => city.id == city_id);
setDestination(destination);
// Check if start and destination are the same
if (startingPoint === destination) {
setError({
message: 'The start and destination must be different.',
flag: true,
});
return;
}
// Reset the error message and shown path
setHighlighted(highlightInitial);
setShortestPath();
setError({ flag: false });
}
// // TODO Find a solution to trigger a re-render of the map
// // Add dashes to shortest path edges
// let path = test.path;
// let pairs = [];
function handleSubmit() {
if (startingPoint === destination) {
setError({
message: 'Please select a start and a destination',
flag: true,
});
} else if (startingPoint && destination) {
getShortestPath(startingPoint.id, destination.id)
.then((data) => {
setShortestPath(data);
// for (let i = 0; path.length - 1 > i; i++) {
// let obj = { from: path[i], to: path[i+1]}
// pairs.push(obj);
// }
// Add cities to highlight
let updatedgHighlighted = {};
data.path.forEach((city) => {
updatedgHighlighted[city.name] = '#E63318';
});
// let updatedEdges = graph.edges.map(edge => {
// if (pairs.includes(edge)){
// edge['dashes'] = true;
// }
// return edge
// })
// console.log(updatedEdges)
// setGraph({...graph, edges: updatedEdges});
setHighlighted(updatedgHighlighted);
})
.catch((error) => console.log(error));
setError({ flag: false });
} else {
setError({
message: 'Please select a start and a destination',
flag: true,
});
}
}
return(
<Main>
<h1>Dijkstra</h1>
<p>Find the shortest path between different cities in Belgium with Dijkstra algorithm.</p>
<Section>
<h2>Starting Point</h2>
<div>
<StyledSelect defaultValue="Belgium" disabled>
</StyledSelect>
<Select
defaultValue="Select a city"
onChange={handleStart}
style={{ width: 139 }}
>
{cities.map(city => (
<Option key={city.id}>{city.name}</Option>
))}
</Select>
</div>
</Section>
<Section>
<h2>Destination</h2>
<div>
<StyledSelect defaultValue="Belgium" disabled>
</StyledSelect>
<Select
defaultValue="Select a city"
onChange={handleDestination}
style={{ width: 139 }}
>
{cities.map(city => (
<Option key={city.id}>{city.name}</Option>
))}
</Select>
</div>
</Section>
<Section>
<Button
type="primary"
onClick={handleSubmit}
>
Get shortest path between the cities
<Icon type="right" />
</Button>
{errorSelect.flag &&
<p>{errorSelect.message}</p>
}
</Section>
{
shortestPath &&
<Section>
<h2>Shortest path from {startingPoint.name} to {destination.name} ({shortestPath.distance}km)</h2>
<StyledP>{shortestPath.path.map(city => (
<StyledSpan key={city.id} class="cityPath">{city.name}</StyledSpan>
))}
</StyledP>
return (
<>
<Header
style={{ backgroundColor: '#ededed', padding: '0 0 5px 0', display: 'flex', justifyContent: 'center' }}
>
<div style={{ margin: '0 auto', maxWidth: '800px' }}>
<InlineH1>Dijkstra | </InlineH1>
<InlineP>Find the shortest path between cities</InlineP>
</div>
</Header>
</Section>
}
{ graph.nodes.length > 0 &&
<Content>
<div
style={{
display: 'flex',
justifyContent: 'center',
margin: '3vh 0 0 0',
}}
>
<h3>
Dockerized NodeJS backend (
<a href='https://git.ruihildt.xyz/ruihildt/dijkstra-backend'>
Git Source
</a>
) & React Frontend (
<a href='https://git.ruihildt.xyz/ruihildt/dijkstra-frontend'>
Git Source
</a>
) communicating through a rest API
</h3>
</div>
<Main
style={{
display: 'flex',
flexFlow: 'row wrap',
justifyContent: 'space-between',
}}
>
<div style={{ margin: '3vh 1vw' }}>
<Section>
<h2>Starting Point</h2>
<div>
<StyledSelect
defaultValue='Belgium'
disabled
></StyledSelect>
<Select
defaultValue='Select a city'
onChange={handleStart}
style={{ width: 139 }}
>
{cities.map((city) => (
<Option key={city.id}>
{city.name}
</Option>
))}
</Select>
</div>
</Section>
<Section>
<h2>Destination</h2>
<div>
<StyledSelect
defaultValue='Belgium'
disabled
></StyledSelect>
<Select
defaultValue='Select a city'
onChange={handleDestination}
style={{ width: 139 }}
>
{cities.map((city) => (
<Option key={city.id}>
{city.name}
</Option>
))}
</Select>
</div>
</Section>
<Section>
<Button type='primary' onClick={handleSubmit}>
Get shortest path between the cities
</Button>
{errorSelect.flag && <p>{errorSelect.message}</p>}
</Section>
</div>
<Graph
graph={graph}
options={options}
events={events}
getNetwork={network => {
// if you want access to vis.js network api you can set the state in a parent component using this property
}}
/>
}
<Section>
<p>On github: <a href="https://github.com/ruihildt/dijkstra">backend</a> & <a href="https://github.com/ruihildt/dijkstra-frontend">frontend</a> </p>
</Section>
</Main>
);
<div>
{graph.nodes.length > 0 && (
<div>
<div style={{ width: '600px' }}>
<Map highlighted={highlighted} />
</div>
</div>
)}
{shortestPath && (
<Section>
<h2>
Shortest path from {startingPoint.name} to{' '}
{destination.name} ({shortestPath.distance}
km)
</h2>
<StyledP>
{shortestPath.path.map((city) => (
<StyledSpan
key={city.id}
className='cityPath'
>
{city.name}
</StyledSpan>
))}
</StyledP>
</Section>
)}
</div>
</Main>
</Content>
</>
);
}
export default HomeView
export default HomeView;
// STYLED COMPONENTS
const InlineP = styled.p`
display: inline;
`;
const InlineH1 = styled.h1`
display: inline;
`;
const Main = styled.main`
padding-top: 20px;
max-width: 800px;
margin: 0 auto;
`
max-width: 1000px;
margin: 0 auto;
`;
const Section = styled.section`
margin: 20px 0;
`
margin: 20px 0;
`;
const StyledSelect = styled(Select)`
margin-right:10px;
`
margin-right: 10px;
`;
const StyledSpan = styled.span`
::after {
content: "";
background-image: url(${arrow});
background-size: 13px 17px;
display: inline-block;
width: 13px;
height: 17px;
margin-right: 10px;
margin-left: 10px;
padding-top: 10px;
bottom: -10px;
}
font-size:1.5rem;
color: #40a9ff;
`
::after {
content: '';
background-image: url(${arrow});
background-size: 13px 17px;
display: inline-block;
width: 13px;
height: 17px;
margin-right: 10px;
margin-left: 10px;
padding-top: 10px;
bottom: -10px;
}
font-size: 1.5rem;
color: #40a9ff;
`;
const StyledP = styled.p`
span:last-child {
::after {
background-image: none;
}
}
`
span:last-child {
::after {
background-image: none;
}
}
`;

27
src/components/Map.jsx Normal file
View File

@ -0,0 +1,27 @@
import React from 'react';
import { SvgLoader, SvgProxy } from 'react-svgmt';
export default function Map({ highlighted }) {
return (
<div>
<SvgLoader
path='/belgium-map.svg'
style={{
width: '500px',
height: '500px',
}}
>
<SvgProxy selector='.ghent' fill={highlighted.ghent} />
<SvgProxy selector='.brussels' fill={highlighted.brussels} />
<SvgProxy selector='.antwerp' fill={highlighted.antwerp} />
<SvgProxy selector='.tournai' fill={highlighted.tournai} />
<SvgProxy selector='.mechelen' fill={highlighted.mechelen} />
<SvgProxy selector='.bruges' fill={highlighted.bruges} />
<SvgProxy selector='.mons' fill={highlighted.mons} />
<SvgProxy selector='.liege' fill={highlighted.liege} />
<SvgProxy selector='.namur' fill={highlighted.namur} />
<SvgProxy selector='.arlon' fill={highlighted.arlon} />
</SvgLoader>
</div>
);
}

View File

@ -1,6 +1,6 @@
import axios from "axios";
export default axios.create({
baseURL: "https://dijkstra-backend.herokuapp.com/",
baseURL: "https://dijkstra-backend.ruihildt.xyz",
responseType: "json"
});
});

View File

@ -1,4 +1,4 @@
import Axios from '../utils/API';
import Axios from './API';
export async function fetchRoads() {
try {