ChartUtilities.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /* *
  2. *
  3. * (c) 2009-2020 Øystein Moseng
  4. *
  5. * Utils for dealing with charts.
  6. *
  7. * License: www.highcharts.com/license
  8. *
  9. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  10. *
  11. * */
  12. 'use strict';
  13. import HTMLUtilities from './HTMLUtilities.js';
  14. var stripHTMLTags = HTMLUtilities.stripHTMLTagsFromString;
  15. import U from '../../Core/Utilities.js';
  16. var defined = U.defined, find = U.find, fireEvent = U.fireEvent;
  17. /* eslint-disable valid-jsdoc */
  18. /**
  19. * @return {string}
  20. */
  21. function getChartTitle(chart) {
  22. return stripHTMLTags(chart.options.title.text ||
  23. chart.langFormat('accessibility.defaultChartTitle', { chart: chart }));
  24. }
  25. /**
  26. * @param {Highcharts.Axis} axis
  27. * @return {string}
  28. */
  29. function getAxisDescription(axis) {
  30. return stripHTMLTags(axis && (axis.userOptions && axis.userOptions.accessibility &&
  31. axis.userOptions.accessibility.description ||
  32. axis.axisTitle && axis.axisTitle.textStr ||
  33. axis.options.id ||
  34. axis.categories && 'categories' ||
  35. axis.dateTime && 'Time' ||
  36. 'values'));
  37. }
  38. /**
  39. * Get the DOM element for the first point in the series.
  40. * @private
  41. * @param {Highcharts.Series} series
  42. * The series to get element for.
  43. * @return {Highcharts.HTMLDOMElement|Highcharts.SVGDOMElement|undefined}
  44. * The DOM element for the point.
  45. */
  46. function getSeriesFirstPointElement(series) {
  47. if (series.points &&
  48. series.points.length &&
  49. series.points[0].graphic) {
  50. return series.points[0].graphic.element;
  51. }
  52. }
  53. /**
  54. * Get the DOM element for the series that we put accessibility info on.
  55. * @private
  56. * @param {Highcharts.Series} series
  57. * The series to get element for.
  58. * @return {Highcharts.HTMLDOMElement|Highcharts.SVGDOMElement|undefined}
  59. * The DOM element for the series
  60. */
  61. function getSeriesA11yElement(series) {
  62. var firstPointEl = getSeriesFirstPointElement(series);
  63. return (firstPointEl &&
  64. firstPointEl.parentNode || series.graph &&
  65. series.graph.element || series.group &&
  66. series.group.element); // Could be tracker series depending on series type
  67. }
  68. /**
  69. * Remove aria-hidden from element. Also unhides parents of the element, and
  70. * hides siblings that are not explicitly unhidden.
  71. * @private
  72. * @param {Highcharts.Chart} chart
  73. * @param {Highcharts.HTMLDOMElement|Highcharts.SVGDOMElement} element
  74. */
  75. function unhideChartElementFromAT(chart, element) {
  76. element.setAttribute('aria-hidden', false);
  77. if (element === chart.renderTo || !element.parentNode) {
  78. return;
  79. }
  80. // Hide siblings unless their hidden state is already explicitly set
  81. Array.prototype.forEach.call(element.parentNode.childNodes, function (node) {
  82. if (!node.hasAttribute('aria-hidden')) {
  83. node.setAttribute('aria-hidden', true);
  84. }
  85. });
  86. // Repeat for parent
  87. unhideChartElementFromAT(chart, element.parentNode);
  88. }
  89. /**
  90. * Hide series from screen readers.
  91. * @private
  92. * @param {Highcharts.Series} series
  93. * The series to hide
  94. * @return {void}
  95. */
  96. function hideSeriesFromAT(series) {
  97. var seriesEl = getSeriesA11yElement(series);
  98. if (seriesEl) {
  99. seriesEl.setAttribute('aria-hidden', true);
  100. }
  101. }
  102. /**
  103. * Get series objects by series name.
  104. * @private
  105. * @param {Highcharts.Chart} chart
  106. * @param {string} name
  107. * @return {Array<Highcharts.Series>}
  108. */
  109. function getSeriesFromName(chart, name) {
  110. if (!name) {
  111. return chart.series;
  112. }
  113. return (chart.series || []).filter(function (s) {
  114. return s.name === name;
  115. });
  116. }
  117. /**
  118. * Get point in a series from x/y values.
  119. * @private
  120. * @param {Array<Highcharts.Series>} series
  121. * @param {number} x
  122. * @param {number} y
  123. * @return {Highcharts.Point|undefined}
  124. */
  125. function getPointFromXY(series, x, y) {
  126. var i = series.length, res;
  127. while (i--) {
  128. res = find(series[i].points || [], function (p) {
  129. return p.x === x && p.y === y;
  130. });
  131. if (res) {
  132. return res;
  133. }
  134. }
  135. }
  136. /**
  137. * Get relative position of point on an x/y axis from 0 to 1.
  138. * @private
  139. * @param {Highcharts.Axis} axis
  140. * @param {Highcharts.Point} point
  141. * @return {number}
  142. */
  143. function getRelativePointAxisPosition(axis, point) {
  144. if (!defined(axis.dataMin) || !defined(axis.dataMax)) {
  145. return 0;
  146. }
  147. var axisStart = axis.toPixels(axis.dataMin);
  148. var axisEnd = axis.toPixels(axis.dataMax);
  149. // We have to use pixel position because of axis breaks, log axis etc.
  150. var positionProp = axis.coll === 'xAxis' ? 'x' : 'y';
  151. var pointPos = axis.toPixels(point[positionProp] || 0);
  152. return (pointPos - axisStart) / (axisEnd - axisStart);
  153. }
  154. /**
  155. * Get relative position of point on an x/y axis from 0 to 1.
  156. * @private
  157. * @param {Highcharts.Point} point
  158. */
  159. function scrollToPoint(point) {
  160. var xAxis = point.series.xAxis;
  161. var yAxis = point.series.yAxis;
  162. var axis = (xAxis === null || xAxis === void 0 ? void 0 : xAxis.scrollbar) ? xAxis : yAxis;
  163. var scrollbar = axis === null || axis === void 0 ? void 0 : axis.scrollbar;
  164. if (scrollbar && defined(scrollbar.to) && defined(scrollbar.from)) {
  165. var range = scrollbar.to - scrollbar.from;
  166. var pos = getRelativePointAxisPosition(axis, point);
  167. scrollbar.updatePosition(pos - range / 2, pos + range / 2);
  168. fireEvent(scrollbar, 'changed', {
  169. from: scrollbar.from,
  170. to: scrollbar.to,
  171. trigger: 'scrollbar',
  172. DOMEvent: null
  173. });
  174. }
  175. }
  176. var ChartUtilities = {
  177. getChartTitle: getChartTitle,
  178. getAxisDescription: getAxisDescription,
  179. getPointFromXY: getPointFromXY,
  180. getSeriesFirstPointElement: getSeriesFirstPointElement,
  181. getSeriesFromName: getSeriesFromName,
  182. getSeriesA11yElement: getSeriesA11yElement,
  183. unhideChartElementFromAT: unhideChartElementFromAT,
  184. hideSeriesFromAT: hideSeriesFromAT,
  185. scrollToPoint: scrollToPoint
  186. };
  187. export default ChartUtilities;