Last active
March 23, 2016 07:01
-
-
Save darosh/2a279cc4df410e749a6b to your computer and use it in GitHub Desktop.
Swagger API Paths
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta charset="utf-8"> | |
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons"> | |
<style> | |
text { | |
font-size: 14px; | |
} | |
.node rect { | |
fill: none; | |
stroke: #666; | |
stroke-opacity: 0.66; | |
stroke-width: 0.5px; | |
shape-rendering: geometricPrecision; | |
} | |
.last rect { | |
fill: #ffdfb3; | |
} | |
.last-param rect { | |
fill: #fae3d4; | |
} | |
.param rect { | |
fill: #f0f0f0; | |
} | |
.node text { | |
fill: #333; | |
} | |
.edgePath path { | |
stroke: #666; | |
stroke-opacity: 0.5; | |
stroke-width: 1.5px; | |
} | |
.material-icons { | |
text-align: center; | |
width: 14px; | |
height: 14px; | |
font-size: 12px; | |
line-height: 14px; | |
padding: 0; | |
color: #fff; | |
background-color: #666; | |
border-radius: 7px; | |
margin: 0 1px; | |
} | |
body { | |
margin: 24px; | |
font-family: sans-serif; | |
} | |
.legend-methods md-icon:not(:first-child) { | |
margin-left: 24px; | |
} | |
hr { | |
border: 0; | |
height: 1px; | |
background: #ccc; | |
margin: 12px 0; | |
} | |
input { | |
width: 600px; | |
} | |
</style> | |
</head> | |
<body> | |
Swagger URL <input type="text" id="url" value="https://apis-guru.github.io/api-models/instagram.com/1.0.0/swagger.json"> | |
<hr> | |
<div> | |
Examples: | |
<a href="https://apis-guru.github.io/api-models/instagram.com/1.0.0/swagger.json">instagram</a>, | |
<a href="https://apis-guru.github.io/api-models/github.com/v3/swagger.json">github</a>, | |
<a href="https://apis-guru.github.io/api-models/gettyimages.com/3.0/swagger.json">gettyimages</a>, | |
<a href="https://apis-guru.github.io/api-models/citrixonline.com/gotomeeting/1.0.0/swagger.json">gotomeeting</a>, | |
<a href="https://apis-guru.github.io/api-models/data2crm.com/1/swagger.json">data2crm</a>, | |
<a href="https://apis-guru.github.io/api-models/googleapis.com/gamesConfiguration/v1configuration/swagger.json">gamesconfiguration</a>, | |
<a href="https://apis-guru.github.io/api-models/googleapis.com/calendar/v3/swagger.json">calendar</a>, | |
<a href="https://apis-guru.github.io/api-models/trello.com/1.0/swagger.json">trello</a>, | |
<a href="https://apis-guru.github.io/api-models/wordnik.com/4.0/swagger.json">wordnik</a>, | |
<a href="https://apis-guru.github.io/api-models/googleapis.com/drive/v3/swagger.json">drive</a>, | |
<a href="http://darosh.github.io/angular-swagger-ui-material/swagger-drupal.json">loopback/drupal</a>, | |
<a href="http://petstore.swagger.io/v2/swagger.json">petstore</a>. | |
</div> | |
<hr> | |
<div class="legend-methods"> | |
<md-icon class="material-icons">arrow_forward</md-icon> | |
GET | |
<md-icon class="material-icons">arrow_backward</md-icon> | |
POST | |
<md-icon class="material-icons">chevron_left</md-icon> | |
PUT | |
<md-icon class="material-icons">first_page</md-icon> | |
PATCH | |
<md-icon class="material-icons">close</md-icon> | |
DELETE | |
<md-icon class="material-icons">radio_button_unchecked</md-icon> | |
OPTIONS | |
<md-icon class="material-icons">sentiment_neutral</md-icon> | |
HEAD | |
</div> | |
<hr> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/dagre-d3/0.4.17/dagre-d3.js"></script> | |
<script> | |
var SVG = d3.select('body').append('svg'); | |
var ROOT = SVG.append('g'); | |
var RENDER = new dagreD3.render(); | |
var ICONS = { | |
get: 'arrow_forward', | |
post: 'arrow_backward', | |
put: 'chevron_left', | |
patch: 'first_page', | |
delete: 'close', | |
options: 'radio_button_unchecked', | |
head: 'sentiment_neutral' | |
}; | |
function chart (data) { | |
var g = new dagreD3.graphlib.Graph({multigraph: false}) | |
.setGraph({ | |
rankdir: 'LR', | |
nodesep: 16, | |
ranksep: 48 | |
}); | |
data.nodes.forEach(function (item, index) { | |
var radius = 13; | |
var x = ''; | |
if (item.methods) { | |
x = '<span class="material-icons">' + item.methods.map(function (m) { | |
return ICONS[m] | |
}).join('</span><span class="material-icons">') + '</span>'; | |
} | |
g.setNode(index, { | |
labelType: "html", | |
label: '<div style="margin-top:19px; font-size: 14px; text-align: center">' + item.name + '</div>' + | |
'<div style="text-align: center; margin-top:-2px; height: 19px">' + x + '</div>', | |
height: 22, | |
class: item.last ? item.param ? 'last-param' : 'last' : item.param ? 'param' : 'intermediate', | |
rx: item.last ? 0 : item.param ? Math.floor(radius / 2) : radius, | |
ry: item.last ? 0 : item.param ? Math.floor(radius / 2) : radius, | |
paddingLeft: 10, | |
paddingRight: 10, | |
paddingTop: 0, | |
paddingBottom: 4 | |
}); | |
}); | |
data.links.forEach(function (link) { | |
var s = data.nodes.indexOf(link[0]); | |
var t = data.nodes.indexOf(link[1]); | |
g.setEdge(s, t, { | |
lineInterpolate: 'basis' | |
}); | |
}); | |
RENDER(ROOT, g); | |
ROOT.attr('transform', 'translate(' + [2, 2.5] + ')'); | |
SVG.attr('height', ((g.graph().height > 0) ? g.graph().height : 0) + 4 + 14) | |
.attr('width', ((g.graph().width > 0) ? g.graph().width : 0) + 4); | |
setTimeout(function () { | |
try { | |
d3.select(self.frameElement).style('height', (48 + document.body.getBoundingClientRect().height) + 'px'); | |
} catch (ign) { | |
} | |
}, 50); | |
} | |
function swaggerPaths (swagger) { | |
var nodes = []; | |
var methods = ['get', 'post', 'put', 'path', 'delete', 'head', 'options']; | |
var links = []; | |
var root = null; | |
var ps = []; | |
var paths = d3.keys(swagger.paths); | |
var max = Number.MIN_VALUE; | |
var id = 0; | |
paths.forEach(function (path) { | |
var parts = path.split('/'); | |
parts.shift(); | |
var p = []; | |
var previous = root; | |
max = Math.max(max, parts.length); | |
for (var i = 0; i < parts.length; i++) { | |
var part = parts[i]; | |
var n = { | |
name: part, | |
path: p.map(function (d) { | |
return d.name; | |
}).join('/'), | |
param: /\{.+}/.test(part), | |
id: id++ | |
}; | |
if (i === (parts.length - 1)) { | |
n.last = true; | |
methods.forEach(function (m) { | |
if (swagger.paths[path][m]) { | |
n.methods = n.methods || []; | |
n.methods.push(m); | |
} | |
}); | |
} | |
p.push(n); | |
previous = n; | |
} | |
ps.push(p); | |
}); | |
for (var j = 0; j < max; j++) { | |
var middles = {}; | |
for (var i = 1; i < ps.length; i++) { | |
var pj = ps[i][j]; | |
if (!pj) { | |
continue; | |
} | |
middles[pj.path] = middles[pj.path] || {}; | |
middles[pj.path][pj.name] = middles[pj.path][pj.name] || pj; | |
middles[pj.path][pj.name].last = middles[pj.path][pj.name].last || pj.last; | |
ps[i][j] = middles[pj.path][pj.name]; | |
} | |
} | |
ps.forEach(function (p, i) { | |
if (!i) { | |
return; | |
} | |
var previous; | |
previous = root; | |
p.forEach(function (n, j) { | |
if (nodes.indexOf(n) === -1) { | |
nodes.push(n); | |
} | |
if (previous) { | |
links.push([previous, n]); | |
} | |
previous = n; | |
}); | |
}); | |
return { | |
org: root, | |
nodes: nodes, | |
links: links | |
}; | |
} | |
function load (url) { | |
d3.select('#url').attr('disabled', true); | |
d3.json(url, function (error, swagger) { | |
d3.select('#url').attr('disabled', null); | |
if (error) throw error; | |
var data = swaggerPaths(swagger); | |
chart(data); | |
}); | |
} | |
d3.select('#url').on('input', function () { | |
load(this.value); | |
}); | |
d3.selectAll('a').on('click', function () { | |
d3.event.preventDefault(); | |
d3.select('#url').attr('value', this.href); | |
load(this.href); | |
}); | |
load('https://apis-guru.github.io/api-models/instagram.com/1.0.0/swagger.json'); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment