_Gauge.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. define("dojox/gauges/_Gauge", ["dojo/_base/declare","dojo/_base/lang","dojo/_base/html","dojo/_base/array","dojo/_base/event",
  2. "dojo/_base/connect","dojo/dom-construct", "dijit/_Widget", "dojox/gfx", "./Range", "dojo/fx/easing"],
  3. function(declare, lang, html, arr, event, connect, dom, Widget, gfx, Range) {
  4. var _tooltipModule = 0;
  5. var _numberModule = 0;
  6. /*=====
  7. Widget = dijit._Widget;
  8. =====*/
  9. return declare("dojox.gauges._Gauge",[Widget],{
  10. // summary:
  11. // The abstract base class for gauges.
  12. //
  13. // description:
  14. // using dojo.gfx (and thus either SVG or VML based on what is supported), this widget
  15. // builds a gauge component, used to display numerical data in a familiar format.
  16. // This widget is not to be used alone. it is meant to be subclassed, such as
  17. // dojox.gauges.BarGauge or dojox.gauges.AnalogGauge
  18. // width: Number
  19. // The width of the gauge (default is 300)
  20. width: 0,
  21. // height: Number
  22. // The height of the gauge (default is 200)
  23. height: 0,
  24. // background: Object
  25. // The color of the background. This must be an object of one of two forms:
  26. // {'color': 'color-name'}
  27. // OR
  28. // (for a gradient:)
  29. // {'type': 'linear', 'x1': 0, 'x2': 0, 'y1': 0, 'y2': 200, 'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}] }
  30. background: null,
  31. // image: String
  32. // Background image for gauge (default is no image)
  33. image: null,
  34. // useRangeStyles: Number
  35. // Indicates whether to use given css classes (dojoxGaugeRangeXX)
  36. // to determine the color (and other style attributes?) of the ranges
  37. // this value should be the number of dojoxGaugeRange classes that are
  38. // defined, starting at dojoxGaugeRange1 (0 indicates falling to default
  39. // hardcoded colors)
  40. useRangeStyles: 0,
  41. // useTooltip: Boolean
  42. // Indicates whether tooltips should be displayed for ranges, indicators, etc.
  43. useTooltip: true,
  44. // majorTicks: Object
  45. // An object representing the tick marks that should be added to the gauge. Major tick marks have a text label
  46. // indicating the value. The object can have the following attributes (required are marked with a *):
  47. // - offset: the distance from the 'center' of the gauge. Used differently for Analog vs. Bar
  48. // - width: The width of the mark
  49. // - length: The length of the mark
  50. // - interval: The interval the ticks should be added on
  51. // - color: The color of the mark and text
  52. // - font: an object with any/all of the following parameters:
  53. // {family: "Helvetica", style: "italic", variant: 'small-caps', weight: 'bold', size: "18pt"}
  54. majorTicks: null,
  55. // minorTicks: Object
  56. // An object of the same format as majorTicks, indicating where the minor (label-less) marks should be placed
  57. // The font parameter is ignored if provided since minor tick marks have no text label.
  58. minorTicks: null,
  59. // _defaultIndicator: Object
  60. // Should be overridden by any extending classes and used to indicate what the 'default' indicator is.
  61. // This object is used as the indicator when creating tick marks or when an anonymous object is passed into
  62. // addIndicator.
  63. _defaultIndicator: null,
  64. // defaultColors: Array
  65. // Set of default colors to color ranges with.
  66. defaultColors: [[0x00,0x54,0xAA,1],
  67. [0x44,0x77,0xBB,1],
  68. [0x66,0x99,0xCC,1],
  69. [0x99,0xBB,0xEE,1],
  70. [0x99,0xCC,0xFF,1],
  71. [0xCC,0xEE,0xFF,1],
  72. [0xDD,0xEE,0xFF,1]],
  73. // min: Number
  74. // The minimum value of the gauge. Normally not set explicitly, as it will be determined by
  75. // the ranges that are added.
  76. min: null,
  77. // max: Number
  78. // The maximum value of the gauge. Normally not set explicitly, as it will be determined by
  79. // the ranges that are added.
  80. max: null,
  81. // surface: Object
  82. // The GFX surface that the shapes are drawn on. Can be accessed/used by indicators to draw themselves
  83. surface: null,
  84. // hideValues: Boolean
  85. // Indicates whether the text boxes showing the value of the indicator (as text
  86. // content) should be hidden or shown. Default is not hidden, aka shown.
  87. hideValues: false,
  88. // internal data
  89. gaugeContent: undefined,
  90. _backgroundDefault: {color: '#E0E0E0'},
  91. _rangeData: null,
  92. _indicatorData: null,
  93. _drag: null,
  94. _img: null,
  95. _overOverlay: false,
  96. _lastHover: '',
  97. startup: function(){
  98. // handle settings from HTML by making sure all the options are
  99. // converted correctly to numbers and that we calculate defaults
  100. // for cx, cy and radius
  101. if(this.image === null){
  102. this.image={};
  103. }
  104. this.connect(this.gaugeContent, 'onmousedown', this.handleMouseDown);
  105. this.connect(this.gaugeContent, 'onmousemove', this.handleMouseMove);
  106. this.connect(this.gaugeContent, 'onmouseover', this.handleMouseOver);
  107. this.connect(this.gaugeContent, 'onmouseout', this.handleMouseOut);
  108. this.connect(this.gaugeContent, 'touchstart', this.handleTouchStart);
  109. this.connect(this.gaugeContent, 'touchend', this.handleTouchEnd);
  110. this.connect(this.gaugeContent, 'touchmove', this.handleTouchMove);
  111. if(!lang.isArray(this.ranges)){ this.ranges = []; }
  112. if(!lang.isArray(this.indicators)){ this.indicators = []; }
  113. var ranges = [], indicators = [];
  114. var i;
  115. if(this.hasChildren()){
  116. var children = this.getChildren();
  117. for(i=0; i<children.length; i++){
  118. if(/.*Indicator/.test(children[i].declaredClass)){
  119. indicators.push(children[i]);
  120. //this.addIndicator(children[i]);
  121. continue;
  122. }
  123. switch(children[i].declaredClass){
  124. case Range.prototype.declaredClass:
  125. ranges.push(children[i]);
  126. break;
  127. }
  128. }
  129. this.ranges = this.ranges.concat(ranges);
  130. this.indicators = this.indicators.concat(indicators);
  131. }
  132. if(!this.background){ this.background = this._backgroundDefault; }
  133. this.background = this.background.color || this.background;
  134. if(!this.surface){ this.createSurface(); }
  135. this.addRanges(this.ranges);
  136. if(this.minorTicks && this.minorTicks.interval){
  137. this.setMinorTicks(this.minorTicks);
  138. }
  139. if(this.majorTicks && this.majorTicks.interval){
  140. this.setMajorTicks(this.majorTicks);
  141. }
  142. for(i=0; i<this.indicators.length; i++){
  143. this.addIndicator(this.indicators[i]);
  144. }
  145. this.inherited(arguments);
  146. },
  147. hasChildren: function(){
  148. // summary:
  149. // Returns true if widget has children, i.e. if this.containerNode contains something.
  150. return this.getChildren().length > 0; // Boolean
  151. },
  152. buildRendering: function(){
  153. // summary:
  154. // Overrides _Widget.buildRendering
  155. var n = this.domNode = this.srcNodeRef ? this.srcNodeRef: dom.create("div");
  156. this.gaugeContent = dom.create("div", {
  157. className: "dojoxGaugeContent"
  158. });
  159. this.containerNode = dom.create("div");
  160. this.mouseNode = dom.create("div");
  161. while(n.hasChildNodes()){
  162. this.containerNode.appendChild(n.firstChild);
  163. }
  164. dom.place(this.gaugeContent, n);
  165. dom.place(this.containerNode, n);
  166. dom.place(this.mouseNode, n);
  167. },
  168. _setTicks: function(/*Object*/ oldTicks, /*Object*/ newTicks, /*Boolean*/ major){
  169. // summary:
  170. // internal method used to clear existing tick marks, then add new ones
  171. var i;
  172. if (oldTicks && lang.isArray(oldTicks._ticks)){
  173. for (i = 0; i < oldTicks._ticks.length; i++){
  174. this._removeScaleTick(oldTicks._ticks[i]);
  175. }
  176. }
  177. var t = {
  178. length: newTicks.length,
  179. offset: newTicks.offset,
  180. noChange: true
  181. };
  182. if (newTicks.color){
  183. t.color = newTicks.color;
  184. }
  185. if (newTicks.font){
  186. t.font = newTicks.font;
  187. }
  188. if (newTicks.labelPlacement){
  189. t.direction = newTicks.labelPlacement;
  190. }
  191. newTicks._ticks = [];
  192. for (i=this.min;i<=this.max;i+=newTicks.interval){
  193. if (i==this.max&&this._isScaleCircular()) continue; // do not draw last tick on fully circular gauges
  194. t.value=i;
  195. if (major){
  196. var NumberUtils = this._getNumberModule();
  197. if (NumberUtils){ // use internationalization if loaded
  198. t.label = (newTicks.fixedPrecision && newTicks.precision) ? NumberUtils.format(i, {
  199. places: newTicks.precision
  200. }): NumberUtils.format(i);
  201. }else{
  202. t.label = (newTicks.fixedPrecision && newTicks.precision) ? i.toFixed(newTicks.precision): i.toString();
  203. }
  204. }
  205. newTicks._ticks.push(this._addScaleTick(t, major));
  206. }
  207. return newTicks;
  208. },
  209. _isScaleCircular: function(){
  210. // summary:
  211. // Internal method to check if the scale is fully circular
  212. return false;
  213. },
  214. setMinorTicks: function(/*Object*/ ticks){
  215. // summary:
  216. // Creates and draws the minor tick marks based on the passed object (expecting the same format
  217. // as the minorTicks object documented above)
  218. this.minorTicks = this._setTicks(this.minorTicks, ticks, false);
  219. },
  220. setMajorTicks: function(/*Object*/ ticks){
  221. // summary:
  222. // Creates and draws the major tick marks based on the passed object (expecting the same format
  223. // as the majorTicks object documented above)
  224. this.majorTicks = this._setTicks(this.majorTicks, ticks, true);
  225. },
  226. postCreate: function(){
  227. if(this.hideValues){
  228. html.style(this.containerNode, "display", "none");
  229. }
  230. html.style(this.mouseNode, 'width', '0');
  231. html.style(this.mouseNode, 'height', '0');
  232. html.style(this.mouseNode, 'position', 'absolute');
  233. html.style(this.mouseNode, 'z-index', '100');
  234. if(this.useTooltip){
  235. require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
  236. Tooltip.show('test', this.mouseNode, !this.isLeftToRight());
  237. Tooltip.hide(this.mouseNode);
  238. }));
  239. }
  240. },
  241. _getNumberModule :function() {
  242. // summary:
  243. // Tests is AMD dojo/number is loaded
  244. if (_numberModule == 0) {
  245. try {
  246. _numberModule = require("dojo/number");
  247. }
  248. catch (e) {
  249. _numberModule = null;
  250. }
  251. }
  252. return _numberModule;
  253. },
  254. createSurface: function(){
  255. // summary:
  256. // Internal method used by the gauge to create the graphics surface area
  257. this.gaugeContent.style.width = this.width + 'px';
  258. this.gaugeContent.style.height = this.height + 'px';
  259. this.surface = gfx.createSurface(this.gaugeContent, this.width, this.height);
  260. // create several groups where various gauge elements will be created.
  261. this._backgroundGroup = this.surface.createGroup();
  262. this._rangeGroup = this.surface.createGroup();
  263. this._minorTicksGroup = this.surface.createGroup();
  264. this._majorTicksGroup = this.surface.createGroup();
  265. this._overlayGroup = this.surface.createGroup();
  266. this._indicatorsGroup = this.surface.createGroup();
  267. this._foregroundGroup = this.surface.createGroup();
  268. this._background = this._backgroundGroup.createRect({x: 0, y: 0, width: this.width, height: this.height });
  269. this._background.setFill(this.background);
  270. if(this.image.url){
  271. var imageGroup = this._backgroundGroup;
  272. if (this.image.overlay)
  273. imageGroup = this._overlayGroup;
  274. this._img = imageGroup.createImage({width: this.image.width || this.width, height: this.image.height || this.height, src: this.image.url});
  275. if(this.image.x || this.image.y){
  276. this._img.setTransform({dx: this.image.x || 0, dy: this.image.y || 0});
  277. }
  278. }
  279. },
  280. draw: function(){
  281. // summary:
  282. // This function is used to draw (or redraw) the gauge.
  283. // description:
  284. // Draws the gauge by drawing the surface, the ranges, and the indicators.
  285. var i;
  286. if (!this.surface)return;
  287. this.drawBackground(this._backgroundGroup);
  288. if(this._rangeData){
  289. for(i=0; i<this._rangeData.length; i++){
  290. this.drawRange(this._rangeGroup, this._rangeData[i]);
  291. }
  292. }
  293. if(this._minorTicksData){
  294. for(i=0; i<this._minorTicksData.length; i++){
  295. this._minorTicksData[i].draw(this._minorTicksGroup);
  296. }
  297. }
  298. if(this._majorTicksData){
  299. for(i=0; i<this._majorTicksData.length; i++){
  300. this._majorTicksData[i].draw(this._majorTicksGroup);
  301. }
  302. }
  303. if(this._indicatorData){
  304. for(i=0; i<this._indicatorData.length; i++){
  305. this._indicatorData[i].draw(this._indicatorsGroup);
  306. }
  307. }
  308. this.drawForeground(this._foregroundGroup);
  309. },
  310. drawBackground:function(group){
  311. // summary:
  312. // This function is used to draw (or redraw) the background of the gauge.
  313. // description:
  314. // The method may be used by subclasses to draw (or redraw) the background of the gauge.
  315. },
  316. drawForeground:function(group){
  317. // summary:
  318. // This function is used to draw (or redraw) the foreground of the gauge.
  319. // description:
  320. // The method may be used by subclasses to draw (or redraw) the foreground of the gauge.
  321. },
  322. setBackground: function(background){
  323. // summary:
  324. // This method is used to set the background of the gauge after it is created.
  325. // description:
  326. // Sets the background using the given object. Must be the same 'type' of object
  327. // as the original background argument.
  328. // background: Object
  329. // An object in one of the two forms:
  330. // {'color': 'color-name'}
  331. // OR
  332. // (for a gradient:)
  333. // {'type': 'linear', 'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}] }
  334. // If background is null or undefined, this will set the fill to this._backgroundDefault
  335. if(!background){ background = this._backgroundDefault; }
  336. this.background = background.color || background;
  337. this._background.setFill(this.background);
  338. },
  339. addRange: function(/*Object*/range){
  340. // summary:
  341. // This method is used to add a range to the gauge.
  342. // description:
  343. // Creates a range (colored area on the background of the gauge)
  344. // based on the given arguments.
  345. // range: Object
  346. // A range is either a dojox.gauges.Range object, or a object
  347. // with similar parameters (low, high, hover, etc.).
  348. this.addRanges([range]);
  349. },
  350. addRanges: function(/*Array*/ranges){
  351. // summary:
  352. // This method is used to add ranges to the gauge.
  353. // description:
  354. // Creates a range (colored area on the background of the gauge)
  355. // based on the given arguments.
  356. // range: Range
  357. // A range is either a dojox.gauges.Range object, or a object
  358. // with similar parameters (low, high, hover, etc.).
  359. if(!this._rangeData){
  360. this._rangeData = [];
  361. }
  362. var range;
  363. for(var i=0; i<ranges.length; i++){
  364. range = ranges[i];
  365. if((this.min === null) || (range.low < this.min)){this.min = range.low;}
  366. if((this.max === null) || (range.high > this.max)){this.max = range.high;}
  367. if(!range.color){
  368. var colorIndex = this._rangeData.length % this.defaultColors.length;
  369. if(gfx.svg && this.useRangeStyles > 0){
  370. colorIndex = (this._rangeData.length % this.useRangeStyles)+1;
  371. range.color = {style: "dojoxGaugeRange"+colorIndex};
  372. }else{
  373. colorIndex = this._rangeData.length % this.defaultColors.length;
  374. range.color = this.defaultColors[colorIndex];
  375. }
  376. }
  377. this._rangeData[this._rangeData.length] = range;
  378. }
  379. this.draw();
  380. },
  381. _addScaleTick: function(/*Object*/indicator, /*Boolean*/ major){
  382. // summary:
  383. // Adds a scale ticks, that is an indicator.
  384. // description:
  385. // This method adds a tick mark to the gauge
  386. // indicator: dojox.gauges._Indicator
  387. // A dojox.gauges._Indicator or an object with similar parameters
  388. // (value, color, offset, etc.).
  389. if(!indicator.declaredClass){// !== 'dojox.gauges.Indicator'){
  390. // We were passed a plain object, need to make an indicator out of it.
  391. indicator = new this._defaultIndicator(indicator);
  392. }
  393. indicator._gauge = this;
  394. if (major){
  395. if (!this._majorTicksData){
  396. this._majorTicksData = [];
  397. }
  398. this._majorTicksData[this._majorTicksData.length] = indicator;
  399. indicator.draw(this._majorTicksGroup);
  400. } else {
  401. if (!this._minorTicksData){
  402. this._minorTicksData = [];
  403. }
  404. this._minorTicksData[this._minorTicksData.length] = indicator;
  405. indicator.draw(this._minorTicksGroup);
  406. }
  407. return indicator;
  408. },
  409. _removeScaleTick: function(/*Object*/indicator){
  410. // summary:
  411. // Removes the given scale tick from the gauge by calling it's remove function
  412. // and removing it from the local cache.
  413. var i;
  414. if (this._majorTicksData) for (i = 0; i < this._majorTicksData.length; i++){
  415. if (this._majorTicksData[i] === indicator){
  416. this._majorTicksData.splice(i, 1);
  417. indicator.remove();
  418. return;
  419. }
  420. }
  421. if (this._minorTicksData) for (i = 0; i < this._minorTicksData.length; i++){
  422. if (this._minorTicksData[i] === indicator){
  423. this._minorTicksData.splice(i, 1);
  424. indicator.remove();
  425. return;
  426. }
  427. }
  428. },
  429. addIndicator: function(/*Object*/indicator){
  430. // summary:
  431. // This method is used to add an indicator to the gauge.
  432. // description:
  433. // This method adds an indicator, such as a t needle,
  434. // to the gauge.
  435. // indicator: dojox.gauges._Indicator
  436. // A dojox.gauges._Indicator or an object with similar parameters
  437. // (value, color, offset, etc.).
  438. if(!indicator.declaredClass){// !== 'dojox.gauges.Indicator'){
  439. // We were passed a plain object, need to make an indicator out of it.
  440. indicator = new this._defaultIndicator(indicator);
  441. }
  442. indicator._gauge = this;
  443. if(!indicator.hideValue){
  444. this.containerNode.appendChild(indicator.domNode);
  445. }
  446. if(!this._indicatorData){this._indicatorData = [];}
  447. this._indicatorData[this._indicatorData.length] = indicator;
  448. indicator.draw(this._indicatorsGroup);
  449. return indicator;
  450. },
  451. removeIndicator: function(/*Object*/indicator){
  452. // summary:
  453. // Removes the given indicator from the gauge by calling it's remove function
  454. // and removing it from the local cache.
  455. // indicator: dojox.gauges._Indicator
  456. // The indicator to remove.
  457. for(var i=0; i<this._indicatorData.length; i++){
  458. if(this._indicatorData[i] === indicator){
  459. this._indicatorData.splice(i, 1);
  460. indicator.remove();
  461. break;
  462. }
  463. }
  464. },
  465. moveIndicatorToFront: function(/*Object*/indicator){
  466. // summary:
  467. // This function is used to move an indicator the the front (top)
  468. // of the gauge
  469. // indicator: dojox.gauges._Indicator
  470. // A dojox.gauges._Indicator or an object with similar parameters
  471. // (value, color, offset, etc.).
  472. if(indicator.shape)
  473. indicator.shape.moveToFront();
  474. },
  475. drawText: function(/*dojox.gfx.Group*/ group, /*String*/txt, /*Number*/x, /*Number*/y, /*String?*/align, /*String?*/color, /*Object?*/font){
  476. // summary:
  477. // This function is used draw text onto the gauge. The text object
  478. // is also returned by the function so that may be removed later
  479. // by calling removeText
  480. // group: dojox.gfx.Group
  481. // The GFX Group where the text will be added.
  482. // txt: String
  483. // The text to be drawn
  484. // x: Number
  485. // The x coordinate at which to place the text
  486. // y: Number
  487. // The y coordinate at which to place the text
  488. // align?: String
  489. // Indicates how to align the text
  490. // Valid value is 'right', otherwise text is left-aligned
  491. // color?: String
  492. // Indicates the color of the text
  493. // font?: Object
  494. // A font object, generally of the following format:
  495. // {family: "Helvetica", style: "italic", variant: 'small-caps', weight: 'bold', size: "18pt"}
  496. var t = group.createText({x: x, y: y, text: txt, align: align});
  497. t.setFill(color ? color: 'black');
  498. if (font) t.setFont(font);
  499. return t;
  500. },
  501. removeText:function(/*String*/t){
  502. // summary:
  503. // Removes a text element from the gauge.
  504. // t: String
  505. // The text to remove.
  506. if (t.parent)
  507. t.parent.remove(t);
  508. },
  509. updateTooltip: function(/*String*/txt, /*Event*/ e){
  510. // summary:
  511. // Updates the tooltip for the gauge to display the given text.
  512. // txt: String
  513. // The text to put in the tooltip.
  514. if (this.useTooltip) {
  515. require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
  516. if (this._lastHover != txt) {
  517. if (txt !== '') {
  518. Tooltip.hide(this.mouseNode);
  519. Tooltip.show(txt, this.mouseNode, !this.isLeftToRight());
  520. } else {
  521. Tooltip.hide(this.mouseNode);
  522. }
  523. this._lastHover = txt;
  524. }
  525. }));
  526. }
  527. },
  528. handleMouseOver: function(/*Object*/e){
  529. // summary:
  530. // This is an internal handler used by the gauge to support
  531. // hover text
  532. // e: Object
  533. // The event object
  534. if (this.image && this.image.overlay){
  535. if (e.target == this._img.getEventSource()){
  536. var hover;
  537. this._overOverlay = true;
  538. var r = this.getRangeUnderMouse(e);
  539. if (r && r.hover){
  540. hover = r.hover;
  541. }
  542. if (this.useTooltip && !this._drag){
  543. if (hover){
  544. this.updateTooltip(hover, e);
  545. } else {
  546. this.updateTooltip('', e);
  547. }
  548. }
  549. }
  550. }
  551. },
  552. handleMouseOut: function(/*Object*/e){
  553. // summary:
  554. // This is an internal handler used by the gauge to support
  555. // hover text
  556. // e: Object
  557. // The event object
  558. this._overOverlay = false;
  559. this._hideTooltip();
  560. },
  561. handleMouseMove: function(/*Object*/e){
  562. // summary:
  563. // This is an internal handler used by the gauge to support using
  564. // the mouse to show the tooltips
  565. // e: Object
  566. // The event object
  567. if (this.useTooltip) {
  568. if (e) {
  569. html.style(this.mouseNode, 'left', e.pageX + 1 + 'px');
  570. html.style(this.mouseNode, 'top', e.pageY + 1 + 'px');
  571. }
  572. if (this._overOverlay) {
  573. var r = this.getRangeUnderMouse(e);
  574. if (r && r.hover) {
  575. this.updateTooltip(r.hover, e);
  576. } else {
  577. this.updateTooltip('', e);
  578. }
  579. }
  580. }
  581. },
  582. handleMouseDown: function(e){
  583. // summary:
  584. // This is an internal handler used by the gauge to support using
  585. // the mouse to move indicators
  586. // e: Object
  587. // The event object
  588. var indicator = this._getInteractiveIndicator();
  589. if (indicator){
  590. this._handleMouseDownIndicator(indicator, e);
  591. }
  592. },
  593. _handleDragInteractionMouseMove: function(e){
  594. // summary:
  595. // This is an internal handler used by the gauge to support using
  596. // the mouse to drag an indicator to modify it's value
  597. // e: Object
  598. // The event object
  599. if(this._drag){
  600. this._dragIndicator(this, e);
  601. event.stop(e);
  602. }
  603. },
  604. _handleDragInteractionMouseUp: function(/*Object*/e){
  605. // summary:
  606. // This is an internal handler used by the gauge to support using
  607. // the mouse to drag an indicator to modify it's value
  608. // e: Object
  609. // The event object
  610. this._drag = null;
  611. for (var i = 0 ; i < this._mouseListeners.length; i++){
  612. connect.disconnect(this._mouseListeners[i]);
  613. }
  614. this._mouseListeners = [];
  615. event.stop(e);
  616. },
  617. _handleMouseDownIndicator: function (indicator, e){
  618. // summary:
  619. // This is an internal handler used by the gauge to support using
  620. // the mouse to drag an indicator to modify it's value
  621. // indicator: _Indicator
  622. // The indicator object
  623. // e:Object
  624. // The event object
  625. if (!indicator.noChange){
  626. if (!this._mouseListeners) this._mouseListeners = [];
  627. this._drag = indicator;
  628. this._mouseListeners.push(connect.connect(document, "onmouseup", this, this._handleDragInteractionMouseUp));
  629. this._mouseListeners.push(connect.connect(document, "onmousemove", this, this._handleDragInteractionMouseMove));
  630. this._mouseListeners.push(connect.connect(document, "ondragstart", this, event.stop));
  631. this._mouseListeners.push(connect.connect(document, "onselectstart", this, event.stop));
  632. this._dragIndicator(this, e);
  633. event.stop(e);
  634. }
  635. },
  636. _handleMouseOverIndicator: function (indicator, e){
  637. // summary:
  638. // This is an internal handler used by the gauge to support using
  639. // the mouse to drag an indicator to modify it's value
  640. // indicator: _Indicator
  641. // The indicator object
  642. // e: Object
  643. // The event object
  644. if (this.useTooltip && !this._drag){
  645. if (indicator.hover){
  646. require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
  647. html.style(this.mouseNode, 'left', e.pageX + 1 + 'px');
  648. html.style(this.mouseNode, 'top', e.pageY + 1 + 'px');
  649. Tooltip.show(indicator.hover, this.mouseNode, !this.isLeftToRight());
  650. }));
  651. } else {
  652. this.updateTooltip('', e);
  653. }
  654. }
  655. if (indicator.onDragMove && !indicator.noChange){
  656. this.gaugeContent.style.cursor = 'pointer';
  657. }
  658. },
  659. _handleMouseOutIndicator: function (indicator, e){
  660. // summary:
  661. // This is an internal handler used by the gauge to support using
  662. // the mouse to drag an indicator to modify it's value
  663. // indicator: _Indicator
  664. // The indicator object
  665. // e: Object
  666. // The event object
  667. this._hideTooltip();
  668. this.gaugeContent.style.cursor = 'pointer';
  669. },
  670. _hideTooltip: function(){
  671. if (this.useTooltip && this.mouseNode) {
  672. require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
  673. Tooltip.hide(this.mouseNode);
  674. }));
  675. }
  676. },
  677. _handleMouseOutRange: function ( range, e){
  678. this._hideTooltip();
  679. },
  680. _handleMouseOverRange: function (range, e){
  681. if (this.useTooltip && !this._drag){
  682. if (range.hover) {
  683. html.style(this.mouseNode, 'left', e.pageX + 1 + 'px');
  684. html.style(this.mouseNode, 'top', e.pageY + 1 + 'px');
  685. require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
  686. Tooltip.show(range.hover, this.mouseNode, !this.isLeftToRight());
  687. }));
  688. } else {
  689. this.updateTooltip('', e);
  690. }
  691. }
  692. },
  693. handleTouchStartIndicator: function(indicator, e){
  694. // summary:
  695. // This is an internal handler used by the gauge to support using
  696. // touch events to drag an indicator to modify it's value
  697. // indicator: _Indicator
  698. // The indicator object
  699. // e: Object
  700. // The event object
  701. if (!indicator.noChange){
  702. this._drag = indicator;
  703. event.stop(e);
  704. }
  705. },
  706. handleTouchStart: function(e){
  707. // summary:
  708. // This is an internal handler used by the gauge to support using
  709. // touch events to drag an indicator to modify it's value
  710. // e: Object
  711. // The touch event object
  712. this._drag = this._getInteractiveIndicator();
  713. this.handleTouchMove(e); //drag indicator to touch position
  714. },
  715. handleTouchEnd: function(e){
  716. // summary:
  717. // This is an internal handler used by the gauge to support using
  718. // touch events to drag an indicator to modify it's value
  719. // e: Object
  720. // The touch e object
  721. if (this._drag){
  722. this._drag = null;
  723. event.stop(e);
  724. }
  725. },
  726. handleTouchMove: function(e){
  727. // summary:
  728. // This is an internal handler used by the gauge to support using
  729. // touch events to drag an indicator to modify it's value
  730. // e: Object
  731. // The touch event object
  732. if (this._drag && !this._drag.noChange){
  733. var touches = e.touches;
  734. var firstTouch = touches[0];
  735. this._dragIndicatorAt(this, firstTouch.pageX, firstTouch.pageY);
  736. event.stop(e);
  737. }
  738. },
  739. _getInteractiveIndicator: function(){
  740. for (var i = 0; i < this._indicatorData.length; i++){
  741. var indicator = this._indicatorData[i];
  742. if (indicator.interactionMode == "gauge" && !indicator.noChange){
  743. return indicator;
  744. }
  745. }
  746. return null;
  747. }
  748. });
  749. });