You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
6.8 KiB

9 years ago
  1. /**
  2. * @license Highcharts JS v4.1.8 (2015-08-20)
  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. pointAttrToOptions: {}, // #4301, don't inherit line marker's attribs
  146. bindAxes: function () {
  147. var axis;
  148. H.seriesTypes.gauge.prototype.bindAxes.call(this);
  149. axis = this.yAxis;
  150. H.extend(axis, colorAxisMethods);
  151. // Prepare data classes
  152. if (axis.options.dataClasses) {
  153. axis.initDataClasses(axis.options);
  154. }
  155. axis.initStops(axis.options);
  156. },
  157. /**
  158. * Draw the points where each point is one needle
  159. */
  160. drawPoints: function () {
  161. var series = this,
  162. yAxis = series.yAxis,
  163. center = yAxis.center,
  164. options = series.options,
  165. renderer = series.chart.renderer,
  166. overshoot = options.overshoot,
  167. overshootVal = overshoot && typeof overshoot === 'number' ? overshoot / 180 * Math.PI : 0;
  168. H.each(series.points, function (point) {
  169. var graphic = point.graphic,
  170. rotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true),
  171. radius = (pInt(pick(point.options.radius, options.radius, 100)) * center[2]) / 200,
  172. innerRadius = (pInt(pick(point.options.innerRadius, options.innerRadius, 60)) * center[2]) / 200,
  173. shapeArgs,
  174. d,
  175. toColor = yAxis.toColor(point.y, point),
  176. fromColor,
  177. axisMinAngle = Math.min(yAxis.startAngleRad, yAxis.endAngleRad),
  178. axisMaxAngle = Math.max(yAxis.startAngleRad, yAxis.endAngleRad),
  179. minAngle,
  180. maxAngle;
  181. if (toColor === 'none') { // #3708
  182. toColor = point.color || series.color || 'none';
  183. }
  184. if (toColor !== 'none') {
  185. fromColor = point.color;
  186. point.color = toColor;
  187. }
  188. // Handle overshoot and clipping to axis max/min
  189. rotation = Math.max(axisMinAngle - overshootVal, Math.min(axisMaxAngle + overshootVal, rotation));
  190. // Handle the wrap option
  191. if (options.wrap === false) {
  192. rotation = Math.max(axisMinAngle, Math.min(axisMaxAngle, rotation));
  193. }
  194. minAngle = Math.min(rotation, yAxis.startAngleRad);
  195. maxAngle = Math.max(rotation, yAxis.startAngleRad);
  196. if (maxAngle - minAngle > 2 * Math.PI) {
  197. maxAngle = minAngle + 2 * Math.PI;
  198. }
  199. point.shapeArgs = shapeArgs = {
  200. x: center[0],
  201. y: center[1],
  202. r: radius,
  203. innerR: innerRadius,
  204. start: minAngle,
  205. end: maxAngle,
  206. fill: toColor
  207. };
  208. point.startR = radius; // For PieSeries.animate
  209. if (graphic) {
  210. d = shapeArgs.d;
  211. graphic.animate(shapeArgs);
  212. if (d) {
  213. shapeArgs.d = d; // animate alters it
  214. }
  215. } else {
  216. point.graphic = renderer.arc(shapeArgs)
  217. .attr({
  218. stroke: options.borderColor || 'none',
  219. 'stroke-width': options.borderWidth || 0,
  220. fill: toColor,
  221. 'sweep-flag': 0
  222. })
  223. .add(series.group);
  224. }
  225. });
  226. },
  227. /**
  228. * Extend the pie slice animation by animating from start angle and up
  229. */
  230. animate: function (init) {
  231. if (!init) {
  232. this.startAngleRad = this.yAxis.startAngleRad;
  233. H.seriesTypes.pie.prototype.animate.call(this, init);
  234. }
  235. }
  236. });
  237. }(Highcharts));