-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanimatedLTT.html
220 lines (192 loc) · 10.8 KB
/
animatedLTT.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Animated Lineage Through Time (LTT) Plots</title>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="https://jembrown.github.io/phyleaux.js"></script>
<style type="text/css">
@font-face { font-family: Glober; font-weight: semibold; src: url('../Glober-SemiBold.otf'); }
.axis text {
font-family: Glober;
font-size: 14px;
}
h1 {
font-family: Glober;
font-size: 24px;
}
p,form {
font-family: Glober;
font-size: 14px;
}
</style>
</head>
<body>
<h1>
Click tree to start the animated lineage-through-time (LTT) plot
</h1>
<section id="controls">
<form id="userForm">
Tree: <input type="text" id="userTree" size=100>
</form>
<br>
<button id="readTree"
style="display: inline-block; text-align: right">Read Tree
</button>
<br><br>
<label for="animSpeed"
style="display: inline-block; width: 115px; text-align: right">
Animation Time: <span id="animSpeed-value"></span>
</label>
<input type="range" min="1000" max="10000" id="animSpeed">
<br><br>
<button id="reset"
style="display: inline-block; text-align: right">Reset
</button>
<br><br>
<label for="height"
style="display: inline-block; width: 90px; text-align: right">
Plot Heights: <span id="height-value"></span>
</label>
<input type="range" min="300" max="600" id="height">
<br><br>
<button id="redraw"
style="display: inline-block; text-align: right">Redraw
</button>
</section>
<section id="visualization">
<script type="text/javascript">
// Initializing animation time and plot heights
var inputTime = 4000;
var newHeight = 350;
// Initializing height and tree variables
d3.select("#height").property("value",350);
d3.select("#userTree").property("value","((((((((((((((((((((((Fagus:95.1,Carya:95.1):7.589938,Cucumis:102.68994):0.991322,Morus:103.68126):0.643278,Pisum:104.32454):2.032216,((Parnassia:98.750046,Oxalis:98.750046):1.712544,Populus:100.462585):5.894165):0.00128,Bulnesia:106.35803):2.41062,((((((Gossypium:84.47311,Cleome:84.47311):11.118127,Tapiscia:95.59123):2.779864,Acer:98.37109):7.760231,Picramnia:106.131325):1.199301,Crossosoma:107.33063):0.862363,((Terminalia:87.3,Eucalyptus:87.3):17.705576,Pelargonium:105.00558):3.187415):0.575665):4.381711,(((Itea:50.703365,Pterostemon:50.703365):43.54422,Liquidambar:94.24759):17.264275,Vitis:111.51186):1.638504):0.809405,Dillenia:113.95977):0.649031,((((((((((((Paracryphia:52.490395,Lonicera:52.490395):3.74022,Daucus:56.230614):0.317339,Brunia:56.547955):0.438631,Escallonia:56.986588):24.54444,Helianthus:81.53103):6.114358,(Ilex:66.5,Helwingia:66.5):21.145384):4.077858,(((Antirrhinum:60.68952,Nicotiana:60.68952):2.351834,Nerium:63.041355):20.26629,Aucuba:83.30765):8.415594):5.050216,Enkianthus:96.77345):1.506261,(Cornus:87.3,Grubbia:87.3):10.979717):7.807598,Spinacia:106.08732):6.533299,Berberidopsis:112.62061):1.110552,Ximenia:113.73116):0.877635):1.110502,Gunnera:115.7193):6.201286,Pachysandra:121.92059):0.89091,Trochodendron:122.8115):1.818607,((Platanus:107.3,Nelumbo:107.3):16.168238,Meliosma:123.46824):1.161869):1.869893,(((Coptis:100.372314,Cocculus:100.372314):19.248432,Papaver:119.62075):1.61306,Euptelea:121.23381):5.26619):4.856025,Ceratophyllum:131.35602):1.517098,((((((((((Typha:61.068348,Sparganium:61.068348):24.390734,Oryza:85.45908):15.234818,(Musa:90.70971,Eichhornia:90.70971):9.984187):1.595022,(Serenoa:87.0,Calamus:87.0):15.288921):3.789045,Apostasia:106.077965):2.237676,Lilium:108.31564):1.637316,(Pandanus:107.51273,Dioscorea:107.51273):2.440223):5.187115,Japonolirion:115.140076):8.556882,(Spathiphyllum:113.5,Orontium:113.5):10.196955):3.339147,Acorus:127.0361):5.837022):0.164182,((((((Saururus:75.527534,Piper:75.527534):45.92045,Asarum:121.44798):8.940091,(Drimys:126.5,Canella:126.5):3.888077):1.096029,(((Hedycarya:101.1,Persea:101.1):2.339544,Atherosperma:103.439545):3.860456,Calycanthus:107.3):24.184107):0.185027,((Magnolia:87.721115,Liriodendron:87.721115):27.778889,Eupomatia:115.5):16.169132):1.098512,((Chloranthus:115.55476,Ascarina:115.55476):7.468146,Hedyosmum:123.0229):9.744738):0.26966):2.669566,(((Illicium:106.80325,Schisandra:106.80325):19.696749,Trimenia:126.5):4.163047,Austrobaileya:130.66304):5.043825):2.395419,(((Nuphar:86.827286,Nymphaea:86.827286):8.061111,Brasenia:94.88839):31.611607,Trithuria:126.5):11.60229):1.89771,Amborella:140.0):177.16982,(((((((((Juniperus:28.909595,Cupressus:28.909595):76.431274,Cryptomeria:105.34087):15.171681,Sequoia:120.51255):77.98745,(Taxus:180.22873,Torreya:180.22873):18.271276):40.048042,((Podocarpus:94.51272,Phyllocladus:94.51272):119.98728,Araucaria:214.5):24.04804):25.673899,(((Picea:78.557785,Pinus:78.557785):22.871145,Abies:101.428925):7.969642,Cedrus:109.39857):154.82336):11.159094,((Gnetum:115.5,Welwitschia:115.5):38.984795,Ephedra:154.4848):120.89624):17.5573,Ginkgo:292.93832):8.061667,((Zamia:172.42001,Encephalartos:172.42001):75.73096,Cycas:248.15097):52.84903):16.169813);")
// Tree taken from Beaulieu et al. (2015) Heterogeneous rates of molecular evolution and diversification could explain the Triassic age estimate for angiosperms. Systematic Biology
// https://academic.oup.com/sysbio/article/64/5/869/1685167
// Initializing these variables here, so they are accessible throughout page,
// in order to add listeners and adjust attributes from outside pageReset()
// function.
var myTree = null;
var myAnimatedLine = null;
var myLTT = null;
// This function will be called to recreate graphics, associated event listeners
// and credit text.
var pageReset = function(){
// Initializes tree with current value associated with input box.
myTree = new Tree(d3.select("#userTree").property("value"));
// Creates initial Animated Line object, which consists of a phylogram
// plus an animation line.
myAnimatedLine = new AnimatedLineOverTree(myTree,
w=1000,
h=newHeight,
scale=0.8,
padding=50,
lwd=2,
color="orange",
moveTime=inputTime,
tipLabels=false);
myLTT = new AnimatedLTT(myTree,
w=1000,
h=newHeight,
scale=0.8,
padding=50,
lwd=4,
color="orange",
plotTime=inputTime);
// This event listener is here, rather than in the Animated Line constructor,
// because I can't figure out how to reference variables in that Animated Line
// instance to pass to the function attached to the event listener. "this" doesn't
// work in that context. By placing the event listener after the object instantiation
// these variables can be passed directly.
d3.select("#phylosvg")
.on("click",function(){
moveLine(myAnimatedLine.lineX,
myAnimatedLine.svg,
myAnimatedLine.finalX,
myAnimatedLine.moveTime);
// Activates LTT animation
for (var i = 1; i < myLTT.nodeXvals.length; i++){ // Iterates through unique x coordinates
window.setTimeout(drawLTTLines, // Name of function to call
myLTT.plotTime * myLTT.nodeXvals[i], // Delay time
myLTT.nodeXvals[i-1],myLTT.nodeXvals[i], // Function arguments
myLTT.lineageCounts[i-1],myLTT.lineageCounts[i],
myLTT.svg,
myLTT.xScale,
myLTT.yScale,
myLTT.color);
}
});
var credits = d3.select("body").append("section").attr("id","pageCredits");
// For some reason, d3 did not like when I used the id "credits" for this section.
var pCredits = d3.select("#pageCredits").append("p")
// Creating page credits section from inside javascript
// This is almost certainly not the best way to do this, but it works (for now).
for (var b = 0; b < 3; b++){ pCredits.append("br"); }
pCredits.append("img")
.attr("src","https://raw.githubusercontent.com/jembrown/websiteImages/master/ssb.png")
.attr("width",100)
.attr("height",100)
for (var b = 0; b < 2; b++){ pCredits.append("br"); }
pCredits.append("text")
.text("Development of the Phyleaux Javascript Library and related interactive phylogenetics tools is supported by the Society of Systematic Biologists.")
for (var b = 0; b < 2; b++){ pCredits.append("br"); }
pCredits.append("text")
.text("Comments and bug reports should be directed to [email protected].")
for (var b = 0; b < 2; b++){ pCredits.append("br"); }
pCredits.append("text")
.text("Example tree taken from Beaulieu JM, O'Meara BC, Crane P, and Donoghue MJ. 2015. Heterogeneous rates of molecular evolution and diversification could explain the Triassic age estimate for angiosperms.")
pCredits.append("i")
.text(" Systematic Biology")
pCredits.append("text")
.text(" 64:869-878")
}
// Calls this function on initial page load to create first version of all graphics and text
pageReset();
// The ".line" portion of the name adds a namespace to the event listener so that
// other event listeners (e.g., for the LTT plot can also be added to the same svg).
d3.select("#animSpeed")
.on("input",function(){
myAnimatedLine.moveTime = this.value;
myLTT.plotTime = this.value;
})
d3.select("#animSpeed").property("value",4000);
d3.select("#reset")
.on("click",function(){ // Sets actions for "Reset" button.
d3.select("#LTTsvg")
.selectAll("line")
.remove();
d3.select("#progressLine")
.attr("x1",myAnimatedLine.padding)
.attr("x2",myAnimatedLine.padding);
})
d3.select("#height")
.on("input",function(){
newHeight = this.value;
})
d3.select("#redraw")
.on("click",function(){
d3.select("body").select("#phylosvg").remove();
d3.select("body").select("#LTTsvg").remove();
d3.select("body").select("#pageCredits").remove();
pageReset();
})
var form = document.getElementById("userForm");
form.addEventListener("submit",function(event){
event.preventDefault();
d3.select("body").select("#phylosvg").remove();
d3.select("body").select("#LTTsvg").remove();
d3.select("body").select("#pageCredits").remove();
pageReset();
})
d3.select("#readTree") // When this button is clicked, everything on page after creation of myTree reexecutes.
.on("click",function(){
d3.select("body").select("#phylosvg").remove();
d3.select("body").select("#LTTsvg").remove();
d3.select("body").select("#pageCredits").remove();
pageReset();
});
</script>
</section>
</body>
</html>