Skip to content

Instantly share code, notes, and snippets.

@kristw
Last active February 20, 2018 05:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristw/32be275e694b27e98ec14f1034f5bcf0 to your computer and use it in GitHub Desktop.
Save kristw/32be275e694b27e98ec14f1034f5bcf0 to your computer and use it in GitHub Desktop.
CRISPR Timeline
license: mit
"use strict";!function(a,b){"function"==typeof define&&define.amd?define(["d3","d3kit","labella"],b):"object"==typeof exports?module.exports=b(require("d3"),require("d3kit"),require("labella")):a.d3Kit=b(a.d3,a.d3Kit,a.labella)}(this,function(a,b,c){var d={margin:{left:40,right:20,top:20,bottom:20},initialWidth:400,initialHeight:400,scale:a.time.scale(),domain:void 0,direction:"right",dotRadius:3,layerGap:60,labella:{},keyFn:void 0,timeFn:function(a){return a.time},textFn:function(a){return a.text},dotColor:"#222",labelBgColor:"#222",labelTextColor:"#fff",linkColor:"#222",labelPadding:{left:4,right:4,top:3,bottom:2},textYOffset:"0.85em"},e=["dotClick","dotMouseover","dotMousemove","dotMouseout","labelClick","labelMouseover","labelMousemove","labelMouseout"];return b.Timeline=b.factory.createChart(d,e,function(b){function d(a){return a.w}function e(a){return a.h}function f(a){return j.scale(j.timeFn(a))}function g(){if(b.hasData()){var d=b.data();j.domain?j.scale.domain(j.domain):j.scale.domain(a.extent(d,j.timeFn)).nice(),j.scale.range([0,"left"===j.direction||"right"===j.direction?b.getInnerHeight():b.getInnerWidth()]),n.scale(j.scale);var e;switch(j.direction){case"right":n.orient("left"),e="translate(0,0)";break;case"left":n.orient("right"),e="translate("+b.getInnerWidth()+",0)";break;case"up":n.orient("bottom"),e="translate(0,"+b.getInnerHeight()+")";break;case"down":n.orient("top"),e="translate(0,0)"}l.get("main").attr("transform",e),l.get("main.axis").call(n),h(d);var g=l.get("dummy").append("text").classed("label-text",!0),k=d.map(function(a){var b=g.text(j.textFn(a))[0][0].getBBox(),d=b.width+j.labelPadding.left+j.labelPadding.right,e=b.height+j.labelPadding.top+j.labelPadding.bottom,h=new c.Node(f(a),"left"===j.direction||"right"===j.direction?e:d,a);return h.w=d,h.h=e,h});g.remove(),m.options(j.labella).nodes(k).on("end",function(){i(m.nodes())}).start(100)}}function h(a){var b=l.get("main.dot").selectAll("circle.dot").data(a,j.keyFn),c="left"===j.direction||"right"===j.direction?"cy":"cx";b.enter().append("circle").classed("dot",!0).on("click",function(a,b){k.dotClick(a,b)}).on("mouseover",function(a,b){k.dotMouseover(a,b)}).on("mousemove",function(a,b){k.dotMousemove(a,b)}).on("mouseout",function(a,b){k.dotMouseout(a,b)}).style("fill",j.dotColor).attr("r",j.dotRadius).attr(c,f),b.transition().style("fill",j.dotColor).attr("r",j.dotRadius).attr(c,f),b.exit().remove()}function i(b){function f(a){switch(j.direction){case"right":return"translate("+a.x+","+(a.y-a.dy/2)+")";case"left":return"translate("+(a.x+g-a.w)+","+(a.y-a.dy/2)+")";case"up":return"translate("+(a.x-a.dx/2)+","+a.y+")";case"down":return"translate("+(a.x-a.dx/2)+","+a.y+")"}}var g;g="left"===j.direction||"right"===j.direction?a.max(b,d):a.max(b,e);var h=new c.Renderer({nodeHeight:g,layerGap:j.layerGap,direction:j.direction});h.layout(b);var i=a.functor(j.labelBgColor),m=a.functor(j.labelTextColor),n=a.functor(j.linkColor),o=l.get("main.label").selectAll("g.label-g").data(b,j.keyFn?function(a){return j.keyFn(a.data)}:void 0),p=o.enter().append("g").classed("label-g",!0).on("click",function(a,b){k.labelClick(a.data,b)}).on("mouseover",function(a,b){k.labelMouseover(a.data,b)}).on("mousemove",function(a,b){k.labelMousemove(a.data,b)}).on("mouseout",function(a,b){k.labelMouseout(a.data,b)}).attr("transform",f);p.append("rect").classed("label-bg",!0).attr("rx",2).attr("ry",2).attr("width",d).attr("height",e).style("fill",function(a){return i(a.data)}),p.append("text").classed("label-text",!0).attr("dy",j.textYOffset).attr("x",j.labelPadding.left).attr("y",j.labelPadding.top).style("fill",function(a){return m(a.data)}).text(function(a){return j.textFn(a.data)});var q=o.transition().attr("transform",f);q.select("rect").attr("width",d).attr("height",e).style("fill",function(a){return i(a.data)}),q.select("text.label-text").attr("dy",j.textYOffset).attr("x",j.labelPadding.left).attr("y",j.labelPadding.top).style("fill",function(a){return m(a.data)}).text(function(a){return j.textFn(a.data)}),o.exit().remove();var r=l.get("main.link").selectAll("path.link").data(b,j.keyFn?function(a){return j.keyFn(a.data)}:void 0);r.enter().append("path").classed("link",!0).attr("d",function(a){return h.generatePath(a)}).style("stroke",function(a){return n(a.data)}).style("fill","none"),r.transition().style("stroke",function(a){return n(a.data)}).attr("d",function(a){return h.generatePath(a)}),r.exit().remove()}var j=b.options(),k=b.getDispatcher(),l=b.getLayerOrganizer();l.create(["dummy",{main:["axis","link","label","dot"]}]);var m=new c.Force(j.labella),n=a.svg.axis();return k.on("resize",g),k.on("options",g),k.on("data",g),l.get("main.axis").classed("axis",!0),b.mixin({axis:n,visualize:g})}),b});
!function(a,b){"function"==typeof define&&define.amd?define(["d3"],b):"object"==typeof exports?module.exports=b(require("d3")):a.d3Kit=b(a.d3)}(this,function(a){var b;b=function(){var a=function(){function a(a,b,c){return a.on("click",b[c+"Click"]).on("mouseover",b[c+"MouseOver"]).on("mousemove",b[c+"MouseMove"]).on("mouseout",b[c+"MouseOut"])}function b(a,b){return b?a.selectAll("*").remove():a.selectAll("*").transition().style("opacity",0).remove()}function c(a){return"object"==typeof HTMLElement?a instanceof HTMLElement:a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName}function d(a){return c(a)?a:document.querySelector(a)}function e(a){return Array.isArray(a)?a:[].slice.call(document.querySelectorAll(a))}function f(a){a=a||{};for(var b=1;b<arguments.length;b++){var c=arguments[b];if(c)for(var d in c)if(c.hasOwnProperty(d)){var e=c[d];!k(e)||Array.isArray(e)||m(e)?a[d]=e:a[d]=f(a[d],e)}}return a}function g(a){a=a||{};for(var b=1;b<arguments.length;b++)if(arguments[b])for(var c in arguments[b])arguments[b].hasOwnProperty(c)&&(a[c]=arguments[b][c]);return a}function h(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c)}function i(a,b,c){a.removeEventListener(b,c,!1)}function j(a,b,c){var d,e=function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;return clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f),e};return e.isDebounced=!0,e.now=function(){return clearTimeout(d),a.apply(this,arguments)},e}function k(a){return!(!a||!r[typeof a])}function l(a){return"number"==typeof a||a&&"object"==typeof a&&u.call(a)==s||!1}function m(a){var b={};return!!a&&"[object Function]"===b.toString.call(a)}function n(a){return null==a?"":String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}function o(a,b){return null==a?"":!b&&v?v.call(a):(b=w(b),String(a).replace(new RegExp("^"+b+"+|"+b+"+$","g"),""))}function p(a){return o(a).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()}var q=Number.isNaN?Number.isNaN:window.isNaN,r={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},s="[object Number]",t=Object.prototype,u=t.toString,v=String.prototype.trim,w=function(a){return null==a?"\\s":a.source?a.source:"["+n(a)+"]"};return{$:d,$$:e,dasherize:p,debounce:j,deepExtend:f,extend:g,isElement:c,isFunction:m,isNaN:q,isNumber:l,isObject:k,on:h,off:i,trim:o,removeAllChildren:b,bindMouseEventsToDispatcher:a}}();return a}();var c;c=function(a){return function(b){function c(b,c,d){var e=d?d+"."+c:c;if(i.hasOwnProperty(e))throw"invalid or duplicate layer id: "+e;var f=b.append("g").classed(a.dasherize(c)+"-layer",!0);return i[e]=f,f}function d(b,e,f){if(Array.isArray(e))return e.map(function(a){d(b,a,f)});if(a.isObject(e)){var g=Object.keys(e)[0],h=c(b,g,f);return d(h,e[g],f?f+"."+g:g),h}return c(b,e,f)}function e(a){return d(b,a)}function f(a){return Array.isArray(a)?a.map(e):e(a)}function g(a){return i[a]}function h(a){return!!i[a]}var i={};return{create:f,get:g,has:h}}}(b);var d;d=function(a,b,c){function d(d,g,h){function i(a,b){return 0===arguments.length?E:(E=a,b||S.data(a),D)}function j(a,b){return 0===arguments.length?F:(F=c.deepExtend(F,a),a&&(a.margin?l(b):a.offset&&k()),b||S.options(a),D)}function k(){P.attr("transform","translate("+(F.margin.left+F.offset[0])+","+(F.margin.top+F.offset[1])+")")}function l(a){k(),I=G-F.margin.left-F.margin.right,J=H-F.margin.top-F.margin.bottom,a||S.resize([G,H,I,J])}function m(a,b){return 0===arguments.length?F.margin:(F.margin=c.extend(F.margin,a),l(b),D)}function n(a){return 0===arguments.length?F.offset:(F.offset=a,k(),D)}function o(a,b){if(0===arguments.length||null===a||void 0===a)return G;if(G=c.isNumber(a)?+a:"auto"==a.trim().toLowerCase()?d.clientWidth:+(a+"").replace(/px/gi,"").trim(),c.isNaN(G))throw Error("invalid width: "+G);return G=Math.floor(G),I=G-F.margin.left-F.margin.right,O.attr("width",G),b||S.resize([G,H,I,J]),D}function p(a,b){if(0===arguments.length||null===a||void 0===a)return H;if(H=c.isNumber(a)?+a:"auto"==a.trim().toLowerCase()?d.clientHeight:+(a+"").replace(/px/gi,"").trim(),c.isNaN(H))throw Error("invalid height: "+H);return H=Math.floor(H),J=H-F.margin.top-F.margin.bottom,O.attr("height",H),b||S.resize([G,H,I,J]),D}function q(a,b){return 0===arguments.length?[G,H]:(o(a[0],!0),p(a[1],b),D)}function r(a){return 0===arguments.length?L:L!=a?w(a,K):D}function s(a){return 0===arguments.length?K:K!=a?w(L,a):D}function t(a){return 0===arguments.length?N:(N=null===a||void 0===a||""===a||a===!1||"false"===(a+"").toLowerCase()?!1:c.isNumber(a)?0===+a?!1:+a:!1,D)}function u(){if(M)switch(K){case"dom":c.off(d,"resize",M);break;default:case"window":c.off(window,"resize",M)}return M=null,D}function v(a){if(a)switch(K){case"dom":c.on(d,"resize",a);break;default:case"window":c.on(window,"resize",a)}return M=a,D}function w(a,b){if(a=a&&"false"==(a+"").toLowerCase()?!1:a,b=b||K,a!=L)u(),L=a,K=b,a&&(M=c.debounce(function(){N?(z(L,!0),A(N)):z(L)},100),v(M));else if(b!=K){var d=M;u(),K=b,v(d)}return M&&M(),D}function x(){return Object.keys(S).filter(function(a){return f.indexOf(a)<0})}function y(a){var b=D;return c.isObject(a)&&Object.keys(a).forEach(function(c){b[c]=a[c]}),b}function z(a,b){switch(a){case"all":case"full":case"both":q(["auto","auto"],b);break;case"height":p("auto",b);break;default:case"width":o("auto",b)}return D}function A(a,b){var d=G,e=H;if(!c.isNumber(a))throw"Invalid ratio: must be a Number";if(a=+a,(d/e).toFixed(4)==a.toFixed(4))return D;var f=Math.floor(d/a);return f>e?o(Math.floor(e*a),b):p(f,b),D}function B(){return null!==E&&void 0!==E}function C(){return I>0&&J>0}var D={};d=c.$(d);var E=null,F=c.deepExtend({},e,g),G=0,H=0,I=0,J=0,K="window",L=!1,M=null,N=!1,O=a.select(d).append("svg"),P=O.append("g");k();var Q=new b(P),R=h?h.concat(f):f,S=a.dispatch.apply(a,R);return q([F.initialWidth,F.initialHeight]),c.extend(D,{getCustomEventNames:x,getDispatcher:function(){return S},getInnerWidth:function(){return I},getInnerHeight:function(){return J},getLayerOrganizer:function(){return Q},getRootG:function(){return P},getSvg:function(){return O},data:i,options:j,margin:m,offset:n,width:o,height:p,dimension:q,autoResize:r,autoResizeDetection:s,autoResizeToAspectRatio:t,hasData:B,hasNonZeroArea:C,mixin:y,resizeToFitContainer:z,resizeToAspectRatio:A}),a.rebind(D,S,"on"),D}var e={margin:{top:30,right:30,bottom:30,left:30},offset:[.5,.5],initialWidth:720,initialHeight:500},f=["data","options","resize"];return d}(a,c,b);var e;e=function(a,b){var c=function(){function c(c,d,e){var f=function(f,g){var h=new a(f,b.deepExtend({},c,g),d);return e&&e(h),h};return d=d?d:[],f.getCustomEvents=function(){return d},f}return{createChart:c}}();return c}(d,b);var f;f=function(a,b){function c(a,b){b()}function d(d,e,f,g){function h(b,c){return arguments.length>1?(o[b]=a.functor(c),this):a.functor(o[b])}function i(a,b,c){return h(a)(b,c)}function j(a,c){return function(d){a(d,b.debounce(function(a,b){var e=p[c];e&&e(d)}),5)}}function k(a,b,c){return o[c||b]=function(c,d){return a.property(b)(c,d)},this}function l(a,b,c){return b.forEach(function(b,d){k(a,b,c&&d<c.length?c[d]:void 0)}),this}function m(a){return g.forEach(function(b){p.on(b,a[b])}),this}function n(){return g}e=e||c,f=f||c,g=g||[];var o={},p=a.dispatch.apply(a,["enterDone","updateDone","exitDone"].concat(g)),q={getDispatcher:function(){return p},getPropertyValue:i,inheritPropertyFrom:k,inheritPropertiesFrom:l,publishEventsTo:m,getCustomEventNames:n,property:h,enter:j(d,"enterDone"),update:j(e,"updateDone"),exit:j(f,"exitDone")};return a.rebind(q,p,"on"),q}return d}(a,b);var g;return g=function(a,b,c,d,e){return{factory:a,helper:b,Skeleton:c,LayerOrganizer:d,Chartlet:e}}(e,b,d,c,f)});
var data = [
{"title" : "Discovery of CRISPR and its function ",
"date" : "1993-2005",
"time": new Date(1993, 1, 1),
"person": "Francisco Mojica",
"institute": "University of Alicante, Spain",
"references": ["mojica", "pourcel"],
"discovery": "Francisco Mojica was the first researcher to characterize what is now called a CRISPR locus, reported in 1993. He worked on them throughout the 1990s, and in 2000, he recognized that what had been reported as disparate repeat sequences actually shared a common set of features, now known to be hallmarks of CRISPR sequences (he coined the term CRISPR through correspondence with Ruud Jansen, who first used the term in print in 2002). In 2005 he reported that these sequences matched snippets from the genomes of bacteriophage (Mojica et al., 2005). This finding led him to hypothesize, correctly, that CRISPR is an adaptive immune system. Another group, working independently, published similar findings around this same time (Pourcel et al., 2005)"
},
{"title" : "Discovery of Cas9 and PAM",
"time": new Date(2005, 5, 1),
"date" : "May, 2005",
"person": "Alexander Bolotin",
"references": ["bolotin"],
"institute": "French National Institute for Agricultural Research (INRA)",
"discovery": "Bolotin was studying the bacteria Streptococcus thermophilus, which had just been sequenced, revealing an unusual CRISPR locus (Bolotin et al., 2005). Although the CRISPR array was similar to previously reported systems, it lacked some of the known cas genes and instead contained novel cas genes, including one encoding a large protein they predicted to have nuclease activity, which is now known as Cas9. Furthermore, they noted that the spacers, which have homology to viral genes, all share a common sequence at one end. This sequence, the protospacer adjacent motif (PAM), is required for target recognition."
},
{"title" : "Experimental demonstration of adaptive immunity",
"date" : "March, 2007",
"time": new Date(2007, 3, 1),
"person": "Philippe Horvath",
"institute": "Danisco France SAS",
"references": ["barrangou"],
"discovery": "S. thermophilus is widely used in the dairy industry to make yogurt and cheese, and scientists at Danisco wanted to explore how it responds to phage attack, a common problem in industrial yogurt making. Horvath and colleagues showed experimentally that CRISPR systems are indeed an adaptive immune system: they integrate new phage DNA into the CRISPR array, which allows them to fight off the next wave of attacking phage (Barrangou et al., 2007). Furthermore, they showed that Cas9 is likely the only protein required for interference, the process by which the CRISPR system inactivates invading phage, details of which were not yet known."},
{"title" : "Spacer sequences are transcribed into guide RNAs",
"date" : "August, 2008",
"time": new Date(2008, 8, 1),
"person": "John van der Oost",
"institute": "University of Wageningen, Netherlands",
"references": ["brouns"],
"discovery": "Scientists soon began to fill in some of the details on exactly how CRISPR-Cas systems “interfere” with invading phage. The first piece of critical information came from John van der Oost and colleagues who showed that in E-scherichia coli, spacer sequences, which are derived from phage, are transcribed into small RNAs, termed CRISPR RNAs (crRNAs), that guide Cas proteins to the target DNA (Brouns et al., 2008)."},
{"title" : "CRISPR acts on DNA targets",
"date" : "December, 2008",
"time": new Date(2008, 12, 1),
"person": "Luciano Marraffini and Erik Sontheimer",
"institute": "Northwestern University, Illinois",
"references": ["marraffini", "hale"],
"discovery": "The next key piece in understanding the mechanism of interference came from Marraffini and Sontheimer, who elegantly demonstrated that the target molecule is DNA, not RNA (Marraffini and Sontheimer, 2008). This was somewhat surprising, as many people had considered CRISPR to be a parallel to eukaryotic RNAi silencing mechanisms, which target RNA. Marraffini and Sontheimer explicitly noted in their paper that this system could be a powerful tool if it could be transferred to non-bacterial systems. (It should be noted, however, that a different type of CRISPR system can target RNA (Hale et al., 2009))."},
{"title" : "Cas9 cleaves target DNA",
"date" : "December, 2010",
"time": new Date(2010, 12, 1),
"person": "Sylvain Moineau",
"institute": "University of Laval, Quebec City, Canada",
"references": ["moineau"],
"discovery": "Moineau and colleagues demonstrated that CRISPR-Cas9 creates double-stranded breaks in target DNA at precise positions, 3 nucleotides upstream of the PAM (Garneau et al., 2010). They also confirmed that Cas9 is the only protein required for cleavage in the CRISPR-Cas9 system. This is a distinguishing feature of Type II CRISPR systems, in which interference is mediated by a single large protein (here Cas9) in conjunction with crRNAs."},
{"title" : "Discovery of tracrRNA for Cas9 system",
"date" : "March, 2011",
"time": new Date(2011, 3, 1),
"person": "Emmanuelle Charpentier",
"references": ["deltcheva"],
"institute": "Umea University, Sweden and University of Vienna, Austria",
"discovery": "The final piece to the puzzle in the mechanism of natural CRISPR-Cas9-guided interference came from the group of Emmanuelle Charpentier. They performed small RNA sequencing on Streptococcus pyogenes, which has a Cas9-containing CRISPR-Cas system. They discovered that in addition to the crRNA, a second small RNA exists, which they called trans-activating CRISPR RNA (tracrRNA) (Deltcheva et al., 2011). They showed that tracrRNA forms a duplex with crRNA, and that it is this duplex that guides Cas9 to its targets."},
{"title" : "CRISPR systems can function heterologously in other species",
"date" : "July, 2011",
"time": new Date(2011, 7, 1),
"person": "Virginijus Siksnys",
"institute": "Vilnius University, Lithuania",
"references": ["sapranauskas"],
"discovery": "Siksnys and colleagues cloned the entire CRISPR-Cas locus from S. thermophilus (a Type II system) and expressed it in E. coli (which does not contain a Type II system), where they demonstrated that it was capable of providing plasmid resistance (Sapranauskas et al., 2011). This suggested that CRISPR systems are self-contained units and verified that all of the required components of the Type II system were known."},
{"title" : "Biochemical characterization of Cas9-mediated cleavage",
"date" : "September, 2012",
"person": "Virginijus Siksnys",
"time": new Date(2012, 9, 1),
"institute": "Vilnius University, Lithuania",
"references": ["gasiunas"],
"discovery": "Taking advantage of their heterologous system, Siksnys and his team purified Cas9 in complex with crRNA from the E. coli strain engineered to carry the S. thermophilus CRISPR locus and undertook a series of biochemical experiments to mechanistically characterize Cas9’s mode of action (Gasiunas et al., 2012).They verified the cleavage site and the requirement for the PAM, and using point mutations, they showed that the RuvC domain cleaves the non-complementary strand while the HNH domain cleaves the complementary site. They also noted that the crRNA could be trimmed down to a 20-nt stretch sufficient for efficient cleavage. Most impressively, they showed that they could reprogram Cas9 to a target a site of their choosing by changing the sequence of the crRNA."},
{"title" : "Biochemical characterization of Cas9-mediated cleavage",
"date" : "June, 2012",
"time": new Date(2012, 6, 1),
"person": "Charpentier and Jennifer Doudna",
"institute": "University of California, Berkeley",
"references": ["jinek"],
"discovery": "Similar findings as those in Gasiunas et al. were reported at almost the same time by Emmanuelle Charpentier in collaboration with Jennifer Doudna at the University of California, Berkeley (Jinek et al., 2012). Charpentier and Doudna also reported that the crRNA and the tracrRNA could be fused together to create a single, synthetic guide, further simplifying the system. (Although published in June 2012, this paper was submitted after Gasiunas et al.)"},
{"title" : "CRISPR-Cas9 harnessed for genome editing",
"date" : "January, 2013",
"time": new Date(2013, 1, 1),
"person": "Feng Zhang",
"references": ["cong", "mali"],
"institute": " Broad Institute of MIT and Harvard, McGovern Institute for Brain Research at MIT, Massachusetts",
"discovery": "Zhang, who had previously worked on other genome editing systems such as TALENs, was first to successfully adapt CRISPR-Cas9 for genome editing in eukaryotic cells (Cong et al., 2013). Zhang and his team engineered two different Cas9 orthologs (from S. thermophilus and S. pyogenes) and demonstrated targeted genome cleavage in human and mouse cells. They also showed that the system (i) could be programmed to target multiple genomic loci, and (ii) could drive homology-directed repair. Researchers from George Church’s lab at Harvard University reported similar findings in the same issue of Science (Mali et al., 2013)."}
];
var citations = [
{"id" : "barrangou",
"year" : 2007,
"authors": "Barrangou, R., Fremaux, C., Deveau, H., Richards, M., Boyaval, P., Moineau, S., Romero, D.A., and Horvath, P.",
"title": "CRISPR provides acquired resistance against viruses in prokaryotes.",
"journal": "Science",
"edition": "315, 1709–1712."},
{"id" : "bolotin",
"year" : 2005,
"authors": "Bolotin, A., Quinquis, B., Sorokin, A.,and Ehrlich, S.D.",
"title": "Clustered regularly interspaced short palindrome repeats (CRISPRs) have spacers of extrachromosomal origin.",
"journal": "Microbiology",
"edition": "151, 2551–2561"},
{"id" : "cong",
"year" : 2013,
"authors": "Cong, L., Ran, F.A., Cox, D., Lin, S., Barretto, R., Habib, N., Hsu, P.D., Wu, X., Jiang, W., Marraffini, L.A.",
"title": "Multiplex genome engineering using CRISPR/Cas systems.",
"journal": "Science",
"edition": "39, 819–823"},
{"id" : "deltcheva",
"year" : 2011,
"authors": "Deltcheva, E., Chylinski, K., Sharma, C.M., Gonzales, K., Chao, Y., Pirzada, Z.A., Eckert, M.R., Vogel, J., and Charpentier, E.",
"title": "CRISPR RNA maturation by trans-encoded small RNA and host factor RNase III",
"journal": "Nature",
"edition": "471, 602–607."},
{"id" : "gasiunas",
"year" : 2012,
"authors": "Gasiunas, G., Barrangou, R., Horvath, P., and Siksnys, V.",
"title": "Cas9–crRNA ribonucleoprotein complex mediates specific DNA cleavage for adaptive immunity in bacteria.",
"journal": "Pnas",
"edition": "109, E2579–E2586"},
{"id" : "hale",
"year" : 2009,
"authors": "Hale, C.R., Zhao, P., Olson, S., Duff, M.O., Graveley, B.R., Wells, L., Terns, R.M., and Terns, M.P.",
"title": "RNA-Guided RNA Cleavage by a CRISPR RNA-Cas Protein Complex",
"journal": "Cell",
"edition": "139, 945–956"},
{"id" : "jinek",
"year" : 2012,
"authors": "Jinek, M., Chylinski, K., Fonfara, I., Hauer, M., Doudna, J.A., and Charpentier, E. ",
"title": "A programmable dual-RNA-guided DNA endonuclease in adaptive bacterial immunity",
"journal": "Science",
"edition": "337, 816–821."},
{"id" : "mali",
"year" : 2013,
"authors": "Mali, P., Yang, L., Esvelt, K.M., Aach, J., Guell, M., DiCarlo, J.E., Norville, J.E., and Church, G.M.",
"title": "RNA-guided human genome engineering via Cas9",
"journal": "Science",
"edition": "339, 823–826."},
{"id" : "marraffii",
"year" : 2008,
"authors": "Marraffini, L.A., and Sontheimer, E.J.",
"title": "CRISPR interference limits horizontal gene transfer in staphylococci by targeting DNA.",
"journal": "Science",
"edition": "322, 1843–1845"},
{"id" : "mojica",
"year" : 2005,
"authors": "Mojica, F.J.M., D ez-Villase or, C.S., Garc a-Mart nez, J.S., and Soria, E.",
"title": "Intervening Sequences of Regularly Spaced Prokaryotic Repeats Derive from Foreign Genetic Elements",
"journal": "J Mol Evol",
"edition": "60, 174–182"},
{"id" : "pourcel",
"year" : 2005,
"authors": "Pourcel, C., Salvignol, G., and Vergnaud, G.",
"title": "CRISPR elements in Yersinia pestis acquire new repeats by preferential uptake of bacteriophage DNA, and provide additional tools for evolutionary studies.",
"journal": "Microbiology",
"edition": "151, 653–663"},
{"id" : "sapranauskas",
"year" : 2011,
"authors": "Sapranauskas, R., Gasiunas, G., Fremaux, C., Barrangou, R., Horvath, P., and Siksnys, V.",
"title": "The Streptococcus thermophilus CRISPR/Cas system provides immunity in Escherichia coli.",
"journal": "Nucl. Acids Res",
"edition": "39, gkr606–gkr9282"}
]
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
.axis path{
fill: none;
stroke-width: 2px;
stroke: #222;
}
.axis line{
fill: none;
stroke-width: 1px;
stroke: #222;
}
.axis text{
font-size: 10px;
}
path.link{
stroke-width: 2px;
opacity: 0.6;
}
text.label-text{
font-size: 12px;
}
</style>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">CRISPR-timeline</h1>
<p>The discovery of the CRISPR-Cas microbial adaptive immune system and its ongoing development into a genome editing tool represents the work of many scientists from around the world. This timeline presents a concise history of the seminal contributions and the scientists who pushed this field forward, from the initial discovery to the first demonstrations of CRISPR-mediated genome editing.
</p>
<div class="col-md-5">
<div class="timeline" id="crisprtimeline"></div>
</div>
<div class="col-md-6">
<div id="crisprdata"></div>
</div>
</div>
</div>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3kit/3.2.0/d3kit.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/labella/1.1.4/labella.min.js"></script>
<script src="https://rawgit.com/kristw/d3kit-timeline/master/dist/d3kit-timeline.min.js"></script>
<script src="data.js"></script>
<script>
var chart = new d3KitTimeline('#crisprtimeline', {
direction: 'right',
initialWidth: 600,
initialHeight: 600,
labelBgColor: "#777",
textFn: function(d){
return d.time.getFullYear() + ' - ' + d.title;
}
});
var setdata = function(d,i){
var cdata = d3.select("#crisprdata");
cdata.selectAll("*").remove()
cdata.data([d]).append("h3").text(function(d){return d.title});
cdata.data([d]).append("hr");
cdata.data([d]).append("h4").text(function(d){return d.person + " - " + d.institute});
cdata.data([d]).append("h4").text(function(d){return d.date});
cdata.data([d]).append("p").text(function(d){return d.discovery});
};
chart.data(data);
chart.on("labelMouseover", function(d,i){setdata(d,i)} );
</script>
</body>
!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.labella=b()}(this,function(){var a;a=function(){var a=Object.prototype.hasOwnProperty,b=Object.prototype.toString,c=function(a){return"function"==typeof Array.isArray?Array.isArray(a):"[object Array]"===b.call(a)},d=function(c){if(!c||"[object Object]"!==b.call(c))return!1;var d=a.call(c,"constructor"),e=c.constructor&&c.constructor.prototype&&a.call(c.constructor.prototype,"isPrototypeOf");if(c.constructor&&!d&&!e)return!1;var f;for(f in c);return void 0===f||a.call(c,f)};return function e(){var a,b,f,g,h,i,j=arguments[0],k=1,l=arguments.length,m=!1;for("boolean"==typeof j?(m=j,j=arguments[1]||{},k=2):("object"!=typeof j&&"function"!=typeof j||null==j)&&(j={});l>k;++k)if(a=arguments[k],null!=a)for(b in a)f=j[b],g=a[b],j!==g&&(m&&g&&(d(g)||(h=c(g)))?(h?(h=!1,i=f&&c(f)?f:[]):i=f&&d(f)?f:{},j[b]=e(m,i,g)):void 0!==g&&(j[b]=g));return j}}();var b;b=function(){function a(a,b){try{for(var c in b)Object.defineProperty(a.prototype,c,{value:b[c],enumerable:!1})}catch(d){a.prototype=b}}function b(){}function c(a){return k+a in this}function d(a){return a=k+a,a in this&&delete this[a]}function e(){var a=[];return this.forEach(function(b){a.push(b)}),a}function f(){var a=0;for(var b in this)b.charCodeAt(0)===l&&++a;return a}function g(){for(var a in this)if(a.charCodeAt(0)===l)return!1;return!0}function h(){}function i(a){function c(){for(var b,c=d,e=-1,f=c.length;++e<f;)(b=c[e].on)&&b.apply(this,arguments);return a}var d=[],e=new b;return c.on=function(b,c){var f,g=e.get(b);return arguments.length<2?g&&g.on:(g&&(g.on=null,d=d.slice(0,f=d.indexOf(g)).concat(d.slice(f+1)),e.remove(b)),c&&d.push(e.set(b,{on:c})),a)},c}var j={version:"3.4.4"};j.map=function(a){var c=new b;if(a instanceof b)a.forEach(function(a,b){c.set(a,b)});else for(var d in a)c.set(d,a[d]);return c},a(b,{has:c,get:function(a){return this[k+a]},set:function(a,b){return this[k+a]=b},remove:d,keys:e,values:function(){var a=[];return this.forEach(function(b,c){a.push(c)}),a},entries:function(){var a=[];return this.forEach(function(b,c){a.push({key:b,value:c})}),a},size:f,empty:g,forEach:function(a){for(var b in this)b.charCodeAt(0)===l&&a.call(this,b.substring(1),this[b])}});var k="\x00",l=k.charCodeAt(0);return j.dispatch=function(){for(var a=new h,b=-1,c=arguments.length;++b<c;)a[arguments[b]]=i(a);return a},h.prototype.on=function(a,b){var c=a.indexOf("."),d="";if(c>=0&&(d=a.substring(c+1),a=a.substring(0,c)),a)return arguments.length<2?this[a].on(d):this[a].on(d,b);if(2===arguments.length){if(null==b)for(a in this)this.hasOwnProperty(a)&&this[a].on(d,null);return this}},j.dispatch}();var c;c=function(){function a(a,b,c){return function(){var d=c.apply(b,arguments);return d===b?a:d}}var b=function(b,c){for(var d,e=1,f=arguments.length;++e<f;)b[d=arguments[e]]=a(b,c,c[d]);return b};return b}();var d;d=function(a,b,c){var d=function(){var d={};return d.sum=function(a,b){return a.map(b).reduce(function(a,b){return a+b},0)},d.isObject=function(a){return"object"==typeof a&&null!==a},d.isDefined=function(a){return null!==a&&void 0!==a},d.extend=a,d.dispatch=b,d.rebind=c,d.extractKeys=function(a,b){return b.reduce(function(b,c){return b[c]=a[c],b},{})},d}();return d}(a,b,c);var e;e=function(a){var b=function(b,c,d){if(1===arguments.length&&a.isObject(b)){var e=b;this.idealPos=e.idealPos,this.currentPos=null!==e.currentPos&&void 0!==e.currentPos?e.currentPos:e.idealPos,this.width=e.width,this.data=e.data}else this.idealPos=b,this.currentPos=b,this.width=c,this.data=d;this.previousPos=this.currentPos},c=b.prototype;return c.distanceFrom=function(a){var b=this.width/2,c=a.width/2;return Math.max(this.currentPos-b,a.currentPos-c)-Math.min(this.currentPos+b,a.currentPos+c)},c.moveToIdealPosition=function(){return this.currentPos=this.idealPos,this},c.displacement=function(){return this.idealPos-this.currentPos},c.overlapWithNode=function(a,b){return b=null===b||void 0===b?0:b,this.distanceFrom(a)-b<0},c.overlapWithPoint=function(a){var b=this.width/2;return a>=this.currentPos-b&&a<=this.currentPos+b},c.positionBefore=function(a,b){return b=b?b:0,a.currentLeft()-this.width/2-b},c.positionAfter=function(a,b){return b=b?b:0,a.currentRight()+this.width/2+b},c.currentRight=function(){return this.currentPos+this.width/2},c.currentLeft=function(){return this.currentPos-this.width/2},c.idealRight=function(){return this.idealPos+this.width/2},c.idealLeft=function(){return this.idealPos-this.width/2},c.halfWidth=function(){return this.width/2},c.velocity=function(a){return a=a||1,(this.currentPos-this.previousPos)/a},c.kineticEnergy=function(){var a=this.velocity();return a*a},c.createStub=function(a){var c=new b({idealPos:this.idealPos,currentPos:this.currentPos,width:a,data:this.data});return c.child=this,this.parent=c,c},c.isStub=function(){return!!this.child},c.getPathToRoot=function(){for(var a=[],b=this;b;)a.push(b),b=b.parent;return a},c.getPathFromRoot=function(){return this.getPathToRoot().reverse()},c.getRoot=function(){for(var a=this,b=this;b;)a=b,b=b.parent;return a},c.getLevel=function(){for(var a=0,b=this.parent;b;)b=b.parent,a++;return a},c.clone=function(){return new b({idealPos:this.idealPos,currentPos:this.currentPos,width:this.width,data:this.data})},c.isBumping=function(a,b){var c=this.force||0,d=a.force||0;return this.overlapWithNode(a,b)&&(c*d>0||0===c&&0>d||c>0&&0===d||c>0&&0>d)},b}(d);var f;f=function(){var a=function(a){this.nodes=a||[],this.force=0},b=a.prototype;return b.push=function(a){return this.nodes.push(a),this},b.merge=function(b){var c=new a(this.nodes.concat(b.nodes));return c.force=this.force+b.force,c},b.overlapWithGroup=function(a,b){return this.nodes.length>0&&a.nodes.length>0&&this.nodes[this.nodes.length-1].overlapWithNode(a.nodes[0],b)},b.totalForce=function(){return this.nodes.map(function(a){return a.force}).reduce(function(a,b){return a+b},0)},b.assignForceToChildren=function(){var a=this;this.nodes.forEach(function(b){b.force=a.force})},b.isBumping=function(a,b){var c=this.force||0,d=a.force||0;return this.overlapWithGroup(a,b)&&(c*d>0||0===c&&0>d||c>0&&0===d||c>0&&0>d)},a.groupAdjacentNodes=function(b,c){if(b&&b.length>0){for(var d=new a([b[0]]),e=[d],f=1;f<b.length;f++){var g=b[f],h=b[f-1];c(h,g)?d.push(g):(d=new a([g]),e.push(d))}return e}return[]},a.mergeAdjacentGroups=function(a,b){if(a&&a.length>0){for(var c=[],d=a[0],e=1;e<a.length;e++){var f=a[e],g=a[e-1];b(g,f)?d=d.merge(f):(c.push(d),d=f)}return c.push(d),c}return a},a}();var g;g=function(){function a(a){this.springK=a}return a.prototype.computeForce=function(a){return this.springK*a},a}();var h;h=function(a,b,c){var d={damping:.1,epsilon:.003,timestep:1,nodeSpacing:3,minPos:0,maxPos:null,pullForce:new b(1),roundsPerTick:100},e=function(b){function e(a,c){return a.isBumping(c,b.nodeSpacing)}var f={},g=[],h=c.dispatch("start","tick","end"),i=!1,j=0;return b=c.extend({},d,b),f.nodes=function(a){return arguments.length?(g=a,f):g},f.options=function(a){return arguments.length?(b=c.extend(b,a),f):b},f.pushRightToIdealPositions=function(){for(var a=g.length-1;a>=0;a--){var c=g[a];if(c.currentPos<c.idealPos){var d=a===g.length-1?null:g[a+1];if(!d||c.idealRight()<d.currentLeft())c.moveToIdealPosition();else{var e=c.positionBefore(d,b.nodeSpacing);Math.abs(c.idealPos-e)<Math.abs(c.displacement())&&(c.currentPos=e)}}}return f},f.pushLeftToIdealPositions=function(){for(var a=0;a<g.length;a++){var c=g[a];if(c.currentPos>c.idealPos){var d=0===a?null:g[a-1];if(!d||c.idealLeft()>d.currentRight())c.moveToIdealPosition();else{var e=c.positionAfter(d,b.nodeSpacing);Math.abs(c.idealPos-e)<Math.abs(c.displacement())&&(c.currentPos=e)}}}return f},f.pushToIdealPositions=function(a){return a?f.pushRightToIdealPositions().pushLeftToIdealPositions():f.pushLeftToIdealPositions().pushRightToIdealPositions()},f.initialize=function(){if(i)throw"This function cannot be called while the simulator is running. Stop it first.";return g.filter(function(a){return!!a.parent}).forEach(function(a){a.idealPos=a.parent.currentPos}),g.sort(function(a,b){return a.idealPos-b.idealPos}).forEach(function(a,c){a.currentPos=0===c?a.halfWidth():a.positionAfter(g[c-1],b.nodeSpacing),a.previousPos=a.currentPos}),f},f.step=function(){g.forEach(function(a){a.force=b.pullForce.computeForce(a.displacement())});var d=a.groupAdjacentNodes(g,e);for(d.forEach(function(a){if(a.force=a.totalForce(),a.force<0&&c.isDefined(b.minPos)){var d=a.nodes[0].currentLeft()-b.minPos;0===d?a.force=0:0>d&&(a.force=b.pullForce.computeForce(-d))}});d.length>1;){var h=a.mergeAdjacentGroups(d,e);if(h.length===d.length)break;d=h}d.forEach(function(a){a.assignForceToChildren()});for(var i=g.length-1;i>=0;i--){var j=g[i],k=j.currentPos+j.force*b.damping*b.timestep*b.timestep;if(c.isDefined(b.minPos)&&(k=Math.max(b.minPos+j.halfWidth(),k)),c.isDefined(b.maxPos)&&(k=Math.min(b.maxPos-j.halfWidth(),k)),i>0){var l=g[i-1];k=Math.max(j.positionAfter(l,b.nodeSpacing-1),k)}if(i<g.length-1){var m=g[i+1];k=Math.min(j.positionBefore(m,b.nodeSpacing-1),k)}j.previousPos=j.currentPos,j.currentPos=k}return f},f.start=function(a){if(i)throw"This function cannot be called while the simulator is running. Stop it first.";return f.initialize().resume(a)},f.increaseMaxRound=function(a){a?j+=a:j=0},f.resume=function(a){if(f.increaseMaxRound(a),!i){i=!0,h.start({type:"start"});var c=0,d=function(){return i?c>0&&f.isStable()?"simulation stable, energy: "+f.energy():j&&c>=j?"maximum number of rounds reached: "+j:(f.step(),c++,!1):"stopped"},e=function(){for(var a=0;a<b.roundsPerTick;a++){var f=d();if(f)return h.end({type:"end",round:c,maxRound:j,reason:f}),i=!1,void(j=0)}h.tick({type:"tick",round:c,maxRound:j}),setTimeout(e,0)};e()}return f},f.stop=function(){return i=!1,f},f.energy=function(){return c.sum(g,function(a){return a.kineticEnergy()})},f.isStable=function(){return f.energy()<b.epsilon},f.reset=f.initialize,c.rebind(f,h,"on"),f};return e.DEFAULT_OPTIONS=d,e}(f,g,d);var i;!function(a,b){i=function(){return"function"==typeof b?b():b}()}(this,function(){var a=function b(){var a=null,c={},d=arguments;["0","1"].forEach(function(b){var e=d[b];Array.isArray(e)?a=e:e&&"object"==typeof e&&(c=e)}),"function"==typeof c.filter&&(this._filter=c.filter),"function"==typeof c.compare?this._compare=c.compare:"string"==typeof c.compare&&b.compares[c.compare]&&(this._compare=b.compares[c.compare]),this._unique=!!c.unique,c.resume&&a?a.forEach(function(a,b){this.push(a)},this):a&&this.insert.apply(this,a)};return a.create=function(b,c){return new a(b,c)},a.prototype=new Array,a.prototype.constructor=Array.prototype.constructor,a.prototype.insertOne=function(a){var b=this.bsearch(a);return this._unique&&null!=this.key(a,b)?!1:this._filter(a,b)?(this.splice(b+1,0,a),b+1):!1},a.prototype.insert=function(){return Array.prototype.map.call(arguments,function(a){return this.insertOne(a)},this)},a.prototype.remove=function(a){return this.splice(a,1),this},a.prototype.bsearch=function(a){if(!this.length)return-1;for(var b,c=0,d=this.length;d-c>1;){b=Math.floor((c+d)/2),mval=this[b];var e=this._compare(a,mval);if(0==e)return b;e>0?c=b:d=b}return 0==c&&this._compare(this[0],a)>0?-1:c},a.prototype.key=function(a,b){null==b&&(b=this.bsearch(a));var c=b;if(-1==c||this._compare(this[c],a)<0)return c+1<this.length&&0==this._compare(this[c+1],a)?c+1:null;for(;c>=1&&0==this._compare(this[c-1],a);)c--;return c},a.prototype.keys=function(a,b){var c=[];null==b&&(b=this.bsearch(a));for(var d=b;d>=0&&0==this._compare(this[d],a);)c.push(d),d--;var e=this.length;for(d=b+1;e>d&&0==this._compare(this[d],a);)c.push(d),d++;return c.length?c:null},a.prototype.unique=function(a){if(a)return this.filter(function(a,b){return 0==b||0!=this._compare(this[b-1],a)},this);var b=0;return this.map(function(a,c){return 0==c||0!=this._compare(this[c-1],a)?null:c-b++},this).forEach(function(a){null!=a&&this.remove(a)},this),this},a.prototype.toArray=function(){return this.slice()},a.prototype._filter=function(a,b){return!0},a.compares={number:function(a,b){var c=a-b;return c>0?1:0==c?0:-1},string:function(a,b){return a>b?1:a==b?0:-1}},a.prototype._compare=a.compares.string,a});var j;j=function(a){function b(b,c){if(c||(c={}),this.startKey=c.startKey||0,this.endKey=c.endKey||1,this.intervalHash={},this.pointTree=new a({compare:function(a,b){if(null==a)return-1;if(null==b)return 1;var c=a[0]-b[0];return c>0?1:0==c?0:-1}}),this._autoIncrement=0,!b||"number"!=typeof b)throw new Error("you must specify center index as the 2nd argument.");this.root=new f(b,this)}function c(a,b){return b.end<a.idx?(a.left||(a.left=new f(b.start+b.end>>1,this)),c.call(this,a.left,b)):a.idx<b.start?(a.right||(a.right=new f(b.start+b.end>>1,this)),c.call(this,a.right,b)):a.insert(b)}function d(a,b,c){return a?b<a.idx?(a.starts.every(function(a){var d=a.start<=b;return d&&c.push(a.result()),d}),d.call(this,a.left,b,c)):b>a.idx?(a.ends.every(function(a){var d=a.end>=b;return d&&c.push(a.result()),d}),d.call(this,a.right,b,c)):void a.starts.map(function(a){c.push(a.result())}):void 0}function e(a,b,c){if(0>=b-a)throw new Error("end must be greater than start. start: "+a+", end: "+b);var e={},f=[];d.call(this,this.root,a+b>>1,f,!0),f.forEach(function(a){e[a.id]=!0});for(var g=this.pointTree.bsearch([a,null]),h=this.pointTree;g>=0&&h[g][0]==a;)g--;var i=this.pointTree.bsearch([b,null]);if(i>=0){for(var j=h.length-1;j>=i&&h[i][0]<=b;)i++;h.slice(g+1,i).forEach(function(a){var b=a[1];e[b]=!0},this),Object.keys(e).forEach(function(d){var e=this.intervalHash[d];c.push(e.result(a,b))},this)}}function f(b){this.idx=b,this.starts=new a({compare:function(a,b){if(null==a)return-1;if(null==b)return 1;var c=a.start-b.start;return c>0?1:0==c?0:-1}}),this.ends=new a({compare:function(a,b){if(null==a)return-1;if(null==b)return 1;var c=a.end-b.end;return 0>c?1:0==c?0:-1}})}function g(a,b,c,d){if(this.id=b,this.start=a[c],this.end=a[d],this.data=a,"number"!=typeof this.start||"number"!=typeof this.end)throw new Error("start, end must be number. start: "+this.start+", end: "+this.end);if(this.start>=this.end)throw new Error("start must be smaller than end. start: "+this.start+", end: "+this.end)}return b.prototype.add=function(a,b){if(this.intervalHash[b])throw new Error("id "+b+" is already registered.");if(void 0==b){for(;this.intervalHash[this._autoIncrement];)this._autoIncrement++;b=this._autoIncrement}var d=new g(a,b,this.startKey,this.endKey);this.pointTree.insert([d.start,b]),this.pointTree.insert([d.end,b]),this.intervalHash[b]=d,this._autoIncrement++,c.call(this,this.root,d)},b.prototype.search=function(a,b){var c=[];if("number"!=typeof a)throw new Error(a+": invalid input");if(void 0==b)d.call(this,this.root,a,c);else{if("number"!=typeof b)throw new Error(a+","+b+": invalid input");e.call(this,a,b,c)}return c},b.prototype.remove=function(a){},f.prototype.insert=function(a){this.starts.insert(a),this.ends.insert(a)},g.prototype.result=function(a,b){var c={id:this.id,data:this.data};if("number"==typeof a&&"number"==typeof b){var d=Math.max(this.start,a),e=Math.min(this.end,b),f=e-d;c.rate1=f/(b-a),c.rate2=f/(this.end-this.start)}return c},b}(i);var k;k=function(a,b){var c={algorithm:"overlap",layerWidth:1e3,density:.75,nodeSpacing:3,stubWidth:1},d=function(d){var e={};d=a.extend({},c,d),e.options=function(b){return arguments.length?(d=a.extend(d,b),e):d},e.computeRequiredWidth=function(b){return a.sum(b,function(a){return a.width+d.nodeSpacing})-d.nodeSpacing},e.maxWidthPerLayer=function(){return d.density*d.layerWidth},e.needToSplit=function(a){return e.estimateRequiredLayers(a)>1},e.estimateRequiredLayers=function(a){return d.layerWidth?Math.ceil(e.computeRequiredWidth(a)/e.maxWidthPerLayer()):1};var f={simple:function(a){for(var b=e.estimateRequiredLayers(a),c=[],f=0;b>f;f++)c.push([]);return a.forEach(function(a,e){var f=e%b;c[f].push(a);for(var g=a,h=f-1;h>=0;h--)g=g.createStub(d.stubWidth),c[h].push(g)}),c},roundRobin:function(a){var b=[];return b},overlap:function(a){for(var b=[],c=e.maxWidthPerLayer(),f=a.concat(),g=e.computeRequiredWidth(f);g>c;){e.countIdealOverlaps(f);var h=f.concat(),i=g;for(f=[];h.length>2&&i>c;){h.sort(function(a,b){return b.overlapCount-a.overlapCount});var j=h.shift();i-=j.width,i+=d.stubWidth,j.overlaps.forEach(function(a){a.overlapCount--}),f.push(j)}b.push(h),g=e.computeRequiredWidth(f)}f.length>0&&b.push(f);for(var k=b.length-1;k>=1;k--)for(var l=b[k],m=0;m<l.length;m++){var n=l[m];if(!n.isStub())for(var o=n,p=k-1;p>=0;p--)o=o.createStub(d.stubWidth),b[p].push(o)}return b}};return e.countIdealOverlaps=function(a){var c=new b(d.layerWidth/2);return a.forEach(function(a){c.add([a.idealLeft(),a.idealRight(),a])}),a.forEach(function(a){var b=c.search(a.idealLeft(),a.idealRight());a.overlaps=b,a.overlapCount=b.length}),a},e.distribute=function(a){if(!a||0===a.length)return[];if(a=a.concat().sort(function(a,b){return a.idealPos-b.idealPos}),!e.needToSplit(a))return[a];if("function"==typeof d.algorithm)return d.algorithm(a,d);if("none"==d.algorithm)return a;if(f.hasOwnProperty(d.algorithm))return f[d.algorithm](a);throw"Unknown algorithm: "+d.algorithm},e};return d.DEFAULT_OPTIONS=c,d}(d,j);var l;l=function(a){var b=function(){function b(a){return 0===a.length||Array.isArray(a[0])?a:[a]}var c={};return c.displacement=function(c){if(0===c.length)return 0;var d=b(c);return a.sum(d,function(b){return a.sum(b,function(a){return Math.abs(a.displacement())})})},c.overflow=function(c,d,e){if(0===c.length||!a.isDefined(d)&&!a.isDefined(e))return 0;var f=b(c);return a.sum(f,function(b){return a.sum(b,function(b){var c=b.currentLeft(),f=b.currentRight();if(a.isDefined(d)){if(d>=f)return b.width;if(d>c)return d-c}if(a.isDefined(e)){if(c>=e)return b.width;if(f>e)return f-e}return 0})})},c.overDensity=function(c,d,e,f){if(0===c.length)return 0;var g=d*e,h=b(c);return a.sum(h,function(b){var c=a.sum(b,function(a){return a.width+f})-f;return g>=c?0:c-g})},c.overlapCount=function(c,d){if(0===c.length)return 0;var e=b(c);return a.sum(e,function(a){for(var b=0,c=0;c<a.length;c++)for(var e=c+1;e<a.length;e++)a[c].overlapWithNode(a[e],d)&&b++;return b})},c.overlapSpace=function(c){if(0===c.length)return 0;var d=b(c);return a.sum(d,function(a){for(var b=0,c=0;c<a.length;c++)for(var d=c+1;d<a.length;d++){var e=a[c].distanceFrom(a[d]);b+=0>e?Math.abs(e):0}return b})},c.weightedAllocatedSpace=function(c){if(0===c.length)return 0;var d=b(c);return a.sum(d,function(b,c){return c*a.sum(b,function(a){return a.width})})},c}();return b}(d);var m;m=function(a,b,c,d,e){var f={damping:.1,epsilon:.003,timestep:1,nodeSpacing:3,minPos:0,maxPos:null,pullForce:new e(1),roundsPerTick:100,algorithm:"overlap",density:.85,stubWidth:1},g=function(e){var g={},h=d.dispatch("start","tick","endLayer","end"),i=d.extend({},f),j=new b,k=[],l=[],m=null,n=!1;return g.nodes=function(a){return arguments.length?(l=a,m=null,k=[],g):l},g.getLayers=function(){return m},g.options=function(c){if(!arguments.length)return i;i=d.extend(i,c);var e=d.extractKeys(i,Object.keys(b.DEFAULT_OPTIONS));d.isDefined(i.minPos)&&d.isDefined(i.maxPos)?e.layerWidth=i.maxPos-i.minPos:e.layerWidth=null,j.options(e);var f=d.extractKeys(i,Object.keys(a.DEFAULT_OPTIONS));return k.forEach(function(a){a.options(f)}),g},g.options(e),g.distribute=function(){if(n)throw"This function cannot be called while the simulator is running. Stop it first.";m=j.distribute(l);var b=d.extractKeys(i,Object.keys(a.DEFAULT_OPTIONS));return k=m.map(function(c){return new a(b).nodes(c)}),g},g.initialize=function(){if(n)throw"This function cannot be called while the simulator is running. Stop it first.";return k.forEach(function(a){a.initialize()}),g},g.step=function(){return k.forEach(function(a){a.step()}),g},g.stop=function(){return k.forEach(function(a){a.stop()}),g},g.start=function(a){if(n)throw"This function cannot be called while the simulator is running. Stop it first.";return setTimeout(function(){m||g.distribute(),g.initialize().resume(a)},0),g},g.resume=function(a){if(0===m.length)return g;if(!n){var b=0;h.start({type:"start"});var c=function(){var e=k[b];e&&(e.on("tick",function(a){h.tick(d.extend({},a,{layerIndex:b}))}),e.on("end",function(a){h.endLayer(d.extend({},a,{type:"endLayer",layerIndex:b})),b++,b<m.length?c():(h.end({type:"end"}),n=!1)}),b>0?e.start(a):e.resume(a))};c()}return g},g.energy=function(){return d.sum(k,function(a){return a.energy()})},g.isStable=function(){return k.every(function(a){return a.isStable()})},g.reset=g.initialize,g.metrics=function(){return Object.keys(c).map(function(a){return{name:a,value:g.metric(a)}})},g.metric=function(a){switch(a){case"overflow":return c[a](m,i.minPos,i.maxPos);case"overDensity":return c[a](m,i.density,i.layerWidth,i.nodeSpacing-1);case"overlapCount":return c[a](m,i.nodeSpacing-1);default:return c[a]?c[a](m):null}},d.rebind(g,h,"on"),g};return g.DEFAULT_OPTIONS=f,g}(h,k,l,d,g);var n;n=function(a){function b(b){this.options=a.extend({layerGap:60,nodeHeight:10,direction:"down"},b)}function c(a){return"L "+a.join(" ")}function d(a){return"M "+a.join(" ")}function e(a,b,c){return"C "+a.join(" ")+" "+b.join(" ")+" "+c.join(" ")}function f(a,b){var c=(a[1]+b[1])/2;return e([a[0],c],[b[0],c],b)}function g(a,b){var c=(a[0]+b[0])/2;return e([c,a[1]],[c,b[1]],b)}return b.prototype.getWaypoints=function(a){var b=this.options,c=b.direction,d=a.getPathFromRoot(),e=b.nodeHeight+b.layerGap;return"left"===c?[[[0,d[0].idealPos]]].concat(d.map(function(a,c){var d=e*(c+1)*-1;return[[d+b.nodeHeight,a.currentPos],[d,a.currentPos]]})):"right"===c?[[[0,d[0].idealPos]]].concat(d.map(function(a,c){var d=e*(c+1);return[[d-b.nodeHeight,a.currentPos],[d,a.currentPos]]})):"up"===c?[[[d[0].idealPos,0]]].concat(d.map(function(a,c){var d=e*(c+1)*-1;return[[a.currentPos,d+b.nodeHeight],[a.currentPos,d]]})):[[[d[0].idealPos,0]]].concat(d.map(function(a,c){var d=e*(c+1);return[[a.currentPos,d-b.nodeHeight],[a.currentPos,d]]}))},b.prototype.layout=function(a){var b=this.options,c=b.layerGap+b.nodeHeight;switch(b.direction){case"left":a.forEach(function(a){var d=a.getLevel()*c+b.layerGap;a.x=-d-b.nodeHeight,a.y=a.currentPos,a.dx=b.nodeHeight,a.dy=a.width});break;case"right":a.forEach(function(a){var d=a.getLevel()*c+b.layerGap;a.x=d,a.y=a.currentPos,a.dx=b.nodeHeight,a.dy=a.width});break;case"up":a.forEach(function(a){var d=a.getLevel()*c+b.layerGap;a.x=a.currentPos,a.y=-d-b.nodeHeight,a.dx=a.width,a.dy=b.nodeHeight});break;default:case"down":a.forEach(function(a){var d=a.getLevel()*c+b.layerGap;a.x=a.currentPos,a.y=d,a.dx=a.width,a.dy=b.nodeHeight})}return a},b.prototype.generatePath=function(a){var b=this.options,e=b.direction,h=this.getWaypoints(a,e),i=[d(h[0][0])];return"left"===e||"right"===e?h.reduce(function(a,b,d){return i.push(g(a[a.length-1],b[0])),d<h.length-1&&i.push(c(b[1])),b}):h.reduce(function(a,b,d){return i.push(f(a[a.length-1],b[0])),d<h.length-1&&i.push(c(b[1])),b}),i.join(" ")},b}(d);var o;o=function(a,b){var c=function(){var c={},d={minWidth:20,maxWidth:20,minPos:0,maxPos:800};return c.generateNodes=function(c,e){var f=[];e=a.extend({},d,e);for(var g=e.maxPos-e.minPos,h=e.maxWidth-e.minWidth,i=0;c>i;i++)f.push(new b(Math.floor(Math.random()*g)+e.minPos,Math.floor(Math.random()*h)+e.minWidth));return f},c.convertNodesToGraph=function(a){yGap=60;var b={nodes:[],links:[],constraints:[]},c={type:"alignment",axis:"y",offsets:[]};return b.constraints.push(c),b.nodes.push({index:0,x:1,y:yGap,width:1,height:1,fixed:!0}),b.nodes.push({index:0,x:925,y:yGap,width:1,height:1,fixed:!0}),a.forEach(function(a){var d={index:b.nodes.length,x:a.idealPos,y:0,width:1,height:1,fixed:!0};b.nodes.push(d);var e={index:b.nodes.length,x:a.currentPos,y:yGap,width:a.width,height:12,originalNode:a};c.offsets.push({node:e.index,offset:0}),b.nodes.push(e),b.links.push({source:d.index,target:e.index}),b.constraints.push({axis:"y",left:d.index,right:e.index,gap:yGap,equality:!0}),b.constraints.push({axis:"x",left:0,right:e.index,gap:0}),b.constraints.push({axis:"x",left:e.index,right:1,gap:0})}),b},c.updateNodesInGraph=function(a){return graph.nodes.filter(function(a){return a.originalNode}).map(function(a){return a.originalNode.currentPos=a.x,a.originalNode})},c}();return c}(d,e);var p;return p=function(a,b,c,d,e,f,g,h){return{Node:a,NodeGroup:b,Force:c,Simulator:d,Distributor:e,Renderer:f,metrics:g,util:h}}(e,f,m,h,k,n,l,o)});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment