Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

273 rader
10 KiB

  1. /**
  2. * Copyright (c) 2009 Chris Leonello
  3. * jqPlot is currently available for use in all personal or commercial projects
  4. * under both the MIT and GPL version 2.0 licenses. This means that you can
  5. * choose the license that best suits your project and use it accordingly.
  6. *
  7. * The author would appreciate an email letting him know of any substantial
  8. * use of jqPlot. You can reach the author at: chris dot leonello at gmail
  9. * dot com or see http://www.jqplot.com/info.php . This is, of course,
  10. * not required.
  11. *
  12. * If you are feeling kind and generous, consider supporting the project by
  13. * making a donation at: http://www.jqplot.com/donate.php .
  14. *
  15. * Thanks for using jqPlot!
  16. *
  17. */
  18. (function($) {
  19. /**
  20. * Class: $.jqplot.PointLabels
  21. * Plugin for putting labels at the data points.
  22. *
  23. * To use this plugin, include the js
  24. * file in your source:
  25. *
  26. * > <script type="text/javascript" src="plugins/jqplot.pointLabels.js"></script>
  27. *
  28. * By default, the last value in the data ponit array in the data series is used
  29. * for the label. For most series renderers, extra data can be added to the
  30. * data point arrays and the last value will be used as the label.
  31. *
  32. * For instance,
  33. * this series:
  34. *
  35. * > [[1,4], [3,5], [7,2]]
  36. *
  37. * Would, by default, use the y values in the labels.
  38. * Extra data can be added to the series like so:
  39. *
  40. * > [[1,4,'mid'], [3 5,'hi'], [7,2,'low']]
  41. *
  42. * And now the point labels would be 'mid', 'low', and 'hi'.
  43. *
  44. * Options to the point labels and a custom labels array can be passed into the
  45. * "pointLabels" option on the series option like so:
  46. *
  47. * > series:[{pointLabels:{
  48. * > labels:['mid', 'hi', 'low'],
  49. * > location:'se',
  50. * > ypadding: 12
  51. * > }
  52. * > }]
  53. *
  54. * A custom labels array in the options takes precendence over any labels
  55. * in the series data. If you have a custom labels array in the options,
  56. * but still want to use values from the series array as labels, set the
  57. * "labelsFromSeries" option to true.
  58. *
  59. * By default, html entities (<, >, etc.) are escaped in point labels.
  60. * If you want to include actual html markup in the labels,
  61. * set the "escapeHTML" option to false.
  62. *
  63. */
  64. $.jqplot.PointLabels = function(options) {
  65. // Group: Properties
  66. //
  67. // prop: show
  68. // show the labels or not.
  69. this.show = $.jqplot.config.enablePlugins;
  70. // prop: location
  71. // compass location where to position the label around the point.
  72. // 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'
  73. this.location = 'n';
  74. // prop: labelsFromSeries
  75. // true to use labels within data point arrays.
  76. this.labelsFromSeries = false;
  77. // prop: seriesLabelIndex
  78. // array index for location of labels within data point arrays.
  79. // if null, will use the last element of teh data point array.
  80. this.seriesLabelIndex = null;
  81. // prop: labels
  82. // array of arrays of labels, one array for each series.
  83. this.labels = [];
  84. // prop: stackedValue
  85. // true to display value as stacked in a stacked plot.
  86. // no effect if labels is specified.
  87. this.stackedValue = false;
  88. // prop: ypadding
  89. // vertical padding in pixels between point and label
  90. this.ypadding = 6;
  91. // prop: xpadding
  92. // horizontal padding in pixels between point and label
  93. this.xpadding = 6;
  94. // prop: escapeHTML
  95. // true to escape html entities in the labels.
  96. // If you want to include markup in the labels, set to false.
  97. this.escapeHTML = true;
  98. // prop: edgeTolerance
  99. // Number of pixels that the label must be away from an axis
  100. // boundary in order to be drawn. Negative values will allow overlap
  101. // with the grid boundaries.
  102. this.edgeTolerance = 0;
  103. // prop: hideZeros
  104. // true to not show a label for a value which is 0.
  105. this.hideZeros = false;
  106. // prop: formatString
  107. // format string to format label value
  108. this.formatString = '';
  109. // prop: formatter
  110. // formatter function to use with format string.
  111. this.formatter = $.jqplot.sprintf;
  112. $.extend(true, this, options);
  113. };
  114. var locations = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];
  115. var locationIndicies = {'nw':0, 'n':1, 'ne':2, 'e':3, 'se':4, 's':5, 'sw':6, 'w':7};
  116. var oppositeLocations = ['se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'];
  117. // called with scope of a series
  118. $.jqplot.PointLabels.init = function (target, data, seriesDefaults, opts){
  119. var options = $.extend(true, {}, seriesDefaults, opts);
  120. // add a pointLabels attribute to the series plugins
  121. this.plugins.pointLabels = new $.jqplot.PointLabels(options.pointLabels);
  122. var p = this.plugins.pointLabels;
  123. if (p.labels.length == 0 || p.labelsFromSeries) {
  124. if (p.stackedValue) {
  125. if (this._plotData.length && this._plotData[0].length){
  126. var idx = p.seriesLabelIndex || this._plotData[0].length -1;
  127. for (var i=0; i<this._plotData.length; i++) {
  128. p.labels.push(this._plotData[i][idx]);
  129. }
  130. }
  131. }
  132. else {
  133. var d = this.data;
  134. if (this.renderer.constructor == $.jqplot.BarRenderer && this.waterfall) {
  135. d = this._data;
  136. }
  137. if (d.length && d[0].length) {
  138. var idx = p.seriesLabelIndex || d[0].length -1;
  139. for (var i=0; i<d.length; i++) {
  140. p.labels.push(d[i][idx]);
  141. }
  142. }
  143. }
  144. }
  145. };
  146. $.jqplot.PointLabels.prototype.xOffset = function(elem, location, padding) {
  147. location = location || this.location;
  148. padding = padding || this.xpadding;
  149. var offset;
  150. switch (location) {
  151. case 'nw':
  152. offset = -elem.outerWidth(true) - this.xpadding;
  153. break;
  154. case 'n':
  155. offset = -elem.outerWidth(true)/2;
  156. break;
  157. case 'ne':
  158. offset = this.xpadding;
  159. break;
  160. case 'e':
  161. offset = this.xpadding;
  162. break;
  163. case 'se':
  164. offset = this.xpadding;
  165. break;
  166. case 's':
  167. offset = -elem.outerWidth(true)/2;
  168. break;
  169. case 'sw':
  170. offset = -elem.outerWidth(true) - this.xpadding;
  171. break;
  172. case 'w':
  173. offset = -elem.outerWidth(true) - this.xpadding;
  174. break;
  175. default: // same as 'nw'
  176. offset = -elem.outerWidth(true) - this.xpadding;
  177. break;
  178. }
  179. return offset;
  180. };
  181. $.jqplot.PointLabels.prototype.yOffset = function(elem, location, padding) {
  182. location = location || this.location;
  183. padding = padding || this.xpadding;
  184. var offset;
  185. switch (location) {
  186. case 'nw':
  187. offset = -elem.outerHeight(true) - this.ypadding;
  188. break;
  189. case 'n':
  190. offset = -elem.outerHeight(true) - this.ypadding;
  191. break;
  192. case 'ne':
  193. offset = -elem.outerHeight(true) - this.ypadding;
  194. break;
  195. case 'e':
  196. offset = -elem.outerHeight(true)/2;
  197. break;
  198. case 'se':
  199. offset = this.ypadding;
  200. break;
  201. case 's':
  202. offset = this.ypadding;
  203. break;
  204. case 'sw':
  205. offset = this.ypadding;
  206. break;
  207. case 'w':
  208. offset = -elem.outerHeight(true)/2;
  209. break;
  210. default: // same as 'nw'
  211. offset = -elem.outerHeight(true) - this.ypadding;
  212. break;
  213. }
  214. return offset;
  215. };
  216. // called with scope of series
  217. $.jqplot.PointLabels.draw = function (sctx, options) {
  218. var p = this.plugins.pointLabels;
  219. if (p.show) {
  220. for (var i=0; i<p.labels.length; i++) {
  221. var pd = this._plotData;
  222. var xax = this._xaxis;
  223. var yax = this._yaxis;
  224. var label = p.labels[i];
  225. if (p.hideZeros && parseInt(p.labels[i], 10) == 0) {
  226. label = '';
  227. }
  228. var elem = $('<div class="jqplot-point-label" style="position:absolute"></div>');
  229. elem.insertAfter(sctx.canvas);
  230. if (p.escapeHTML) {
  231. elem.text(label);
  232. }
  233. else {
  234. elem.html(label);
  235. }
  236. var location = p.location;
  237. if (this.waterfall && parseInt(label, 10) < 0) {
  238. location = oppositeLocations[locationIndicies[location]];
  239. }
  240. var ell = xax.u2p(pd[i][0]) + p.xOffset(elem, location);
  241. var elt = yax.u2p(pd[i][1]) + p.yOffset(elem, location);
  242. elem.css('left', ell);
  243. elem.css('top', elt);
  244. var elr = ell + $(elem).width();
  245. var elb = elt + $(elem).height();
  246. var et = p.edgeTolerance;
  247. var scl = $(sctx.canvas).position().left;
  248. var sct = $(sctx.canvas).position().top;
  249. var scr = sctx.canvas.width + scl;
  250. var scb = sctx.canvas.height + sct;
  251. // if label is outside of allowed area, remove it
  252. if (ell - et < scl || elt - et < sct || elr + et > scr || elb + et > scb) {
  253. $(elem).remove();
  254. }
  255. }
  256. }
  257. };
  258. $.jqplot.postSeriesInitHooks.push($.jqplot.PointLabels.init);
  259. $.jqplot.postDrawSeriesHooks.push($.jqplot.PointLabels.draw);
  260. })(jQuery);