solid-gauge.src.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /**
  2. * @license Highcharts JS v6.1.0 (2018-04-13)
  3. * Solid angular gauge module
  4. *
  5. * (c) 2010-2017 Torstein Honsi
  6. *
  7. * License: www.highcharts.com/license
  8. */
  9. 'use strict';
  10. (function (factory) {
  11. if (typeof module === 'object' && module.exports) {
  12. module.exports = factory;
  13. } else {
  14. factory(Highcharts);
  15. }
  16. }(function (Highcharts) {
  17. (function (H) {
  18. /**
  19. * Solid angular gauge module
  20. *
  21. * (c) 2010-2017 Torstein Honsi
  22. *
  23. * License: www.highcharts.com/license
  24. */
  25. var pInt = H.pInt,
  26. pick = H.pick,
  27. each = H.each,
  28. isNumber = H.isNumber,
  29. wrap = H.wrap,
  30. Renderer = H.Renderer,
  31. colorAxisMethods;
  32. /**
  33. * Symbol definition of an arc with round edges.
  34. *
  35. * @param {Number} x - The X coordinate for the top left position.
  36. * @param {Number} y - The Y coordinate for the top left position.
  37. * @param {Number} w - The pixel width.
  38. * @param {Number} h - The pixel height.
  39. * @param {Object} [options] - Additional options, depending on the actual
  40. * symbol drawn.
  41. * @param {boolean} [options.rounded] - Whether to draw rounded edges.
  42. * @return {Array} Path of the created arc.
  43. */
  44. wrap(
  45. Renderer.prototype.symbols,
  46. 'arc',
  47. function (proceed, x, y, w, h, options) {
  48. var arc = proceed,
  49. path = arc(x, y, w, h, options);
  50. if (options.rounded) {
  51. var r = options.r || w,
  52. smallR = (r - options.innerR) / 2,
  53. x1 = path[1],
  54. y1 = path[2],
  55. x2 = path[12],
  56. y2 = path[13],
  57. roundStart = ['A', smallR, smallR, 0, 1, 1, x1, y1],
  58. roundEnd = ['A', smallR, smallR, 0, 1, 1, x2, y2];
  59. // Insert rounded edge on end, and remove line.
  60. path.splice.apply(path, [path.length - 1, 0].concat(roundStart));
  61. // Insert rounded edge on end, and remove line.
  62. path.splice.apply(path, [11, 3].concat(roundEnd));
  63. }
  64. return path;
  65. }
  66. );
  67. // These methods are defined in the ColorAxis object, and copied here.
  68. // If we implement an AMD system we should make ColorAxis a dependency.
  69. colorAxisMethods = {
  70. initDataClasses: function (userOptions) {
  71. var chart = this.chart,
  72. dataClasses,
  73. colorCounter = 0,
  74. options = this.options;
  75. this.dataClasses = dataClasses = [];
  76. each(userOptions.dataClasses, function (dataClass, i) {
  77. var colors;
  78. dataClass = H.merge(dataClass);
  79. dataClasses.push(dataClass);
  80. if (!dataClass.color) {
  81. if (options.dataClassColor === 'category') {
  82. colors = chart.options.colors;
  83. dataClass.color = colors[colorCounter++];
  84. // loop back to zero
  85. if (colorCounter === colors.length) {
  86. colorCounter = 0;
  87. }
  88. } else {
  89. dataClass.color = H.color(options.minColor).tweenTo(
  90. H.color(options.maxColor),
  91. i / (userOptions.dataClasses.length - 1)
  92. );
  93. }
  94. }
  95. });
  96. },
  97. initStops: function (userOptions) {
  98. this.stops = userOptions.stops || [
  99. [0, this.options.minColor],
  100. [1, this.options.maxColor]
  101. ];
  102. each(this.stops, function (stop) {
  103. stop.color = H.color(stop[1]);
  104. });
  105. },
  106. /**
  107. * Translate from a value to a color
  108. */
  109. toColor: function (value, point) {
  110. var pos,
  111. stops = this.stops,
  112. from,
  113. to,
  114. color,
  115. dataClasses = this.dataClasses,
  116. dataClass,
  117. i;
  118. if (dataClasses) {
  119. i = dataClasses.length;
  120. while (i--) {
  121. dataClass = dataClasses[i];
  122. from = dataClass.from;
  123. to = dataClass.to;
  124. if (
  125. (from === undefined || value >= from) &&
  126. (to === undefined || value <= to)
  127. ) {
  128. color = dataClass.color;
  129. if (point) {
  130. point.dataClass = i;
  131. }
  132. break;
  133. }
  134. }
  135. } else {
  136. if (this.isLog) {
  137. value = this.val2lin(value);
  138. }
  139. pos = 1 - ((this.max - value) / (this.max - this.min));
  140. i = stops.length;
  141. while (i--) {
  142. if (pos > stops[i][0]) {
  143. break;
  144. }
  145. }
  146. from = stops[i] || stops[i + 1];
  147. to = stops[i + 1] || from;
  148. // The position within the gradient
  149. pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
  150. color = from.color.tweenTo(
  151. to.color,
  152. pos
  153. );
  154. }
  155. return color;
  156. }
  157. };
  158. /**
  159. * A solid gauge is a circular gauge where the value is indicated by a filled
  160. * arc, and the color of the arc may variate with the value.
  161. *
  162. * @sample highcharts/demo/gauge-solid/ Solid gauges
  163. * @extends plotOptions.gauge
  164. * @excluding dial,pivot,wrap
  165. * @product highcharts
  166. * @optionparent plotOptions.solidgauge
  167. */
  168. var solidGaugeOptions = {
  169. /**
  170. * Whether the strokes of the solid gauge should be `round` or `square`.
  171. *
  172. * @validvalue ["square", "round"]
  173. * @type {String}
  174. * @sample {highcharts} highcharts/demo/gauge-activity/ Rounded gauge
  175. * @default round
  176. * @since 4.2.2
  177. * @product highcharts
  178. * @apioption plotOptions.solidgauge.linecap
  179. */
  180. /**
  181. * Allow the gauge to overshoot the end of the perimeter axis by this
  182. * many degrees. Say if the gauge axis goes from 0 to 60, a value of
  183. * 100, or 1000, will show 5 degrees beyond the end of the axis when this
  184. * option is set to 5.
  185. *
  186. * @type {Number}
  187. * @default 0
  188. * @since 3.0.10
  189. * @product highcharts
  190. * @apioption plotOptions.solidgauge.overshoot
  191. */
  192. /**
  193. * Wether to draw rounded edges on the gauge.
  194. *
  195. * @type {Boolean}
  196. * @sample {highcharts} highcharts/demo/gauge-activity/ Activity Gauge
  197. * @default false
  198. * @since 5.0.8
  199. * @product highcharts
  200. * @apioption plotOptions.solidgauge.rounded
  201. */
  202. /**
  203. * The threshold or base level for the gauge.
  204. *
  205. * @type {Number}
  206. * @sample {highcharts} highcharts/plotoptions/solidgauge-threshold/
  207. * Zero threshold with negative and positive values
  208. * @default null
  209. * @since 5.0.3
  210. * @product highcharts
  211. * @apioption plotOptions.solidgauge.threshold
  212. */
  213. /**
  214. * Whether to give each point an individual color.
  215. */
  216. colorByPoint: true
  217. };
  218. // The solidgauge series type
  219. H.seriesType('solidgauge', 'gauge', solidGaugeOptions, {
  220. /**
  221. * Extend the translate function to extend the Y axis with the necessary
  222. * decoration (#5895).
  223. */
  224. translate: function () {
  225. var axis = this.yAxis;
  226. H.extend(axis, colorAxisMethods);
  227. // Prepare data classes
  228. if (!axis.dataClasses && axis.options.dataClasses) {
  229. axis.initDataClasses(axis.options);
  230. }
  231. axis.initStops(axis.options);
  232. // Generate points and inherit data label position
  233. H.seriesTypes.gauge.prototype.translate.call(this);
  234. },
  235. /**
  236. * Draw the points where each point is one needle
  237. */
  238. drawPoints: function () {
  239. var series = this,
  240. yAxis = series.yAxis,
  241. center = yAxis.center,
  242. options = series.options,
  243. renderer = series.chart.renderer,
  244. overshoot = options.overshoot,
  245. overshootVal = isNumber(overshoot) ? overshoot / 180 * Math.PI : 0,
  246. thresholdAngleRad;
  247. // Handle the threshold option
  248. if (isNumber(options.threshold)) {
  249. thresholdAngleRad = yAxis.startAngleRad + yAxis.translate(
  250. options.threshold,
  251. null,
  252. null,
  253. null,
  254. true
  255. );
  256. }
  257. this.thresholdAngleRad = pick(thresholdAngleRad, yAxis.startAngleRad);
  258. each(series.points, function (point) {
  259. var graphic = point.graphic,
  260. rotation = yAxis.startAngleRad +
  261. yAxis.translate(point.y, null, null, null, true),
  262. radius = (
  263. pInt(
  264. pick(point.options.radius, options.radius, 100)
  265. ) * center[2]
  266. ) / 200,
  267. innerRadius = (
  268. pInt(
  269. pick(point.options.innerRadius, options.innerRadius, 60)
  270. ) * center[2]
  271. ) / 200,
  272. shapeArgs,
  273. d,
  274. toColor = yAxis.toColor(point.y, point),
  275. axisMinAngle = Math.min(yAxis.startAngleRad, yAxis.endAngleRad),
  276. axisMaxAngle = Math.max(yAxis.startAngleRad, yAxis.endAngleRad),
  277. minAngle,
  278. maxAngle;
  279. if (toColor === 'none') { // #3708
  280. toColor = point.color || series.color || 'none';
  281. }
  282. if (toColor !== 'none') {
  283. point.color = toColor;
  284. }
  285. // Handle overshoot and clipping to axis max/min
  286. rotation = Math.max(
  287. axisMinAngle - overshootVal,
  288. Math.min(axisMaxAngle + overshootVal, rotation)
  289. );
  290. // Handle the wrap option
  291. if (options.wrap === false) {
  292. rotation = Math.max(
  293. axisMinAngle,
  294. Math.min(axisMaxAngle, rotation)
  295. );
  296. }
  297. minAngle = Math.min(rotation, series.thresholdAngleRad);
  298. maxAngle = Math.max(rotation, series.thresholdAngleRad);
  299. if (maxAngle - minAngle > 2 * Math.PI) {
  300. maxAngle = minAngle + 2 * Math.PI;
  301. }
  302. point.shapeArgs = shapeArgs = {
  303. x: center[0],
  304. y: center[1],
  305. r: radius,
  306. innerR: innerRadius,
  307. start: minAngle,
  308. end: maxAngle,
  309. rounded: options.rounded
  310. };
  311. point.startR = radius; // For PieSeries.animate
  312. if (graphic) {
  313. d = shapeArgs.d;
  314. graphic.animate(H.extend({ fill: toColor }, shapeArgs));
  315. if (d) {
  316. shapeArgs.d = d; // animate alters it
  317. }
  318. } else {
  319. point.graphic = renderer.arc(shapeArgs)
  320. .addClass(point.getClassName(), true)
  321. .attr({
  322. fill: toColor,
  323. 'sweep-flag': 0
  324. })
  325. .add(series.group);
  326. if (options.linecap !== 'square') {
  327. point.graphic.attr({
  328. 'stroke-linecap': 'round',
  329. 'stroke-linejoin': 'round'
  330. });
  331. }
  332. point.graphic.attr({
  333. stroke: options.borderColor || 'none',
  334. 'stroke-width': options.borderWidth || 0
  335. });
  336. }
  337. });
  338. },
  339. /**
  340. * Extend the pie slice animation by animating from start angle and up
  341. */
  342. animate: function (init) {
  343. if (!init) {
  344. this.startAngleRad = this.thresholdAngleRad;
  345. H.seriesTypes.pie.prototype.animate.call(this, init);
  346. }
  347. }
  348. });
  349. /**
  350. * A `solidgauge` series. If the [type](#series.solidgauge.type) option
  351. * is not specified, it is inherited from [chart.type](#chart.type).
  352. *
  353. *
  354. * @type {Object}
  355. * @extends series,plotOptions.solidgauge
  356. * @excluding animationLimit,boostThreshold,connectEnds,connectNulls,
  357. * cropThreshold,dashStyle,dataParser,dataURL,dial,
  358. * findNearestPointBy,getExtremesFromAll,marker,negativeColor,
  359. * pointPlacement,pivot,shadow,softThreshold,stack,stacking,states,
  360. * step,threshold,turboThreshold,wrap,zoneAxis,zones
  361. * @product highcharts
  362. * @apioption series.solidgauge
  363. */
  364. /**
  365. * An array of data points for the series. For the `solidgauge` series
  366. * type, points can be given in the following ways:
  367. *
  368. * 1. An array of numerical values. In this case, the numerical values
  369. * will be interpreted as `y` options. Example:
  370. *
  371. * ```js
  372. * data: [0, 5, 3, 5]
  373. * ```
  374. *
  375. * 2. An array of objects with named values. The objects are point
  376. * configuration objects as seen below. If the total number of data
  377. * points exceeds the series' [turboThreshold](
  378. * #series.solidgauge.turboThreshold), this option is not available.
  379. *
  380. * ```js
  381. * data: [{
  382. * y: 5,
  383. * name: "Point2",
  384. * color: "#00FF00"
  385. * }, {
  386. * y: 7,
  387. * name: "Point1",
  388. * color: "#FF00FF"
  389. * }]
  390. * ```
  391. *
  392. * The typical gauge only contains a single data value.
  393. *
  394. * @type {Array<Object|Number>}
  395. * @extends series.gauge.data
  396. * @sample {highcharts} highcharts/chart/reflow-true/
  397. * Numerical values
  398. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  399. * Arrays of numeric x and y
  400. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  401. * Arrays of datetime x and y
  402. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  403. * Arrays of point.name and y
  404. * @sample {highcharts} highcharts/series/data-array-of-objects/
  405. * Config objects
  406. * @product highcharts
  407. * @apioption series.solidgauge.data
  408. */
  409. /**
  410. * The inner radius of an individual point in a solid gauge. Can be
  411. * given as a number (pixels) or percentage string.
  412. *
  413. * @type {Number|String}
  414. * @sample {highcharts} highcharts/plotoptions/solidgauge-radius/ Individual radius and innerRadius
  415. * @since 4.1.6
  416. * @product highcharts
  417. * @apioption series.solidgauge.data.innerRadius
  418. */
  419. /**
  420. * The outer radius of an individual point in a solid gauge. Can be
  421. * given as a number (pixels) or percentage string.
  422. *
  423. * @type {Number|String}
  424. * @sample {highcharts} highcharts/plotoptions/solidgauge-radius/ Individual radius and innerRadius
  425. * @since 4.1.6
  426. * @product highcharts
  427. * @apioption series.solidgauge.data.radius
  428. */
  429. }(Highcharts));
  430. }));