solid-gauge.src.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /**
  2. * @license Highcharts JS v4.1.5 (2015-04-13)
  3. * Solid angular gauge module
  4. *
  5. * (c) 2010-2014 Torstein Honsi
  6. *
  7. * License: www.highcharts.com/license
  8. */
  9. /*global Highcharts, HighchartsAdapter*/
  10. (function (H) {
  11. "use strict";
  12. var defaultPlotOptions = H.getOptions().plotOptions,
  13. pInt = H.pInt,
  14. pick = H.pick,
  15. each = H.each,
  16. colorAxisMethods,
  17. UNDEFINED;
  18. // The default options
  19. defaultPlotOptions.solidgauge = H.merge(defaultPlotOptions.gauge, {
  20. colorByPoint: true
  21. });
  22. // These methods are defined in the ColorAxis object, and copied here.
  23. // If we implement an AMD system we should make ColorAxis a dependency.
  24. colorAxisMethods = {
  25. initDataClasses: function (userOptions) {
  26. var axis = this,
  27. chart = this.chart,
  28. dataClasses,
  29. colorCounter = 0,
  30. options = this.options;
  31. this.dataClasses = dataClasses = [];
  32. each(userOptions.dataClasses, function (dataClass, i) {
  33. var colors;
  34. dataClass = H.merge(dataClass);
  35. dataClasses.push(dataClass);
  36. if (!dataClass.color) {
  37. if (options.dataClassColor === 'category') {
  38. colors = chart.options.colors;
  39. dataClass.color = colors[colorCounter++];
  40. // loop back to zero
  41. if (colorCounter === colors.length) {
  42. colorCounter = 0;
  43. }
  44. } else {
  45. dataClass.color = axis.tweenColors(H.Color(options.minColor), H.Color(options.maxColor), i / (userOptions.dataClasses.length - 1));
  46. }
  47. }
  48. });
  49. },
  50. initStops: function (userOptions) {
  51. this.stops = userOptions.stops || [
  52. [0, this.options.minColor],
  53. [1, this.options.maxColor]
  54. ];
  55. each(this.stops, function (stop) {
  56. stop.color = H.Color(stop[1]);
  57. });
  58. },
  59. /**
  60. * Translate from a value to a color
  61. */
  62. toColor: function (value, point) {
  63. var pos,
  64. stops = this.stops,
  65. from,
  66. to,
  67. color,
  68. dataClasses = this.dataClasses,
  69. dataClass,
  70. i;
  71. if (dataClasses) {
  72. i = dataClasses.length;
  73. while (i--) {
  74. dataClass = dataClasses[i];
  75. from = dataClass.from;
  76. to = dataClass.to;
  77. if ((from === UNDEFINED || value >= from) && (to === UNDEFINED || value <= to)) {
  78. color = dataClass.color;
  79. if (point) {
  80. point.dataClass = i;
  81. }
  82. break;
  83. }
  84. }
  85. } else {
  86. if (this.isLog) {
  87. value = this.val2lin(value);
  88. }
  89. pos = 1 - ((this.max - value) / (this.max - this.min));
  90. i = stops.length;
  91. while (i--) {
  92. if (pos > stops[i][0]) {
  93. break;
  94. }
  95. }
  96. from = stops[i] || stops[i + 1];
  97. to = stops[i + 1] || from;
  98. // The position within the gradient
  99. pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
  100. color = this.tweenColors(
  101. from.color,
  102. to.color,
  103. pos
  104. );
  105. }
  106. return color;
  107. },
  108. /*
  109. * Return an intermediate color between two colors, according to pos where 0
  110. * is the from color and 1 is the to color.
  111. */
  112. tweenColors: function (from, to, pos) {
  113. // Check for has alpha, because rgba colors perform worse due to lack of
  114. // support in WebKit.
  115. var hasAlpha,
  116. ret;
  117. // Unsupported color, return to-color (#3920)
  118. if (!to.rgba.length || !from.rgba.length) {
  119. ret = to.raw || 'none';
  120. // Interpolate
  121. } else {
  122. from = from.rgba;
  123. to = to.rgba;
  124. hasAlpha = (to[3] !== 1 || from[3] !== 1);
  125. ret = (hasAlpha ? 'rgba(' : 'rgb(') +
  126. Math.round(to[0] + (from[0] - to[0]) * (1 - pos)) + ',' +
  127. Math.round(to[1] + (from[1] - to[1]) * (1 - pos)) + ',' +
  128. Math.round(to[2] + (from[2] - to[2]) * (1 - pos)) +
  129. (hasAlpha ? (',' + (to[3] + (from[3] - to[3]) * (1 - pos))) : '') + ')';
  130. }
  131. return ret;
  132. }
  133. };
  134. /**
  135. * Handle animation of the color attributes directly
  136. */
  137. each(['fill', 'stroke'], function (prop) {
  138. HighchartsAdapter.addAnimSetter(prop, function (fx) {
  139. fx.elem.attr(prop, colorAxisMethods.tweenColors(H.Color(fx.start), H.Color(fx.end), fx.pos));
  140. });
  141. });
  142. // The series prototype
  143. H.seriesTypes.solidgauge = H.extendClass(H.seriesTypes.gauge, {
  144. type: 'solidgauge',
  145. bindAxes: function () {
  146. var axis;
  147. H.seriesTypes.gauge.prototype.bindAxes.call(this);
  148. axis = this.yAxis;
  149. H.extend(axis, colorAxisMethods);
  150. // Prepare data classes
  151. if (axis.options.dataClasses) {
  152. axis.initDataClasses(axis.options);
  153. }
  154. axis.initStops(axis.options);
  155. },
  156. /**
  157. * Draw the points where each point is one needle
  158. */
  159. drawPoints: function () {
  160. var series = this,
  161. yAxis = series.yAxis,
  162. center = yAxis.center,
  163. options = series.options,
  164. renderer = series.chart.renderer,
  165. overshoot = options.overshoot,
  166. overshootVal = overshoot && typeof overshoot === 'number' ? overshoot / 180 * Math.PI : 0;
  167. H.each(series.points, function (point) {
  168. var graphic = point.graphic,
  169. rotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true),
  170. radius = (pInt(pick(point.options.radius, options.radius, 100)) * center[2]) / 200, // docs: series<solidgauge>.data.radius http://jsfiddle.net/highcharts/7nwebu4b/
  171. innerRadius = (pInt(pick(point.options.innerRadius, options.innerRadius, 60)) * center[2]) / 200, // docs: series<solidgauge>.data.innerRadius
  172. shapeArgs,
  173. d,
  174. toColor = yAxis.toColor(point.y, point),
  175. fromColor;
  176. if (toColor === 'none') { // #3708
  177. toColor = point.color || series.color || 'none';
  178. }
  179. if (toColor !== 'none') {
  180. fromColor = point.color;
  181. point.color = toColor;
  182. }
  183. // Handle overshoot and clipping to axis max/min
  184. rotation = Math.max(yAxis.startAngleRad - overshootVal, Math.min(yAxis.endAngleRad + overshootVal, rotation));
  185. // Handle the wrap option
  186. if (options.wrap === false) {
  187. rotation = Math.max(yAxis.startAngleRad, Math.min(yAxis.endAngleRad, rotation));
  188. }
  189. rotation = rotation * 180 / Math.PI;
  190. var angle1 = rotation / (180 / Math.PI),
  191. angle2 = yAxis.startAngleRad,
  192. minAngle = Math.min(angle1, angle2),
  193. maxAngle = Math.max(angle1, angle2);
  194. if (maxAngle - minAngle > 2 * Math.PI) {
  195. maxAngle = minAngle + 2 * Math.PI;
  196. }
  197. point.shapeArgs = shapeArgs = {
  198. x: center[0],
  199. y: center[1],
  200. r: radius,
  201. innerR: innerRadius,
  202. start: minAngle,
  203. end: maxAngle,
  204. fill: toColor
  205. };
  206. point.startR = radius; // For PieSeries.animate
  207. if (graphic) {
  208. d = shapeArgs.d;
  209. graphic.animate(shapeArgs);
  210. shapeArgs.d = d; // animate alters it
  211. } else {
  212. point.graphic = renderer.arc(shapeArgs)
  213. .attr({
  214. stroke: options.borderColor || 'none',
  215. 'stroke-width': options.borderWidth || 0,
  216. fill: toColor,
  217. 'sweep-flag': 0
  218. })
  219. .add(series.group);
  220. }
  221. });
  222. },
  223. /**
  224. * Extend the pie slice animation by animating from start angle and up
  225. */
  226. animate: function (init) {
  227. if (!init) {
  228. this.startAngleRad = this.yAxis.startAngleRad;
  229. H.seriesTypes.pie.prototype.animate.call(this, init);
  230. }
  231. }
  232. });
  233. }(Highcharts));