UNPKG

cacatoo

Version:

Building, exploring, and sharing spatially structured models

255 lines 591 kB
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"> <style> .KEYW {color: #933;} .COMM {color: #bbb; font-style: italic;} .NUMB {color: #393;} .STRN {color: #393;} .REGX {color: #339;} .line {border-right: 1px dotted #666; color: #666; font-style: normal;} </style></head><body><pre><span class='line'> 1</span> <span class="STRN">'use strict'</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 2</span> <span class='line'> 3</span> </span><span class="COMM">/** <span class='line'> 4</span> * Gridpoint is what Gridmodels are made of. Contains everything that may happen in 1 locality. <span class='line'> 5</span> */</span><span class="WHIT"> <span class='line'> 6</span> <span class='line'> 7</span> </span><span class="NAME">class</span><span class="WHIT"> </span><span class="NAME">Gridpoint</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 8</span> </span><span class="WHIT"> </span><span class="COMM">/** <span class='line'> 9</span> * The constructor function for a @Gridpoint object. Takes an optional template to copy primitives from. (NOTE!! Other types of objects are NOT deep copied by default) <span class='line'> 10</span> * If you need synchronous updating with complex objects (for whatever reason), replate line 18 with line 19. This will slow things down quite a bit, so ony use this <span class='line'> 11</span> * if you really need it. A better option is to use asynchronous updating so you won't have to worry about this at all :) <span class='line'> 12</span> * @param {Gridpoint} template Optional template to make a new @Gridpoint from <span class='line'> 13</span> */</span><span class="WHIT"> <span class='line'> 14</span> </span><span class="WHIT"> </span><span class="NAME">constructor</span><span class="PUNC">(</span><span class="NAME">template</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 15</span> </span><span class="WHIT"> </span><span class="KEYW">for</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">prop</span><span class="WHIT"> </span><span class="KEYW">in</span><span class="WHIT"> </span><span class="NAME">template</span><span class="PUNC">)</span><span class="WHIT"> <span class='line'> 16</span> </span><span class="WHIT"> </span><span class="KEYW">this</span><span class="PUNC">[</span><span class="NAME">prop</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">template</span><span class="PUNC">[</span><span class="NAME">prop</span><span class="PUNC">]</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="COMM">// Shallow copy. It's fast, but be careful with syncronous updating!</span><span class="WHIT"> <span class='line'> 17</span> </span><span class="WHIT"> </span><span class="COMM">// this[prop] = copy(template[prop]) // Deep copy. Takes much more time, and you'll likely end up copying much more than necessary. Use only if you're sure you need it!</span><span class="WHIT"> <span class='line'> 18</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'> 19</span> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'> 20</span> <span class='line'> 21</span> </span><span class="COMM">/** <span class='line'> 22</span> * Graph is a wrapper-class for a Dygraph element (see https://dygraphs.com/). It is attached to the DOM-windows, and stores all values to be plotted, colours, title, axis names, etc. <span class='line'> 23</span> */</span><span class="WHIT"> <span class='line'> 24</span> <span class='line'> 25</span> </span><span class="NAME">class</span><span class="WHIT"> </span><span class="NAME">Graph</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 26</span> </span><span class="WHIT"> </span><span class="COMM">/** <span class='line'> 27</span> * The constructor function for a @Canvas object. <span class='line'> 28</span> * @param {Array} labels array of strings containing the labels for datapoints (e.g. for the legend) <span class='line'> 29</span> * @param {Array} values Array of floats to plot (here plotted over time) <span class='line'> 30</span> * @param {Array} colours Array of colours to use for plotting <span class='line'> 31</span> * @param {String} title Title of the plot <span class='line'> 32</span> * @param {Object} opts dictionary-style list of opts to pass onto dygraphs <span class='line'> 33</span> */</span><span class="WHIT"> <span class='line'> 34</span> </span><span class="WHIT"> </span><span class="NAME">constructor</span><span class="PUNC">(</span><span class="NAME">labels</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">values</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">colours</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">title</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">opts</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 35</span> <span class='line'> 36</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">typeof</span><span class="WHIT"> </span><span class="NAME">window</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="NAME">undefined</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="KEYW">throw</span><span class="WHIT"> </span><span class="STRN">"Using dygraphs with cashJS only works in browser-mode"</span><span class="WHIT"> <span class='line'> 37</span> </span><span class="WHIT"> </span><span class="NAME">this.labels</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">labels</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 38</span> </span><span class="WHIT"> </span><span class="NAME">this.data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="NAME">values</span><span class="PUNC">]</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 39</span> </span><span class="WHIT"> </span><span class="NAME">this.title</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">title</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 40</span> </span><span class="WHIT"> </span><span class="NAME">this.num_dps</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">this.labels.length</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="COMM">// number of data points for this graphs </span><span class="WHIT"> <span class='line'> 41</span> </span><span class="WHIT"> </span><span class="NAME">this.elem</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">document.createElement</span><span class="PUNC">(</span><span class="STRN">"div"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 42</span> </span><span class="WHIT"> </span><span class="NAME">this.elem.className</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="STRN">"graph-holder"</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 43</span> </span><span class="WHIT"> </span><span class="NAME">this.colours</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="PUNC">]</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 44</span> <span class='line'> 45</span> </span><span class="WHIT"> </span><span class="KEYW">for</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">let</span><span class="WHIT"> </span><span class="NAME">v</span><span class="WHIT"> </span><span class="KEYW">in</span><span class="WHIT"> </span><span class="NAME">colours</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 46</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">v</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="STRN">"Time"</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="KEYW">continue</span><span class="WHIT"> <span class='line'> 47</span> </span><span class="WHIT"> </span><span class="KEYW">else</span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">colours</span><span class="PUNC">[</span><span class="NAME">v</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="NAME">undefined</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="NAME">this.colours.push</span><span class="PUNC">(</span><span class="STRN">"#000000"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 48</span> </span><span class="WHIT"> </span><span class="KEYW">else</span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">colours</span><span class="PUNC">[</span><span class="NAME">v</span><span class="PUNC">]</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">colours</span><span class="PUNC">[</span><span class="NAME">v</span><span class="PUNC">]</span><span class="PUNC">[</span><span class="NUMB">1</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">colours</span><span class="PUNC">[</span><span class="NAME">v</span><span class="PUNC">]</span><span class="PUNC">[</span><span class="NUMB">2</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="NUMB">765</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="NAME">this.colours.push</span><span class="PUNC">(</span><span class="STRN">"#dddddd"</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 49</span> </span><span class="WHIT"> </span><span class="KEYW">else</span><span class="WHIT"> </span><span class="NAME">this.colours.push</span><span class="PUNC">(</span><span class="NAME">rgbToHex</span><span class="PUNC">(</span><span class="NAME">colours</span><span class="PUNC">[</span><span class="NAME">v</span><span class="PUNC">]</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">colours</span><span class="PUNC">[</span><span class="NAME">v</span><span class="PUNC">]</span><span class="PUNC">[</span><span class="NUMB">1</span><span class="PUNC">]</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">colours</span><span class="PUNC">[</span><span class="NAME">v</span><span class="PUNC">]</span><span class="PUNC">[</span><span class="NUMB">2</span><span class="PUNC">]</span><span class="PUNC">)</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 50</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'> 51</span> <span class='line'> 52</span> </span><span class="WHIT"> </span><span class="NAME">document.body.appendChild</span><span class="PUNC">(</span><span class="NAME">this.elem</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 53</span> </span><span class="WHIT"> </span><span class="NAME">document.getElementById</span><span class="PUNC">(</span><span class="STRN">"graph_holder"</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">appendChild</span><span class="PUNC">(</span><span class="NAME">this.elem</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 54</span> </span><span class="WHIT"> </span><span class="NAME">this.g</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Dygraph</span><span class="PUNC">(</span><span class="NAME">this.elem</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">this.data</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 55</span> </span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 56</span> </span><span class="WHIT"> </span><span class="NAME">title</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">this.title</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 57</span> </span><span class="WHIT"> </span><span class="NAME">showRoller</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 58</span> </span><span class="WHIT"> </span><span class="NAME">ylabel</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">this.labels.length</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="NUMB">2</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="NAME">this.labels</span><span class="PUNC">[</span><span class="NUMB">1</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="STRN">""</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 59</span> </span><span class="WHIT"> </span><span class="NAME">width</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NUMB">500</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 60</span> </span><span class="WHIT"> </span><span class="NAME">height</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NUMB">200</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 61</span> </span><span class="WHIT"> </span><span class="NAME">xlabel</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">this.labels</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 62</span> </span><span class="WHIT"> </span><span class="NAME">drawPoints</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">opts</span><span class="WHIT"> </span><span class="PUNC">&&</span><span class="WHIT"> </span><span class="NAME">opts.drawPoints</span><span class="WHIT"> </span><span class="PUNC">||</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 63</span> </span><span class="WHIT"> </span><span class="NAME">pointSize</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">opts</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">opts.pointSize</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="NAME">opts.pointSize</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NUMB">0</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 64</span> </span><span class="WHIT"> </span><span class="NAME">strokePattern</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">opts</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">opts.strokePattern</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="NAME">opts.strokePattern</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="KEYW">null</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="KEYW">null</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 65</span> </span><span class="WHIT"> </span><span class="NAME">dateWindow</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NUMB">100</span><span class="PUNC">]</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 66</span> </span><span class="WHIT"> </span><span class="NAME">axisLabelFontSize</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NUMB">10</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 67</span> </span><span class="WHIT"> </span><span class="NAME">valueRange</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="NUMB">0.000</span><span class="PUNC">,</span><span class="PUNC">]</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 68</span> </span><span class="WHIT"> </span><span class="NAME">strokeWidth</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">opts</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="NAME">opts.strokeWidth</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NUMB">3</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 69</span> </span><span class="WHIT"> </span><span class="NAME">colors</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">this.colours</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'> 70</span> </span><span class="WHIT"> </span><span class="NAME">labels</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">this.labels</span><span class="WHIT"> <span class='line'> 71</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 72</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'> 73</span> <span class='line'> 74</span> <span class='line'> 75</span> </span><span class="WHIT"> </span><span class="COMM">/** Push data to your graph-element <span class='line'> 76</span> * @param {array} array of floats to be added to the dygraph object (stored in 'data') <span class='line'> 77</span> */</span><span class="WHIT"> <span class='line'> 78</span> </span><span class="WHIT"> </span><span class="NAME">push_data</span><span class="PUNC">(</span><span class="NAME">data_array</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 79</span> </span><span class="WHIT"> </span><span class="NAME">this.data.push</span><span class="PUNC">(</span><span class="NAME">data_array</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 80</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'> 81</span> <span class='line'> 82</span> </span><span class="WHIT"> </span><span class="NAME">reset_plot</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 83</span> </span><span class="WHIT"> </span><span class="NAME">this.data</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="NAME">this.data</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">]</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 84</span> </span><span class="WHIT"> </span><span class="NAME">this.g.updateOptions</span><span class="PUNC">(</span><span class="WHIT"> <span class='line'> 85</span> </span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 86</span> </span><span class="WHIT"> </span><span class="STRN">'file'</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="NAME">this.data</span><span class="PUNC">]</span><span class="WHIT"> <span class='line'> 87</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 88</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'> 89</span> <span class='line'> 90</span> </span><span class="WHIT"> </span><span class="COMM">/** <span class='line'> 91</span> * Update the graph axes <span class='line'> 92</span> */</span><span class="WHIT"> <span class='line'> 93</span> </span><span class="WHIT"> </span><span class="NAME">update</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 94</span> </span><span class="WHIT"> </span><span class="NAME">let</span><span class="WHIT"> </span><span class="NAME">max_x</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 95</span> </span><span class="WHIT"> </span><span class="NAME">let</span><span class="WHIT"> </span><span class="NAME">min_x</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">999999999999</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 96</span> </span><span class="WHIT"> </span><span class="KEYW">for</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">let</span><span class="WHIT"> </span><span class="NAME">i</span><span class="WHIT"> </span><span class="NAME">of</span><span class="WHIT"> </span><span class="NAME">this.data</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'> 97</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">i</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">></span><span class="WHIT"> </span><span class="NAME">max_x</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="NAME">max_x</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 98</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">i</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">&lt;</span><span class="WHIT"> </span><span class="NAME">min_x</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="NAME">min_x</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">[</span><span class="NUMB">0</span><span class="PUNC">]</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'> 99</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>100</span> </span><span class="WHIT"> </span><span class="NAME">this.g.updateOptions</span><span class="PUNC">(</span><span class="WHIT"> <span class='line'>101</span> </span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>102</span> </span><span class="WHIT"> </span><span class="STRN">'file'</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">this.data</span><span class="PUNC">,</span><span class="WHIT"> <span class='line'>103</span> </span><span class="WHIT"> </span><span class="NAME">dateWindow</span><span class="PUNC">:</span><span class="WHIT"> </span><span class="PUNC">[</span><span class="NAME">min_x</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">max_x</span><span class="PUNC">]</span><span class="WHIT"> <span class='line'>104</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>105</span> <span class='line'>106</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>107</span> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>108</span> <span class='line'>109</span> </span><span class="COMM">/* <span class='line'>110</span> Functions below are to make sure dygraphs understands the colours used by Cacatoo (converts to hex) <span class='line'>111</span> */</span><span class="WHIT"> <span class='line'>112</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">componentToHex</span><span class="PUNC">(</span><span class="NAME">c</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>113</span> </span><span class="WHIT"> </span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">hex</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">c.toString</span><span class="PUNC">(</span><span class="NUMB">16</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>114</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="WHIT"> </span><span class="NAME">hex.length</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="NUMB">1</span><span class="WHIT"> </span><span class="PUNC">?</span><span class="WHIT"> </span><span class="STRN">"0"</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">hex</span><span class="WHIT"> </span><span class="PUNC">:</span><span class="WHIT"> </span><span class="NAME">hex</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>115</span> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>116</span> <span class='line'>117</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">rgbToHex</span><span class="PUNC">(</span><span class="NAME">r</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">g</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">b</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>118</span> </span><span class="WHIT"> </span><span class="KEYW">return</span><span class="WHIT"> </span><span class="STRN">"#"</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">componentToHex</span><span class="PUNC">(</span><span class="NAME">r</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">componentToHex</span><span class="PUNC">(</span><span class="NAME">g</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">+</span><span class="WHIT"> </span><span class="NAME">componentToHex</span><span class="PUNC">(</span><span class="NAME">b</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>119</span> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>120</span> <span class='line'>121</span> </span><span class="COMM">/** <span class='line'>122</span> * The ODE class is used to call the odex.js library and numerically solve ODEs <span class='line'>123</span> */</span><span class="WHIT"> <span class='line'>124</span> <span class='line'>125</span> </span><span class="NAME">class</span><span class="WHIT"> </span><span class="NAME">ODE</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>126</span> </span><span class="WHIT"> </span><span class="COMM">/** <span class='line'>127</span> * The constructor function for a @ODE object. <span class='line'>128</span> * @param {function} eq Function that describes the ODE (see examples starting with ode) <span class='line'>129</span> * @param {Array} state_vector Initial state vector <span class='line'>130</span> * @param {Array} pars Array of parameters for the ODEs <span class='line'>131</span> * @param {Array} diff_rates Array of rates at which each state diffuses to neighbouring grid point (Has to be less than 0.25!) <span class='line'>132</span> * @param {String} ode_name Name of this ODE <span class='line'>133</span> */</span><span class="WHIT"> <span class='line'>134</span> </span><span class="WHIT"> </span><span class="NAME">constructor</span><span class="PUNC">(</span><span class="NAME">eq</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">state_vector</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">pars</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">diff_rates</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">ode_name</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">acceptable_error</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>135</span> </span><span class="WHIT"> </span><span class="NAME">this.name</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">ode_name</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>136</span> </span><span class="WHIT"> </span><span class="NAME">this.eq</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">eq</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>137</span> </span><span class="WHIT"> </span><span class="NAME">this.state</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">state_vector</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>138</span> </span><span class="WHIT"> </span><span class="NAME">this.diff_rates</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">diff_rates</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>139</span> </span><span class="WHIT"> </span><span class="NAME">this.pars</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">pars</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>140</span> </span><span class="WHIT"> </span><span class="NAME">this.solver</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Solver</span><span class="PUNC">(</span><span class="NAME">state_vector.length</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>141</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">acceptable_error</span><span class="WHIT"> </span><span class="PUNC">!==</span><span class="WHIT"> </span><span class="NAME">undefined</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="NAME">this.solver.absoluteTolerance</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">this.solver.relativeTolerance</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">acceptable_error</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>142</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>143</span> <span class='line'>144</span> </span><span class="WHIT"> </span><span class="COMM">/** <span class='line'>145</span> * Numerically solve the ODE <span class='line'>146</span> * @param {float} delta_t Step size <span class='line'>147</span> * @param {bool} opt_pos When enabled, negative values are set to 0 automatically <span class='line'>148</span> */</span><span class="WHIT"> <span class='line'>149</span> </span><span class="WHIT"> </span><span class="NAME">solveTimestep</span><span class="PUNC">(</span><span class="NAME">delta_t</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0.1</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="NAME">pos</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">false</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>150</span> </span><span class="WHIT"> </span><span class="NAME">let</span><span class="WHIT"> </span><span class="NAME">newstate</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">this.solver.solve</span><span class="PUNC">(</span><span class="WHIT"> <span class='line'>151</span> </span><span class="WHIT"> </span><span class="NAME">this.eq</span><span class="PUNC">(</span><span class="PUNC">.</span><span class="PUNC">.</span><span class="PUNC">.</span><span class="NAME">this.pars</span><span class="PUNC">)</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="COMM">// function to solve and its pars (... unlists the array as a list of args)</span><span class="WHIT"> <span class='line'>152</span> </span><span class="WHIT"> </span><span class="NUMB">0</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="COMM">// Initial x value</span><span class="WHIT"> <span class='line'>153</span> </span><span class="WHIT"> </span><span class="NAME">this.state</span><span class="PUNC">,</span><span class="WHIT"> </span><span class="COMM">// Initial y value(s)</span><span class="WHIT"> <span class='line'>154</span> </span><span class="WHIT"> </span><span class="NAME">delta_t</span><span class="WHIT"> </span><span class="COMM">// Final x value </span><span class="WHIT"> <span class='line'>155</span> </span><span class="WHIT"> </span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">y</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>156</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">pos</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="KEYW">for</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="KEYW">var</span><span class="WHIT"> </span><span class="NAME">i</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="WHIT"> </span><span class="PUNC">&lt;</span><span class="WHIT"> </span><span class="NAME">newstate.length</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="NAME">i</span><span class="PUNC">++</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">newstate</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">&lt;</span><span class="WHIT"> </span><span class="NUMB">0.000001</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="NAME">newstate</span><span class="PUNC">[</span><span class="NAME">i</span><span class="PUNC">]</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0.0</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>157</span> </span><span class="WHIT"> </span><span class="NAME">this.state</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NAME">newstate</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>158</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>159</span> </span><span class="WHIT"> </span><span class="COMM">/** <span class='line'>160</span> * Prints the current state to the console <span class='line'>161</span> */</span><span class="WHIT"> <span class='line'>162</span> </span><span class="WHIT"> </span><span class="NAME">print_state</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>163</span> </span><span class="WHIT"> </span><span class="NAME">console.log</span><span class="PUNC">(</span><span class="NAME">this.state</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>164</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>165</span> </span><span class="PUNC">}</span><span class="WHIT"> <span class='line'>166</span> <span class='line'>167</span> </span><span class="COMM">/* <span class='line'>168</span> I've wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace <span class='line'>169</span> so it's better encapsulated. Now you can have multiple random number generators <span class='line'>170</span> and they won't stomp all over eachother's state. <span class='line'>171</span> <span class='line'>172</span> If you want to use this as a substitute for Math.random(), use the random() <span class='line'>173</span> method like so: <span class='line'>174</span> <span class='line'>175</span> var m = new MersenneTwister(); <span class='line'>176</span> var randomNumber = m.random(); <span class='line'>177</span> <span class='line'>178</span> You can also call the other genrand_{foo}() methods on the instance. <span class='line'>179</span> If you want to use a specific seed in order to get a repeatable random <span class='line'>180</span> sequence, pass an integer into the constructor: <span class='line'>181</span> var m = new MersenneTwister(123); <span class='line'>182</span> and that will always produce the same random sequence. <span class='line'>183</span> Sean McCullough (banksean@gmail.com) <span class='line'>184</span> */</span><span class="WHIT"> <span class='line'>185</span> <span class='line'>186</span> </span><span class="COMM">/* <span class='line'>187</span> A C-program for MT19937, with initialization improved 2002/1/26. <span class='line'>188</span> Coded by Takuji Nishimura and Makoto Matsumoto. <span class='line'>189</span> <span class='line'>190</span> Before using, initialize the state by using init_genrand(seed) <span class='line'>191</span> or init_by_array(init_key, key_length). <span class='line'>192</span> <span class='line'>193</span> Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, <span class='line'>194</span> All rights reserved. <span class='line'>195</span> <span class='line'>196</span> Redistribution and use in source and binary forms, with or without <span class='line'>197</span> modification, are permitted provided that the following conditions <span class='line'>198</span> are met: <span class='line'>199</span> <span class='line'>200</span> 1. Redistributions of source code must retain the above copyright <span class='line'>201</span> notice, this list of conditions and the following disclaimer. <span class='line'>202</span> <span class='line'>203</span> 2. Redistributions in binary form must reproduce the above copyright <span class='line'>204</span> notice, this list of conditions and the following disclaimer in the <span class='line'>205</span> documentation and/or other materials provided with the distribution. <span class='line'>206</span> <span class='line'>207</span> 3. The names of its contributors may not be used to endorse or promote <span class='line'>208</span> products derived from this software without specific prior written <span class='line'>209</span> permission. <span class='line'>210</span> <span class='line'>211</span> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS <span class='line'>212</span> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT <span class='line'>213</span> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR <span class='line'>214</span> A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR <span class='line'>215</span> CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, <span class='line'>216</span> EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, <span class='line'>217</span> PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR <span class='line'>218</span> PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF <span class='line'>219</span> LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING <span class='line'>220</span> NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <span class='line'>221</span> SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <span class='line'>222</span> <span class='line'>223</span> <span class='line'>224</span> Any feedback is very welcome. <span class='line'>225</span> http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html <span class='line'>226</span> email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) <span class='line'>227</span> */</span><span class="WHIT"> <span class='line'>228</span> <span class='line'>229</span> </span><span class="KEYW">function</span><span class="WHIT"> </span><span class="NAME">MersenneTwister</span><span class="PUNC">(</span><span class="NAME">seed</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>230</span> </span><span class="WHIT"> </span><span class="KEYW">if</span><span class="WHIT"> </span><span class="PUNC">(</span><span class="NAME">seed</span><span class="WHIT"> </span><span class="PUNC">==</span><span class="WHIT"> </span><span class="NAME">undefined</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>231</span> </span><span class="WHIT"> </span><span class="NAME">seed</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Date</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">.</span><span class="NAME">getTime</span><span class="PUNC">(</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>232</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> </span><span class="WHIT"> <span class='line'>233</span> </span><span class="WHIT"> </span><span class="COMM">/* Period parameters */</span><span class="WHIT"> </span><span class="WHIT"> <span class='line'>234</span> </span><span class="WHIT"> </span><span class="NAME">this.N</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">624</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>235</span> </span><span class="WHIT"> </span><span class="NAME">this.M</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">397</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>236</span> </span><span class="WHIT"> </span><span class="NAME">this.MATRIX_A</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0x9908b0df</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="COMM">/* constant vector a */</span><span class="WHIT"> <span class='line'>237</span> </span><span class="WHIT"> </span><span class="NAME">this.UPPER_MASK</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0x80000000</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="COMM">/* most significant w-r bits */</span><span class="WHIT"> <span class='line'>238</span> </span><span class="WHIT"> </span><span class="NAME">this.LOWER_MASK</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="NUMB">0x7fffffff</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="COMM">/* least significant r bits */</span><span class="WHIT"> <span class='line'>239</span> </span><span class="WHIT"> </span><span class="WHIT"> <span class='line'>240</span> </span><span class="WHIT"> </span><span class="NAME">this.mt</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">new</span><span class="WHIT"> </span><span class="NAME">Array</span><span class="PUNC">(</span><span class="NAME">this.N</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="COMM">/* the array for the state vector */</span><span class="WHIT"> <span class='line'>241</span> </span><span class="WHIT"> </span><span class="NAME">this.mti</span><span class="PUNC">=</span><span class="NAME">this.N</span><span class="PUNC">+</span><span class="NUMB">1</span><span class="PUNC">;</span><span class="WHIT"> </span><span class="COMM">/* mti==N+1 means mt[N] is not initialized */</span><span class="WHIT"> <span class='line'>242</span> </span><span class="WHIT"> </span><span class="WHIT"> <span class='line'>243</span> </span><span class="WHIT"> </span><span class="NAME">this.init_genrand</span><span class="PUNC">(</span><span class="NAME">seed</span><span class="PUNC">)</span><span class="PUNC">;</span><span class="WHIT"> <span class='line'>244</span> </span><span class="WHIT"> </span><span class="PUNC">}</span><span class="WHIT"> </span><span class="WHIT"> <span class='line'>245</span> </span><span class="WHIT"> </span><span class="WHIT"> <span class='line'>246</span> </span><span class="WHIT"> </span><span class="COMM">/* initializes mt[N] with a seed */</span><span class="WHIT"> <span class='line'>247</span> </span><span class="WHIT"> </span><span class="NAME">MersenneTwister.prototype.init_genrand</span><span class="WHIT"> </span><span class="PUNC">=</span><span class="WHIT"> </span><span class="KEYW">function</span><span class="PUNC">(</span><span class="NAME">s</span><span class="PUNC">)</span><span class="WHIT"> </span><span class="PUNC">{</span><span class="WHIT"> <span class='line'>248</span> </span><span class="WHIT"> </span><span class="NAME">this.mt</span><span class="PUNC">[</s