Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transcribed during lecture #1

Open
wants to merge 35 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
62a16f2
transcribed during lecture
mixelpixel Nov 1, 2017
3cd0730
after lecture
mixelpixel Nov 1, 2017
671875a
idem
mixelpixel Nov 1, 2017
1dcaaf2
add graph sample
beejjorgensen Nov 1, 2017
138aca9
add assignment
beejjorgensen Nov 1, 2017
e912168
Add more to assignment in readme
beejjorgensen Nov 1, 2017
bfcdab2
first pass at d3 integration
beejjorgensen Nov 2, 2017
380cfab
prior to 2nd lecture
mixelpixel Nov 2, 2017
a397f81
Merge branch 'master' of https://github.com/LambdaSchool/DijkstrasD3Demo
mixelpixel Nov 2, 2017
704ccc9
added lecture link
mixelpixel Nov 2, 2017
dec073e
Another dijkstra solution
beejjorgensen Nov 2, 2017
54693ef
Merge branch 'master' of https://github.com/LambdaSchool/DijkstrasD3Demo
mixelpixel Nov 2, 2017
78d4194
setup
mixelpixel Nov 3, 2017
12d6bd1
cities
mixelpixel Nov 3, 2017
62321b6
idem
mixelpixel Nov 3, 2017
2a3dc72
city coordinates from a big list
mixelpixel Nov 3, 2017
f33c936
...
mixelpixel Nov 3, 2017
ed2939b
vertexes and edges generated from USA city list
mixelpixel Nov 3, 2017
ceee1ba
attempting to put the cities list data into dijkstra's algo
mixelpixel Nov 3, 2017
c2b2cbf
linting and updated path destination for USA big city list object
mixelpixel Nov 3, 2017
9225d00
trying less total cities
mixelpixel Nov 3, 2017
5b4d303
working dijkstra algorithm from LA to NY with big list of cities, BUT…
mixelpixel Nov 3, 2017
a16f7a3
less direct, but still very predictable given random cities... edges …
mixelpixel Nov 3, 2017
9ea2642
random "weight"
mixelpixel Nov 3, 2017
59fe3a9
ha - dynamic randomness!!!
mixelpixel Nov 3, 2017
2f8fd10
added initial revision
beejjorgensen Nov 3, 2017
ba8e95b
random number of vertexes 1 - 100
mixelpixel Nov 3, 2017
edfb058
Merge branch 'solution' of https://github.com/LambdaSchool/DijkstrasD…
mixelpixel Nov 3, 2017
70a52ea
after Fri lecture
mixelpixel Nov 3, 2017
f5fe1d7
highlight path
beejjorgensen Nov 6, 2017
1d84184
add link weights
beejjorgensen Nov 6, 2017
3f3bc74
...
mixelpixel Nov 6, 2017
53c3714
Merge branch 'solution' of https://github.com/LambdaSchool/DijkstrasD…
mixelpixel Nov 6, 2017
93201c5
ignore node moules
mixelpixel Nov 6, 2017
23e8eec
Merge branch 'solution'
mixelpixel Nov 6, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"presets":[
"es2015"
]
}
33 changes: 33 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es6": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module"
},
"rules": {
"indent": [
"error",
2
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
};
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.swp
.DS_Store

node_modules
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ Variants

* One of the key speedups in the algorithm is how you go about finding the the nearest city. You could use linear search O(n), but you can get O(log n) with a [priority queue](https://en.wikipedia.org/wiki/Priority_queue).


Alternate Implementation
---

IIRC, the above is from Cormen's Algorithms. [Wikipedia has a different, equivalent algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Pseudocode).

The included code in `example/` uses the Wikipedia algorithm.


Dijkstra's D3 Demo
---

Expand All @@ -112,3 +121,21 @@ Swap the commented lines in the file to perform Dijkstra's Algorithm on the tree
let tree = build_tree(graph_spec.V, graph_spec.E);
//let tree = build_tree(V,E);
//console.log(JSON.stringify(tree,null,2));


Assignment
---
1. Get a graph built from a list of verts and edges.

2. Implement Dijkstra's algorithm over that graph.

3. Integrate the solver with the D3 demo; make it quick and dirty to just get it going.

4. Add text fields for starting and ending cities.

5. Refactor from quick and dirty integration into an nice React app.

6. ...

7. Profit!

21 changes: 21 additions & 0 deletions d3_dijkstra/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
/node_modules

# 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*
2,228 changes: 2,228 additions & 0 deletions d3_dijkstra/README.md

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions d3_dijkstra/d3_demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!DOCTYPE html>
<!-- saved from url=(0040)http://bl.ocks.org/mbostock/raw/1153292/ -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>

.link {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}

.link-path {
fill: none;
stroke: #44f;
stroke-width: 5.5px;
}

.link.licensing {
stroke: green;
}

.link.resolved {
stroke-dasharray: 0,2 1;
}

circle {
stroke: #333;
stroke-width: 1.5px;
}

text {
font: 10px sans-serif;
pointer-events: none;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}

.link-text {
text-anchor: middle;
alignment-baseline: middle;
color: blue;
font: 8px sans-serif;
pointer-events: none;
}

</style>

<div id="option">
<input name="updateButton"
type="button"
value="Update"
onclick="updateData()" />
</div>
<div id="demo"></div>

<script src="d3_demo_data.js"></script>
<script src='dijkstra.js'></script>
<script src="d3.v3.min.js"></script>
<script src="d3_demo.js"></script>

</body></html>
168 changes: 168 additions & 0 deletions d3_dijkstra/d3_demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
var nodes = {};

[demo_nodes, links] = Dijkstra.getNodes();

// Compute the distinct nodes from the links.
// Creates nodes from edges if they don't already exist
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});

var width = 800,
height = 400,
radius = 16;

// This is the d3 force layout - this uses the nodes and links specified
// to run the d3.layout.force() function, automatically laying them out
// visually and separating them.
// The various parameters linkDistance, charge, chargeDistance, and gravity
// change the spacing and speed with which the layout settles.
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(10)
.charge(-900)
.chargeDistance(700)
.gravity(.007)
.on("tick", tick);

// Connect to the html document
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

console.log(force);
console.log(nodes);

// Fix the ROOT node to the center, not necessary with Dijkstra's
/*
nodes["ROOT"].x = width/2;
nodes["ROOT"].y = height/2;
nodes["ROOT"].fixed = true;
*/

// This looks up the "group" id from d3_demo_data.js and appends it to
// the existing nodes. This is used for coloring and grouping.
Object.keys(nodes).forEach(function(key) {
console.log(key);
console.log(nodes[key]);
console.log(demo_nodes[key]);
if(demo_nodes[key] && demo_nodes[key].group) {
nodes[key].group = demo_nodes[key].group;
}
});

// Begin the simulation
force.start();

// All this specifies the layout of the edge. Tweaking it gets
// slightly different edges.
// Identifying Dijkstra's path would involve bolding these edges.
// Per-type markers, as they don't inherit styles.
/*
svg.append("defs").selectAll("marker")
.data(["link"])
.enter().append("marker")
.attr("id", function(d) { return d; })
.attr("viewBox", "-50 -50 100 100")
.attr("refX", 35)
.attr("refY", 0)
.attr("markerWidth", 16)
.attr("markerHeight", 16)
.attr("orient", "auto")
.append("path")
.attr("d", "M-50,-25L-25,0L-50,25"); // this weird code draws the arrow
*/

// Seems like this enables link clicking on the edges - it doesn't seem
// to do anything and can probably be stripped.
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link" })
.attr("key", function(d) {
return `${d.source.name},${d.target.name}`;
})
.attr("marker-end", function(d) { return "url(#link)"; });

// This draws the edge label, great for displaying the weight
var link_text = svg.append("g").selectAll("text")
.data(force.links())
.enter().append("text")
.attr("class", "link-text")
.text(function(d) { return d.label; });

// This color object allows the circle fill function below to fill
// each circle based on their group number.
var color = d3.scale.category20();
console.log(color);
console.log(color(0));
console.log(color(1));

// Drawing code for each node
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 16)
.attr("fill", function(d) { return color(d.group); })
.call(force.drag);

// Text labelling code for each node
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", -12)
.attr("y", ".31em")
.text(function(d) { return d.name; });

// The tick function is called by d3.force during layout. The delta function
// for each circle is modified as below for cx and cy, maybe enforcing that
// circles don't overlap one another?
// It also applies the linkArc function to each path element, the transform
// function to text objects, and placeText function to link_text.
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr("d", linkArc);
circle.attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
.attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });
text.attr("transform", transform);
link_text.attr("transform", placeText);
}

// line goes from target to source in x and y, below is an affine matrix
function linkArc(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = 0;//Math.sqrt(dx * dx + dy * dy - 200);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + (d.target.y);
}

// Put the link text in the middle of each edge
function placeText(d) {
var dx = (d.target.px - d.source.px)/2 + d.source.px,
dy = (d.target.py - d.source.py)/2 + d.source.py;
return "translate(" + dx + "," + dy + ")";
}

// write the text where the circle is
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
}

// This reloads the data from d3_demo_data.js, then reruns the force code.
// This would be fly for redrawing new Dijkstra's nodes.
var updateData = function() {
//links = d3.json('d3_demo_data.js');
let [path, distance] = Dijkstra.run();

for (let i = 1; i < path.length; i++) {
d3.selectAll('path[key="' + path[i-1] + ',' + path[i] + '"]')
.attr("class", "link-path");
d3.selectAll('path[key="' + path[i] + ',' + path[i-1] + '"]')
.attr("class", "link-path");
}
force.resume();
};

16 changes: 16 additions & 0 deletions d3_dijkstra/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "d3dijkstra",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-scripts": "1.0.16"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
5 changes: 5 additions & 0 deletions d3_dijkstra/public/d3.v3.min.js

Large diffs are not rendered by default.

Binary file added d3_dijkstra/public/favicon.ico
Binary file not shown.
43 changes: 43 additions & 0 deletions d3_dijkstra/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
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>React App</title>

<script src="d3.v3.min.js"></script>

</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Loading