gerbilcharts 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.2.5 2009-10-27
2
+ * Changes
3
+ * Negative values work good
4
+ * Much better timerange selection
5
+ * Auto tooltips for surfaces that allow it
6
+ * Butterfly surface Area surface (such as in/out charts)
7
+ * Other misc changes
8
+
1
9
  == 0.2.3 2009-10-19
2
10
  * Changes
3
11
  * New Squarized Line Surface
@@ -27,7 +27,7 @@ class AreaChart < ChartBase
27
27
 
28
28
  # optional features
29
29
  if @feature_timetracker
30
- @thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_SOUTH, :dim => 10 ))
30
+ @thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
31
31
  end
32
32
  end
33
33
 
@@ -24,9 +24,11 @@ module GerbilCharts::Charts
24
24
  # [+:width+] Width of the generated SVG chart in pixels
25
25
  # [+:height+] Height of the generated SVG chart in pixels
26
26
  # [+:style+] CSS Stylesheet to use for the chart (default = brushmetal.css see public gem directory)
27
+ # Use "inline:css_name" to embed the stylesheet inline default is to use xref
27
28
  # [+:scaling_x+] Allowed values are :auto, :auto_0, and an array [min,max] (default = :auto)
28
29
  # [+:scaling_y+] Allowed values are :auto, :auto_0, and an array [min,max] (default = :auto)
29
30
  # [+:circle_data_points+] Draws a tiny circle around datapoints for tooltips
31
+ # [+:enabletimetracker+] Time tracker javascript selector (default = false)
30
32
  #
31
33
  class ChartBase
32
34
 
@@ -41,6 +43,8 @@ class ChartBase
41
43
  ORIENT_SOUTHEAST=7
42
44
  ORIENT_SOUTHWEST=8
43
45
  ORIENT_OVERLAY=9
46
+ ORIENT_OVERLAY_NORTH=10
47
+ ORIENT_OVERLAY_SOUTH=11
44
48
 
45
49
 
46
50
  attr_reader :thechart
@@ -56,7 +56,7 @@ protected
56
56
  def format_suffix raw_value
57
57
  return "0" if raw_value == 0
58
58
  UNITPRESETS.each do |unit|
59
- if raw_value >= unit[0]
59
+ if raw_value.abs >= unit[0]
60
60
  retval = raw_value / unit[0]
61
61
  sout=format("%.2f %s", retval, unit[1])
62
62
  sout.gsub! ".00",""
@@ -63,12 +63,17 @@ private
63
63
  # round_max (ceiling)
64
64
  def round_max(raw)
65
65
  last_pre=1
66
- if raw > PRESETS.last[0]
66
+ if raw.abs > PRESETS.last[0]
67
67
  return raw
68
68
  else
69
69
  PRESETS.reverse_each do |pre|
70
- break if pre[0] < raw
71
- last_pre=pre[0]
70
+ if raw >= 0
71
+ break if pre[0] < raw.abs
72
+ last_pre=pre[0]
73
+ else
74
+ last_pre=-pre[0]
75
+ break if pre[0] < raw.abs
76
+ end
72
77
  end
73
78
  end
74
79
  return last_pre
@@ -78,8 +83,13 @@ private
78
83
  def round_min(raw)
79
84
  last_pre=0
80
85
  PRESETS.each do |pre|
81
- break if pre[0] > raw
82
- last_pre=pre[0]
86
+ if raw >=0
87
+ break if pre[0] > raw
88
+ last_pre=pre[0]
89
+ else
90
+ last_pre=-pre[0]
91
+ break if pre[0] > raw.abs
92
+ end
83
93
  end
84
94
  return last_pre
85
95
  end
@@ -203,22 +203,25 @@
203
203
  }
204
204
  .trackerpanel
205
205
  {
206
- fill: yellow;
207
- fill-opacity: 0.5;
206
+ fill: white;
207
+ fill-opacity: 0.01;
208
208
  }
209
209
  .trackerrect
210
210
  {
211
211
  fill: red;
212
- fill-opacity: 0.2;
212
+ fill-opacity: 0.4;
213
213
  }
214
214
  .trackertextinterval
215
215
  {
216
- font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
217
- font-size: 14px;
216
+ font-family: courier;
217
+ font-size: 11px;
218
+ fill: black;
219
+ stroke: none;
218
220
  }
219
- 209,1 97%
220
221
  .trackertextfromts
221
222
  {
222
- font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
223
- font-size: 10px;
223
+ font-family: courier;
224
+ font-size: 9px;
225
+ fill: black;
226
+ stroke: none;
224
227
  }
@@ -1,327 +1,334 @@
1
- var SVGDocument = null;
2
- var SVGRoot = null;
3
- var SVGViewBox = null;
4
- var svgns = 'http://www.w3.org/2000/svg';
5
- var xlinkns = 'http://www.w3.org/1999/xlink';
6
- var toolTip = null;
7
- var TrueCoords = null;
8
- var tipBox = null;
9
- var tipText = null;
10
- var tipTitle = null;
11
- var tipDesc = null;
12
- var ajaxPE = null;
13
- var lastElement = null;
14
- var titleText = '';
15
- var titleDesc = '';
16
-
17
- function OpacityDown(mouseover_evt)
18
- {
19
- var obj=mouseover_evt.target;
20
- obj.style.setProperty("opacity","0.5","");
21
- }
22
-
23
-
24
- function OpacityUp(mouseout_evt)
25
- {
26
- var obj=mouseout_evt.target;
27
- obj.style.setProperty("opacity","1.0","");
28
- }
29
-
30
- function GerbilNavigate()
31
- {
32
- window.top.location='/dashboard/show';
33
- }
34
-
35
- function parseXMLFromString(text)
36
- {
37
- if (typeof DOMParser != "undefined")
38
- {
39
- // Mozilla, Firefox, and related browsers
40
- return (new DOMParser()).parseFromString(text, "application/xml");
41
- }
42
- else if (typeof ActiveXObject != "undefined")
43
- {
44
- // Internet Explorer.
45
- var xmlDOM = new ActiveXObject("Microsoft.XMLDOM");
46
- var doc = xmlDOM.newDocument();
47
- doc.loadXML(text);
48
- return doc.documentElement;
49
- }
50
- return null;
51
- }
52
-
53
-
54
- function TestUpdates1(evt)
55
- {
56
- var tnode=SVGDocument.getElementById("graphtitle");
57
- tnode.firstChild.nodeValue="Changed by Ajax2";
58
- }
59
-
60
- function TestAjaxUpdates()
61
- {
62
- var gerbilAjaxBlock=SVGDocument.getElementById("GerbilAjaxBlock");
63
- var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
64
- var gerbilAjaxContext=SVGDocument.getElementById("GerbilAjaxContext");
65
-
66
- // extract the URL & other ajax options from the Gerbil Ajax Block
67
- var url = gerbilAjaxOptions.attributes.getNamedItem('axurl').nodeValue;
68
- var freq = gerbilAjaxOptions.attributes.getNamedItem('axfrequency').nodeValue;
69
- var decay = gerbilAjaxOptions.attributes.getNamedItem('axdecay').nodeValue;
70
-
71
- // return the entire ajax context in request
72
- var aa = $A(gerbilAjaxContext.attributes);
73
- var hContext = new Hash();
74
- aa.each(function (at){
75
- hContext[at.localName]=at.nodeValue;
76
- });
77
-
78
- // console.log ("URL = "+ url );
79
-
80
- new Ajax.Request(url, {
81
- method: 'get',
82
- parameters: hContext,
83
- onSuccess: function(transport) {
84
- updateSVG(transport.responseXML)
85
- }
86
- });
87
-
88
- }
89
- ///////////////////////////////////////////////////////////////////////////////
90
- // Squirell Release 1.0 - uses Gerbil Charts that donot yet do delta replace !
91
- ///////////////////////////////////////////////////////////////////////////////
92
- function updateSVG(node)
93
- {
94
- var cmd = '';
95
-
96
- cmd = node.documentElement.getAttribute("command")
97
-
98
- if (cmd == "noop")
99
- {
100
- // do nothing (we got a noop ajax response)
101
- }
102
- else if (cmd=="full_replace")
103
- {
104
- var newnode = node.documentElement.childNodes[1];
105
- var currnode = SVGDocument.getElementById('GerbilSVGGraph');
106
- var par = currnode.parentNode;
107
- var newLayer = SVGDocument.importNode(newnode,true);
108
- par.appendChild(newLayer);
109
- par.removeChild(currnode);
110
-
111
- // move tooltip to top of rendering stack
112
- par.removeChild(toolTip);
113
- par.appendChild(toolTip);
114
- }
115
- }
116
-
117
- function Init(evt)
118
- {
119
- SVGDocument = evt.target.ownerDocument;
120
- SVGRoot = SVGDocument.documentElement;
121
- TrueCoords = SVGRoot.createSVGPoint();
122
-
123
- toolTip = SVGDocument.getElementById('ToolTip');
124
- tipBox = SVGDocument.getElementById('tipbox');
125
- tipText = SVGDocument.getElementById('tipText');
126
- tipTitle = SVGDocument.getElementById('tipTitle');
127
- tipDesc = SVGDocument.getElementById('tipDesc');
128
- //window.status = (TrueCoords);
129
-
130
- //create event for object
131
- SVGRoot.addEventListener('mousemove', ShowTooltip, false);
132
- SVGRoot.addEventListener('mouseout', HideTooltip, false);
133
-
134
- // periodical executor
135
- var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
136
- if (gerbilAjaxOptions!=null)
137
- {
138
- var ajaxInterval = gerbilAjaxOptions.getAttribute('axfrequency')
139
- ajaxPE = new PeriodicalExecuter(TestAjaxUpdates,parseInt(ajaxInterval))
140
- // for Adobe SVG later setTimeout("TestAjaxUpdates()",3)
141
- }
142
- };
143
-
144
-
145
- function GetTrueCoords(evt)
146
- {
147
- // zoom / pan adjustment
148
- var newScale = SVGRoot.currentScale;
149
- var translation = SVGRoot.currentTranslate;
150
- TrueCoords.x = (evt.clientX - translation.x)/newScale;
151
- TrueCoords.y = (evt.clientY - translation.y)/newScale;
152
- };
153
-
154
-
155
- function HideTooltip( evt )
156
- {
157
- toolTip.setAttributeNS(null, 'visibility', 'hidden');
158
- };
159
-
160
-
161
- function ShowTooltip( evt )
162
- {
163
- // bail out early, if same target
164
- var targetElement = evt.target;
165
- if ( lastElement == targetElement )
166
- {
167
- return
168
- }
169
-
170
- // bail out early, if no 'gerbiltooltipX' tags
171
- // tooltip1 is the heading (appears in bold face)
172
- // tooltip2 is the tip text
173
- var tooltip1 = '';
174
- var tooltip2 = '';
175
- tooltip1 = targetElement.getAttributeNS(null, 'gerbiltooltip1');
176
- tooltip2 = targetElement.getAttributeNS(null, 'gerbiltooltip2');
177
- if (tooltip1=='' && tooltip2 == '')
178
- {
179
- return;
180
- }
181
-
182
- // Positon the tooltip box relative to the mouse pos
183
- GetTrueCoords( evt );
184
- var tipScale = 1/SVGRoot.currentScale;
185
- var textWidth = 0;
186
- var tspanWidth = 0;
187
- var boxHeight = 20;
188
- tipBox.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
189
- tipText.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
190
-
191
- // Values for tooltip text
192
- tipTitle.firstChild.nodeValue = tooltip1;
193
- tipTitle.setAttributeNS(null, 'display', 'inline' );
194
- tipDesc.firstChild.nodeValue = tooltip2;
195
- tipDesc.setAttributeNS(null, 'display', 'inline' );
196
-
197
-
198
- // Box size
199
- var outline = tipText.getBBox();
200
- tipBox.setAttributeNS(null, 'width', Number(outline.width) + 10);
201
- tipBox.setAttributeNS(null, 'height', Number(outline.height));
202
-
203
-
204
- // Update position (keep tooltip inside client area ! )
205
- var yPos = TrueCoords.y + (10 * tipScale);
206
- if (yPos+Number(outline.height)>SVGRoot.height.baseVal.value)
207
- {
208
- yPos = SVGRoot.height.baseVal.value - Number(outline.height)
209
- }
210
- var xPos = TrueCoords.x + (10 * tipScale);
211
- if (xPos+Number(outline.width)>SVGRoot.width.baseVal.value)
212
- {
213
- xPos = SVGRoot.width.baseVal.value - Number(outline.width)
214
- }
215
-
216
- toolTip.setAttributeNS(null, 'transform', 'translate(' + xPos + ',' + yPos + ')');
217
- toolTip.setAttributeNS(null, 'visibility', 'visible');
218
- }
219
-
220
-
221
-
222
- //////////////////////////////////////
223
- // Tracker - for SVG
224
- var fTracking=0;
225
- var nTrackBegin=0;
226
- var nTrackEnd=0;
227
- var nTrackCurrent=0;
228
- var pGTrackingRect=null;
229
- var pTrackingRect=null;
230
- var pTrackFromTS=null;
231
- var nTrackScale=0;
232
- var pTrackTextFromTS=null;
233
- var pTrackTextInterval=null;
234
- var pTrackerData=null;
235
-
236
- function TrackerMouseDown( evt )
237
- {
238
- fTracking=1;
239
- nTrackBegin=evt.clientX;
240
- nTrackCurrent=evt.clientX;
241
-
242
- SVGDocument = evt.target.ownerDocument;
243
-
244
- pGTrackingRect= SVGDocument.getElementById('gtrackerrect');
245
- pTrackingRect= SVGDocument.getElementById('trackerrect');
246
- pTrackingRect.setAttributeNS(null,"x",nTrackCurrent);
247
- pTrackingRect.setAttributeNS(null,"width",1);
248
-
249
- pTrackingText= SVGDocument.getElementById('gtrackertext');
250
- pTrackingText.setAttributeNS(null,"transform","translate(" + nTrackBegin + ',' + 150 + ')');
251
-
252
- // compute begin state
253
- pTrackerData = SVGDocument.getElementById('gtrackerdata');
254
- nTrackScale = parseInt(pTrackerData.getAttributeNS(null,"gerb_scale"));
255
- var from_secs = parseInt(pTrackerData.getAttributeNS(null,"gerb_fromts"));
256
-
257
- // clicked to time delta
258
- var xbegin = parseInt(SVGDocument.getElementById('trackerpanel').getAttributeNS(null,"x"));
259
- pTrackFromTS = new Date();
260
- pTrackFromTS.setTime(1000* (from_secs + (nTrackBegin-xbegin)*nTrackScale));
261
-
262
- // text svg elements
263
- pTrackTextFromTS=SVGDocument.getElementById('trackertextfromts');
264
- pTrackTextInterval=SVGDocument.getElementById('trackertextinterval');
265
-
266
- // visibility off (move 5-10 pixels to turn it on)
267
- pGTrackingRect.setAttributeNS(null,"visibility","hidden");
268
- pTrackingText.setAttributeNS(null,"visibility","hidden");
269
-
270
- }
271
-
272
- function TrackerMouseMove(evt)
273
- {
274
- if (fTracking==2 && evt.clientX > nTrackBegin)
275
- {
276
- var delta = nTrackCurrent-nTrackBegin;
277
- var mid = nTrackBegin+(delta)/2;
278
- nTrackCurrent=evt.clientX;
279
- pTrackingRect.setAttributeNS(null,"width",delta);
280
- pTrackingText.setAttributeNS(null,"transform","translate(" + mid + ')');
281
-
282
- // text box
283
- var szwin = FormatSecs(delta*nTrackScale)
284
- var szbegin = "Starting : " + pTrackFromTS.toLocaleString();
285
- pTrackTextInterval.firstChild.nodeValue = szwin;
286
- pTrackTextFromTS.firstChild.nodeValue = szbegin;
287
- }
288
- else if (fTracking==1 && (evt.clientX-nTrackBegin) > 5 )
289
- {
290
- // we need to move atleast 5 pixels to turn on tracking
291
- fTracking=2;
292
-
293
- // visibility on
294
- pGTrackingRect.setAttributeNS(null,"visibility","visible");
295
- pTrackingText.setAttributeNS(null,"visibility","visible");
296
- }
297
- }
298
- function TrackerMouseUp(evt)
299
- {
300
- if (fTracking==2)
301
- {
302
- pTrackingRect=null;
303
- nTrackEnd=evt.clientX;
304
-
305
- pTrackerData.setAttributeNS(null,"gerb_selsecs",(nTrackEnd-nTrackBegin)*nTrackScale);
306
- pTrackerData.setAttributeNS(null,"gerb_selts", pTrackFromTS.getTime()/1000);
307
-
308
- }
309
- fTracking=0;
310
- }
311
-
312
- function FormatSecs(secs)
313
- {
314
- if (secs>86400)
315
- {
316
- return "" + Math.round(secs/86400) + " Days" + (secs%86400)/3600 + " Hrs" + Math.round((secs%3600)/60) + " Mins";
317
- }
318
- else if (secs>3600)
319
- {
320
- return "" + Math.round(secs/3600) + " Hrs " + Math.round((secs%3600)/60) + " Mins";
321
- }
322
- else if (secs>60)
323
- {
324
- return "" + Math.round(secs/60) + " Mins " + secs%60 + " Secs";
325
- }
326
- return "" + secs + " Secs";
327
- }
1
+ var SVGDocument = null;
2
+ var SVGRoot = null;
3
+ var SVGViewBox = null;
4
+ var svgns = 'http://www.w3.org/2000/svg';
5
+ var xlinkns = 'http://www.w3.org/1999/xlink';
6
+ var toolTip = null;
7
+ var TrueCoords = null;
8
+ var tipBox = null;
9
+ var tipText = null;
10
+ var tipTitle = null;
11
+ var tipDesc = null;
12
+ var ajaxPE = null;
13
+ var lastElement = null;
14
+ var titleText = '';
15
+ var titleDesc = '';
16
+
17
+ function OpacityDown(mouseover_evt)
18
+ {
19
+ var obj=mouseover_evt.target;
20
+ obj.style.setProperty("opacity","0.5","");
21
+ }
22
+
23
+
24
+ function OpacityUp(mouseout_evt)
25
+ {
26
+ var obj=mouseout_evt.target;
27
+ obj.style.setProperty("opacity","1.0","");
28
+ }
29
+
30
+ function GerbilNavigate()
31
+ {
32
+ window.top.location='/dashboard/show';
33
+ }
34
+
35
+ function parseXMLFromString(text)
36
+ {
37
+ if (typeof DOMParser != "undefined")
38
+ {
39
+ // Mozilla, Firefox, and related browsers
40
+ return (new DOMParser()).parseFromString(text, "application/xml");
41
+ }
42
+ else if (typeof ActiveXObject != "undefined")
43
+ {
44
+ // Internet Explorer.
45
+ var xmlDOM = new ActiveXObject("Microsoft.XMLDOM");
46
+ var doc = xmlDOM.newDocument();
47
+ doc.loadXML(text);
48
+ return doc.documentElement;
49
+ }
50
+ return null;
51
+ }
52
+
53
+
54
+ function TestUpdates1(evt)
55
+ {
56
+ var tnode=SVGDocument.getElementById("graphtitle");
57
+ tnode.firstChild.nodeValue="Changed by Ajax2";
58
+ }
59
+
60
+ function TestAjaxUpdates()
61
+ {
62
+ var gerbilAjaxBlock=SVGDocument.getElementById("GerbilAjaxBlock");
63
+ var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
64
+ var gerbilAjaxContext=SVGDocument.getElementById("GerbilAjaxContext");
65
+
66
+ // extract the URL & other ajax options from the Gerbil Ajax Block
67
+ var url = gerbilAjaxOptions.attributes.getNamedItem('axurl').nodeValue;
68
+ var freq = gerbilAjaxOptions.attributes.getNamedItem('axfrequency').nodeValue;
69
+ var decay = gerbilAjaxOptions.attributes.getNamedItem('axdecay').nodeValue;
70
+
71
+ // return the entire ajax context in request
72
+ var aa = $A(gerbilAjaxContext.attributes);
73
+ var hContext = new Hash();
74
+ aa.each(function (at){
75
+ hContext[at.localName]=at.nodeValue;
76
+ });
77
+
78
+ // console.log ("URL = "+ url );
79
+
80
+ new Ajax.Request(url, {
81
+ method: 'get',
82
+ parameters: hContext,
83
+ onSuccess: function(transport) {
84
+ updateSVG(transport.responseXML)
85
+ }
86
+ });
87
+
88
+ }
89
+ ///////////////////////////////////////////////////////////////////////////////
90
+ // Squirell Release 1.0 - uses Gerbil Charts that donot yet do delta replace !
91
+ ///////////////////////////////////////////////////////////////////////////////
92
+ function updateSVG(node)
93
+ {
94
+ var cmd = '';
95
+
96
+ cmd = node.documentElement.getAttribute("command")
97
+
98
+ if (cmd == "noop")
99
+ {
100
+ // do nothing (we got a noop ajax response)
101
+ }
102
+ else if (cmd=="full_replace")
103
+ {
104
+ var newnode = node.documentElement.childNodes[1];
105
+ var currnode = SVGDocument.getElementById('GerbilSVGGraph');
106
+ var par = currnode.parentNode;
107
+ var newLayer = SVGDocument.importNode(newnode,true);
108
+ par.appendChild(newLayer);
109
+ par.removeChild(currnode);
110
+
111
+ // move tooltip to top of rendering stack
112
+ par.removeChild(toolTip);
113
+ par.appendChild(toolTip);
114
+ }
115
+ }
116
+
117
+ function Init(evt)
118
+ {
119
+ SVGDocument = evt.target.ownerDocument;
120
+ SVGRoot = SVGDocument.documentElement;
121
+ TrueCoords = SVGRoot.createSVGPoint();
122
+
123
+ toolTip = SVGDocument.getElementById('ToolTip');
124
+ tipBox = SVGDocument.getElementById('tipbox');
125
+ tipText = SVGDocument.getElementById('tipText');
126
+ tipTitle = SVGDocument.getElementById('tipTitle');
127
+ tipDesc = SVGDocument.getElementById('tipDesc');
128
+ //window.status = (TrueCoords);
129
+
130
+ //create event for object
131
+ SVGRoot.addEventListener('mousemove', ShowTooltip, false);
132
+ SVGRoot.addEventListener('mouseout', HideTooltip, false);
133
+
134
+ // periodical executor
135
+ var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
136
+ if (gerbilAjaxOptions!=null)
137
+ {
138
+ var ajaxInterval = gerbilAjaxOptions.getAttribute('axfrequency')
139
+ ajaxPE = new PeriodicalExecuter(TestAjaxUpdates,parseInt(ajaxInterval))
140
+ // for Adobe SVG later setTimeout("TestAjaxUpdates()",3)
141
+ }
142
+ };
143
+
144
+
145
+ function GetTrueCoords(evt)
146
+ {
147
+ // zoom / pan adjustment
148
+ var newScale = SVGRoot.currentScale;
149
+ var translation = SVGRoot.currentTranslate;
150
+ TrueCoords.x = (evt.clientX - translation.x)/newScale;
151
+ TrueCoords.y = (evt.clientY - translation.y)/newScale;
152
+ };
153
+
154
+
155
+ function HideTooltip( evt )
156
+ {
157
+ toolTip.setAttributeNS(null, 'visibility', 'hidden');
158
+ };
159
+
160
+
161
+ function ShowTooltip( evt )
162
+ {
163
+ // bail out early, if same target
164
+ var targetElement = evt.target;
165
+ if ( lastElement == targetElement )
166
+ {
167
+ return
168
+ }
169
+
170
+ // bail out early, if no 'gerbiltooltipX' tags
171
+ // tooltip1 is the heading (appears in bold face)
172
+ // tooltip2 is the tip text
173
+ var tooltip1 = '';
174
+ var tooltip2 = '';
175
+ tooltip1 = targetElement.getAttributeNS(null, 'gerbiltooltip1');
176
+ tooltip2 = targetElement.getAttributeNS(null, 'gerbiltooltip2');
177
+ if (tooltip1=='' && tooltip2 == '')
178
+ {
179
+ return;
180
+ }
181
+
182
+ // Positon the tooltip box relative to the mouse pos
183
+ GetTrueCoords( evt );
184
+ var tipScale = 1/SVGRoot.currentScale;
185
+ var textWidth = 0;
186
+ var tspanWidth = 0;
187
+ var boxHeight = 20;
188
+ tipBox.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
189
+ tipText.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
190
+
191
+ // Values for tooltip text
192
+ tipTitle.firstChild.nodeValue = tooltip1;
193
+ tipTitle.setAttributeNS(null, 'display', 'inline' );
194
+ tipDesc.firstChild.nodeValue = tooltip2;
195
+ tipDesc.setAttributeNS(null, 'display', 'inline' );
196
+
197
+
198
+ // Box size
199
+ var outline = tipText.getBBox();
200
+ tipBox.setAttributeNS(null, 'width', Number(outline.width) + 10);
201
+ tipBox.setAttributeNS(null, 'height', Number(outline.height));
202
+
203
+
204
+ // Update position (keep tooltip inside client area ! )
205
+ var yPos = TrueCoords.y + (10 * tipScale);
206
+ if (yPos+Number(outline.height)>SVGRoot.height.baseVal.value)
207
+ {
208
+ yPos = SVGRoot.height.baseVal.value - Number(outline.height)
209
+ }
210
+ var xPos = TrueCoords.x + (10 * tipScale);
211
+ if (xPos+Number(outline.width)>SVGRoot.width.baseVal.value)
212
+ {
213
+ xPos = SVGRoot.width.baseVal.value - Number(outline.width)
214
+ }
215
+
216
+ toolTip.setAttributeNS(null, 'transform', 'translate(' + xPos + ',' + yPos + ')');
217
+ toolTip.setAttributeNS(null, 'visibility', 'visible');
218
+ }
219
+
220
+
221
+
222
+ //////////////////////////////////////
223
+ // Tracker - for SVG
224
+ var fTracking=0;
225
+ var nTrackBegin=0;
226
+ var nTrackEnd=0;
227
+ var nTrackCurrent=0;
228
+ var pGTrackingRect=null;
229
+ var pTrackingRect=null;
230
+ var pTrackFromTS=null;
231
+ var nTrackScale=0;
232
+ var pTrackTextFromTS=null;
233
+ var pTrackTextInterval=null;
234
+ var pTrackerData=null;
235
+
236
+ function TrackerMouseDown( evt )
237
+ {
238
+ fTracking=1;
239
+ nTrackBegin=evt.clientX;
240
+ nTrackCurrent=evt.clientX;
241
+
242
+ SVGDocument = evt.target.ownerDocument;
243
+
244
+ pGTrackingRect= SVGDocument.getElementById('gtrackerrect');
245
+ pTrackingRect= SVGDocument.getElementById('trackerrect');
246
+ pTrackingRect.setAttributeNS(null,"x",nTrackCurrent);
247
+ pTrackingRect.setAttributeNS(null,"width",1);
248
+
249
+ pTrackingText= SVGDocument.getElementById('gtrackertext');
250
+ pTrackingText.setAttributeNS(null,"transform","translate(" + nTrackBegin + ',' + 150 + ')');
251
+
252
+ // compute begin state
253
+ pTrackerData = SVGDocument.getElementById('gtrackerdata');
254
+ nTrackScale = parseFloat(pTrackerData.getAttributeNS(null,"gerb_scale"));
255
+ var from_secs = parseInt(pTrackerData.getAttributeNS(null,"gerb_fromts"));
256
+
257
+ // clicked to time delta
258
+ var xbegin = parseFloat(SVGDocument.getElementById('trackerpanel').getAttributeNS(null,"x"));
259
+ pTrackFromTS = new Date();
260
+ pTrackFromTS.setTime(1000* (from_secs + (nTrackBegin-xbegin)*nTrackScale));
261
+
262
+ // text svg elements
263
+ pTrackTextFromTS=SVGDocument.getElementById('trackertextfromts');
264
+ pTrackTextInterval=SVGDocument.getElementById('trackertextinterval');
265
+
266
+ // visibility off (move 5-10 pixels to turn it on)
267
+ pGTrackingRect.setAttributeNS(null,"visibility","hidden");
268
+ pTrackingText.setAttributeNS(null,"visibility","hidden");
269
+
270
+ }
271
+
272
+ function TrackerMouseMove(evt)
273
+ {
274
+ if (fTracking==2)
275
+ {
276
+ var fSelectAfter = evt.clientX > nTrackBegin;
277
+ var delta = nTrackCurrent-nTrackBegin;
278
+ var mid = nTrackBegin+(delta)/2;
279
+ nTrackCurrent=evt.clientX;
280
+ pTrackingRect.setAttributeNS(null,"width",Math.abs(delta));
281
+ pTrackingText.setAttributeNS(null,"transform","translate(" + mid + ')');
282
+
283
+ // negative
284
+ pTrackingRect.setAttribute("transform","translate(" + (fSelectAfter?0:delta) + ',0)');
285
+
286
+ // text box
287
+ var szwin = FormatSecs(Math.round(Math.abs(delta)*nTrackScale))
288
+ var szbegin = fSelectAfter?"After ":"Before ";
289
+ szbegin += pTrackFromTS.toLocaleString();
290
+ pTrackTextInterval.firstChild.nodeValue = szwin;
291
+ pTrackTextFromTS.firstChild.nodeValue = szbegin;
292
+ }
293
+ else if (fTracking==1 && Math.abs(evt.clientX-nTrackBegin) > 3 )
294
+ {
295
+ // we need to move atleast 3 pixels tracking
296
+ fTracking=2;
297
+
298
+ // visibility on
299
+ pGTrackingRect.setAttributeNS(null,"visibility","visible");
300
+ pTrackingText.setAttributeNS(null,"visibility","visible");
301
+ }
302
+ }
303
+ function TrackerMouseUp(evt)
304
+ {
305
+ if (fTracking==2)
306
+ {
307
+ pTrackingRect=null;
308
+ nTrackEnd=evt.clientX;
309
+
310
+ pTrackerData.setAttributeNS(null,"gerb_selsecs",(nTrackEnd-nTrackBegin)*nTrackScale);
311
+ pTrackerData.setAttributeNS(null,"gerb_selts", pTrackFromTS.getTime()/1000);
312
+
313
+ console.log("Selts = " + pTrackerData.getAttributeNS(null,"gerb_selts"));
314
+ console.log("Selwin = " + pTrackerData.getAttributeNS(null,"gerb_selsecs"));
315
+ }
316
+ fTracking=0;
317
+ }
318
+
319
+ function FormatSecs(secs)
320
+ {
321
+ if (secs>86400)
322
+ {
323
+ return "" + Math.round(secs/86400) + " Days" + (secs%86400)/3600 + " Hrs" + Math.round((secs%3600)/60) + " Mins";
324
+ }
325
+ else if (secs>3600)
326
+ {
327
+ return "" + Math.round(secs/3600) + " Hrs " + Math.round((secs%3600)/60) + " Mins";
328
+ }
329
+ else if (secs>60)
330
+ {
331
+ return "" + Math.round(secs/60) + " Mins " + secs%60 + " Secs";
332
+ }
333
+ return "" + secs + " Secs";
334
+ }