<link rel="stylesheet" href="./lib/bootstrap/dist/css/bootstrap.css"></link>
<link rel="stylesheet" href="./lib/fontawesome/css/font-awesome.css"></link>
<link rel="stylesheet" href="./lib/bootswatch/cyborg/bootstrap.css"></link>
<link rel="stylesheet" href="./lib/codemirror/lib/codemirror.css"></link>
<link rel="stylesheet" href="./lib/codemirror/theme/monokai.css"></link>
background-color: #434343;
background-image: linear-gradient(#434343, #282828);
-webkit-box-shadow: 2px 2px 4px 2px rgba(0,0,0,0.5);
box-shadow: 2px 2px 4px 2px rgba(0,0,0,0.5);
background-color: transparent;
background-image: linear-gradient(0deg, transparent 24%, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, .05) 75%, rgba(255, 255, 255, .05) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(255, 255, 255, .05) 25%, rgba(255, 255, 255, .05) 26%, transparent 27%, transparent 74%, rgba(255, 255, 255, .05) 75%, rgba(255, 255, 255, .05) 76%, transparent 77%, transparent);
background-size:50px 50px;
<div class="overlays col-lg-3">
<div class="overlay about">
<div class="panel panel-default">
<span class="fa-stack fa-lg">
<i class="fa fa-rocket fa-stack-2x text-muted"></i>
<i class="fa fa-wrench fa-stack-1x text-primary"></i>
Build and share reactive flows of JSON data. Featuring:
- [JSON-LD](https://json-ld.org)
- [JSON Schema](https://json-schema.org)
- [JSON Patch](https://tools.ietf.org/html/draft-ietf-appsawg-json-patch-10)
<span class="fa-stack fa-lg">
<i class="fa fa-cube fa-stack-2x text-muted"></i>
<i class="fa fa-cog fa-stack-1x text-primary"></i>
Don't see your favorite JSON-related technology here? Hyperground uses:
- [Backbone models](https://backbonejs.org#Model) for managing data flows
- [RequireJS](https://requirejs.org) for in-browser dependency management
- [cdnjs](https://cdnjs.com) for snappy file delivery
To get started, check out the [hyperground piece generator](https://github.com/bollwyvl/generator-hyperground).
<div class="overlay create-piece">
<div class="panel panel-default">
<div class="well pieceTypes">
<div class="pieces container-fluid"></div>
<script src="./lib/jquery/dist/jquery.js"></script>
<script src="./lib/d3/d3.js"></script>
<script src="./lib/underscore/underscore.js"></script>
<script src="./lib/guid/guid.js"></script>
<script src="./lib/backbone/backbone.js"></script>
<script src="./lib/jsonld.js/js/jsonld.js"></script>
<script src="./lib/marked/lib/marked.js"></script>
<script src="./lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="./lib/codemirror/lib/codemirror.js"></script>
<script src="./lib/codemirror/mode/javascript/javascript.js"></script>
<script src="./lib/codemirror/addon/edit/matchbrackets.js"></script>
<script src="./lib/codemirror/addon/edit/closebrackets.js"></script>
<script type="text/template" class="template panel">
<div class="panel panel-info">
<div class="panel-heading">
<a class="drag"><i class="fa fa-arrows"></i></a>
<script type="text/template" class="template jsonld">
<div class="form-horizontal" role="form">
<label class="col-sm-2 control-label">Document</label>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
Action <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Remote Document</a></li>
<label class="col-sm-2 control-label">Feature</label>
<div class="btn-group" data-toggle="buttons">
<button type="button" class="btn btn-info active">
<input type="radio" name="feature" class="expand" checked>
<button type="button" class="btn btn-info">
<input type="radio" name="feature" class="compact" checked>
<button type="button" class="btn btn-info">
<input type="radio" name="feature" class="flatten" checked>
<button type="button" class="btn btn-info">
<input type="radio" name="feature" class="frame" checked>
"name": "json-hyperground",
"guid": "https://github.com/dandean/guid.git",
"uuid-lib": "https://github.com/dandean/uuid-lib.git",
"jsonld.js": "https://github.com/digitalbazaar/jsonld.js.git#~0.2.13"
var PieceTypeModel = Backbone.Model.extend({});
var PieceTypeCollection = Backbone.Collection.extend({
var PieceModel = Backbone.Model.extend({});
var PieceCollection = Backbone.Collection.extend({
var PieceView = Backbone.View.extend({
.origin(function(d){ return d.attributes; })
var x = parseFloat(d.get("x")),
y = parseFloat(d.get("y"));
x: (_.isNaN(x) ? 0 : x) + d3.event.dx,
y: (_.isNaN(y) ? 0 : y) + d3.event.dy
this.$el.html($('script.template.panel').text());
this.d3 = d3.select(this.el).datum(this.model)
.attr("class", "piece col-lg-4");
this.listenTo(this.model, {
"change:x": this.positionChanged,
"change:y": this.positionChanged
positionChanged: function(){
left: this.model.get("x") + "px",
top: this.model.get("y") + "px"
var CodeMirrorView = PieceView.extend({
PieceView.prototype.initialize.call(this);
var textarea = $("<textarea/>");
this.$(".panel").append(textarea);
this.editor = CodeMirror.fromTextArea(textarea[0], {
mode: "application/ld+json",
this.editor.on("change", this.editorChange);
this.model.on("change:text", this.textChange);
editorChange: function(cm, delta){
if(!delta.origin){ return; }
model.set({text: editor.getValue()}, {source: this.cid});
textChange: function(model, value, options){
if(options.source === this.cid){ return; }
this.editor.setValue(model.get("text"));
var JsonLdView = PieceView.extend({
PieceView.prototype.initialize.call(this);
this.$(".panel").append($("script.template.jsonld").text())
var PieceTypeButton = Backbone.View.extend({
className: "btn btn-primary",
this.$el.text(this.model.get("label"));
this.trigger("create", this.model);
var AppView = Backbone.View.extend({
this.d3 = d3.select(this.el);
this.pieceTypes = new PieceTypeCollection();
this.listenTo(this.pieceTypes, "add", this.onAddPieceType);
this.pieces = new PieceCollection();
this.listenTo(this.pieces, "add", this.onAddPiece);
onAddPieceType: function(pieceType){
var btn = new PieceTypeButton({model: pieceType});
this.$(".pieceTypes").append(btn.el);
this.children.pieceTypes.push(btn);
this.listenTo(btn, "create", this.addPiece);
addPiece: function(pieceType){
label: pieceType.get("label"),
handler: pieceType.get("id"),
onAddPiece: function(piece){
var panel = this.d3.select(".pieces").append("div").node(),
codemirror: CodeMirrorView,
Handler = handlers[piece.get("handler")];
this.children.pieces.push(new Handler({
var app = new AppView({el: $(".app")});
d3.selectAll(".marked").each(function(){
var container = d3.select(this),
txt = container.text().split("\n").slice(1).join("\n"),
indent = new RegExp("^" + txt.match(/^(\s+)/)[1], "gm");
container.html(marked(txt.replace(indent, "")));