Scrollbar.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. /* *
  2. *
  3. * (c) 2010-2020 Torstein Honsi
  4. *
  5. * License: www.highcharts.com/license
  6. *
  7. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8. *
  9. * */
  10. 'use strict';
  11. import Axis from './Axis/Axis.js';
  12. import H from './Globals.js';
  13. import ScrollbarAxis from './Axis/ScrollbarAxis.js';
  14. import U from './Utilities.js';
  15. var addEvent = U.addEvent, correctFloat = U.correctFloat, defined = U.defined, destroyObjectProperties = U.destroyObjectProperties, fireEvent = U.fireEvent, merge = U.merge, pick = U.pick, removeEvent = U.removeEvent;
  16. import O from './Options.js';
  17. var defaultOptions = O.defaultOptions;
  18. var hasTouch = H.hasTouch, isTouchDevice = H.isTouchDevice;
  19. /**
  20. * When we have vertical scrollbar, rifles and arrow in buttons should be
  21. * rotated. The same method is used in Navigator's handles, to rotate them.
  22. *
  23. * @function Highcharts.swapXY
  24. *
  25. * @param {Highcharts.SVGPathArray} path
  26. * Path to be rotated.
  27. *
  28. * @param {boolean} [vertical]
  29. * If vertical scrollbar, swap x-y values.
  30. *
  31. * @return {Highcharts.SVGPathArray}
  32. * Rotated path.
  33. *
  34. * @requires modules/stock
  35. */
  36. var swapXY = H.swapXY = function (path, vertical) {
  37. if (vertical) {
  38. path.forEach(function (seg) {
  39. var len = seg.length;
  40. var temp;
  41. for (var i = 0; i < len; i += 2) {
  42. temp = seg[i + 1];
  43. if (typeof temp === 'number') {
  44. seg[i + 1] = seg[i + 2];
  45. seg[i + 2] = temp;
  46. }
  47. }
  48. });
  49. }
  50. return path;
  51. };
  52. /* eslint-disable no-invalid-this, valid-jsdoc */
  53. /**
  54. * A reusable scrollbar, internally used in Highstock's navigator and optionally
  55. * on individual axes.
  56. *
  57. * @private
  58. * @class
  59. * @name Highcharts.Scrollbar
  60. * @param {Highcharts.SVGRenderer} renderer
  61. * @param {Highcharts.ScrollbarOptions} options
  62. * @param {Highcharts.Chart} chart
  63. */
  64. var Scrollbar = /** @class */ (function () {
  65. /* *
  66. *
  67. * Constructors
  68. *
  69. * */
  70. function Scrollbar(renderer, options, chart) {
  71. /* *
  72. *
  73. * Properties
  74. *
  75. * */
  76. this._events = [];
  77. this.chartX = 0;
  78. this.chartY = 0;
  79. this.from = 0;
  80. this.group = void 0;
  81. this.scrollbar = void 0;
  82. this.scrollbarButtons = [];
  83. this.scrollbarGroup = void 0;
  84. this.scrollbarLeft = 0;
  85. this.scrollbarRifles = void 0;
  86. this.scrollbarStrokeWidth = 1;
  87. this.scrollbarTop = 0;
  88. this.size = 0;
  89. this.to = 0;
  90. this.track = void 0;
  91. this.trackBorderWidth = 1;
  92. this.userOptions = {};
  93. this.x = 0;
  94. this.y = 0;
  95. this.chart = chart;
  96. this.options = options;
  97. this.renderer = chart.renderer;
  98. this.init(renderer, options, chart);
  99. }
  100. /* *
  101. *
  102. * Functions
  103. *
  104. * */
  105. /**
  106. * Set up the mouse and touch events for the Scrollbar
  107. *
  108. * @private
  109. * @function Highcharts.Scrollbar#addEvents
  110. * @return {void}
  111. */
  112. Scrollbar.prototype.addEvents = function () {
  113. var buttonsOrder = this.options.inverted ? [1, 0] : [0, 1], buttons = this.scrollbarButtons, bar = this.scrollbarGroup.element, track = this.track.element, mouseDownHandler = this.mouseDownHandler.bind(this), mouseMoveHandler = this.mouseMoveHandler.bind(this), mouseUpHandler = this.mouseUpHandler.bind(this), _events;
  114. // Mouse events
  115. _events = [
  116. [buttons[buttonsOrder[0]].element, 'click', this.buttonToMinClick.bind(this)],
  117. [buttons[buttonsOrder[1]].element, 'click', this.buttonToMaxClick.bind(this)],
  118. [track, 'click', this.trackClick.bind(this)],
  119. [bar, 'mousedown', mouseDownHandler],
  120. [bar.ownerDocument, 'mousemove', mouseMoveHandler],
  121. [bar.ownerDocument, 'mouseup', mouseUpHandler]
  122. ];
  123. // Touch events
  124. if (hasTouch) {
  125. _events.push([bar, 'touchstart', mouseDownHandler], [bar.ownerDocument, 'touchmove', mouseMoveHandler], [bar.ownerDocument, 'touchend', mouseUpHandler]);
  126. }
  127. // Add them all
  128. _events.forEach(function (args) {
  129. addEvent.apply(null, args);
  130. });
  131. this._events = _events;
  132. };
  133. Scrollbar.prototype.buttonToMaxClick = function (e) {
  134. var scroller = this;
  135. var range = (scroller.to - scroller.from) * pick(scroller.options.step, 0.2);
  136. scroller.updatePosition(scroller.from + range, scroller.to + range);
  137. fireEvent(scroller, 'changed', {
  138. from: scroller.from,
  139. to: scroller.to,
  140. trigger: 'scrollbar',
  141. DOMEvent: e
  142. });
  143. };
  144. Scrollbar.prototype.buttonToMinClick = function (e) {
  145. var scroller = this;
  146. var range = correctFloat(scroller.to - scroller.from) *
  147. pick(scroller.options.step, 0.2);
  148. scroller.updatePosition(correctFloat(scroller.from - range), correctFloat(scroller.to - range));
  149. fireEvent(scroller, 'changed', {
  150. from: scroller.from,
  151. to: scroller.to,
  152. trigger: 'scrollbar',
  153. DOMEvent: e
  154. });
  155. };
  156. /**
  157. * Get normalized (0-1) cursor position over the scrollbar
  158. *
  159. * @private
  160. * @function Highcharts.Scrollbar#cursorToScrollbarPosition
  161. *
  162. * @param {*} normalizedEvent
  163. * normalized event, with chartX and chartY values
  164. *
  165. * @return {Highcharts.Dictionary<number>}
  166. * Local position {chartX, chartY}
  167. */
  168. Scrollbar.prototype.cursorToScrollbarPosition = function (normalizedEvent) {
  169. var scroller = this, options = scroller.options, minWidthDifference = options.minWidth > scroller.calculatedWidth ?
  170. options.minWidth :
  171. 0; // minWidth distorts translation
  172. return {
  173. chartX: (normalizedEvent.chartX - scroller.x -
  174. scroller.xOffset) /
  175. (scroller.barWidth - minWidthDifference),
  176. chartY: (normalizedEvent.chartY - scroller.y -
  177. scroller.yOffset) /
  178. (scroller.barWidth - minWidthDifference)
  179. };
  180. };
  181. /**
  182. * Destroys allocated elements.
  183. *
  184. * @private
  185. * @function Highcharts.Scrollbar#destroy
  186. * @return {void}
  187. */
  188. Scrollbar.prototype.destroy = function () {
  189. var scroller = this.chart.scroller;
  190. // Disconnect events added in addEvents
  191. this.removeEvents();
  192. // Destroy properties
  193. [
  194. 'track',
  195. 'scrollbarRifles',
  196. 'scrollbar',
  197. 'scrollbarGroup',
  198. 'group'
  199. ].forEach(function (prop) {
  200. if (this[prop] && this[prop].destroy) {
  201. this[prop] = this[prop].destroy();
  202. }
  203. }, this);
  204. // #6421, chart may have more scrollbars
  205. if (scroller && this === scroller.scrollbar) {
  206. scroller.scrollbar = null;
  207. // Destroy elements in collection
  208. destroyObjectProperties(scroller.scrollbarButtons);
  209. }
  210. };
  211. /**
  212. * Draw the scrollbar buttons with arrows
  213. *
  214. * @private
  215. * @function Highcharts.Scrollbar#drawScrollbarButton
  216. * @param {number} index
  217. * 0 is left, 1 is right
  218. * @return {void}
  219. */
  220. Scrollbar.prototype.drawScrollbarButton = function (index) {
  221. var scroller = this, renderer = scroller.renderer, scrollbarButtons = scroller.scrollbarButtons, options = scroller.options, size = scroller.size, group, tempElem;
  222. group = renderer.g().add(scroller.group);
  223. scrollbarButtons.push(group);
  224. // Create a rectangle for the scrollbar button
  225. tempElem = renderer.rect()
  226. .addClass('highcharts-scrollbar-button')
  227. .add(group);
  228. // Presentational attributes
  229. if (!this.chart.styledMode) {
  230. tempElem.attr({
  231. stroke: options.buttonBorderColor,
  232. 'stroke-width': options.buttonBorderWidth,
  233. fill: options.buttonBackgroundColor
  234. });
  235. }
  236. // Place the rectangle based on the rendered stroke width
  237. tempElem.attr(tempElem.crisp({
  238. x: -0.5,
  239. y: -0.5,
  240. width: size + 1,
  241. height: size + 1,
  242. r: options.buttonBorderRadius
  243. }, tempElem.strokeWidth()));
  244. // Button arrow
  245. tempElem = renderer
  246. .path(swapXY([[
  247. 'M',
  248. size / 2 + (index ? -1 : 1),
  249. size / 2 - 3
  250. ], [
  251. 'L',
  252. size / 2 + (index ? -1 : 1),
  253. size / 2 + 3
  254. ], [
  255. 'L',
  256. size / 2 + (index ? 2 : -2),
  257. size / 2
  258. ]], options.vertical))
  259. .addClass('highcharts-scrollbar-arrow')
  260. .add(scrollbarButtons[index]);
  261. if (!this.chart.styledMode) {
  262. tempElem.attr({
  263. fill: options.buttonArrowColor
  264. });
  265. }
  266. };
  267. /**
  268. * @private
  269. * @function Highcharts.Scrollbar#init
  270. * @param {Highcharts.SVGRenderer} renderer
  271. * @param {Highcharts.ScrollbarOptions} options
  272. * @param {Highcharts.Chart} chart
  273. */
  274. Scrollbar.prototype.init = function (renderer, options, chart) {
  275. this.scrollbarButtons = [];
  276. this.renderer = renderer;
  277. this.userOptions = options;
  278. this.options = merge(Scrollbar.defaultOptions, options);
  279. this.chart = chart;
  280. // backward compatibility
  281. this.size = pick(this.options.size, this.options.height);
  282. // Init
  283. if (options.enabled) {
  284. this.render();
  285. this.addEvents();
  286. }
  287. };
  288. Scrollbar.prototype.mouseDownHandler = function (e) {
  289. var scroller = this;
  290. var normalizedEvent = scroller.chart.pointer.normalize(e), mousePosition = scroller.cursorToScrollbarPosition(normalizedEvent);
  291. scroller.chartX = mousePosition.chartX;
  292. scroller.chartY = mousePosition.chartY;
  293. scroller.initPositions = [scroller.from, scroller.to];
  294. scroller.grabbedCenter = true;
  295. };
  296. /**
  297. * Event handler for the mouse move event.
  298. * @private
  299. */
  300. Scrollbar.prototype.mouseMoveHandler = function (e) {
  301. var scroller = this;
  302. var normalizedEvent = scroller.chart.pointer.normalize(e), options = scroller.options, direction = options.vertical ? 'chartY' : 'chartX', initPositions = scroller.initPositions || [], scrollPosition, chartPosition, change;
  303. // In iOS, a mousemove event with e.pageX === 0 is fired when
  304. // holding the finger down in the center of the scrollbar. This
  305. // should be ignored.
  306. if (scroller.grabbedCenter &&
  307. // #4696, scrollbar failed on Android
  308. (!e.touches || e.touches[0][direction] !== 0)) {
  309. chartPosition = scroller.cursorToScrollbarPosition(normalizedEvent)[direction];
  310. scrollPosition = scroller[direction];
  311. change = chartPosition - scrollPosition;
  312. scroller.hasDragged = true;
  313. scroller.updatePosition(initPositions[0] + change, initPositions[1] + change);
  314. if (scroller.hasDragged) {
  315. fireEvent(scroller, 'changed', {
  316. from: scroller.from,
  317. to: scroller.to,
  318. trigger: 'scrollbar',
  319. DOMType: e.type,
  320. DOMEvent: e
  321. });
  322. }
  323. }
  324. };
  325. /**
  326. * Event handler for the mouse up event.
  327. * @private
  328. */
  329. Scrollbar.prototype.mouseUpHandler = function (e) {
  330. var scroller = this;
  331. if (scroller.hasDragged) {
  332. fireEvent(scroller, 'changed', {
  333. from: scroller.from,
  334. to: scroller.to,
  335. trigger: 'scrollbar',
  336. DOMType: e.type,
  337. DOMEvent: e
  338. });
  339. }
  340. scroller.grabbedCenter =
  341. scroller.hasDragged =
  342. scroller.chartX =
  343. scroller.chartY = null;
  344. };
  345. /**
  346. * Position the scrollbar, method called from a parent with defined
  347. * dimensions.
  348. *
  349. * @private
  350. * @function Highcharts.Scrollbar#position
  351. * @param {number} x
  352. * x-position on the chart
  353. * @param {number} y
  354. * y-position on the chart
  355. * @param {number} width
  356. * width of the scrollbar
  357. * @param {number} height
  358. * height of the scorllbar
  359. * @return {void}
  360. */
  361. Scrollbar.prototype.position = function (x, y, width, height) {
  362. var scroller = this, options = scroller.options, vertical = options.vertical, xOffset = height, yOffset = 0, method = scroller.rendered ? 'animate' : 'attr';
  363. scroller.x = x;
  364. scroller.y = y + this.trackBorderWidth;
  365. scroller.width = width; // width with buttons
  366. scroller.height = height;
  367. scroller.xOffset = xOffset;
  368. scroller.yOffset = yOffset;
  369. // If Scrollbar is a vertical type, swap options:
  370. if (vertical) {
  371. scroller.width = scroller.yOffset = width = yOffset = scroller.size;
  372. scroller.xOffset = xOffset = 0;
  373. scroller.barWidth = height - width * 2; // width without buttons
  374. scroller.x = x = x + scroller.options.margin;
  375. }
  376. else {
  377. scroller.height = scroller.xOffset = height = xOffset =
  378. scroller.size;
  379. scroller.barWidth = width - height * 2; // width without buttons
  380. scroller.y = scroller.y + scroller.options.margin;
  381. }
  382. // Set general position for a group:
  383. scroller.group[method]({
  384. translateX: x,
  385. translateY: scroller.y
  386. });
  387. // Resize background/track:
  388. scroller.track[method]({
  389. width: width,
  390. height: height
  391. });
  392. // Move right/bottom button ot it's place:
  393. scroller.scrollbarButtons[1][method]({
  394. translateX: vertical ? 0 : width - xOffset,
  395. translateY: vertical ? height - yOffset : 0
  396. });
  397. };
  398. /**
  399. * Removes the event handlers attached previously with addEvents.
  400. *
  401. * @private
  402. * @function Highcharts.Scrollbar#removeEvents
  403. * @return {void}
  404. */
  405. Scrollbar.prototype.removeEvents = function () {
  406. this._events.forEach(function (args) {
  407. removeEvent.apply(null, args);
  408. });
  409. this._events.length = 0;
  410. };
  411. /**
  412. * Render scrollbar with all required items.
  413. *
  414. * @private
  415. * @function Highcharts.Scrollbar#render
  416. */
  417. Scrollbar.prototype.render = function () {
  418. var scroller = this, renderer = scroller.renderer, options = scroller.options, size = scroller.size, styledMode = this.chart.styledMode, group;
  419. // Draw the scrollbar group
  420. scroller.group = group = renderer.g('scrollbar').attr({
  421. zIndex: options.zIndex,
  422. translateY: -99999
  423. }).add();
  424. // Draw the scrollbar track:
  425. scroller.track = renderer.rect()
  426. .addClass('highcharts-scrollbar-track')
  427. .attr({
  428. x: 0,
  429. r: options.trackBorderRadius || 0,
  430. height: size,
  431. width: size
  432. }).add(group);
  433. if (!styledMode) {
  434. scroller.track.attr({
  435. fill: options.trackBackgroundColor,
  436. stroke: options.trackBorderColor,
  437. 'stroke-width': options.trackBorderWidth
  438. });
  439. }
  440. this.trackBorderWidth = scroller.track.strokeWidth();
  441. scroller.track.attr({
  442. y: -this.trackBorderWidth % 2 / 2
  443. });
  444. // Draw the scrollbar itself
  445. scroller.scrollbarGroup = renderer.g().add(group);
  446. scroller.scrollbar = renderer.rect()
  447. .addClass('highcharts-scrollbar-thumb')
  448. .attr({
  449. height: size,
  450. width: size,
  451. r: options.barBorderRadius || 0
  452. }).add(scroller.scrollbarGroup);
  453. scroller.scrollbarRifles = renderer
  454. .path(swapXY([
  455. ['M', -3, size / 4],
  456. ['L', -3, 2 * size / 3],
  457. ['M', 0, size / 4],
  458. ['L', 0, 2 * size / 3],
  459. ['M', 3, size / 4],
  460. ['L', 3, 2 * size / 3]
  461. ], options.vertical))
  462. .addClass('highcharts-scrollbar-rifles')
  463. .add(scroller.scrollbarGroup);
  464. if (!styledMode) {
  465. scroller.scrollbar.attr({
  466. fill: options.barBackgroundColor,
  467. stroke: options.barBorderColor,
  468. 'stroke-width': options.barBorderWidth
  469. });
  470. scroller.scrollbarRifles.attr({
  471. stroke: options.rifleColor,
  472. 'stroke-width': 1
  473. });
  474. }
  475. scroller.scrollbarStrokeWidth = scroller.scrollbar.strokeWidth();
  476. scroller.scrollbarGroup.translate(-scroller.scrollbarStrokeWidth % 2 / 2, -scroller.scrollbarStrokeWidth % 2 / 2);
  477. // Draw the buttons:
  478. scroller.drawScrollbarButton(0);
  479. scroller.drawScrollbarButton(1);
  480. };
  481. /**
  482. * Set scrollbar size, with a given scale.
  483. *
  484. * @private
  485. * @function Highcharts.Scrollbar#setRange
  486. * @param {number} from
  487. * scale (0-1) where bar should start
  488. * @param {number} to
  489. * scale (0-1) where bar should end
  490. * @return {void}
  491. */
  492. Scrollbar.prototype.setRange = function (from, to) {
  493. var scroller = this, options = scroller.options, vertical = options.vertical, minWidth = options.minWidth, fullWidth = scroller.barWidth, fromPX, toPX, newPos, newSize, newRiflesPos, method = (this.rendered &&
  494. !this.hasDragged &&
  495. !(this.chart.navigator && this.chart.navigator.hasDragged)) ? 'animate' : 'attr';
  496. if (!defined(fullWidth)) {
  497. return;
  498. }
  499. from = Math.max(from, 0);
  500. fromPX = Math.ceil(fullWidth * from);
  501. toPX = fullWidth * Math.min(to, 1);
  502. scroller.calculatedWidth = newSize = correctFloat(toPX - fromPX);
  503. // We need to recalculate position, if minWidth is used
  504. if (newSize < minWidth) {
  505. fromPX = (fullWidth - minWidth + newSize) * from;
  506. newSize = minWidth;
  507. }
  508. newPos = Math.floor(fromPX + scroller.xOffset + scroller.yOffset);
  509. newRiflesPos = newSize / 2 - 0.5; // -0.5 -> rifle line width / 2
  510. // Store current position:
  511. scroller.from = from;
  512. scroller.to = to;
  513. if (!vertical) {
  514. scroller.scrollbarGroup[method]({
  515. translateX: newPos
  516. });
  517. scroller.scrollbar[method]({
  518. width: newSize
  519. });
  520. scroller.scrollbarRifles[method]({
  521. translateX: newRiflesPos
  522. });
  523. scroller.scrollbarLeft = newPos;
  524. scroller.scrollbarTop = 0;
  525. }
  526. else {
  527. scroller.scrollbarGroup[method]({
  528. translateY: newPos
  529. });
  530. scroller.scrollbar[method]({
  531. height: newSize
  532. });
  533. scroller.scrollbarRifles[method]({
  534. translateY: newRiflesPos
  535. });
  536. scroller.scrollbarTop = newPos;
  537. scroller.scrollbarLeft = 0;
  538. }
  539. if (newSize <= 12) {
  540. scroller.scrollbarRifles.hide();
  541. }
  542. else {
  543. scroller.scrollbarRifles.show(true);
  544. }
  545. // Show or hide the scrollbar based on the showFull setting
  546. if (options.showFull === false) {
  547. if (from <= 0 && to >= 1) {
  548. scroller.group.hide();
  549. }
  550. else {
  551. scroller.group.show();
  552. }
  553. }
  554. scroller.rendered = true;
  555. };
  556. Scrollbar.prototype.trackClick = function (e) {
  557. var scroller = this;
  558. var normalizedEvent = scroller.chart.pointer.normalize(e), range = scroller.to - scroller.from, top = scroller.y + scroller.scrollbarTop, left = scroller.x + scroller.scrollbarLeft;
  559. if ((scroller.options.vertical && normalizedEvent.chartY > top) ||
  560. (!scroller.options.vertical && normalizedEvent.chartX > left)) {
  561. // On the top or on the left side of the track:
  562. scroller.updatePosition(scroller.from + range, scroller.to + range);
  563. }
  564. else {
  565. // On the bottom or the right side of the track:
  566. scroller.updatePosition(scroller.from - range, scroller.to - range);
  567. }
  568. fireEvent(scroller, 'changed', {
  569. from: scroller.from,
  570. to: scroller.to,
  571. trigger: 'scrollbar',
  572. DOMEvent: e
  573. });
  574. };
  575. /**
  576. * Update the scrollbar with new options
  577. *
  578. * @private
  579. * @function Highcharts.Scrollbar#update
  580. * @param {Highcharts.ScrollbarOptions} options
  581. * @return {void}
  582. */
  583. Scrollbar.prototype.update = function (options) {
  584. this.destroy();
  585. this.init(this.chart.renderer, merge(true, this.options, options), this.chart);
  586. };
  587. /**
  588. * Update position option in the Scrollbar, with normalized 0-1 scale
  589. *
  590. * @private
  591. * @function Highcharts.Scrollbar#updatePosition
  592. * @param {number} from
  593. * @param {number} to
  594. * @return {void}
  595. */
  596. Scrollbar.prototype.updatePosition = function (from, to) {
  597. if (to > 1) {
  598. from = correctFloat(1 - correctFloat(to - from));
  599. to = 1;
  600. }
  601. if (from < 0) {
  602. to = correctFloat(to - from);
  603. from = 0;
  604. }
  605. this.from = from;
  606. this.to = to;
  607. };
  608. /* *
  609. *
  610. * Static Properties
  611. *
  612. * */
  613. /**
  614. *
  615. * The scrollbar is a means of panning over the X axis of a stock chart.
  616. * Scrollbars can also be applied to other types of axes.
  617. *
  618. * Another approach to scrollable charts is the [chart.scrollablePlotArea](
  619. * https://api.highcharts.com/highcharts/chart.scrollablePlotArea) option that
  620. * is especially suitable for simpler cartesian charts on mobile.
  621. *
  622. * In styled mode, all the presentational options for the
  623. * scrollbar are replaced by the classes `.highcharts-scrollbar-thumb`,
  624. * `.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,
  625. * `.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.
  626. *
  627. * @sample stock/yaxis/inverted-bar-scrollbar/
  628. * A scrollbar on a simple bar chart
  629. *
  630. * @product highstock gantt
  631. * @optionparent scrollbar
  632. *
  633. * @private
  634. */
  635. Scrollbar.defaultOptions = {
  636. /**
  637. * The height of the scrollbar. The height also applies to the width
  638. * of the scroll arrows so that they are always squares. Defaults to
  639. * 20 for touch devices and 14 for mouse devices.
  640. *
  641. * @sample stock/scrollbar/height/
  642. * A 30px scrollbar
  643. *
  644. * @type {number}
  645. * @default 20/14
  646. */
  647. height: isTouchDevice ? 20 : 14,
  648. /**
  649. * The border rounding radius of the bar.
  650. *
  651. * @sample stock/scrollbar/style/
  652. * Scrollbar styling
  653. */
  654. barBorderRadius: 0,
  655. /**
  656. * The corner radius of the scrollbar buttons.
  657. *
  658. * @sample stock/scrollbar/style/
  659. * Scrollbar styling
  660. */
  661. buttonBorderRadius: 0,
  662. /**
  663. * Enable or disable the scrollbar.
  664. *
  665. * @sample stock/scrollbar/enabled/
  666. * Disable the scrollbar, only use navigator
  667. *
  668. * @type {boolean}
  669. * @default true
  670. * @apioption scrollbar.enabled
  671. */
  672. /**
  673. * Whether to redraw the main chart as the scrollbar or the navigator
  674. * zoomed window is moved. Defaults to `true` for modern browsers and
  675. * `false` for legacy IE browsers as well as mobile devices.
  676. *
  677. * @sample stock/scrollbar/liveredraw
  678. * Setting live redraw to false
  679. *
  680. * @type {boolean}
  681. * @since 1.3
  682. */
  683. liveRedraw: void 0,
  684. /**
  685. * The margin between the scrollbar and its axis when the scrollbar is
  686. * applied directly to an axis.
  687. */
  688. margin: 10,
  689. /**
  690. * The minimum width of the scrollbar.
  691. *
  692. * @since 1.2.5
  693. */
  694. minWidth: 6,
  695. /**
  696. * Whether to show or hide the scrollbar when the scrolled content is
  697. * zoomed out to it full extent.
  698. *
  699. * @type {boolean}
  700. * @default true
  701. * @apioption scrollbar.showFull
  702. */
  703. step: 0.2,
  704. /**
  705. * The z index of the scrollbar group.
  706. */
  707. zIndex: 3,
  708. /**
  709. * The background color of the scrollbar itself.
  710. *
  711. * @sample stock/scrollbar/style/
  712. * Scrollbar styling
  713. *
  714. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  715. */
  716. barBackgroundColor: '#cccccc',
  717. /**
  718. * The width of the bar's border.
  719. *
  720. * @sample stock/scrollbar/style/
  721. * Scrollbar styling
  722. */
  723. barBorderWidth: 1,
  724. /**
  725. * The color of the scrollbar's border.
  726. *
  727. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  728. */
  729. barBorderColor: '#cccccc',
  730. /**
  731. * The color of the small arrow inside the scrollbar buttons.
  732. *
  733. * @sample stock/scrollbar/style/
  734. * Scrollbar styling
  735. *
  736. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  737. */
  738. buttonArrowColor: '#333333',
  739. /**
  740. * The color of scrollbar buttons.
  741. *
  742. * @sample stock/scrollbar/style/
  743. * Scrollbar styling
  744. *
  745. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  746. */
  747. buttonBackgroundColor: '#e6e6e6',
  748. /**
  749. * The color of the border of the scrollbar buttons.
  750. *
  751. * @sample stock/scrollbar/style/
  752. * Scrollbar styling
  753. *
  754. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  755. */
  756. buttonBorderColor: '#cccccc',
  757. /**
  758. * The border width of the scrollbar buttons.
  759. *
  760. * @sample stock/scrollbar/style/
  761. * Scrollbar styling
  762. */
  763. buttonBorderWidth: 1,
  764. /**
  765. * The color of the small rifles in the middle of the scrollbar.
  766. *
  767. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  768. */
  769. rifleColor: '#333333',
  770. /**
  771. * The color of the track background.
  772. *
  773. * @sample stock/scrollbar/style/
  774. * Scrollbar styling
  775. *
  776. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  777. */
  778. trackBackgroundColor: '#f2f2f2',
  779. /**
  780. * The color of the border of the scrollbar track.
  781. *
  782. * @sample stock/scrollbar/style/
  783. * Scrollbar styling
  784. *
  785. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  786. */
  787. trackBorderColor: '#f2f2f2',
  788. /**
  789. * The corner radius of the border of the scrollbar track.
  790. *
  791. * @sample stock/scrollbar/style/
  792. * Scrollbar styling
  793. *
  794. * @type {number}
  795. * @default 0
  796. * @apioption scrollbar.trackBorderRadius
  797. */
  798. /**
  799. * The width of the border of the scrollbar track.
  800. *
  801. * @sample stock/scrollbar/style/
  802. * Scrollbar styling
  803. */
  804. trackBorderWidth: 1
  805. };
  806. return Scrollbar;
  807. }());
  808. if (!H.Scrollbar) {
  809. defaultOptions.scrollbar = merge(true, Scrollbar.defaultOptions, defaultOptions.scrollbar);
  810. H.Scrollbar = Scrollbar;
  811. ScrollbarAxis.compose(Axis, Scrollbar);
  812. }
  813. export default H.Scrollbar;