Last active
August 29, 2015 13:56
-
-
Save ariutta/9257167 to your computer and use it in GitHub Desktop.
d3-drag-examples
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
| .jsondiffpatch-annotated-delta { | |
| font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace; | |
| font-size: 12px; | |
| margin: 0; | |
| padding: 0 0 0 12px; | |
| display: inline-block; | |
| } | |
| .jsondiffpatch-annotated-delta pre { | |
| font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace; | |
| font-size: 12px; | |
| margin: 0; | |
| padding: 0; | |
| display: inline-block; | |
| } | |
| .jsondiffpatch-annotated-delta td { | |
| margin: 0; | |
| padding: 0; | |
| } | |
| .jsondiffpatch-annotated-delta td pre:hover { | |
| font-weight: bold; | |
| } | |
| td.jsondiffpatch-delta-note { | |
| font-style: italic; | |
| padding-left: 10px; | |
| } | |
| .jsondiffpatch-delta-note > div { | |
| margin: 0; | |
| padding: 0; | |
| } | |
| .jsondiffpatch-delta-note pre { | |
| font-style: normal; | |
| } | |
| .jsondiffpatch-annotated-delta .jsondiffpatch-delta-note { | |
| color: #777; | |
| } | |
| .jsondiffpatch-annotated-delta tr:hover { | |
| background: #ffc; | |
| } | |
| .jsondiffpatch-annotated-delta tr:hover > td.jsondiffpatch-delta-note { | |
| color: black; | |
| } | |
| .jsondiffpatch-error { | |
| background: red; | |
| color: white; | |
| font-weight: bold; | |
| } |
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
| !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.jsondiffpatch=e()}}(function(){return function e(t,r,i){function n(s,f){if(!r[s]){if(!t[s]){var l="function"==typeof require&&require;if(!f&&l)return l(s,!0);if(o)return o(s,!0);throw new Error("Cannot find module '"+s+"'")}var a=r[s]={exports:{}};t[s][0].call(a.exports,function(e){var r=t[s][1][e];return n(r?r:e)},a,a.exports,e,t,r,i)}return r[s].exports}for(var o="function"==typeof require&&require,s=0;s<i.length;s++)n(i[s]);return n}({1:[function(e,t){var r=t.exports={};r.nextTick=function(){var e="undefined"!=typeof window&&window.setImmediate,t="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(e)return function(e){return window.setImmediate(e)};if(t){var r=[];return window.addEventListener("message",function(e){var t=e.source;if((t===window||null===t)&&"process-tick"===e.data&&(e.stopPropagation(),r.length>0)){var i=r.shift();i()}},!0),function(e){r.push(e),window.postMessage("process-tick","*")}}return function(e){setTimeout(e,0)}}(),r.title="browser",r.browser=!0,r.env={},r.argv=[],r.binding=function(){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(){throw new Error("process.chdir is not supported")}},{}],2:[function(e,t,r){var i=e("../pipe").Pipe,n=function(){};n.prototype.setResult=function(e){return this.result=e,this.hasResult=!0,this},n.prototype.exit=function(){return this.exiting=!0,this},n.prototype.switchTo=function(e,t){return"string"==typeof e||e instanceof i?this.nextPipe=e:(this.next=e,t&&(this.nextPipe=t)),this},n.prototype.push=function(e,t){return e.parent=this,"undefined"!=typeof t&&(e.childName=t),e.root=this.root||this,e.options=e.options||this.options,this.children?(this.children[this.children.length-1].next=e,this.children.push(e)):(this.children=[e],this.nextAfterChildren=this.next||null,this.next=e),e.next=this,this},r.Context=n},{"../pipe":15}],3:[function(e,t,r){var i=e("./context").Context,n=function(e,t){this.left=e,this.right=t,this.pipe="diff"};n.prototype=new i,r.DiffContext=n},{"./context":2}],4:[function(e,t,r){var i=e("./context").Context,n=function(e,t){this.left=e,this.delta=t,this.pipe="patch"};n.prototype=new i,r.PatchContext=n},{"./context":2}],5:[function(e,t,r){var i=e("./context").Context,n=function(e){this.delta=e,this.pipe="reverse"};n.prototype=new i,r.ReverseContext=n},{"./context":2}],6:[function(e,t){t.exports=function(e,t){var r;return"string"==typeof t&&(r=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(Z|([+\-])(\d{2}):(\d{2}))$/.exec(t))?new Date(Date.UTC(+r[1],+r[2]-1,+r[3],+r[4],+r[5],+r[6])):t}},{}],7:[function(e,t,r){var i=e("./processor").Processor,n=e("./pipe").Pipe,o=e("./contexts/diff").DiffContext,s=e("./contexts/patch").PatchContext,f=e("./contexts/reverse").ReverseContext,l=e("./filters/trivial"),a=e("./filters/nested"),c=e("./filters/arrays"),u=e("./filters/dates"),h=e("./filters/texts"),p=function(e){this.processor=new i(e),this.processor.pipe(new n("diff").append(a.collectChildrenDiffFilter,l.diffFilter,u.diffFilter,h.diffFilter,a.objectsDiffFilter,c.diffFilter).shouldHaveResult()),this.processor.pipe(new n("patch").append(a.collectChildrenPatchFilter,c.collectChildrenPatchFilter,l.patchFilter,h.patchFilter,a.patchFilter,c.patchFilter).shouldHaveResult()),this.processor.pipe(new n("reverse").append(a.collectChildrenReverseFilter,c.collectChildrenReverseFilter,l.reverseFilter,h.reverseFilter,a.reverseFilter,c.reverseFilter).shouldHaveResult())};p.prototype.options=function(){return this.processor.options.apply(this.processor,arguments)},p.prototype.diff=function(e,t){return this.processor.process(new o(e,t))},p.prototype.patch=function(e,t){return this.processor.process(new s(e,t))},p.prototype.reverse=function(e){return this.processor.process(new f(e))},p.prototype.unpatch=function(e,t){return this.patch(e,this.reverse(t))},r.DiffPatcher=p},{"./contexts/diff":3,"./contexts/patch":4,"./contexts/reverse":5,"./filters/arrays":9,"./filters/dates":10,"./filters/nested":12,"./filters/texts":13,"./filters/trivial":14,"./pipe":15,"./processor":16}],8:[function(e,t,r){(function(t){var i=e("./diffpatcher").DiffPatcher;r.DiffPatcher=i,r.create=function(e){return new i(e)},r.dateReviver=e("./date-reviver");var n;r.diff=function(){return n||(n=new i),n.diff.apply(n,arguments)},r.patch=function(){return n||(n=new i),n.patch.apply(n,arguments)},r.unpatch=function(){return n||(n=new i),n.unpatch.apply(n,arguments)},r.reverse=function(){return n||(n=new i),n.reverse.apply(n,arguments)};var o="undefined"!=typeof t&&"string"==typeof t.execPath;if(o){var s=e("./formatters/index");r.formatters=s,r.console=s.console}else r.homepage="https://github.com/benjamine/jsondiffpatch",r.version="0.1.4"}).call(this,e("/home/sheila/proj/JsonDiffPatch/node_modules/gulp-browserify/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))},{"./date-reviver":6,"./diffpatcher":7,"/home/sheila/proj/JsonDiffPatch/node_modules/gulp-browserify/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":1}],9:[function(e,t,r){var i=e("../contexts/diff").DiffContext,n=e("../contexts/patch").PatchContext,o=e("../contexts/reverse").ReverseContext,s=e("./lcs"),f=3,l="function"==typeof Array.isArray?Array.isArray:function(e){return e instanceof Array},a="function"==typeof Array.prototype.indexOf?function(e,t){return e.indexOf(t)}:function(e,t){for(var r=e.length,i=0;r>i;i++)if(e[i]===t)return i;return-1},c=function(e){if(e.leftIsArray){for(var t,r,n,o,l=e.options&&e.options.objectHash,c=function(e,t,r,i,n){var o=e[r],s=t[i];if(o===s)return!0;if("object"!=typeof o||"object"!=typeof s)return!1;if(!l)return!1;var f,a;return"number"==typeof r?(n.hashCache1=n.hashCache1||[],f=n.hashCache1[r],"undefined"==typeof f&&(n.hashCache1[r]=f=l(o,r))):f=l(o),"undefined"==typeof f?!1:("number"==typeof i?(n.hashCache2=n.hashCache2||[],a=n.hashCache2[i],"undefined"==typeof a&&(n.hashCache2[i]=a=l(s,i))):a=l(s),"undefined"==typeof a?!1:f===a)},u={},h=0,p=0,d=e.left,v=e.right,y=d.length,x=v.length;y>h&&x>h&&c(d,v,h,h,u);)t=h,o=new i(e.left[t],e.right[t]),e.push(o,t),h++;for(;y>p+h&&x>p+h&&c(d,v,y-1-p,x-1-p,u);)r=y-1-p,n=x-1-p,o=new i(e.left[r],e.right[n]),e.push(o,n),p++;var g;if(h+p===y){if(y===x)return void e.setResult(void 0).exit();for(g=g||{_t:"a"},t=h;x-p>t;t++)g[t]=[v[t]];return void e.setResult(g).exit()}if(h+p===x){for(g=g||{_t:"a"},t=h;y-p>t;t++)g["_"+t]=[d[t],0,0];return void e.setResult(g).exit()}u={};var m=d.slice(h,y-p),w=v.slice(h,x-p),C=s.get(m,w,c,u),_=[];for(g=g||{_t:"a"},t=h;y-p>t;t++)a(C.indices1,t-h)<0&&(g["_"+t]=[d[t],0,0],_.push(t));var R=!0;e.options&&e.options.arrays&&e.options.arrays.detectMove===!1&&(R=!1);var b=!1;e.options&&e.options.arrays&&e.options.arrays.includeValueOnMove&&(b=!0);var F=_.length;for(t=h;x-p>t;t++){var N=a(C.indices2,t-h);if(0>N){var A=!1;if(R&&F>0)for(r=0;F>r;r++)if(c(m,w,_[r]-h,t-h,u)){g["_"+_[r]].splice(1,2,t,f),b||(g["_"+_[r]][0]=""),r=_[r],n=t,o=new i(e.left[r],e.right[n]),e.push(o,n),_.splice(r,1),A=!0;break}A||(g[t]=[v[t]])}else r=C.indices1[N]+h,n=C.indices2[N]+h,o=new i(e.left[r],e.right[n]),e.push(o,n)}e.setResult(g).exit()}};c.filterName="arrays";var u={numerically:function(e,t){return e-t},numericallyBy:function(e){return function(t,r){return t[e]-r[e]}}},h=function(e){if(e.nested&&"a"===e.delta._t){var t,r,i=e.delta,o=e.left,s=[],l=[],a=[];for(t in i)if("_t"!==t)if("_"===t[0]){if(0!==i[t][2]&&i[t][2]!==f)throw new Error("only removal or move can be applied at original array indices, invalid diff type: "+i[t][2]);s.push(parseInt(t.slice(1),10))}else 1===i[t].length?l.push({index:parseInt(t,10),value:i[t][0]}):a.push({index:parseInt(t,10),delta:i[t]});for(s=s.sort(u.numerically),t=s.length-1;t>=0;t--){r=s[t];var c=i["_"+r],h=o.splice(r,1)[0];c[2]===f&&l.push({index:c[1],value:h})}l=l.sort(u.numericallyBy("index"));var p=l.length;for(t=0;p>t;t++){var d=l[t];o.splice(d.index,0,d.value)}var v,y=a.length;if(y>0)for(t=0;y>t;t++){var x=a[t];v=new n(e.left[x.index],x.delta),e.push(v,x.index)}return e.children?void e.exit():void e.setResult(e.left).exit()}};h.filterName="arrays";var p=function(e){if(e&&e.children&&"a"===e.delta._t){for(var t,r=e.children.length,i=0;r>i;i++)t=e.children[i],e.left[t.childName]=t.result;e.setResult(e.left).exit()}};p.filterName="arraysCollectChildren";var d=function(e){if(!e.nested)return void(e.delta[2]===f&&(e.newName="_"+e.delta[1],e.setResult([e.delta[0],parseInt(e.childName.substr(1),10),f]).exit()));if("a"===e.delta._t){var t,r;for(t in e.delta)"_t"!==t&&(r=new o(e.delta[t]),e.push(r,t));e.exit()}};d.filterName="arrays";var v=function(e,t,r){var i=t;if("string"==typeof t&&"_"===t[0])i=parseInt(t.substr(1),10);else{var n="_"+t;if(l(r)&&0===r[2])i=n;else for(var o in e){var s=e[o];l(s)&&s[2]===f&&s[1].toString()===t&&(i=o.substr(1))}}return i},y=function(e){if(e&&e.children&&"a"===e.delta._t){for(var t,r=e.children.length,i={_t:"a"},n=0;r>n;n++){t=e.children[n];var o=t.newName;"undefined"==typeof o&&(o=v(e.delta,t.childName,t.result)),i[o]!==t.result&&(i[o]=t.result)}e.setResult(i).exit()}};y.filterName="arraysCollectChildren",r.diffFilter=c,r.patchFilter=h,r.collectChildrenPatchFilter=p,r.reverseFilter=d,r.collectChildrenReverseFilter=y},{"../contexts/diff":3,"../contexts/patch":4,"../contexts/reverse":5,"./lcs":11}],10:[function(e,t,r){var i=function(e){e.left instanceof Date?(e.setResult(e.right instanceof Date?e.left.getTime()!==e.right.getTime()?[e.left,e.right]:void 0:[e.left,e.right]),e.exit()):e.right instanceof Date&&e.setResult([e.left,e.right]).exit()};i.filterName="dates",r.diffFilter=i},{}],11:[function(e,t,r){var i=function(e,t,r,i){return e[r]===t[i]},n=function(e,t,r,i){var n,o,s=e.length,f=t.length,l=[s+1];for(n=0;s+1>n;n++)for(l[n]=[f+1],o=0;f+1>o;o++)l[n][o]=0;for(l.match=r,n=1;s+1>n;n++)for(o=1;f+1>o;o++)l[n][o]=r(e,t,n-1,o-1,i)?l[n-1][o-1]+1:Math.max(l[n-1][o],l[n][o-1]);return l},o=function(e,t,r,i,n,s){if(0===i||0===n)return{sequence:[],indices1:[],indices2:[]};if(e.match(t,r,i-1,n-1,s)){var f=o(e,t,r,i-1,n-1,s);return f.sequence.push(t[i-1]),f.indices1.push(i-1),f.indices2.push(n-1),f}return e[i][n-1]>e[i-1][n]?o(e,t,r,i,n-1,s):o(e,t,r,i-1,n,s)},s=function(e,t,r,s){s=s||{};var f=n(e,t,r||i,s),l=o(f,e,t,e.length,t.length,s);return"string"==typeof e&&"string"==typeof t&&(l.sequence=l.sequence.join("")),l};r.get=s},{}],12:[function(e,t,r){var i=e("../contexts/diff").DiffContext,n=e("../contexts/patch").PatchContext,o=e("../contexts/reverse").ReverseContext,s=function(e){if(e&&e.children){for(var t,r=e.children.length,i=e.result,n=0;r>n;n++)t=e.children[n],"undefined"!=typeof t.result&&(i=i||{},i[t.childName]=t.result);i&&e.leftIsArray&&(i._t="a"),e.setResult(i).exit()}};s.filterName="collectChildren";var f=function(e){if(!e.leftIsArray&&"object"===e.leftType){var t,r;for(t in e.left)r=new i(e.left[t],e.right[t]),e.push(r,t);for(t in e.right)"undefined"==typeof e.left[t]&&(r=new i(void 0,e.right[t]),e.push(r,t));return e.children&&0!==e.children.length?void e.exit():void e.setResult(void 0).exit()}};f.filterName="objects";var l=function(e){if(e.nested&&!e.delta._t){var t,r;for(t in e.delta)r=new n(e.left[t],e.delta[t]),e.push(r,t);e.exit()}};l.filterName="objects";var a=function(e){if(e&&e.children&&!e.delta._t){for(var t,r=e.children.length,i=0;r>i;i++)t=e.children[i],e.left[t.childName]!==t.result&&(e.left[t.childName]=t.result);e.setResult(e.left).exit()}};a.filterName="collectChildren";var c=function(e){if(e.nested&&!e.delta._t){var t,r;for(t in e.delta)r=new o(e.delta[t]),e.push(r,t);e.exit()}};c.filterName="objects";var u=function(e){if(e&&e.children&&!e.delta._t){for(var t,r=e.children.length,i={},n=0;r>n;n++)t=e.children[n],i[t.childName]!==t.result&&(i[t.childName]=t.result);e.setResult(i).exit()}};u.filterName="collectChildren",r.collectChildrenDiffFilter=s,r.objectsDiffFilter=f,r.patchFilter=l,r.collectChildrenPatchFilter=a,r.reverseFilter=c,r.collectChildrenReverseFilter=u},{"../contexts/diff":3,"../contexts/patch":4,"../contexts/reverse":5}],13:[function(e,t,r){var i=2,n=60,o=null,s=function(){if(!o){var t;if("undefined"!=typeof diff_match_patch)t=new diff_match_patch;else if("function"==typeof e){var r=e("../../external/diff_match_patch_uncompressed");t=new r.diff_match_patch}if(!t){var i=new Error("text diff_match_patch library not found");throw i.diff_match_patch_not_found=!0,i}o={diff:function(e,r){return t.patch_toText(t.patch_make(e,r))},patch:function(e,r){for(var i=t.patch_apply(t.patch_fromText(r),e),n=0;n<i[1].length;n++)if(!i[1][n]){var o=new Error("text patch failed");o.textPatchFailed=!0}return i[0]}}}return o},f=function(e){if("string"===e.leftType){var t=e.options&&e.options.textDiff&&e.options.textDiff.minLength||n;if(e.left.length<t||e.right.length<t)return void e.setResult([e.left,e.right]).exit();var r=s().diff;e.setResult([r(e.left,e.right),0,i]).exit()}};f.filterName="texts";var l=function(e){if(!e.nested&&e.delta[2]===i){var t=s().patch;e.setResult(t(e.left,e.delta[0])).exit()}};l.filterName="texts";var a=function(e){var t,r,i,n,o,s,f,l,a=null,c=/^@@ +\-(\d+),(\d+) +\+(\d+),(\d+) +@@$/;for(i=e.split("\n"),t=0,r=i.length;r>t;t++){n=i[t];var u=n.slice(0,1);"@"===u?(a=c.exec(n),s=t,f=null,l=null,i[s]="@@ -"+a[3]+","+a[4]+" +"+a[1]+","+a[2]+" @@"):"+"===u?(f=t,i[t]="-"+i[t].slice(1),"+"===i[t-1].slice(0,1)&&(o=i[t],i[t]=i[t-1],i[t-1]=o)):"-"===u&&(l=t,i[t]="+"+i[t].slice(1))}return i.join("\n")},c=function(e){e.nested||e.delta[2]===i&&e.setResult([a(e.delta[0]),0,i]).exit()};c.filterName="texts",r.diffFilter=f,r.patchFilter=l,r.reverseFilter=c},{}],14:[function(e,t,r){var i="function"==typeof Array.isArray?Array.isArray:function(e){return e instanceof Array},n=function(e){if(e.left===e.right)return void e.setResult(void 0).exit();if("undefined"==typeof e.left){if("function"==typeof e.right)throw new Error("functions are not supported");return void e.setResult([e.right]).exit()}if("undefined"==typeof e.right)return void e.setResult([e.left,0,0]).exit();if("function"==typeof e.left||"function"==typeof e.right)throw new Error("functions are not supported");return e.leftType=null===e.left?"null":typeof e.left,e.rightType=null===e.right?"null":typeof e.right,e.leftType!==e.rightType?void e.setResult([e.left,e.right]).exit():"boolean"===e.leftType||"number"===e.leftType?void e.setResult([e.left,e.right]).exit():("object"===e.leftType&&(e.leftIsArray=i(e.left)),"object"===e.rightType&&(e.rightIsArray=i(e.right)),e.leftIsArray!==e.rightIsArray?void e.setResult([e.left,e.right]).exit():void 0)};n.filterName="trivial";var o=function(e){return"undefined"==typeof e.delta?void e.setResult(e.left).exit():(e.nested=!i(e.delta),e.nested?void 0:1===e.delta.length?void e.setResult(e.delta[0]).exit():2===e.delta.length?void e.setResult(e.delta[1]).exit():3===e.delta.length&&0===e.delta[2]?void e.setResult(void 0).exit():void 0)};o.filterName="trivial";var s=function(e){return"undefined"==typeof e.delta?void e.setResult(e.delta).exit():(e.nested=!i(e.delta),e.nested?void 0:1===e.delta.length?void e.setResult([e.delta[0],0,0]).exit():2===e.delta.length?void e.setResult([e.delta[1],e.delta[0]]).exit():3===e.delta.length&&0===e.delta[2]?void e.setResult([e.delta[0]]).exit():void 0)};s.filterName="trivial",r.diffFilter=n,r.patchFilter=o,r.reverseFilter=s},{}],15:[function(e,t,r){var i=function(e){this.name=e,this.filters=[]};i.prototype.process=function(e){if(!this.processor)throw new Error("add this pipe to a processor before using it");for(var t=this.debug,r=this.filters.length,i=e,n=0;r>n;n++){var o=this.filters[n];if(t&&this.log("filter: "+o.filterName),o(i),"object"==typeof i&&i.exiting){i.exiting=!1;break}}!i.next&&this.resultCheck&&this.resultCheck(i)},i.prototype.log=function(e){console.log("[jsondiffpatch] "+this.name+" pipe, "+e)},i.prototype.append=function(){return this.filters.push.apply(this.filters,arguments),this},i.prototype.prepend=function(){return this.filters.unshift.apply(this.filters,arguments),this},i.prototype.indexOf=function(e){if(!e)throw new Error("a filter name is required");for(var t=0;t<this.filters.length;t++){var r=this.filters[t];if(r.filterName===e)return t}throw new Error("filter not found: "+e)},i.prototype.list=function(){for(var e=[],t=0;t<this.filters.length;t++){var r=this.filters[t];e.push(r.filterName)}return e},i.prototype.after=function(e){var t=this.indexOf(e),r=Array.prototype.slice.call(arguments,1);if(!r.length)throw new Error("a filter is required");return r.unshift(t+1,0),Array.prototype.splice.apply(this.filters,r),this},i.prototype.before=function(e){var t=this.indexOf(e),r=Array.prototype.slice.call(arguments,1);if(!r.length)throw new Error("a filter is required");return r.unshift(t,0),Array.prototype.splice.apply(this.filters,r),this},i.prototype.clear=function(){return this.filters.length=0,this},i.prototype.shouldHaveResult=function(e){if(e===!1)return void(this.resultCheck=null);if(!this.resultCheck){var t=this;return this.resultCheck=function(e){if(!e.hasResult){console.log(e);var r=new Error(t.name+" failed");throw r.noResult=!0,r}},this}},r.Pipe=i},{}],16:[function(e,t,r){var i=function(e){this.selfOptions=e,this.pipes={}};i.prototype.options=function(e){return e&&(this.selfOptions=e),this.selfOptions},i.prototype.pipe=function(e,t){if("string"==typeof e){if("undefined"==typeof t)return this.pipes[e];this.pipes[e]=t}if(e&&e.name){if(t=e,t.processor===this)return t;this.pipes[t.name]=t}return t.processor=this,t},i.prototype.process=function(e,t){var r=e;r.options=this.options();for(var i,n,o=t||e.pipe||"default";o;)"undefined"!=typeof r.nextAfterChildren&&(r.next=r.nextAfterChildren,r.nextAfterChildren=null),"string"==typeof o&&(o=this.pipe(o)),o.process(r),n=r,i=o,o=null,r&&r.next&&(r=r.next,o=n.nextPipe||r.pipe||i);return r.hasResult?r.result:void 0},r.Processor=i},{}]},{},[8])(8)}); |
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
| #!/usr/bin/env node | |
| var util = require('util'), | |
| http = require('http'), | |
| fs = require('fs'), | |
| url = require('url'), | |
| events = require('events'); | |
| var DEFAULT_PORT = 8000; | |
| function main(argv) { | |
| new HttpServer({ | |
| 'GET': createServlet(StaticServlet), | |
| 'HEAD': createServlet(StaticServlet) | |
| }).start(Number(argv[2]) || DEFAULT_PORT); | |
| } | |
| function escapeHtml(value) { | |
| return value.toString(). | |
| replace('<', '<'). | |
| replace('>', '>'). | |
| replace('"', '"'); | |
| } | |
| function createServlet(Class) { | |
| var servlet = new Class(); | |
| return servlet.handleRequest.bind(servlet); | |
| } | |
| /** | |
| * An Http server implementation that uses a map of methods to decide | |
| * action routing. | |
| * | |
| * @param {Object} Map of method => Handler function | |
| */ | |
| function HttpServer(handlers) { | |
| this.handlers = handlers; | |
| this.server = http.createServer(this.handleRequest_.bind(this)); | |
| } | |
| HttpServer.prototype.start = function(port) { | |
| this.port = port; | |
| this.server.listen(port); | |
| util.puts('Http Server running at http://localhost:' + port + '/'); | |
| }; | |
| HttpServer.prototype.parseUrl_ = function(urlString) { | |
| var parsed = url.parse(urlString); | |
| parsed.pathname = url.resolve('/', parsed.pathname); | |
| return url.parse(url.format(parsed), true); | |
| }; | |
| HttpServer.prototype.handleRequest_ = function(req, res) { | |
| var logEntry = req.method + ' ' + req.url; | |
| if (req.headers['user-agent']) { | |
| logEntry += ' ' + req.headers['user-agent']; | |
| } | |
| util.puts(logEntry); | |
| req.url = this.parseUrl_(req.url); | |
| var handler = this.handlers[req.method]; | |
| if (!handler) { | |
| res.writeHead(501); | |
| res.end(); | |
| } else { | |
| handler.call(this, req, res); | |
| } | |
| }; | |
| /** | |
| * Handles static content. | |
| */ | |
| function StaticServlet() {} | |
| StaticServlet.MimeMap = { | |
| 'txt': 'text/plain', | |
| 'html': 'text/html', | |
| 'css': 'text/css', | |
| 'xml': 'application/xml', | |
| 'json': 'application/json', | |
| 'js': 'application/javascript', | |
| 'jpg': 'image/jpeg', | |
| 'jpeg': 'image/jpeg', | |
| 'gif': 'image/gif', | |
| 'png': 'image/png', | |
| 'svg': 'image/svg+xml' | |
| }; | |
| StaticServlet.prototype.handleRequest = function(req, res) { | |
| var self = this; | |
| var path = ('./' + req.url.pathname).replace('//','/').replace(/%(..)/g, function(match, hex){ | |
| return String.fromCharCode(parseInt(hex, 16)); | |
| }); | |
| var parts = path.split('/'); | |
| if (parts[parts.length-1].charAt(0) === '.') | |
| return self.sendForbidden_(req, res, path); | |
| fs.stat(path, function(err, stat) { | |
| if (err) | |
| return self.sendMissing_(req, res, path); | |
| if (stat.isDirectory()) | |
| return self.sendDirectory_(req, res, path); | |
| return self.sendFile_(req, res, path); | |
| }); | |
| } | |
| StaticServlet.prototype.sendError_ = function(req, res, error) { | |
| res.writeHead(500, { | |
| 'Content-Type': 'text/html' | |
| }); | |
| res.write('<!doctype html>\n'); | |
| res.write('<title>Internal Server Error</title>\n'); | |
| res.write('<h1>Internal Server Error</h1>'); | |
| res.write('<pre>' + escapeHtml(util.inspect(error)) + '</pre>'); | |
| util.puts('500 Internal Server Error'); | |
| util.puts(util.inspect(error)); | |
| }; | |
| StaticServlet.prototype.sendMissing_ = function(req, res, path) { | |
| path = path.substring(1); | |
| res.writeHead(404, { | |
| 'Content-Type': 'text/html' | |
| }); | |
| res.write('<!doctype html>\n'); | |
| res.write('<title>404 Not Found</title>\n'); | |
| res.write('<h1>Not Found</h1>'); | |
| res.write( | |
| '<p>The requested URL ' + | |
| escapeHtml(path) + | |
| ' was not found on this server.</p>' | |
| ); | |
| res.end(); | |
| util.puts('404 Not Found: ' + path); | |
| }; | |
| StaticServlet.prototype.sendForbidden_ = function(req, res, path) { | |
| path = path.substring(1); | |
| res.writeHead(403, { | |
| 'Content-Type': 'text/html' | |
| }); | |
| res.write('<!doctype html>\n'); | |
| res.write('<title>403 Forbidden</title>\n'); | |
| res.write('<h1>Forbidden</h1>'); | |
| res.write( | |
| '<p>You do not have permission to access ' + | |
| escapeHtml(path) + ' on this server.</p>' | |
| ); | |
| res.end(); | |
| util.puts('403 Forbidden: ' + path); | |
| }; | |
| StaticServlet.prototype.sendRedirect_ = function(req, res, redirectUrl) { | |
| res.writeHead(301, { | |
| 'Content-Type': 'text/html', | |
| 'Location': redirectUrl | |
| }); | |
| res.write('<!doctype html>\n'); | |
| res.write('<title>301 Moved Permanently</title>\n'); | |
| res.write('<h1>Moved Permanently</h1>'); | |
| res.write( | |
| '<p>The document has moved <a href="' + | |
| redirectUrl + | |
| '">here</a>.</p>' | |
| ); | |
| res.end(); | |
| util.puts('301 Moved Permanently: ' + redirectUrl); | |
| }; | |
| StaticServlet.prototype.sendFile_ = function(req, res, path) { | |
| var self = this; | |
| var file = fs.createReadStream(path); | |
| res.writeHead(200, { | |
| 'Content-Type': StaticServlet. | |
| MimeMap[path.split('.').pop()] || 'text/plain' | |
| }); | |
| if (req.method === 'HEAD') { | |
| res.end(); | |
| } else { | |
| file.on('data', res.write.bind(res)); | |
| file.on('close', function() { | |
| res.end(); | |
| }); | |
| file.on('error', function(error) { | |
| self.sendError_(req, res, error); | |
| }); | |
| } | |
| }; | |
| StaticServlet.prototype.sendDirectory_ = function(req, res, path) { | |
| var self = this; | |
| if (path.match(/[^\/]$/)) { | |
| req.url.pathname += '/'; | |
| var redirectUrl = url.format(url.parse(url.format(req.url))); | |
| return self.sendRedirect_(req, res, redirectUrl); | |
| } | |
| fs.readdir(path, function(err, files) { | |
| if (err) | |
| return self.sendError_(req, res, error); | |
| if (!files.length) | |
| return self.writeDirectoryIndex_(req, res, path, []); | |
| var remaining = files.length; | |
| files.forEach(function(fileName, index) { | |
| fs.stat(path + '/' + fileName, function(err, stat) { | |
| if (err) | |
| return self.sendError_(req, res, err); | |
| if (stat.isDirectory()) { | |
| files[index] = fileName + '/'; | |
| } | |
| if (!(--remaining)) | |
| return self.writeDirectoryIndex_(req, res, path, files); | |
| }); | |
| }); | |
| }); | |
| }; | |
| StaticServlet.prototype.writeDirectoryIndex_ = function(req, res, path, files) { | |
| path = path.substring(1); | |
| res.writeHead(200, { | |
| 'Content-Type': 'text/html' | |
| }); | |
| if (req.method === 'HEAD') { | |
| res.end(); | |
| return; | |
| } | |
| res.write('<!doctype html>\n'); | |
| res.write('<title>' + escapeHtml(path) + '</title>\n'); | |
| res.write('<style>\n'); | |
| res.write(' ol { list-style-type: none; font-size: 1.2em; }\n'); | |
| res.write('</style>\n'); | |
| res.write('<h1>Directory: ' + escapeHtml(path) + '</h1>'); | |
| res.write('<ol>'); | |
| files.forEach(function(fileName) { | |
| if (fileName.charAt(0) !== '.') { | |
| res.write('<li><a href="' + | |
| escapeHtml(fileName) + '">' + | |
| escapeHtml(fileName) + '</a></li>'); | |
| } | |
| }); | |
| res.write('</ol>'); | |
| res.end(); | |
| }; | |
| // Must be last, | |
| main(process.argv); |
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
| var dragUpdate = function() { | |
| 'use strict'; | |
| var dragging = false, viewport, originalDiagramData, currentDiagramData, selectedPoint, dragSegment, selectedEdge, selectedEdgeElement, dragPointX, dragPointY; | |
| var init = function() { | |
| d3.json('input.json', function(json) { | |
| originalDiagramData = json; | |
| var originalDiagramDataString = JSON.stringify(originalDiagramData, null, '\t'); | |
| d3.select('#original-json').text(originalDiagramDataString); | |
| currentDiagramData = JSON.parse(JSON.stringify(originalDiagramData)); | |
| var svg = d3.select('#diagram').append('svg') | |
| .attr('width', 900) | |
| .attr('height', 900) | |
| .attr('style', 'border:1px solid black'); | |
| var defs = svg.append('defs'); | |
| var arrowMarker = defs.append('marker') | |
| .attr('id', 'shape-library-markers-arrow-svg-end-default') | |
| .attr('preserveAspectRatio', 'none') | |
| .attr('viewBox', '0 0 12 12') | |
| .attr('markerWidth', '12') | |
| .attr('markerHeight', '12') | |
| .attr('markerUnits', 'strokeWidth') | |
| .attr('orient', 'auto') | |
| .attr('refX', '12') | |
| .attr('refY', '6'); | |
| var arrowMarkerShapeContainer = arrowMarker.append('g') | |
| .attr('id', 'g-src-shape-library-markers-arrow-svg-end-default') | |
| .attr('transform', 'rotate(180, 6, 6)'); | |
| arrowMarkerShapeContainer.append('rect') | |
| .attr('stroke', 'none') | |
| .attr('x', '0') | |
| .attr('y', '5.4') | |
| .attr('width', '2') | |
| .attr('height', '1.2'); | |
| arrowMarkerShapeContainer.append('polygon') | |
| .attr('stroke-width', '0') | |
| .attr('points', '12,11 0,6 12,1'); | |
| viewport = svg.selectAll('#viewport') | |
| .data([currentDiagramData.viewport]) | |
| .enter() | |
| .append('g') | |
| .attr('id', 'viewport'); | |
| renderAll(); | |
| }); | |
| }; | |
| var jsondiff = function(left, right) { | |
| var instance = jsondiffpatch.create({ | |
| objectHash: function(obj) { | |
| return obj._id || obj.id || obj.name || JSON.stringify(obj); | |
| } | |
| }); | |
| var delta = instance.diff(left, right); | |
| document.getElementById('visual').innerHTML = jsondiffpatch.formatters.html.format(delta, left); | |
| if (!!delta) { | |
| jsondiffpatch.formatters.html.hideUnchanged(); | |
| } | |
| }; | |
| var drag = d3.behavior.drag() | |
| .on("dragstart", function(d) { | |
| dragging = true; | |
| dragPointX = d3.event.sourceEvent.x; | |
| dragPointY = d3.event.sourceEvent.y; | |
| }) | |
| .on("drag", dragmove) | |
| .on("dragend", function(d) { | |
| dragging = false; | |
| selectedEdge.attr('d', function(d) { | |
| return calculatePathData(d).d; | |
| }); | |
| currentDiagramData.viewport = d3.select('#viewport').datum(); | |
| d3.select('svg').attr('class',null); | |
| renderAll(); | |
| }); | |
| function renderDiagramEdgeData(edgeElement, d) { | |
| var edgeElementLength = edgeElement.getTotalLength(), | |
| anchorPoint, | |
| anchorPoints = {}, | |
| elementToUpdate, | |
| pointsToUpdate, | |
| pointToUpdate; | |
| if (d.hasOwnProperty('anchors')) { | |
| d.anchors.forEach(function(anchor) { | |
| anchorPoints[anchor.id] = edgeElement.getPointAtLength(edgeElementLength * anchor.position); | |
| }); | |
| d.hasAnchoredDependencies.forEach(function(elementId) { | |
| elementToUpdate = currentDiagramData.viewport.filter(function(element) { | |
| return element.id === elementId; | |
| })[0]; | |
| pointsToUpdate = elementToUpdate.points.filter(function(point) { | |
| return point.hasOwnProperty('anchor'); | |
| }); | |
| pointsToUpdate.forEach(function(pointToUpdate) { | |
| anchorPoint = anchorPoints[pointToUpdate.anchor]; | |
| if (!!anchorPoint) { | |
| pointToUpdate.x = anchorPoint.x; | |
| pointToUpdate.y = anchorPoint.y; | |
| } | |
| }); | |
| var nextEdge = d3.select('#' + elementId); | |
| var nextEdgeElement = nextEdge[0][0]; | |
| renderDiagramEdgeData(nextEdgeElement, elementToUpdate); | |
| }); | |
| } | |
| renderDiagram(); | |
| } | |
| function dragmove(d) { | |
| dragPointX = d3.event.x; | |
| dragPointY = d3.event.y; | |
| dragSegment.x = dragPointX; | |
| dragSegment.y = dragPointY; | |
| selectedPoint.x = dragPointX; | |
| selectedPoint.y = dragPointY; | |
| currentDiagramData.viewport = d3.select('#viewport').datum(); | |
| renderDiagramEdgeData(selectedEdgeElement, d); | |
| } | |
| var getDragSegment = function(d, selectedDragHandleIdentity) { | |
| selectedEdge = d3.select('#' + d.id); | |
| selectedEdgeElement = selectedEdge[0][0]; | |
| var numberOfItems = selectedEdgeElement.pathSegList.numberOfItems; | |
| if (selectedDragHandleIdentity === 'target') { | |
| selectedPoint = d.points[d.points.length - 1]; | |
| dragSegment = selectedEdgeElement.pathSegList.getItem(numberOfItems - 1); | |
| } | |
| else { | |
| selectedPoint = d.points[0]; | |
| dragSegment = selectedEdgeElement.pathSegList.getItem(0); | |
| } | |
| }; | |
| var calculatePathData = function(d) { | |
| var firstPathSegString, | |
| pathData = {}; | |
| if (d.hasOwnProperty('points')) { | |
| d.points.map(function(point, index) { | |
| var targetEdge, targetEdgeElement, targetEdgeElementLength, anchor, anchorPoint; | |
| if (!point.hasOwnProperty('x')) { | |
| targetEdge = d3.select('#' + point.element); | |
| targetEdgeElement = targetEdge[0][0]; | |
| targetEdgeElementLength = targetEdgeElement.getTotalLength(); | |
| anchor = targetEdge.datum().anchors.filter(function(anchor) {return anchor.id === point.anchor;})[0]; | |
| anchorPoint = targetEdgeElement.getPointAtLength(targetEdgeElementLength * anchor.position); | |
| point.x = anchorPoint.x; | |
| point.y = anchorPoint.y; | |
| } | |
| if (index > 0) { | |
| d += ' L ' + point.x + ' ' + point.y; | |
| } | |
| else { | |
| d = firstPathSegString = 'M ' + point.x + ' ' + point.y; | |
| } | |
| }); | |
| } | |
| pathData.d = d; | |
| pathData.firstPathSegString = firstPathSegString; | |
| return pathData; | |
| }; | |
| var renderDiagram = function(callback){ | |
| var renderableTypeToSvgElementMappings = { | |
| 'node':'rect', | |
| 'edge':'path' | |
| }; | |
| var elements = viewport.selectAll('.element') | |
| .data(function(d) { | |
| return d; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', function(d) { | |
| var cssClassString = 'element ' + d.renderableType; | |
| return cssClassString; | |
| }); | |
| elements.enter() | |
| .append(function(d) { | |
| var childElementName = renderableTypeToSvgElementMappings[d.renderableType]; | |
| var child = document.createElementNS('http://www.w3.org/2000/svg', childElementName); | |
| return child; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', function(d) { | |
| var cssClassString = 'element ' + d.renderableType; | |
| return cssClassString; | |
| }); | |
| elements.attr({ | |
| style: function(d) { return d.style; }, | |
| x: function(d) { return d.x; }, | |
| y: function(d) { return d.y; }, | |
| width: function(d) { return d.width; }, | |
| height: function(d) { return d.height; }, | |
| d: function(d) { | |
| return calculatePathData(d).d; | |
| }, | |
| 'marker-end': function(d) { return 'url(#shape-library-markers-arrow-svg-end-default)'; } | |
| }); | |
| elements.exit().remove(); | |
| if (!!callback) { | |
| callback(elements); | |
| } | |
| }; | |
| var renderAll = function() { | |
| renderDiagram(function(elements) { | |
| elements.each(function(d){ | |
| var element = d3.select(this); | |
| var sourceHandle, sourceHandleUpdated, targetHandle, targetHandleUpdated, sourcePoint, targetPoint, points; | |
| if (d.renderableType === 'edge') { | |
| var edge = d3.select('#' + d.id); | |
| var edgeElement = edge[0][0]; | |
| var edgeLength = edgeElement.getTotalLength(); | |
| var distanceAlongEdge = Math.min(12, edgeLength/3); | |
| points = d.points; | |
| sourcePoint = points[0]; | |
| targetPoint = points[points.length - 1]; | |
| sourceHandle = viewport.selectAll('#' + d.id + '-source-handle') | |
| .data([ d ]) | |
| .enter() | |
| .append('path') | |
| .attr('id', d.id + '-source-handle'); | |
| // TODO Do I need to use this format of defining the sourceHandle again or can I somehow | |
| // reuse the definition above? Same for the targetHandle. | |
| sourceHandleUpdated = d3.select('#' + d.id + '-source-handle') | |
| .attr('d', function(d) { | |
| var firstPoint = d.points[0]; | |
| var point0 = edgeElement.getPointAtLength(0); | |
| var point1 = edgeElement.getPointAtLength(distanceAlongEdge); | |
| return 'M ' + point0.x + ' ' + point0.y + ' L ' + point1.x + ' ' + point1.y; | |
| }) | |
| .attr('class', 'drag-handle') | |
| .on('mouseover', function(d) { | |
| d3.select(this).attr('class','drag-handle grab'); | |
| }) | |
| .on('mousedown', function(d) { | |
| getDragSegment(d, 'source'); | |
| d3.select('#' + d.id).attr('class', 'element edge-selected'); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| d3.select(this).attr('class','drag-handle grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class',null); | |
| d3.select(this).attr('class','drag-handle'); | |
| }) | |
| .call(drag); | |
| targetHandle = viewport.selectAll('#' + d.id + '-target-handle') | |
| .data([ d ]) | |
| .enter() | |
| .append('path') | |
| .attr('id', d.id + '-target-handle'); | |
| targetHandleUpdated = d3.select('#' + d.id + '-target-handle') | |
| .attr('d', function(d) { | |
| var lastPoint = d.points[d.points.length - 1]; | |
| var point0 = edgeElement.getPointAtLength(edgeLength); | |
| var point1 = edgeElement.getPointAtLength(edgeLength - distanceAlongEdge); | |
| return 'M ' + point0.x + ' ' + point0.y + ' L ' + point1.x + ' ' + point1.y; | |
| }) | |
| .attr('class', 'drag-handle') | |
| .on('mouseover', function(d) { | |
| d3.select(this).attr('class','drag-handle grab'); | |
| }) | |
| .on('mousedown', function(d) { | |
| getDragSegment(d, 'target'); | |
| d3.select('#' + d.id).attr('class', 'element edge-selected'); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| d3.select(this).attr('class','drag-handle grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class',null); | |
| d3.select(this).attr('class','drag-handle'); | |
| }) | |
| .call(drag); | |
| } | |
| }); | |
| }); | |
| var currentDiagramDataString = JSON.stringify(currentDiagramData, null, '\t'); | |
| d3.select('#current-json').text(currentDiagramDataString); | |
| jsondiff(originalDiagramData, currentDiagramData); | |
| }; | |
| return { | |
| init:init | |
| }; | |
| }(); |
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> | |
| <meta http-equiv="content-type" content="text/html; charset=utf-8"> | |
| <body> | |
| <div id="diagram"></div> | |
| <p> | |
| Input: | |
| </p> | |
| <p id="input"> | |
| </p> | |
| <p> | |
| Output: | |
| </p> | |
| <p id="output"> | |
| </p> | |
| <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
| <script> | |
| 'use strict'; | |
| var dragging = false; | |
| var diagramData = { | |
| viewport:[ | |
| { | |
| id: 'id123', | |
| renderableType: 'node', | |
| x: 50, | |
| y: 50, | |
| width: 80, | |
| height: 20, | |
| style: 'stroke: blue; fill: white;' | |
| }, | |
| { | |
| id: 'id234', | |
| renderableType: 'node', | |
| x: 200, | |
| y: 50, | |
| width: 80, | |
| height: 20, | |
| style: 'stroke: blue; fill: white;' | |
| }, | |
| { | |
| id: 'id345', | |
| renderableType: 'edge', | |
| points:[ | |
| { | |
| x: 130, | |
| y: 60 | |
| }, | |
| { | |
| x: 200, | |
| y: 60 | |
| } | |
| ], | |
| anchors: [ | |
| { | |
| id: 'id567', | |
| position: 0.3 | |
| } | |
| ], | |
| hasAnchoredDependencies: [ | |
| 'id456' | |
| ], | |
| style: 'stroke: black; stroke-width: 1; fill:yellow;' | |
| }, | |
| { | |
| id: 'id456', | |
| renderableType: 'edge', | |
| points:[ | |
| { | |
| x: 165, | |
| y: 20 | |
| }, | |
| { | |
| element: 'id345', | |
| anchor: 'id567' | |
| } | |
| ], | |
| style: 'stroke: black; stroke-width: 1; fill:yellow;' | |
| } | |
| ] | |
| }; | |
| var inputJsonString = JSON.stringify(diagramData); | |
| d3.select('#input').text(inputJsonString); | |
| var dragSegment, selectedPoint; | |
| var drag = d3.behavior.drag() | |
| .on("dragstart", function(d) { | |
| dragging = true; | |
| var dragPointX = d3.event.sourceEvent.x, | |
| dragPointY = d3.event.sourceEvent.y; | |
| var edge = d3.select(this); | |
| edge.attr('d', function(d) { | |
| return calculatePathData(d).d; | |
| }); | |
| var edgeElement = edge[0][0]; | |
| var numberOfItems = edgeElement.pathSegList.numberOfItems; | |
| var sourcePoint = d.points[0]; | |
| var sourcePointX = sourcePoint.x; | |
| var sourcePointY = sourcePoint.y; | |
| var dragPointToSourcePointDistance = Math.sqrt(Math.pow((dragPointX - sourcePointX),2) + Math.pow((dragPointY - sourcePointY),2)); | |
| var targetPoint = d.points[d.points.length - 1]; | |
| var targetPointX = targetPoint.x; | |
| var targetPointY = targetPoint.y; | |
| var dragPointToTargetPointDistance = Math.sqrt(Math.pow((dragPointX - targetPointX),2) + Math.pow((dragPointY - targetPointY),2)); | |
| if (dragPointToTargetPointDistance < dragPointToSourcePointDistance) { | |
| selectedPoint = targetPoint; | |
| dragSegment = edgeElement.pathSegList.getItem(0); | |
| } | |
| else { | |
| selectedPoint = sourcePoint; | |
| dragSegment = edgeElement.pathSegList.getItem(numberOfItems - 1); | |
| } | |
| }) | |
| .on("drag", dragmove) | |
| .on("dragend", function(d) { | |
| dragging = false; | |
| var thisElement = d3.select(this); | |
| thisElement.attr('d', function(d) { | |
| return calculatePathData(d).d; | |
| }); | |
| diagramData.viewport = d3.select('#viewport').datum(); | |
| var outputJsonString = JSON.stringify(diagramData); | |
| d3.select('#output').text(outputJsonString); | |
| update(); | |
| }); | |
| function dragmove(d) { | |
| var dragPointX = d3.event.x, | |
| dragPointY = d3.event.y; | |
| dragSegment.x = dragPointX; | |
| dragSegment.y = dragPointY; | |
| selectedPoint.x = dragPointX; | |
| selectedPoint.y = dragPointY; | |
| var edgeElement = this, | |
| thisEdgeElementLength = edgeElement.getTotalLength(), | |
| anchorPoint, | |
| anchorPoints = {}, | |
| elementToUpdate, | |
| pointsToUpdate, | |
| pointToUpdate; | |
| diagramData.viewport = d3.select('#viewport').datum(); | |
| if (d.hasOwnProperty('anchors')) { | |
| d.anchors.forEach(function(anchor) { | |
| anchorPoints[anchor.id] = edgeElement.getPointAtLength(thisEdgeElementLength * anchor.position); | |
| }); | |
| d.hasAnchoredDependencies.forEach(function(elementId) { | |
| elementToUpdate = diagramData.viewport.filter(function(element) { | |
| return element.id === elementId; | |
| })[0]; | |
| pointsToUpdate = elementToUpdate.points.filter(function(point) { | |
| return point.hasOwnProperty('anchor'); | |
| }); | |
| pointsToUpdate.forEach(function(pointToUpdate) { | |
| anchorPoint = anchorPoints[pointToUpdate.anchor]; | |
| if (!!anchorPoint) { | |
| pointToUpdate.x = anchorPoint.x; | |
| pointToUpdate.y = anchorPoint.y; | |
| } | |
| }); | |
| }); | |
| } | |
| update(); | |
| } | |
| var svg = d3.select('#diagram').append('svg') | |
| .attr('width', 400) | |
| .attr('height', 200) | |
| .attr('style', 'border:1px solid black'); | |
| var viewport = svg.selectAll('#viewport') | |
| .data([diagramData.viewport]) | |
| .enter() | |
| .append('g') | |
| .attr('id', 'viewport'); | |
| var calculatePathData = function(d) { | |
| var d, | |
| firstPathSegString, | |
| pathData = {}; | |
| if (d.hasOwnProperty('points')) { | |
| d.points.map(function(point, index) { | |
| var targetEdge, targetEdgeElement, targetEdgeElementLength, anchor, anchorPoint; | |
| if (!point.hasOwnProperty('x')) { | |
| targetEdge = d3.select('#' + point.element); | |
| targetEdgeElement = targetEdge[0][0]; | |
| targetEdgeElementLength = targetEdgeElement.getTotalLength(); | |
| anchor = targetEdge.datum().anchors.filter(function(anchor) {return anchor.id === point.anchor;})[0]; | |
| anchorPoint = targetEdgeElement.getPointAtLength(targetEdgeElementLength * anchor.position); | |
| point.x = anchorPoint.x; | |
| point.y = anchorPoint.y; | |
| } | |
| if (index > 0) { | |
| d += ' L ' + point.x + ' ' + point.y; | |
| } | |
| else { | |
| d = firstPathSegString = 'M ' + point.x + ' ' + point.y; | |
| } | |
| }); | |
| } | |
| pathData.d = d; | |
| pathData.firstPathSegString = firstPathSegString; | |
| return pathData; | |
| }; | |
| var update = function(){ | |
| // this is a circle | |
| //var dragHandlePathShapeString = ' m -7, 0 a 7,7 0 1,0 14,0 a 7,7 0 1,0 -14,0 l 14,0 l -7,0 l 0,-7 l 0,14 l 0,-7'; | |
| // this is a square | |
| var dragHandlePathShapeString = ' m 3,0 l 0,3 l -6,0 l 0,-6 l 6,0 l 0,3 m -3,0'; | |
| var renderableTypeToSvgElementMappings = { | |
| 'node':'rect', | |
| 'edge':'path' | |
| }; | |
| var elements = viewport.selectAll('.element') | |
| .data(function(d) { | |
| return d; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', 'element'); | |
| elements.enter() | |
| .append(function(d) { | |
| var childElementName = renderableTypeToSvgElementMappings[d.renderableType]; | |
| var child = document.createElementNS('http://www.w3.org/2000/svg', childElementName); | |
| return child; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', 'element'); | |
| elements.attr({ | |
| style: function(d) { return d.style; }, | |
| x: function(d) { return d.x; }, | |
| y: function(d) { return d.y; }, | |
| width: function(d) { return d.width; }, | |
| height: function(d) { return d.height; }, | |
| d: function(d) { | |
| return calculatePathData(d).d; | |
| } | |
| }) | |
| .on('mouseover', function(d) { | |
| if (!dragging) { | |
| var pathData = calculatePathData(d); | |
| self.mypd = pathData; | |
| var thisElement = d3.select(this); | |
| thisElement.attr('d', function(d) { | |
| var pathDataStringWithoutFirstPathSeg = pathData.d.slice(pathData.firstPathSegString.length,pathData.d.length); | |
| var result = pathData.firstPathSegString + dragHandlePathShapeString + pathDataStringWithoutFirstPathSeg + ' ' + dragHandlePathShapeString; | |
| return result; | |
| }); | |
| } | |
| }) | |
| .on('mouseout', function(d) { | |
| if (!dragging) { | |
| var thisElement = d3.select(this); | |
| thisElement.attr('d', function(d) { | |
| return calculatePathData(d).d; | |
| }); | |
| } | |
| }) | |
| .call(drag); | |
| elements.exit().remove(); | |
| }; | |
| update(); | |
| </script> | |
| </body> | |
| </html> |
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
| !function(t){if("object"==typeof exports)module.exports=t();else if("function"==typeof define&&define.amd)define(t);else{var e;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),(e.jsondiffpatch||(e.jsondiffpatch={})).formatters=t()}}(function(){return function t(e,o,n){function r(a,f){if(!o[a]){if(!e[a]){var d="function"==typeof require&&require;if(!f&&d)return d(a,!0);if(i)return i(a,!0);throw new Error("Cannot find module '"+a+"'")}var s=o[a]={exports:{}};e[a][0].call(s.exports,function(t){var o=e[a][1][t];return r(o?o:t)},s,s.exports,t,e,o,n)}return o[a].exports}for(var i="function"==typeof require&&require,a=0;a<n.length;a++)r(n[a]);return r}({1:[function(t,e){var o=e.exports={};o.nextTick=function(){var t="undefined"!=typeof window&&window.setImmediate,e="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(t)return function(t){return window.setImmediate(t)};if(e){var o=[];return window.addEventListener("message",function(t){var e=t.source;if((e===window||null===e)&&"process-tick"===t.data&&(t.stopPropagation(),o.length>0)){var n=o.shift();n()}},!0),function(t){o.push(t),window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}(),o.title="browser",o.browser=!0,o.env={},o.argv=[],o.binding=function(){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(){throw new Error("process.chdir is not supported")}},{}],2:[function(t,e,o){var n=t("./base"),r=n.BaseFormatter,i=function(){this.includeMoveDestinations=!1};i.prototype=new r,i.prototype.prepareContext=function(t){r.prototype.prepareContext.call(this,t),t.indent=function(t){this.indentLevel=(this.indentLevel||0)+("undefined"==typeof t?1:t),this.indentPad=new Array(this.indentLevel+1).join(" ")},t.row=function(e,o){t.out('<tr><td style="white-space: nowrap;"><pre class="jsondiffpatch-annotated-indent" style="display: inline-block">'),t.out(t.indentPad),t.out('</pre><pre style="display: inline-block">'),t.out(e),t.out('</pre></td><td class="jsondiffpatch-delta-note"><div>'),t.out(o),t.out("</div></td></tr>")}},i.prototype.typeFormattterErrorFormatter=function(t,e){t.row("",'<pre class="jsondiffpatch-error">'+e+"</pre>")},i.prototype.formatTextDiffString=function(t,e){var o=this.parseTextDiff(e);t.out('<ul class="jsondiffpatch-textdiff">');for(var n=0,r=o.length;r>n;n++){var i=o[n];t.out('<li><div class="jsondiffpatch-textdiff-location"><span class="jsondiffpatch-textdiff-line-number">'+i.location.line+'</span><span class="jsondiffpatch-textdiff-char">'+i.location.chr+'</span></div><div class="jsondiffpatch-textdiff-line">');for(var a=i.pieces,f=0,d=a.length;d>f;f++){var s=a[f];t.out('<span class="jsondiffpatch-textdiff-'+s.type+'">'+s.text+"</span>")}t.out("</div></li>")}t.out("</ul>")},i.prototype.rootBegin=function(t,e,o){t.out('<table class="jsondiffpatch-annotated-delta">'),"node"===e&&(t.row("{"),t.indent()),"array"===o&&t.row('"_t": "a",',"Array delta (member names indicate array indices)")},i.prototype.rootEnd=function(t,e){"node"===e&&(t.indent(-1),t.row("}")),t.out("</table>")},i.prototype.nodeBegin=function(t,e,o,n,r){t.row("""+e+"": {"),"node"===n&&t.indent(),"array"===r&&t.row('"_t": "a",',"Array delta (member names indicate array indices)")},i.prototype.nodeEnd=function(t,e,o,n,r,i){"node"===n&&t.indent(-1),t.row("}"+(i?"":","))},i.prototype.format_unchanged=function(){},i.prototype.format_movedestination=function(){},i.prototype.format_node=function(t,e,o){this.formatDeltaChildren(t,e,o)};var a=function(t){return'<pre style="display:inline-block">"'+t+""</pre>"},f={added:function(t,e,o,n){var r=" <pre>([newValue])</pre>";return"undefined"==typeof n?"new value"+r:"number"==typeof n?"insert at index "+n+r:"add property "+a(n)+r},modified:function(t,e,o,n){var r=" <pre>([previousValue, newValue])</pre>";return"undefined"==typeof n?"modify value"+r:"number"==typeof n?"modify at index "+n+r:"modify property "+a(n)+r},deleted:function(t,e,o,n){var r=" <pre>([previousValue, 0, 0])</pre>";return"undefined"==typeof n?"delete value"+r:"number"==typeof n?"remove index "+n+r:"delete property "+a(n)+r},moved:function(t,e,o,n){return'move from <span title="(position to remove at original state)">index '+n+'</span> to <span title="(position to insert at final state)">index '+t[1]+"</span>"},textdiff:function(t,e,o,n){var r="undefined"==typeof n?"":"number"==typeof n?" at index "+n:" at property "+a(n);return"text diff"+r+', format is <a href="https://code.google.com/p/google-diff-match-patch/wiki/Unidiff">a variation of Unidiff</a>'}},d=function(t,e){var o=this.getDeltaType(e),n=f[o],r=n&&n.apply(n,Array.prototype.slice.call(arguments,1)),i=JSON.stringify(e,null,2);"textdiff"===o&&(i=i.split("\\n").join('\\n"+\n "')),t.indent(),t.row(i,r),t.indent(-1)};i.prototype.format_added=d,i.prototype.format_modified=d,i.prototype.format_deleted=d,i.prototype.format_moved=d,i.prototype.format_textdiff=d,o.AnnotatedFormatter=i;var s;o.format=function(t,e){return s||(s=new i),s.format(t,e)}},{"./base":3}],3:[function(t,e,o){var n="function"==typeof Array.isArray?Array.isArray:function(t){return t instanceof Array},r="function"==typeof Object.keys?function(t){return Object.keys(t)}:function(t){var e=[];for(var o in t)t.hasOwnProperty(o)&&e.push(o);return e},i=function(t){return"_"===t.substr(0,1)?t.slice(1):t},a=function(t){return"_t"===t?-1:"_"===t.substr(0,1)?parseInt(t.slice(1),10):parseInt(t,10)+.1},f=function(t,e){return a(t)-a(e)},d=function(){};d.prototype.format=function(t,e){var o={};return this.prepareContext(o),this.recurse(o,t,e),this.finalize(o)},d.prototype.prepareContext=function(t){t.buffer=[],t.out=function(){this.buffer.push.apply(this.buffer,arguments)}},d.prototype.typeFormattterNotFound=function(t,e){throw new Error("cannot format delta type: "+e)},d.prototype.typeFormattterErrorFormatter=function(t,e){return e.toString()},d.prototype.finalize=function(t){return n(t.buffer)?t.buffer.join(""):void 0},d.prototype.recurse=function(t,e,o,n,r,i,a){if("undefined"==typeof e&&"undefined"==typeof n)return void 0;var f=this.getDeltaType(e,i),d="node"===f?"a"===e._t?"array":"object":"";"undefined"!=typeof n?this.nodeBegin(t,n,r,f,d,a):this.rootBegin(t,f,d);var s;try{s=this["format_"+f]||this.typeFormattterNotFound(t,f),s.call(this,t,e,o,n,r,i)}catch(p){this.typeFormattterErrorFormatter(t,p,e,o,n,r,i),"undefined"!=typeof console&&console.error&&console.error(p.stack)}"undefined"!=typeof n?this.nodeEnd(t,n,r,f,d,a):this.rootEnd(t,f,d)},d.prototype.formatDeltaChildren=function(t,e,o){var n=this;this.forEachDeltaKey(e,o,function(r,i,a,f){n.recurse(t,e[r],o?o[i]:void 0,r,i,a,f)})},d.prototype.forEachDeltaKey=function(t,e,o){var a,d=r(t),s="a"===t._t,p={};if("undefined"!=typeof e)for(a in e)"undefined"!=typeof t[a]||s&&"undefined"!=typeof t["_"+a]||d.push(a);for(a in t){var u=t[a];n(u)&&3===u[2]&&(p[u[1].toString()]=u[0],this.includeMoveDestinations!==!1&&"undefined"==typeof e&&"undefined"==typeof t[u[1]]&&d.push(u[1].toString()))}s?d.sort(f):d.sort();for(var c=0,l=d.length;l>c;c++){var h=d[c];if(!s||"_t"!==h){var y=s?"number"==typeof h?h:parseInt(i(h),10):h,v=c===l-1;o(h,y,p[y],v)}}},d.prototype.getDeltaType=function(t,e){if("undefined"==typeof t)return"undefined"!=typeof e?"movedestination":"unchanged";if(n(t)){if(1===t.length)return"added";if(2===t.length)return"modified";if(3===t.length&&0===t[2])return"deleted";if(3===t.length&&2===t[2])return"textdiff";if(3===t.length&&3===t[2])return"moved"}else if("object"==typeof t)return"node";return"unknown"},d.prototype.parseTextDiff=function(t){for(var e=[],o=t.split("\n@@ "),n=0,r=o.length;r>n;n++){var i=o[n],a={pieces:[]},f=/^(?:@@ )?[-+]?(\d+),(\d+)/.exec(i).slice(1);a.location={line:f[0],chr:f[1]};for(var d=i.split("\n").slice(1),s=0,p=d.length;p>s;s++){var u=d[s];if(u.length){var c={type:"context"};"+"===u.substr(0,1)?c.type="added":"-"===u.substr(0,1)&&(c.type="deleted"),c.text=u.slice(1),a.pieces.push(c)}}e.push(a)}return e},o.BaseFormatter=d},{}],4:[function(t,e,o){(function(e){o.html=t("./html"),o.annotated=t("./annotated");var n="undefined"!=typeof e&&"string"==typeof e.execPath;n&&(o.console=t("./console"))}).call(this,t("/home/sheila/proj/JsonDiffPatch/node_modules/gulp-browserify/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))},{"./annotated":2,"./html":5,"/home/sheila/proj/JsonDiffPatch/node_modules/gulp-browserify/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":1}],5:[function(t,e,o){var n=t("./base"),r=n.BaseFormatter,i=function(){};i.prototype=new r,i.prototype.typeFormattterErrorFormatter=function(t,e){t.out('<pre class="jsondiffpatch-error">'+e+"</pre>")},i.prototype.formatValue=function(t,e){t.out("<pre>"+JSON.stringify(e,null,2)+"</pre>")},i.prototype.formatTextDiffString=function(t,e){var o=this.parseTextDiff(e);t.out('<ul class="jsondiffpatch-textdiff">');for(var n=0,r=o.length;r>n;n++){var i=o[n];t.out('<li><div class="jsondiffpatch-textdiff-location"><span class="jsondiffpatch-textdiff-line-number">'+i.location.line+'</span><span class="jsondiffpatch-textdiff-char">'+i.location.chr+'</span></div><div class="jsondiffpatch-textdiff-line">');for(var a=i.pieces,f=0,d=a.length;d>f;f++){var s=a[f];t.out('<span class="jsondiffpatch-textdiff-'+s.type+'">'+s.text+"</span>")}t.out("</div></li>")}t.out("</ul>")};var a=function(t){t=t||document;var e=function(t){return t.textContent||t.innerText},o=function(t,e,o){for(var n=t.querySelectorAll(e),r=0,i=n.length;i>r;r++)o(n[r])},n=function(t,e){for(var o=0,n=t.children.length;n>o;o++)e(t.children[o],o)};o(t,".jsondiffpatch-arrow",function(t){var o=t.parentNode,r=t.children[0],i=r.children[1];r.style.display="none";var a,f=e(o.querySelector(".jsondiffpatch-moved-destination")),d=o.parentNode;if(n(d,function(t){t.getAttribute("data-key")===f&&(a=t)}),a)try{var s=a.offsetTop-o.offsetTop;r.setAttribute("height",Math.abs(s)+6),t.style.top=-8+(s>0?0:s)+"px";var p=s>0?"M30,0 Q-10,"+Math.round(s/2)+" 26,"+(s-4):"M30,"+-s+" Q-10,"+Math.round(-s/2)+" 26,4";i.setAttribute("d",p),r.style.display=""}catch(u){return}})};i.prototype.rootBegin=function(t,e,o){var n="jsondiffpatch-"+e+(o?" jsondiffpatch-child-node-type-"+o:"");t.out('<div class="jsondiffpatch-delta '+n+'">')},i.prototype.rootEnd=function(t){t.out("</div>"+(t.hasArrows?'<script type="text/javascript">setTimeout('+a.toString()+",10);</script>":""))},i.prototype.nodeBegin=function(t,e,o,n,r){var i="jsondiffpatch-"+n+(r?" jsondiffpatch-child-node-type-"+r:"");t.out('<li class="'+i+'" data-key="'+o+'"><div class="jsondiffpatch-property-name">'+o+"</div>")},i.prototype.nodeEnd=function(t){t.out("</li>")},i.prototype.format_unchanged=function(t,e,o){"undefined"!=typeof o&&(t.out('<div class="jsondiffpatch-value">'),this.formatValue(t,o),t.out("</div>"))},i.prototype.format_movedestination=function(t,e,o){"undefined"!=typeof o&&(t.out('<div class="jsondiffpatch-value">'),this.formatValue(t,o),t.out("</div>"))},i.prototype.format_node=function(t,e,o){var n="a"===e._t?"array":"object";t.out('<ul class="jsondiffpatch-node jsondiffpatch-node-type-'+n+'">'),this.formatDeltaChildren(t,e,o),t.out("</ul>")},i.prototype.format_added=function(t,e){t.out('<div class="jsondiffpatch-value">'),this.formatValue(t,e[0]),t.out("</div>")},i.prototype.format_modified=function(t,e){t.out('<div class="jsondiffpatch-value jsondiffpatch-left-value">'),this.formatValue(t,e[0]),t.out('</div><div class="jsondiffpatch-value jsondiffpatch-right-value">'),this.formatValue(t,e[1]),t.out("</div>")},i.prototype.format_deleted=function(t,e){t.out('<div class="jsondiffpatch-value">'),this.formatValue(t,e[0]),t.out("</div>")},i.prototype.format_moved=function(t,e){t.out('<div class="jsondiffpatch-value">'),this.formatValue(t,e[0]),t.out('</div><div class="jsondiffpatch-moved-destination">'+e[1]+"</div>"),t.out('<div class="jsondiffpatch-arrow" style="position: relative; left: -34px;"> <svg width="30" height="60" style="position: absolute; display: none;"> <defs> <marker id="markerArrow" markerWidth="8" markerHeight="8" refx="2" refy="4" orient="auto" markerUnits="userSpaceOnUse"> <path d="M1,1 L1,7 L7,4 L1,1" style="fill: #339;" /> </marker> </defs> <path d="M30,0 Q-10,25 26,50" style="stroke: #88f; stroke-width: 2px; fill: none; stroke-opacity: 0.5; marker-end: url(#markerArrow);"></path> </svg> </div>'),t.hasArrows=!0},i.prototype.format_textdiff=function(t,e){t.out('<div class="jsondiffpatch-value">'),this.formatTextDiffString(t,e[0]),t.out("</div>")};var f=function(t,e,o){var n=e||document.body,r="jsondiffpatch-unchanged-",i={showing:r+"showing",hiding:r+"hiding",visible:r+"visible",hidden:r+"hidden"},f=n.classList;if(f){if(!o)return f.remove(i.showing),f.remove(i.hiding),f.remove(i.visible),f.remove(i.hidden),void(t===!1&&f.add(i.hidden));t===!1?(f.remove(i.showing),f.add(i.visible),setTimeout(function(){f.add(i.hiding)},10)):(f.remove(i.hiding),f.add(i.showing),f.remove(i.hidden));var d=setInterval(function(){a(n)},100);setTimeout(function(){f.remove(i.showing),f.remove(i.hiding),t===!1?(f.add(i.hidden),f.remove(i.visible)):(f.add(i.visible),f.remove(i.hidden)),setTimeout(function(){f.remove(i.visible),clearInterval(d)},o+400)},o)}},d=function(t,e){return f(!1,t,e)};o.HtmlFormatter=i,o.showUnchanged=f,o.hideUnchanged=d;var s;o.format=function(t,e){return s||(s=new i),s.format(t,e)}},{"./base":3}]},{},[4])(4)}); |
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
| .jsondiffpatch-delta { | |
| font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace; | |
| font-size: 12px; | |
| margin: 0; | |
| padding: 0 0 0 12px; | |
| display: inline-block; | |
| } | |
| .jsondiffpatch-delta pre { | |
| font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace; | |
| font-size: 12px; | |
| margin: 0; | |
| padding: 0; | |
| display: inline-block; | |
| } | |
| ul.jsondiffpatch-delta { | |
| list-style-type: none; | |
| padding: 0 0 0 20px; | |
| margin: 0; | |
| } | |
| .jsondiffpatch-delta ul { | |
| list-style-type: none; | |
| padding: 0 0 0 20px; | |
| margin: 0; | |
| } | |
| .jsondiffpatch-added .jsondiffpatch-property-name, | |
| .jsondiffpatch-added .jsondiffpatch-value pre, | |
| .jsondiffpatch-modified .jsondiffpatch-right-value, | |
| .jsondiffpatch-textdiff-added | |
| { | |
| background: #bbffbb; | |
| } | |
| .jsondiffpatch-deleted .jsondiffpatch-property-name, | |
| .jsondiffpatch-deleted pre, | |
| .jsondiffpatch-modified .jsondiffpatch-left-value pre, | |
| .jsondiffpatch-textdiff-deleted | |
| { | |
| background: #ffbbbb; | |
| text-decoration: line-through; | |
| } | |
| .jsondiffpatch-unchanged, .jsondiffpatch-movedestination { | |
| color: gray; | |
| } | |
| .jsondiffpatch-unchanged, .jsondiffpatch-movedestination > .jsondiffpatch-value { | |
| transition: all 0.5s; | |
| -webkit-transition: all 0.5s; | |
| overflow-y: hidden; | |
| } | |
| .jsondiffpatch-unchanged-showing .jsondiffpatch-unchanged, | |
| .jsondiffpatch-unchanged-showing .jsondiffpatch-movedestination > .jsondiffpatch-value { | |
| max-height: 100px; | |
| } | |
| .jsondiffpatch-unchanged-hidden .jsondiffpatch-unchanged, | |
| .jsondiffpatch-unchanged-hidden .jsondiffpatch-movedestination > .jsondiffpatch-value { | |
| max-height: 0; | |
| } | |
| .jsondiffpatch-unchanged-hiding .jsondiffpatch-movedestination > .jsondiffpatch-value, | |
| .jsondiffpatch-unchanged-hidden .jsondiffpatch-movedestination > .jsondiffpatch-value { | |
| display: block; | |
| } | |
| .jsondiffpatch-unchanged-visible .jsondiffpatch-unchanged, | |
| .jsondiffpatch-unchanged-visible .jsondiffpatch-movedestination > .jsondiffpatch-value { | |
| max-height: 100px; | |
| } | |
| .jsondiffpatch-unchanged-hiding .jsondiffpatch-unchanged, | |
| .jsondiffpatch-unchanged-hiding .jsondiffpatch-movedestination > .jsondiffpatch-value { | |
| max-height: 0; | |
| } | |
| .jsondiffpatch-unchanged-showing .jsondiffpatch-arrow, | |
| .jsondiffpatch-unchanged-hiding .jsondiffpatch-arrow { | |
| display: none; | |
| } | |
| .jsondiffpatch-value { | |
| display: inline-block; | |
| } | |
| .jsondiffpatch-property-name { | |
| display: inline-block; | |
| padding-right: 5px; | |
| vertical-align: top; | |
| } | |
| .jsondiffpatch-property-name:after { | |
| content: ': '; | |
| } | |
| .jsondiffpatch-child-node-type-array > .jsondiffpatch-property-name:after { | |
| content: ': ['; | |
| } | |
| .jsondiffpatch-child-node-type-array:after { | |
| content: '],'; | |
| } | |
| div.jsondiffpatch-child-node-type-array:before { | |
| content: '['; | |
| } | |
| div.jsondiffpatch-child-node-type-array:after { | |
| content: ']'; | |
| } | |
| .jsondiffpatch-child-node-type-object > .jsondiffpatch-property-name:after { | |
| content: ': {'; | |
| } | |
| .jsondiffpatch-child-node-type-object:after { | |
| content: '},'; | |
| } | |
| div.jsondiffpatch-child-node-type-object:before { | |
| content: '{'; | |
| } | |
| div.jsondiffpatch-child-node-type-object:after { | |
| content: '}'; | |
| } | |
| .jsondiffpatch-value pre:after { | |
| content: ','; | |
| } | |
| li:last-child > .jsondiffpatch-value pre:after, | |
| .jsondiffpatch-modified > .jsondiffpatch-left-value pre:after | |
| { | |
| content: ''; | |
| } | |
| .jsondiffpatch-modified .jsondiffpatch-value { | |
| display: inline-block; | |
| } | |
| .jsondiffpatch-modified .jsondiffpatch-right-value { | |
| margin-left: 5px; | |
| } | |
| .jsondiffpatch-moved .jsondiffpatch-value { | |
| display: none; | |
| } | |
| .jsondiffpatch-moved .jsondiffpatch-moved-destination { | |
| display: inline-block; | |
| background: #ffffbb; | |
| color: #888; | |
| } | |
| .jsondiffpatch-moved .jsondiffpatch-moved-destination:before { | |
| content: ' => '; | |
| } | |
| ul.jsondiffpatch-textdiff { | |
| padding: 0; | |
| } | |
| .jsondiffpatch-textdiff-location { | |
| color: #bbb; | |
| display: inline-block; | |
| min-width: 60px; | |
| } | |
| .jsondiffpatch-textdiff-line { | |
| display: inline-block; | |
| } | |
| .jsondiffpatch-textdiff-line-number:after { | |
| content: ','; | |
| } | |
| .jsondiffpatch-error { | |
| background: red; | |
| color: white; | |
| font-weight: bold; | |
| } |
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> | |
| <meta http-equiv="content-type" content="text/html; charset=utf-8"> | |
| <style> | |
| body { | |
| font: 10px sans-serif; | |
| } | |
| /* | |
| .drag-handle { | |
| fill: transparent; | |
| fill-opacity: 1; | |
| stroke: transparent; | |
| stroke-width: 0; | |
| } | |
| */ | |
| .drag-handle { | |
| fill: transparent; | |
| stroke: transparent; | |
| } | |
| .drag-handle:hover, .drag-handle-active { | |
| fill: yellow; | |
| fill-opacity: 0.8; | |
| stroke: orange; | |
| stroke-width: 0.5px; | |
| cursor: -moz-grab; | |
| cursor: -webkit-grab; | |
| cursor: grab; | |
| } | |
| .drag-handle-inactive { | |
| fill: gray; | |
| fill-opacity: 0.2; | |
| stroke: gray; | |
| stroke-opacity: 0.5; | |
| stroke-width: 0.5px; | |
| } | |
| .grab, .edge { | |
| cursor: -moz-grab; | |
| cursor: -webkit-grab; | |
| cursor: grab; | |
| } | |
| .grabbing, .edge-selected { | |
| cursor: -moz-grabbing; | |
| cursor: -webkit-grabbing; | |
| cursor: grabbing; | |
| } | |
| </style> | |
| <body> | |
| <div id="diagram"></div> | |
| <p> | |
| Input: | |
| </p> | |
| <p id="input"> | |
| </p> | |
| <p> | |
| Output: | |
| </p> | |
| <p id="output"> | |
| </p> | |
| <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
| <script> | |
| 'use strict'; | |
| var dragging = false; | |
| var diagramData = { | |
| viewport:[ | |
| { | |
| id: 'id123', | |
| renderableType: 'node', | |
| x: 50, | |
| y: 50, | |
| width: 80, | |
| height: 20, | |
| style: 'stroke: blue; fill: white;' | |
| }, | |
| { | |
| id: 'id234', | |
| renderableType: 'node', | |
| x: 200, | |
| y: 50, | |
| width: 80, | |
| height: 20, | |
| style: 'stroke: blue; fill: white;' | |
| }, | |
| { | |
| id: 'id345', | |
| renderableType: 'edge', | |
| points:[ | |
| { | |
| x: 130, | |
| y: 60 | |
| }, | |
| { | |
| x: 200, | |
| y: 60 | |
| } | |
| ], | |
| anchors: [ | |
| { | |
| id: 'id567', | |
| position: 0.3 | |
| } | |
| ], | |
| hasAnchoredDependencies: [ | |
| 'id456' | |
| ], | |
| style: 'stroke: black; stroke-width: 1; fill:yellow;' | |
| }, | |
| { | |
| id: 'id456', | |
| renderableType: 'edge', | |
| points:[ | |
| { | |
| x: 165, | |
| y: 20 | |
| }, | |
| { | |
| element: 'id345', | |
| anchor: 'id567' | |
| } | |
| ], | |
| style: 'stroke: black; stroke-width: 1; fill:yellow;' | |
| } | |
| ] | |
| }; | |
| var inputJsonString = JSON.stringify(diagramData); | |
| d3.select('#input').text(inputJsonString); | |
| var dragSegment, selectedPoint, selectedEdge, selectedEdgeElement, dragPointX, dragPointY, nearerDragHandle, fartherDragHandle; | |
| var getNearestDragHandleIdentity = function(d, dragPointX, dragPointY) { | |
| var nearerDragHandleIdentity; | |
| selectedEdge = d3.select('#' + d.id); | |
| selectedEdgeElement = selectedEdge[0][0]; | |
| var numberOfItems = selectedEdgeElement.pathSegList.numberOfItems; | |
| var sourcePoint = d.points[0]; | |
| var sourcePointX = sourcePoint.x; | |
| var sourcePointY = sourcePoint.y; | |
| var dragPointToSourcePointDistance = Math.sqrt(Math.pow((dragPointX - sourcePointX),2) + Math.pow((dragPointY - sourcePointY),2)); | |
| var targetPoint = d.points[d.points.length - 1]; | |
| var targetPointX = targetPoint.x; | |
| var targetPointY = targetPoint.y; | |
| var dragPointToTargetPointDistance = Math.sqrt(Math.pow((dragPointX - targetPointX),2) + Math.pow((dragPointY - targetPointY),2)); | |
| if (dragPointToTargetPointDistance < dragPointToSourcePointDistance) { | |
| selectedPoint = targetPoint; | |
| dragSegment = selectedEdgeElement.pathSegList.getItem(0); | |
| nearerDragHandleIdentity = 'target'; | |
| } | |
| else { | |
| selectedPoint = sourcePoint; | |
| dragSegment = selectedEdgeElement.pathSegList.getItem(numberOfItems - 1); | |
| nearerDragHandleIdentity = 'source'; | |
| } | |
| return nearerDragHandleIdentity; | |
| }; | |
| var drag = d3.behavior.drag() | |
| .on("dragstart", function(d) { | |
| nearerDragHandle.attr('class', 'drag-handle'); | |
| fartherDragHandle.attr('class', 'drag-handle'); | |
| dragging = true; | |
| dragPointX = d3.event.sourceEvent.x; | |
| dragPointY = d3.event.sourceEvent.y; | |
| var dragHandleIdentities = getNearestDragHandleIdentity(d, dragPointX, dragPointY); | |
| }) | |
| .on("drag", dragmove) | |
| .on("dragend", function(d) { | |
| dragging = false; | |
| console.log('this'); | |
| console.log(this); | |
| console.log('this'); | |
| console.log(this); | |
| /* | |
| var dragHandle = d3.select(this) | |
| .attr('cx', dragPointX) | |
| .attr('cy', dragPointY); | |
| //*/ | |
| selectedEdge.attr('d', function(d) { | |
| return calculatePathData(d).d; | |
| }); | |
| diagramData.viewport = d3.select('#viewport').datum(); | |
| var outputJsonString = JSON.stringify(diagramData); | |
| d3.select('#output').text(outputJsonString); | |
| d3.select('svg').attr('class',null); | |
| init(); | |
| }); | |
| function dragmove(d) { | |
| dragPointX = d3.event.x; | |
| dragPointY = d3.event.y; | |
| dragSegment.x = dragPointX; | |
| dragSegment.y = dragPointY; | |
| selectedPoint.x = dragPointX; | |
| selectedPoint.y = dragPointY; | |
| var selectedEdgeElementLength = selectedEdgeElement.getTotalLength(), | |
| //selectedEdgeElementLength = selectedEdgeElement.getTotalLength() - 185.9791717529297, | |
| anchorPoint, | |
| anchorPoints = {}, | |
| elementToUpdate, | |
| pointsToUpdate, | |
| pointToUpdate; | |
| diagramData.viewport = d3.select('#viewport').datum(); | |
| if (d.hasOwnProperty('anchors')) { | |
| d.anchors.forEach(function(anchor) { | |
| anchorPoints[anchor.id] = selectedEdgeElement.getPointAtLength(selectedEdgeElementLength * anchor.position); | |
| }); | |
| d.hasAnchoredDependencies.forEach(function(elementId) { | |
| elementToUpdate = diagramData.viewport.filter(function(element) { | |
| return element.id === elementId; | |
| })[0]; | |
| pointsToUpdate = elementToUpdate.points.filter(function(point) { | |
| return point.hasOwnProperty('anchor'); | |
| }); | |
| pointsToUpdate.forEach(function(pointToUpdate) { | |
| anchorPoint = anchorPoints[pointToUpdate.anchor]; | |
| if (!!anchorPoint) { | |
| pointToUpdate.x = anchorPoint.x; | |
| pointToUpdate.y = anchorPoint.y; | |
| } | |
| }); | |
| }); | |
| } | |
| update(); | |
| } | |
| var svg = d3.select('#diagram').append('svg') | |
| .attr('width', 400) | |
| .attr('height', 200) | |
| .attr('style', 'border:1px solid black'); | |
| var viewport = svg.selectAll('#viewport') | |
| .data([diagramData.viewport]) | |
| .enter() | |
| .append('g') | |
| .attr('id', 'viewport'); | |
| var calculatePathData = function(d) { | |
| var d, | |
| firstPathSegString, | |
| pathData = {}; | |
| if (d.hasOwnProperty('points')) { | |
| d.points.map(function(point, index) { | |
| var targetEdge, targetEdgeElement, targetEdgeElementLength, anchor, anchorPoint; | |
| if (!point.hasOwnProperty('x')) { | |
| targetEdge = d3.select('#' + point.element); | |
| targetEdgeElement = targetEdge[0][0]; | |
| targetEdgeElementLength = targetEdgeElement.getTotalLength(); | |
| anchor = targetEdge.datum().anchors.filter(function(anchor) {return anchor.id === point.anchor;})[0]; | |
| anchorPoint = targetEdgeElement.getPointAtLength(targetEdgeElementLength * anchor.position); | |
| point.x = anchorPoint.x; | |
| point.y = anchorPoint.y; | |
| } | |
| if (index > 0) { | |
| d += ' L ' + point.x + ' ' + point.y; | |
| } | |
| else { | |
| d = firstPathSegString = 'M ' + point.x + ' ' + point.y; | |
| } | |
| }); | |
| } | |
| pathData.d = d; | |
| pathData.firstPathSegString = firstPathSegString; | |
| return pathData; | |
| }; | |
| var update = function(callback){ | |
| var renderableTypeToSvgElementMappings = { | |
| 'node':'rect', | |
| 'edge':'path' | |
| }; | |
| var elements = viewport.selectAll('.element') | |
| .data(function(d) { | |
| return d; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', function(d) { | |
| var cssClassString = 'element ' + d.renderableType; | |
| if (dragging) { | |
| cssClassString += ' grabbing'; | |
| } | |
| return cssClassString; | |
| }); | |
| elements.enter() | |
| .append(function(d) { | |
| var childElementName = renderableTypeToSvgElementMappings[d.renderableType]; | |
| var child = document.createElementNS('http://www.w3.org/2000/svg', childElementName); | |
| return child; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', function(d) { | |
| var cssClassString = 'element ' + d.renderableType; | |
| if (dragging) { | |
| cssClassString += ' grabbing'; | |
| } | |
| return cssClassString; | |
| }) | |
| .on('mouseover', function(d) { | |
| if (!dragging) { | |
| nearerDragHandle = d3.select('#' + d.id + '-' + nearerDragHandleIdentity + '-handle') | |
| if (!!nearerDragHandle[0][0]) { | |
| nearerDragHandle.attr('class', 'drag-handle'); | |
| fartherDragHandle.attr('class', 'drag-handle'); | |
| } | |
| var pathData = calculatePathData(d); | |
| self.mypd = pathData; | |
| console.log(d3.event); | |
| var nearerDragHandleIdentity = getNearestDragHandleIdentity(d, d3.event.x, d3.event.y); | |
| console.log(nearerDragHandleIdentity); | |
| nearerDragHandle = d3.select('#' + d.id + '-' + nearerDragHandleIdentity + '-handle') | |
| .attr('class', 'drag-handle-active'); | |
| var fartherDragHandleIdentity; | |
| // TODO refactor this for maintability | |
| if (nearerDragHandleIdentity === 'source') { | |
| fartherDragHandleIdentity = 'target'; | |
| } | |
| else { | |
| fartherDragHandleIdentity = 'source'; | |
| } | |
| fartherDragHandle = d3.select('#' + d.id + '-' + fartherDragHandleIdentity + '-handle') | |
| .attr('class', 'drag-handle-inactive'); | |
| } | |
| }) | |
| .on('mousedown', function(d) { | |
| selectedEdge.attr('class', 'element edge-selected'); | |
| nearerDragHandle.attr('class', 'grabbing'); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('svg').attr('class',null); | |
| }) | |
| .on('mouseout', function(d) { | |
| if (!dragging) { | |
| window.setTimeout(function() { | |
| d3.select('#' + d.id + '-source-handle').attr('class', 'drag-handle'); | |
| d3.select('#' + d.id + '-target-handle').attr('class', 'drag-handle'); | |
| }, 400); | |
| } | |
| }) | |
| .call(drag); | |
| elements.attr({ | |
| style: function(d) { | |
| var styleString = d.style, | |
| firstPoint, lastPoint, xDistance, yDistance; | |
| //* this makes the cursor a double-headed arrow to indicate that the user can move an edge end point | |
| // removing this code sends us back to using the grabbing cursor on hover | |
| // we could also look at using the single-headed arrows | |
| if (d.renderableType === 'edge') { | |
| firstPoint = d.points[0]; | |
| lastPoint = d.points[d.points.length - 1]; | |
| xDistance = Math.abs(lastPoint.x - firstPoint.x); | |
| yDistance = Math.abs(lastPoint.y - firstPoint.y); | |
| if (yDistance > xDistance) { | |
| styleString += 'cursor: ns-resize'; | |
| } | |
| else { | |
| styleString += 'cursor: ew-resize'; | |
| } | |
| } | |
| //*/ | |
| return styleString; | |
| }, | |
| x: function(d) { return d.x; }, | |
| y: function(d) { return d.y; }, | |
| width: function(d) { return d.width; }, | |
| height: function(d) { return d.height; }, | |
| d: function(d) { | |
| return calculatePathData(d).d; | |
| } | |
| }); | |
| elements.exit().remove(); | |
| if (!!callback) { | |
| callback(elements); | |
| }; | |
| }; | |
| var init = function() { | |
| var viewport = d3.select('#viewport'); | |
| update(function(elements) { | |
| elements.each(function(d){ | |
| console.log(this); | |
| console.log(d); | |
| var element = d3.select(this); | |
| var sourceHandle, sourceHandle2, targetHandle, targetHandle2, sourcePoint, targetPoint, points; | |
| if (d.renderableType === 'edge') { | |
| console.log('edge'); | |
| points = d.points; | |
| sourcePoint = points[0]; | |
| targetPoint = points[points.length - 1]; | |
| sourceHandle = viewport.selectAll('#' + d.id + '-source-handle') | |
| .data([ d ]) | |
| .enter() | |
| .append('circle') | |
| .attr('id', d.id + '-source-handle') | |
| sourceHandle2 = d3.select('#' + d.id + '-source-handle') | |
| .attr('cx', sourcePoint.x) | |
| .attr('cy', sourcePoint.y) | |
| .attr('r', 4) | |
| .attr('class', 'drag-handle') | |
| .on('mousedown', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge-selected'); | |
| console.log(d3.select('#' + d.id)); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| d3.select(this).attr('class','drag-handle grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class',null); | |
| d3.select(this).attr('class','drag-handle'); | |
| }) | |
| .call(drag); | |
| targetHandle = viewport.selectAll('#' + d.id + '-target-handle') | |
| .data([ d ]) | |
| .enter() | |
| .append('circle') | |
| .attr('id', d.id + '-target-handle'); | |
| targetHandle2 = d3.select('#' + d.id + '-target-handle') | |
| .attr('cx', targetPoint.x) | |
| .attr('cy', targetPoint.y) | |
| .attr('r', 4) | |
| .attr('class', 'drag-handle') | |
| .on('mousedown', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| d3.select(this).attr('class','drag-handle grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class',null); | |
| d3.select(this).attr('class','drag-handle'); | |
| }) | |
| .call(drag); | |
| } | |
| }); | |
| }); | |
| }; | |
| init(); | |
| </script> | |
| </body> | |
| </html> |
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> | |
| <meta http-equiv="content-type" content="text/html; charset=utf-8"> | |
| <style> | |
| body { | |
| font: 10px sans-serif; | |
| } | |
| /* | |
| .drag-handle { | |
| fill: transparent; | |
| fill-opacity: 1; | |
| stroke: transparent; | |
| stroke-width: 0; | |
| } | |
| */ | |
| .drag-handle { | |
| fill: transparent; | |
| stroke: transparent; | |
| } | |
| .drag-handle:hover, .drag-handle-active { | |
| fill: yellow; | |
| fill-opacity: 0.8; | |
| stroke: orange; | |
| stroke-width: 0.5px; | |
| } | |
| .drag-handle-inactive { | |
| fill: gray; | |
| fill-opacity: 0.2; | |
| stroke: gray; | |
| stroke-opacity: 0.5; | |
| stroke-width: 0.5px; | |
| } | |
| .grab, .edge { | |
| cursor: -moz-grab; | |
| cursor: -webkit-grab; | |
| cursor: grab; | |
| } | |
| .grabbing, .edge-selected { | |
| cursor: -moz-grabbing; | |
| cursor: -webkit-grabbing; | |
| cursor: grabbing; | |
| } | |
| </style> | |
| <body> | |
| <div id="diagram"></div> | |
| <p> | |
| Input: | |
| </p> | |
| <p id="input"> | |
| </p> | |
| <p> | |
| Output: | |
| </p> | |
| <p id="output"> | |
| </p> | |
| <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
| <script> | |
| 'use strict'; | |
| var dragging = false; | |
| var diagramData = { | |
| viewport:[ | |
| { | |
| id: 'id123', | |
| renderableType: 'node', | |
| x: 50, | |
| y: 50, | |
| width: 80, | |
| height: 20, | |
| style: 'stroke: blue; fill: white;' | |
| }, | |
| { | |
| id: 'id234', | |
| renderableType: 'node', | |
| x: 200, | |
| y: 50, | |
| width: 80, | |
| height: 20, | |
| style: 'stroke: blue; fill: white;' | |
| }, | |
| { | |
| id: 'id345', | |
| renderableType: 'edge', | |
| points:[ | |
| { | |
| x: 130, | |
| y: 60 | |
| }, | |
| { | |
| x: 200, | |
| y: 60 | |
| } | |
| ], | |
| anchors: [ | |
| { | |
| id: 'id567', | |
| position: 0.3 | |
| } | |
| ], | |
| hasAnchoredDependencies: [ | |
| 'id456' | |
| ], | |
| style: 'stroke: black; stroke-width: 1; fill:yellow;' | |
| }, | |
| { | |
| id: 'id456', | |
| renderableType: 'edge', | |
| points:[ | |
| { | |
| x: 165, | |
| y: 20 | |
| }, | |
| { | |
| element: 'id345', | |
| anchor: 'id567' | |
| } | |
| ], | |
| style: 'stroke: black; stroke-width: 1; fill:yellow;' | |
| } | |
| ] | |
| }; | |
| var inputJsonString = JSON.stringify(diagramData); | |
| d3.select('#input').text(inputJsonString); | |
| var dragSegment, selectedPoint, selectedEdge, selectedEdgeElement, dragPointX, dragPointY, nearerDragHandle, fartherDragHandle; | |
| var getNearestDragHandleIdentity = function(d, dragPointX, dragPointY) { | |
| var nearerDragHandleIdentity; | |
| selectedEdge = d3.select('#' + d.id); | |
| selectedEdgeElement = selectedEdge[0][0]; | |
| var numberOfItems = selectedEdgeElement.pathSegList.numberOfItems; | |
| var sourcePoint = d.points[0]; | |
| var sourcePointX = sourcePoint.x; | |
| var sourcePointY = sourcePoint.y; | |
| var dragPointToSourcePointDistance = Math.sqrt(Math.pow((dragPointX - sourcePointX),2) + Math.pow((dragPointY - sourcePointY),2)); | |
| var targetPoint = d.points[d.points.length - 1]; | |
| var targetPointX = targetPoint.x; | |
| var targetPointY = targetPoint.y; | |
| var dragPointToTargetPointDistance = Math.sqrt(Math.pow((dragPointX - targetPointX),2) + Math.pow((dragPointY - targetPointY),2)); | |
| if (dragPointToTargetPointDistance < dragPointToSourcePointDistance) { | |
| selectedPoint = targetPoint; | |
| dragSegment = selectedEdgeElement.pathSegList.getItem(0); | |
| nearerDragHandleIdentity = 'target'; | |
| } | |
| else { | |
| selectedPoint = sourcePoint; | |
| dragSegment = selectedEdgeElement.pathSegList.getItem(numberOfItems - 1); | |
| nearerDragHandleIdentity = 'source'; | |
| } | |
| return nearerDragHandleIdentity; | |
| }; | |
| var drag = d3.behavior.drag() | |
| .on("dragstart", function(d) { | |
| nearerDragHandle.attr('class', 'drag-handle'); | |
| fartherDragHandle.attr('class', 'drag-handle'); | |
| dragging = true; | |
| dragPointX = d3.event.sourceEvent.x; | |
| dragPointY = d3.event.sourceEvent.y; | |
| var dragHandleIdentities = getNearestDragHandleIdentity(d, dragPointX, dragPointY); | |
| }) | |
| .on("drag", dragmove) | |
| .on("dragend", function(d) { | |
| dragging = false; | |
| console.log('this'); | |
| console.log(this); | |
| console.log('this'); | |
| console.log(this); | |
| /* | |
| var dragHandle = d3.select(this) | |
| .attr('cx', dragPointX) | |
| .attr('cy', dragPointY); | |
| //*/ | |
| selectedEdge.attr('d', function(d) { | |
| return calculatePathData(d).d; | |
| }); | |
| diagramData.viewport = d3.select('#viewport').datum(); | |
| var outputJsonString = JSON.stringify(diagramData); | |
| d3.select('#output').text(outputJsonString); | |
| d3.select('svg').attr('class',null); | |
| init(); | |
| }); | |
| function dragmove(d) { | |
| dragPointX = d3.event.x; | |
| dragPointY = d3.event.y; | |
| dragSegment.x = dragPointX; | |
| dragSegment.y = dragPointY; | |
| selectedPoint.x = dragPointX; | |
| selectedPoint.y = dragPointY; | |
| var selectedEdgeElementLength = selectedEdgeElement.getTotalLength(), | |
| //selectedEdgeElementLength = selectedEdgeElement.getTotalLength() - 185.9791717529297, | |
| anchorPoint, | |
| anchorPoints = {}, | |
| elementToUpdate, | |
| pointsToUpdate, | |
| pointToUpdate; | |
| diagramData.viewport = d3.select('#viewport').datum(); | |
| if (d.hasOwnProperty('anchors')) { | |
| d.anchors.forEach(function(anchor) { | |
| anchorPoints[anchor.id] = selectedEdgeElement.getPointAtLength(selectedEdgeElementLength * anchor.position); | |
| }); | |
| d.hasAnchoredDependencies.forEach(function(elementId) { | |
| elementToUpdate = diagramData.viewport.filter(function(element) { | |
| return element.id === elementId; | |
| })[0]; | |
| pointsToUpdate = elementToUpdate.points.filter(function(point) { | |
| return point.hasOwnProperty('anchor'); | |
| }); | |
| pointsToUpdate.forEach(function(pointToUpdate) { | |
| anchorPoint = anchorPoints[pointToUpdate.anchor]; | |
| if (!!anchorPoint) { | |
| pointToUpdate.x = anchorPoint.x; | |
| pointToUpdate.y = anchorPoint.y; | |
| } | |
| }); | |
| }); | |
| } | |
| update(); | |
| } | |
| var svg = d3.select('#diagram').append('svg') | |
| .attr('width', 400) | |
| .attr('height', 200) | |
| .attr('style', 'border:1px solid black'); | |
| var viewport = svg.selectAll('#viewport') | |
| .data([diagramData.viewport]) | |
| .enter() | |
| .append('g') | |
| .attr('id', 'viewport'); | |
| var calculatePathData = function(d) { | |
| var d, | |
| firstPathSegString, | |
| pathData = {}; | |
| if (d.hasOwnProperty('points')) { | |
| d.points.map(function(point, index) { | |
| var targetEdge, targetEdgeElement, targetEdgeElementLength, anchor, anchorPoint; | |
| if (!point.hasOwnProperty('x')) { | |
| targetEdge = d3.select('#' + point.element); | |
| targetEdgeElement = targetEdge[0][0]; | |
| targetEdgeElementLength = targetEdgeElement.getTotalLength(); | |
| anchor = targetEdge.datum().anchors.filter(function(anchor) {return anchor.id === point.anchor;})[0]; | |
| anchorPoint = targetEdgeElement.getPointAtLength(targetEdgeElementLength * anchor.position); | |
| point.x = anchorPoint.x; | |
| point.y = anchorPoint.y; | |
| } | |
| if (index > 0) { | |
| d += ' L ' + point.x + ' ' + point.y; | |
| } | |
| else { | |
| d = firstPathSegString = 'M ' + point.x + ' ' + point.y; | |
| } | |
| }); | |
| } | |
| pathData.d = d; | |
| pathData.firstPathSegString = firstPathSegString; | |
| return pathData; | |
| }; | |
| var update = function(callback){ | |
| var renderableTypeToSvgElementMappings = { | |
| 'node':'rect', | |
| 'edge':'path' | |
| }; | |
| var elements = viewport.selectAll('.element') | |
| .data(function(d) { | |
| return d; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', function(d) { | |
| var cssClassString = 'element ' + d.renderableType; | |
| if (dragging) { | |
| cssClassString += ' grabbing'; | |
| } | |
| return cssClassString; | |
| }); | |
| elements.enter() | |
| .append(function(d) { | |
| var childElementName = renderableTypeToSvgElementMappings[d.renderableType]; | |
| var child = document.createElementNS('http://www.w3.org/2000/svg', childElementName); | |
| return child; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', function(d) { | |
| var cssClassString = 'element ' + d.renderableType; | |
| if (dragging) { | |
| cssClassString += ' grabbing'; | |
| } | |
| return cssClassString; | |
| }) | |
| .on('mouseover', function(d) { | |
| if (!dragging) { | |
| nearerDragHandle = d3.select('#' + d.id + '-' + nearerDragHandleIdentity + '-handle') | |
| if (!!nearerDragHandle[0][0]) { | |
| nearerDragHandle.attr('class', 'drag-handle'); | |
| fartherDragHandle.attr('class', 'drag-handle'); | |
| } | |
| var pathData = calculatePathData(d); | |
| self.mypd = pathData; | |
| console.log(d3.event); | |
| var nearerDragHandleIdentity = getNearestDragHandleIdentity(d, d3.event.x, d3.event.y); | |
| console.log(nearerDragHandleIdentity); | |
| nearerDragHandle = d3.select('#' + d.id + '-' + nearerDragHandleIdentity + '-handle') | |
| .attr('class', 'drag-handle-active grab'); | |
| var fartherDragHandleIdentity; | |
| // TODO refactor this for maintability | |
| if (nearerDragHandleIdentity === 'source') { | |
| fartherDragHandleIdentity = 'target'; | |
| } | |
| else { | |
| fartherDragHandleIdentity = 'source'; | |
| } | |
| fartherDragHandle = d3.select('#' + d.id + '-' + fartherDragHandleIdentity + '-handle') | |
| .attr('class', 'drag-handle-inactive'); | |
| } | |
| }) | |
| .on('mousedown', function(d) { | |
| selectedEdge.attr('class', 'element edge-selected'); | |
| nearerDragHandle.attr('class', 'grabbing'); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('svg').attr('class',null); | |
| }) | |
| .on('mouseout', function(d) { | |
| if (!dragging) { | |
| window.setTimeout(function() { | |
| d3.select('#' + d.id + '-source-handle').attr('class', 'drag-handle'); | |
| d3.select('#' + d.id + '-target-handle').attr('class', 'drag-handle'); | |
| }, 400); | |
| } | |
| }) | |
| .call(drag); | |
| elements.attr({ | |
| style: function(d) { | |
| var styleString = d.style, | |
| firstPoint, lastPoint, xDistance, yDistance; | |
| /* this makes the cursor a double-headed arrow to indicate that the user can move an edge end point | |
| // removing this code sends us back to using the grabbing cursor on hover | |
| // we could also look at using the single-headed arrows | |
| if (d.renderableType === 'edge') { | |
| firstPoint = d.points[0]; | |
| lastPoint = d.points[d.points.length - 1]; | |
| xDistance = Math.abs(lastPoint.x - firstPoint.x); | |
| yDistance = Math.abs(lastPoint.y - firstPoint.y); | |
| if (yDistance > xDistance) { | |
| styleString += 'cursor: ns-resize'; | |
| } | |
| else { | |
| styleString += 'cursor: ew-resize'; | |
| } | |
| } | |
| //*/ | |
| return styleString; | |
| }, | |
| x: function(d) { return d.x; }, | |
| y: function(d) { return d.y; }, | |
| width: function(d) { return d.width; }, | |
| height: function(d) { return d.height; }, | |
| d: function(d) { | |
| return calculatePathData(d).d; | |
| } | |
| }); | |
| elements.exit().remove(); | |
| if (!!callback) { | |
| callback(elements); | |
| }; | |
| }; | |
| var init = function() { | |
| var viewport = d3.select('#viewport'); | |
| update(function(elements) { | |
| elements.each(function(d){ | |
| console.log(this); | |
| console.log(d); | |
| var element = d3.select(this); | |
| var sourceHandle, sourceHandle2, targetHandle, targetHandle2, sourcePoint, targetPoint, points; | |
| if (d.renderableType === 'edge') { | |
| console.log('edge'); | |
| points = d.points; | |
| sourcePoint = points[0]; | |
| targetPoint = points[points.length - 1]; | |
| sourceHandle = viewport.selectAll('#' + d.id + '-source-handle') | |
| .data([ d ]) | |
| .enter() | |
| .append('circle') | |
| .attr('id', d.id + '-source-handle') | |
| sourceHandle2 = d3.select('#' + d.id + '-source-handle') | |
| .attr('cx', sourcePoint.x) | |
| .attr('cy', sourcePoint.y) | |
| .attr('r', 4) | |
| .attr('class', 'drag-handle') | |
| .on('mousedown', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge-selected'); | |
| console.log(d3.select('#' + d.id)); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| d3.select(this).attr('class','drag-handle grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class',null); | |
| d3.select(this).attr('class','drag-handle'); | |
| }) | |
| .call(drag); | |
| targetHandle = viewport.selectAll('#' + d.id + '-target-handle') | |
| .data([ d ]) | |
| .enter() | |
| .append('circle') | |
| .attr('id', d.id + '-target-handle'); | |
| targetHandle2 = d3.select('#' + d.id + '-target-handle') | |
| .attr('cx', targetPoint.x) | |
| .attr('cy', targetPoint.y) | |
| .attr('r', 4) | |
| .attr('class', 'drag-handle') | |
| .on('mousedown', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| d3.select(this).attr('class','drag-handle grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class',null); | |
| d3.select(this).attr('class','drag-handle'); | |
| }) | |
| .call(drag); | |
| } | |
| }); | |
| }); | |
| }; | |
| init(); | |
| </script> | |
| </body> | |
| </html> | |
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> | |
| <meta http-equiv="content-type" content="text/html; charset=utf-8"> | |
| <style> | |
| body { | |
| font: 10px sans-serif; | |
| } | |
| /* | |
| .drag-handle { | |
| fill: transparent; | |
| fill-opacity: 1; | |
| stroke: transparent; | |
| stroke-width: 0; | |
| } | |
| */ | |
| .drag-handle { | |
| fill: transparent; | |
| stroke: orange; | |
| stroke-width: 5px; | |
| } | |
| .drag-handle:hover { | |
| fill: transparent; | |
| stroke: green; | |
| stroke-width: 10px; | |
| } | |
| .grab { | |
| cursor: -moz-grab; | |
| cursor: -webkit-grab; | |
| cursor: grab; | |
| } | |
| .grabbing { | |
| cursor: -moz-grabbing; | |
| cursor: -webkit-grabbing; | |
| cursor: grabbing; | |
| } | |
| </style> | |
| <body> | |
| <div id="diagram"></div> | |
| <p> | |
| Input: | |
| </p> | |
| <p id="input"> | |
| </p> | |
| <p> | |
| Output: | |
| </p> | |
| <p id="output"> | |
| </p> | |
| <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
| <script> | |
| 'use strict'; | |
| var dragging = false; | |
| var diagramData = { | |
| viewport:[ | |
| { | |
| id: 'id123', | |
| renderableType: 'node', | |
| x: 50, | |
| y: 50, | |
| width: 80, | |
| height: 20, | |
| style: 'stroke: blue; fill: white;' | |
| }, | |
| { | |
| id: 'id234', | |
| renderableType: 'node', | |
| x: 200, | |
| y: 50, | |
| width: 80, | |
| height: 20, | |
| style: 'stroke: blue; fill: white;' | |
| }, | |
| { | |
| id: 'id345', | |
| renderableType: 'edge', | |
| points:[ | |
| { | |
| x: 130, | |
| y: 60 | |
| }, | |
| { | |
| x: 200, | |
| y: 60 | |
| } | |
| ], | |
| anchors: [ | |
| { | |
| id: 'id567', | |
| position: 0.3 | |
| } | |
| ], | |
| hasAnchoredDependencies: [ | |
| 'id456' | |
| ], | |
| style: 'stroke: black; stroke-width: 1; fill:yellow;' | |
| }, | |
| { | |
| id: 'id456', | |
| renderableType: 'edge', | |
| points:[ | |
| { | |
| x: 165, | |
| y: 20 | |
| }, | |
| { | |
| element: 'id345', | |
| anchor: 'id567' | |
| } | |
| ], | |
| style: 'stroke: black; stroke-width: 1; fill:yellow;' | |
| } | |
| ] | |
| }; | |
| var inputJsonString = JSON.stringify(diagramData); | |
| d3.select('#input').text(inputJsonString); | |
| var dragSegment, selectedPoint, selectedEdge, selectedEdgeElement, dragPointX, dragPointY, nearerDragHandle, fartherDragHandle; | |
| var getNearestDragHandleIdentity = function(d, dragPointX, dragPointY) { | |
| var nearerDragHandleIdentity; | |
| selectedEdge = d3.select('#' + d.id); | |
| selectedEdgeElement = selectedEdge[0][0]; | |
| var numberOfItems = selectedEdgeElement.pathSegList.numberOfItems; | |
| var sourcePoint = d.points[0]; | |
| var sourcePointX = sourcePoint.x; | |
| var sourcePointY = sourcePoint.y; | |
| var dragPointToSourcePointDistance = Math.sqrt(Math.pow((dragPointX - sourcePointX),2) + Math.pow((dragPointY - sourcePointY),2)); | |
| var targetPoint = d.points[d.points.length - 1]; | |
| var targetPointX = targetPoint.x; | |
| var targetPointY = targetPoint.y; | |
| var dragPointToTargetPointDistance = Math.sqrt(Math.pow((dragPointX - targetPointX),2) + Math.pow((dragPointY - targetPointY),2)); | |
| if (dragPointToTargetPointDistance < dragPointToSourcePointDistance) { | |
| selectedPoint = targetPoint; | |
| dragSegment = selectedEdgeElement.pathSegList.getItem(0); | |
| nearerDragHandleIdentity = 'target'; | |
| } | |
| else { | |
| selectedPoint = sourcePoint; | |
| dragSegment = selectedEdgeElement.pathSegList.getItem(numberOfItems - 1); | |
| nearerDragHandleIdentity = 'source'; | |
| } | |
| return nearerDragHandleIdentity; | |
| }; | |
| var drag = d3.behavior.drag() | |
| .on("dragstart", function(d) { | |
| dragging = true; | |
| dragPointX = d3.event.sourceEvent.x; | |
| dragPointY = d3.event.sourceEvent.y; | |
| var dragHandleIdentities = getNearestDragHandleIdentity(d, dragPointX, dragPointY); | |
| }) | |
| .on("drag", dragmove) | |
| .on("dragend", function(d) { | |
| dragging = false; | |
| console.log('this'); | |
| console.log(this); | |
| console.log('this'); | |
| console.log(this); | |
| /* | |
| var dragHandle = d3.select(this) | |
| .attr('cx', dragPointX) | |
| .attr('cy', dragPointY); | |
| //*/ | |
| selectedEdge.attr('d', function(d) { | |
| return calculatePathData(d).d; | |
| }); | |
| diagramData.viewport = d3.select('#viewport').datum(); | |
| var outputJsonString = JSON.stringify(diagramData); | |
| d3.select('#output').text(outputJsonString); | |
| d3.select('svg').attr('class',null); | |
| init(); | |
| }); | |
| function dragmove(d) { | |
| dragPointX = d3.event.x; | |
| dragPointY = d3.event.y; | |
| dragSegment.x = dragPointX; | |
| dragSegment.y = dragPointY; | |
| selectedPoint.x = dragPointX; | |
| selectedPoint.y = dragPointY; | |
| var selectedEdgeElementLength = selectedEdgeElement.getTotalLength(), | |
| //selectedEdgeElementLength = selectedEdgeElement.getTotalLength() - 185.9791717529297, | |
| anchorPoint, | |
| anchorPoints = {}, | |
| elementToUpdate, | |
| pointsToUpdate, | |
| pointToUpdate; | |
| diagramData.viewport = d3.select('#viewport').datum(); | |
| if (d.hasOwnProperty('anchors')) { | |
| d.anchors.forEach(function(anchor) { | |
| anchorPoints[anchor.id] = selectedEdgeElement.getPointAtLength(selectedEdgeElementLength * anchor.position); | |
| }); | |
| d.hasAnchoredDependencies.forEach(function(elementId) { | |
| elementToUpdate = diagramData.viewport.filter(function(element) { | |
| return element.id === elementId; | |
| })[0]; | |
| pointsToUpdate = elementToUpdate.points.filter(function(point) { | |
| return point.hasOwnProperty('anchor'); | |
| }); | |
| pointsToUpdate.forEach(function(pointToUpdate) { | |
| anchorPoint = anchorPoints[pointToUpdate.anchor]; | |
| if (!!anchorPoint) { | |
| pointToUpdate.x = anchorPoint.x; | |
| pointToUpdate.y = anchorPoint.y; | |
| } | |
| }); | |
| }); | |
| } | |
| update(); | |
| } | |
| var svg = d3.select('#diagram').append('svg') | |
| .attr('width', 400) | |
| .attr('height', 200) | |
| .attr('style', 'border:1px solid black'); | |
| var viewport = svg.selectAll('#viewport') | |
| .data([diagramData.viewport]) | |
| .enter() | |
| .append('g') | |
| .attr('id', 'viewport'); | |
| var calculatePathData = function(d) { | |
| var d, | |
| firstPathSegString, | |
| pathData = {}; | |
| if (d.hasOwnProperty('points')) { | |
| d.points.map(function(point, index) { | |
| var targetEdge, targetEdgeElement, targetEdgeElementLength, anchor, anchorPoint; | |
| if (!point.hasOwnProperty('x')) { | |
| targetEdge = d3.select('#' + point.element); | |
| targetEdgeElement = targetEdge[0][0]; | |
| targetEdgeElementLength = targetEdgeElement.getTotalLength(); | |
| anchor = targetEdge.datum().anchors.filter(function(anchor) {return anchor.id === point.anchor;})[0]; | |
| anchorPoint = targetEdgeElement.getPointAtLength(targetEdgeElementLength * anchor.position); | |
| point.x = anchorPoint.x; | |
| point.y = anchorPoint.y; | |
| } | |
| if (index > 0) { | |
| d += ' L ' + point.x + ' ' + point.y; | |
| } | |
| else { | |
| d = firstPathSegString = 'M ' + point.x + ' ' + point.y; | |
| } | |
| }); | |
| } | |
| pathData.d = d; | |
| pathData.firstPathSegString = firstPathSegString; | |
| return pathData; | |
| }; | |
| var update = function(callback){ | |
| var renderableTypeToSvgElementMappings = { | |
| 'node':'rect', | |
| 'edge':'path' | |
| }; | |
| var elements = viewport.selectAll('.element') | |
| .data(function(d) { | |
| return d; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', function(d) { | |
| var cssClassString = 'element ' + d.renderableType; | |
| return cssClassString; | |
| }); | |
| elements.enter() | |
| .append(function(d) { | |
| var childElementName = renderableTypeToSvgElementMappings[d.renderableType]; | |
| var child = document.createElementNS('http://www.w3.org/2000/svg', childElementName); | |
| return child; | |
| }) | |
| .attr('id', function(d) { | |
| return d.id; | |
| }) | |
| .attr('class', function(d) { | |
| var cssClassString = 'element ' + d.renderableType; | |
| return cssClassString; | |
| }); | |
| elements.attr({ | |
| style: function(d) { | |
| var styleString = d.style, | |
| firstPoint, lastPoint, xDistance, yDistance; | |
| /* this makes the cursor a double-headed arrow to indicate that the user can move an edge end point | |
| // removing this code sends us back to using the grabbing cursor on hover | |
| // we could also look at using the single-headed arrows | |
| if (d.renderableType === 'edge') { | |
| firstPoint = d.points[0]; | |
| lastPoint = d.points[d.points.length - 1]; | |
| xDistance = Math.abs(lastPoint.x - firstPoint.x); | |
| yDistance = Math.abs(lastPoint.y - firstPoint.y); | |
| if (yDistance > xDistance) { | |
| styleString += 'cursor: ns-resize'; | |
| } | |
| else { | |
| styleString += 'cursor: ew-resize'; | |
| } | |
| } | |
| //*/ | |
| return styleString; | |
| }, | |
| x: function(d) { return d.x; }, | |
| y: function(d) { return d.y; }, | |
| width: function(d) { return d.width; }, | |
| height: function(d) { return d.height; }, | |
| d: function(d) { | |
| return calculatePathData(d).d; | |
| } | |
| }); | |
| elements.exit().remove(); | |
| if (!!callback) { | |
| callback(elements); | |
| }; | |
| }; | |
| var init = function() { | |
| var viewport = d3.select('#viewport'); | |
| update(function(elements) { | |
| elements.each(function(d){ | |
| console.log(this); | |
| console.log(d); | |
| var element = d3.select(this); | |
| var sourceHandle, sourceHandle2, targetHandle, targetHandle2, sourcePoint, targetPoint, points; | |
| if (d.renderableType === 'edge') { | |
| console.log('edge'); | |
| var edge = d3.select('#' + d.id); | |
| var edgeElement = edge[0][0]; | |
| var edgeLength = edgeElement.getTotalLength(); | |
| var distanceAlongEdge = Math.min(15, edgeLength/3); | |
| points = d.points; | |
| sourcePoint = points[0]; | |
| targetPoint = points[points.length - 1]; | |
| sourceHandle = viewport.selectAll('#' + d.id + '-source-handle') | |
| .data([ d ]) | |
| .enter() | |
| .append('path') | |
| .attr('id', d.id + '-source-handle') | |
| sourceHandle2 = d3.select('#' + d.id + '-source-handle') | |
| .attr('d', function(d) { | |
| var firstPoint = d.points[0]; | |
| var point0 = edgeElement.getPointAtLength(0); | |
| var point1 = edgeElement.getPointAtLength(distanceAlongEdge); | |
| return 'M ' + point0.x + ' ' + point0.y + ' L ' + point1.x + ' ' + point1.y; | |
| }) | |
| .attr('class', 'drag-handle') | |
| .on('mouseover', function(d) { | |
| d3.select(this).attr('class','drag-handle grab'); | |
| }) | |
| .on('mousedown', function(d) { | |
| console.log(d3.select('#' + d.id)); | |
| d3.select('#' + d.id).attr('class', 'element edge-selected'); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| d3.select(this).attr('class','drag-handle grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class',null); | |
| d3.select(this).attr('class','drag-handle'); | |
| }) | |
| .call(drag); | |
| targetHandle = viewport.selectAll('#' + d.id + '-target-handle') | |
| .data([ d ]) | |
| .enter() | |
| .append('path') | |
| .attr('id', d.id + '-target-handle'); | |
| targetHandle2 = d3.select('#' + d.id + '-target-handle') | |
| .attr('d', function(d) { | |
| var lastPoint = d.points[d.points.length - 1]; | |
| var point0 = edgeElement.getPointAtLength(edgeLength); | |
| var point1 = edgeElement.getPointAtLength(edgeLength - distanceAlongEdge); | |
| return 'M ' + point0.x + ' ' + point0.y + ' L ' + point1.x + ' ' + point1.y; | |
| }) | |
| .attr('class', 'drag-handle') | |
| .on('mouseover', function(d) { | |
| d3.select(this).attr('class','drag-handle grab'); | |
| }) | |
| .on('mousedown', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge-selected'); | |
| d3.select('svg').attr('class', 'grabbing'); | |
| d3.select(this).attr('class','drag-handle grabbing'); | |
| }) | |
| .on('mouseup', function(d) { | |
| d3.select('#' + d.id).attr('class', 'element edge'); | |
| d3.select('svg').attr('class',null); | |
| d3.select(this).attr('class','drag-handle'); | |
| }) | |
| .call(drag); | |
| } | |
| }); | |
| }); | |
| }; | |
| init(); | |
| </script> | |
| </body> | |
| </html> | |
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> | |
| <meta http-equiv="content-type" content="text/html; charset=utf-8"> | |
| <link rel="stylesheet" href="html.css" /> | |
| <link rel="stylesheet" href="annotated.css" /> | |
| <style> | |
| body { | |
| font: 10px sans-serif; | |
| } | |
| .drag-handle { | |
| fill: transparent; | |
| stroke: transparent; | |
| stroke-width: 10px; | |
| } | |
| .drag-handle:hover { | |
| fill: transparent; | |
| stroke: transparent; | |
| stroke-width: 15px; | |
| } | |
| .grab { | |
| cursor: -moz-grab; | |
| cursor: -webkit-grab; | |
| cursor: grab; | |
| } | |
| .grabbing { | |
| cursor: -moz-grabbing; | |
| cursor: -webkit-grabbing; | |
| cursor: grabbing; | |
| } | |
| </style> | |
| <body> | |
| <h1>D3 Drag and Update Example</h1> | |
| <h2>Independent, Invisible Drag Handles with Real Pathway Data</h2> | |
| <div id="diagram"></div> | |
| <div id="original" style="float:left"> | |
| <p>Input</p> | |
| <textarea name="textarea" id="original-json" rows="1000" cols="50">Write something here</textarea> | |
| </div> | |
| <div id="current" style="float:left"> | |
| <p>Current</p> | |
| <textarea name="textarea" id="current-json" rows="1000" cols="50"></textarea> | |
| </div> | |
| <div id="diff" style="float:left"> | |
| <p>Diff</p> | |
| <div id="visual"></div> | |
| </div> | |
| <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
| <script src="bundle.min.js"></script> | |
| <script src="formatters.min.js"></script> | |
| <script src="drag-update.js"></script> | |
| <script> | |
| window.onload = function() { | |
| dragUpdate.init(); | |
| } | |
| </script> | |
| </body> |
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
| { | |
| "viewport": [ | |
| { | |
| "height": 21, | |
| "id": "fbf", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 128.74774509060222, | |
| "y": 125.66666666666669 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "b69", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 51.49997456868482, | |
| "x": 348.0000254313152, | |
| "y": 150.5 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "e28", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 396.1666666666667, | |
| "y": 184.66666666666666 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "d4e", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 664, | |
| "y": 141.83333333333334 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "cc2", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 159.16666666666666, | |
| "y": 315.3333333333333 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "b8d", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 446, | |
| "y": 317.8333333333333 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "e9a", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 287.5000254313151, | |
| "y": 314.8333333333333 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "d70", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 358.99999999999994, | |
| "y": 343.4833272298177 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "daf", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 207.33333333333334, | |
| "y": 397.9833272298177 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "f52", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 281.33333333333303, | |
| "y": 435.83333333333314 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "cb6", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 303.33333333333354, | |
| "y": 493.5 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a40", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 305.33333333333354, | |
| "y": 605.3333333333334 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a69", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 525.1666666666669, | |
| "y": 447.1666666666669 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a7f", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 468.16666666666674, | |
| "y": 536 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "ab1", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61.00000000000008, | |
| "x": 630.6666666666666, | |
| "y": 422.83333333333354 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "e7e", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61.00000000000008, | |
| "x": 630.6666666666666, | |
| "y": 402.83333333333354 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a92", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 690.6666666666666, | |
| "y": 402.83333333333354 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "aa0", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61.00000000000008, | |
| "x": 690.6666666666666, | |
| "y": 422.83333333333354 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "ba4", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 525.1666666666669, | |
| "y": 427.1666666666669 | |
| }, | |
| { | |
| "height": 20, | |
| "id": "a2a", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 94.33333333333333, | |
| "x": 268.3333435058594, | |
| "y": 218.49999491373697 | |
| }, | |
| { | |
| "height": 20, | |
| "id": "e91", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 70.16666666666663, | |
| "x": 280.83333333333337, | |
| "y": 104.33333333333333 | |
| }, | |
| { | |
| "height": 20, | |
| "id": "e98", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 69.33333333333333, | |
| "x": 197.16666666666669, | |
| "y": 623.6666666666666 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "cb32b", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 66, | |
| "x": 50.24774572638509, | |
| "y": 71 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "bfc36", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 46, | |
| "x": 127, | |
| "y": 94 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "ba1b2", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 86, | |
| "x": 470, | |
| "y": 218 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "e00d0", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 56, | |
| "x": 410.5, | |
| "y": 113.5 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "aceb7", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 75.5, | |
| "x": 559, | |
| "y": 194 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "fc934", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 81, | |
| "x": 654.5, | |
| "y": 218 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "ef70b", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 33.016666666666666, | |
| "x": 134.48333333333335, | |
| "y": 361.48333333333335 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "cea19", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 33.016666666666666, | |
| "x": 298.99167989095054, | |
| "y": 361.48333333333335 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "b20a2", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 33.016666666666666, | |
| "x": 414.48333333333335, | |
| "y": 382.48333333333335 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "d8ba4", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 33.016666666666666, | |
| "x": 385.98333333333335, | |
| "y": 446.48333333333335 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "bb1eb", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 125.33333333333348, | |
| "y": 554.9999999999997 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a658e", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 125.33333333333348, | |
| "y": 574.9999999999997 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a8000", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 413.1666666666668, | |
| "y": 605.333333333334 | |
| }, | |
| { | |
| "height": 20, | |
| "id": "a2188", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 69.33333333333333, | |
| "x": 508.6666666666667, | |
| "y": 621.6666666666666 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "ccc26", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61.00000000000008, | |
| "x": 630.6666666666666, | |
| "y": 442.83333333333354 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "ae20e", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61.00000000000008, | |
| "x": 690.6666666666666, | |
| "y": 442.83333333333354 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "fdc15", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 50, | |
| "x": 572.25, | |
| "y": 314 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "b209b", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 47, | |
| "x": 582.5, | |
| "y": 95.5 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "d7db1", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 69, | |
| "x": 48.74774572638509, | |
| "y": 174 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a2c50", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 68, | |
| "x": 127, | |
| "y": 218 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "e9de6", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 51.75225427361491, | |
| "x": 40.24774572638509, | |
| "y": 245 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "d8c9e", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 44, | |
| "x": 202, | |
| "y": 181 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a47e8", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 54.75, | |
| "x": 497.75, | |
| "y": 113.75 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "f1bbc", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 103, | |
| "x": 430.5, | |
| "y": 75.5 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "ea69f", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 50, | |
| "x": 572.25, | |
| "y": 294 | |
| }, | |
| { | |
| "height": 20, | |
| "id": "d2a61", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 69.33333333333333, | |
| "x": 359.1666666666667, | |
| "y": 541.1666666666666 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "bbbff", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 61, | |
| "x": 525.1666666666669, | |
| "y": 467.16666666666697 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "d07b8", | |
| "renderableType": "node", | |
| "style": "stroke: #0000ff; fill:#ffffff;", | |
| "width": 81, | |
| "x": 556, | |
| "y": 519 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "a990e", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 81, | |
| "x": 348.17550402772156, | |
| "y": 665.7912447684622 | |
| }, | |
| { | |
| "height": 21, | |
| "id": "d71f9", | |
| "renderableType": "node", | |
| "style": "stroke: #000000; fill:#ffffff;", | |
| "width": 81, | |
| "x": 348.17550402772156, | |
| "y": 685.7912447684621 | |
| }, | |
| { | |
| "id": "b5913", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "c1688" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "a2c25", | |
| "position": "0.532258064516129" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 82.74774572638509, | |
| "y": 91 | |
| }, | |
| { | |
| "x": 82.74774572638509, | |
| "y": 174 | |
| } | |
| ], | |
| "style": "stroke: #008040;" | |
| }, | |
| { | |
| "id": "b1c07", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 127, | |
| "y": 104 | |
| }, | |
| { | |
| "x": 109.70007311442089, | |
| "y": 135.46407922232476, | |
| "anchor": "ebe5a", | |
| "element": "c1688" | |
| } | |
| ], | |
| "style": "stroke: #ff0000;" | |
| }, | |
| { | |
| "id": "f6437", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id4aefea78" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "a4d13", | |
| "position": "0.6010452755119678" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 315.000010172526, | |
| "y": 218.49999491373697 | |
| }, | |
| { | |
| "x": 315.4166666666667, | |
| "y": 123.33333333333333 | |
| } | |
| ], | |
| "style": "stroke: #008040;" | |
| }, | |
| { | |
| "id": "d65e1", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id561097a3" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "c907c", | |
| "position": "0.5984615016237494" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 361.66667683919263, | |
| "y": 227.99999491373697 | |
| }, | |
| { | |
| "x": 470, | |
| "y": 228 | |
| } | |
| ], | |
| "style": "stroke: #008040;" | |
| }, | |
| { | |
| "id": "f3edf", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id740045bc" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "e76f1", | |
| "position": "0.5095694152942244" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 465.5, | |
| "y": 123.5 | |
| }, | |
| { | |
| "x": 497.75, | |
| "y": 123.75 | |
| } | |
| ], | |
| "style": "stroke: #008040;" | |
| }, | |
| { | |
| "id": "d870f", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "idb248dd5c", | |
| "id52ac424a", | |
| "idb3964d3f" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "edbc5", | |
| "position": "0.4" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 605.5, | |
| "y": 115.5 | |
| }, | |
| { | |
| "x": 674.5, | |
| "y": 218 | |
| } | |
| ], | |
| "style": "stroke: #008040;" | |
| }, | |
| { | |
| "id": "b61b3", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 315.00001322428386, | |
| "y": 361.48333333333335 | |
| }, | |
| { | |
| "x": 315.000010172526, | |
| "y": 237.49999491373697 | |
| } | |
| ], | |
| "style": "stroke: #008040;" | |
| }, | |
| { | |
| "id": "e011c", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 150.49166666666667, | |
| "y": 361.48333333333335 | |
| }, | |
| { | |
| "x": 291.6666768391927, | |
| "y": 237.49999491373697 | |
| } | |
| ], | |
| "style": "stroke: #008000;" | |
| }, | |
| { | |
| "id": "bb407", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "idb92332b0" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "ec3e3", | |
| "position": "0.46638477808330747" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 298.99167989095054, | |
| "y": 371.48333333333335 | |
| }, | |
| { | |
| "x": 166.5, | |
| "y": 371.48333333333335 | |
| } | |
| ], | |
| "style": "stroke: #008000;" | |
| }, | |
| { | |
| "id": "b2711", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id3adcd55e" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "d552e", | |
| "position": "0.4" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 414.48333333333335, | |
| "y": 392.48333333333335 | |
| }, | |
| { | |
| "x": 331.0083465576172, | |
| "y": 371.48333333333335 | |
| } | |
| ], | |
| "style": "stroke: #008000;" | |
| }, | |
| { | |
| "id": "d0da5", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id54146f13" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "f7c1d", | |
| "position": "0.4" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 393.9875, | |
| "y": 446.48333333333335 | |
| }, | |
| { | |
| "x": 323.0041798909505, | |
| "y": 381.48333333333335 | |
| } | |
| ], | |
| "style": "stroke: #008000;" | |
| }, | |
| { | |
| "id": "e790f", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 422.4875, | |
| "y": 402.48333333333335 | |
| }, | |
| { | |
| "x": 409.99583333333334, | |
| "y": 446.48333333333335 | |
| } | |
| ], | |
| "style": "stroke: #008000;" | |
| }, | |
| { | |
| "id": "ba6c7", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id64bad4e5" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "f13ee", | |
| "position": "0.701099450276439" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 556, | |
| "y": 529 | |
| }, | |
| { | |
| "x": 409.99583333333334, | |
| "y": 466.48333333333335 | |
| } | |
| ], | |
| "style": "stroke: #008000;" | |
| }, | |
| { | |
| "id": "a82d3", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id7a2680f1" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "b11b2", | |
| "position": "0.4" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 418, | |
| "y": 456.48333333333335 | |
| }, | |
| { | |
| "x": 556, | |
| "y": 529 | |
| } | |
| ], | |
| "style": "stroke: #008000;" | |
| }, | |
| { | |
| "id": "c1688", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "b1c07" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "ebe5a", | |
| "position": "0.41407983129230874" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 128.74774509060222, | |
| "y": 135.66666666666669 | |
| }, | |
| { | |
| "x": 82.74774572638509, | |
| "y": 135.17741935483872, | |
| "anchor": "a2c25", | |
| "element": "b5913" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "b4769", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 350.33333333333354, | |
| "y": 605.3333333333334 | |
| }, | |
| { | |
| "x": 376.25000000000006, | |
| "y": 560.1666666666666 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id6a4e25b5", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 433, | |
| "y": 604.75 | |
| }, | |
| { | |
| "x": 393.33333333333337, | |
| "y": 560.1666666666666 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id2abec5f6", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id208b4fc4" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "aebc6", | |
| "position": "0.49763813984634164" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 393.33333333333337, | |
| "y": 541.1666666666666 | |
| }, | |
| { | |
| "x": 393.9875, | |
| "y": 466.48333333333335 | |
| } | |
| ], | |
| "style": "stroke: #006600;" | |
| }, | |
| { | |
| "id": "id129bdce0", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 418, | |
| "y": 456.48333333333335 | |
| }, | |
| { | |
| "x": 338.3333435058593, | |
| "y": 237.49999491373697 | |
| } | |
| ], | |
| "style": "stroke: #006600;" | |
| }, | |
| { | |
| "id": "idba67fe43", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "id5e009fa2" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "fef65", | |
| "position": "0.4929575239801747" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 82.74774572638509, | |
| "y": 194 | |
| }, | |
| { | |
| "x": 127, | |
| "y": 228 | |
| } | |
| ], | |
| "style": "stroke: #006600;" | |
| }, | |
| { | |
| "id": "id5e009fa2", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 78.31193643159628, | |
| "y": 245 | |
| }, | |
| { | |
| "x": 96.86430236148772, | |
| "y": 219.71972515639618, | |
| "anchor": "fef65", | |
| "element": "idba67fe43" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "ide4c980d3", | |
| "renderableType": "edge", | |
| "hasAnchoredDependencies": [ | |
| "idb782318c" | |
| ], | |
| "anchors": [ | |
| { | |
| "id": "f144f", | |
| "position": "0.4" | |
| } | |
| ], | |
| "points": [ | |
| { | |
| "x": 194, | |
| "y": 228 | |
| }, | |
| { | |
| "x": 268.3333435058594, | |
| "y": 227.99999491373697 | |
| } | |
| ], | |
| "style": "stroke: #006600;" | |
| }, | |
| { | |
| "id": "idb782318c", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 223.5, | |
| "y": 201 | |
| }, | |
| { | |
| "x": 223.73333740234375, | |
| "y": 227.9999979654948, | |
| "anchor": "f144f", | |
| "element": "ide4c980d3" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id4aefea78", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 348.0000254313152, | |
| "y": 160.5 | |
| }, | |
| { | |
| "x": 315.25043958984065, | |
| "y": 161.30052258458906, | |
| "anchor": "a4d13", | |
| "element": "f6437" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id561097a3", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 426.1666666666667, | |
| "y": 204.66666666666666 | |
| }, | |
| { | |
| "x": 426.5000000939003, | |
| "y": 227.9999979576696, | |
| "anchor": "c907c", | |
| "element": "d65e1" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id740045bc", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 481.5, | |
| "y": 95.5 | |
| }, | |
| { | |
| "x": 481.93361364323874, | |
| "y": 123.62739235382355, | |
| "anchor": "e76f1", | |
| "element": "f3edf" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "idb248dd5c", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 664, | |
| "y": 151.83333333333334 | |
| }, | |
| { | |
| "x": 633.1, | |
| "y": 156.5, | |
| "anchor": "edbc5", | |
| "element": "d870f" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id52ac424a", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 538.0625, | |
| "y": 133.75 | |
| }, | |
| { | |
| "x": 633.1, | |
| "y": 156.5, | |
| "anchor": "edbc5", | |
| "element": "d870f" | |
| } | |
| ], | |
| "style": "stroke: #006633;" | |
| }, | |
| { | |
| "id": "idb3964d3f", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 633.1, | |
| "y": 156.5, | |
| "anchor": "edbc5", | |
| "element": "d870f" | |
| }, | |
| { | |
| "x": 614.875, | |
| "y": 194 | |
| } | |
| ], | |
| "style": "stroke: #006633;" | |
| }, | |
| { | |
| "id": "id208b4fc4", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 363.33333333333354, | |
| "y": 503.5 | |
| }, | |
| { | |
| "x": 393.6588716164828, | |
| "y": 504.0013915891424, | |
| "anchor": "aebc6", | |
| "element": "id2abec5f6" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id54146f13", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 341.33333333333303, | |
| "y": 445.83333333333314 | |
| }, | |
| { | |
| "x": 365.5941719563802, | |
| "y": 420.48333333333335, | |
| "anchor": "f7c1d", | |
| "element": "d0da5" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id3adcd55e", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 388.99999999999994, | |
| "y": 363.4833272298177 | |
| }, | |
| { | |
| "x": 381.09333862304686, | |
| "y": 384.08333333333337, | |
| "anchor": "d552e", | |
| "element": "b2711" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "idb92332b0", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 237.33333333333337, | |
| "y": 397.9833272298177 | |
| }, | |
| { | |
| "x": 237.19957716712497, | |
| "y": 371.48333333333335, | |
| "anchor": "ec3e3", | |
| "element": "bb407" | |
| } | |
| ], | |
| "style": "stroke: #006633;" | |
| }, | |
| { | |
| "id": "id7a2680f1", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 513.1666666666669, | |
| "y": 457.16666666666697 | |
| }, | |
| { | |
| "x": 473.2, | |
| "y": 485.49, | |
| "anchor": "b11b2", | |
| "element": "a82d3" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id64bad4e5", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 468.16666666666674, | |
| "y": 546 | |
| }, | |
| { | |
| "x": 439.6880504456605, | |
| "y": 505.82823846118526, | |
| "anchor": "f13ee", | |
| "element": "ba6c7" | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id3ee32f14", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 388.17550402772156, | |
| "y": 657.7912447684621 | |
| }, | |
| { | |
| "x": 350.33333333333354, | |
| "y": 625.3333333333334 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id3976b167-9266-4125-8c83-739b1b86f34a", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 555, | |
| "y": 228 | |
| }, | |
| { | |
| "x": 596.75, | |
| "y": 282 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "ida81c40a5-026e-4e39-a9a6-694b8533f105", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 214.25, | |
| "y": 623.6666666666666 | |
| }, | |
| { | |
| "x": 193.33333333333348, | |
| "y": 574.9999999999997 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "id834a20bc-e8fc-44d4-8b60-6913b1dd1465", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 508.66666666666674, | |
| "y": 631.1666666666666 | |
| }, | |
| { | |
| "x": 458.1666666666668, | |
| "y": 625.333333333334 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "d9a19", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 388.17550402772156, | |
| "y": 657.7912447684621 | |
| }, | |
| { | |
| "x": 428.1666666666668, | |
| "y": 625.333333333334 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "d6e4f", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 596.25, | |
| "y": 214 | |
| }, | |
| { | |
| "x": 596.75, | |
| "y": 282 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| }, | |
| { | |
| "id": "cd80c", | |
| "renderableType": "edge", | |
| "points": [ | |
| { | |
| "x": 654.5, | |
| "y": 228 | |
| }, | |
| { | |
| "x": 596.75, | |
| "y": 282 | |
| } | |
| ], | |
| "style": "stroke: #000000;" | |
| } | |
| ] | |
| } |
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
| // TODO this code is terrible and hacky. It's just a quick data-munge, not anything worth keeping. | |
| var newExample = {viewport:[]}; | |
| myPathway.DataNode.forEach(function(DataNode){ | |
| var newElement = {}; | |
| newElement.height = DataNode.height; | |
| newElement.id = DataNode.id; | |
| newElement.renderableType = 'node'; | |
| newElement.style = "stroke: " + DataNode.borderColor + "; fill:" + DataNode.backgroundColor + ";"; | |
| newElement.width = DataNode.width; | |
| newElement.x = DataNode.x; | |
| newElement.y = DataNode.y; | |
| newExample.viewport.push(newElement); | |
| }); | |
| myPathway.Interaction.forEach(function(Interaction){ | |
| var newElement = {}; | |
| newElement.id = Interaction.id; | |
| newElement.renderableType = 'edge'; | |
| if (Interaction.hasOwnProperty('Anchor')) { | |
| newElement.hasAnchoredDependencies = []; | |
| newElement.anchors = Interaction.Anchor.map(function(anchor){ | |
| var dependencies = myPathway.Interaction.filter(function(interaction){ | |
| return interaction.Point.filter(function(point){return anchor.id === point.hasReference;}).length > 0; | |
| }); | |
| console.log('Interaction'); | |
| console.log(Interaction); | |
| console.log('dependencies'); | |
| console.log(dependencies); | |
| if (dependencies.length > 0) { | |
| var dependencyIds = dependencies.map(function(dependency){ | |
| return dependency.id; | |
| }); | |
| newElement.hasAnchoredDependencies = newElement.hasAnchoredDependencies.concat(dependencyIds); | |
| } | |
| var newAnchor = {}; | |
| newAnchor.id = anchor.id; | |
| newAnchor.position = anchor.anchorPosition; | |
| return newAnchor; | |
| }); | |
| } | |
| newElement.points = []; | |
| Interaction.Point.forEach(function(point, index){ | |
| if (index === 0 || (index === Interaction.Point.length - 1)) { | |
| var newPoint = {}; | |
| newPoint.x = point.x; | |
| newPoint.y = point.y; | |
| if (point.hasOwnProperty('hasReference')) { | |
| var references = myPathway.elements.filter(function(element){return element.GraphId === point.hasReference;}); | |
| if (references.length === 0) { | |
| newPoint.anchor = point.hasReference; | |
| newPoint.element = myPathway.Interaction.filter(function(interaction){ | |
| if (interaction.hasOwnProperty('Anchor')) { | |
| return interaction.Anchor.filter(function(anchor) {return anchor.id === point.hasReference;}).length > 0; | |
| } | |
| })[0].id; | |
| } | |
| } | |
| newElement.points.push(newPoint); | |
| } | |
| }); | |
| var strokeColor = Interaction.stroke || '000000'; | |
| newElement.style = "stroke: #" + strokeColor + ";"; | |
| newExample.viewport.push(newElement); | |
| }); | |
| JSON.stringify(newExample); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment