Files
T-DAS/Epost.TestToolsWeb/Content/code/es-modules/parts/ScrollablePlotArea.js
2023-01-13 15:30:20 +08:00

264 lines
7.9 KiB
JavaScript

/**
* (c) 2010-2018 Torstein Honsi
*
* License: www.highcharts.com/license
*
* Highcharts feature to make the Y axis stay fixed when scrolling the chart
* horizontally on mobile devices. Supports left and right side axes.
*/
'use strict';
import H from './Globals.js';
var addEvent = H.addEvent,
Chart = H.Chart;
/**
* Options for a scrollable plot area. This feature provides a minimum width for
* the plot area of the chart. If the width gets smaller than this, typically
* on mobile devices, a native browser scrollbar is presented below the chart.
* This scrollbar provides smooth scrolling for the contents of the plot area,
* whereas the title, legend and axes are fixed.
*
* @sample {highcharts} highcharts/chart/scrollable-plotarea
* Scrollable plot area
*
* @since 6.1.0
* @product highcharts gantt
* @apioption chart.scrollablePlotArea
*/
/**
* The minimum width for the plot area. If it gets smaller than this, the plot
* area will become scrollable.
*
* @type {number}
* @apioption chart.scrollablePlotArea.minWidth
*/
/**
* The initial scrolling position of the scrollable plot area. Ranges from 0 to
* 1, where 0 aligns the plot area to the left and 1 aligns it to the right.
* Typically we would use 1 if the chart has right aligned Y axes.
*
* @type {number}
* @apioption chart.scrollablePlotArea.scrollPositionX
*/
addEvent(Chart, 'afterSetChartSize', function (e) {
var scrollablePlotArea = this.options.chart.scrollablePlotArea,
scrollableMinWidth =
scrollablePlotArea && scrollablePlotArea.minWidth,
scrollablePixels;
if (scrollableMinWidth && !this.renderer.forExport) {
// The amount of pixels to scroll, the difference between chart
// width and scrollable width
this.scrollablePixels = scrollablePixels = Math.max(
0,
scrollableMinWidth - this.chartWidth
);
if (scrollablePixels) {
this.plotWidth += scrollablePixels;
this.clipBox.width += scrollablePixels;
if (!e.skipAxes) {
this.axes.forEach(function (axis) {
if (axis.side === 1) {
// Get the plot lines right in getPlotLinePath,
// temporarily set it to the adjusted plot width.
axis.getPlotLinePath = function () {
var right = this.right,
path;
this.right = right - axis.chart.scrollablePixels;
path = H.Axis.prototype.getPlotLinePath.apply(
this,
arguments
);
this.right = right;
return path;
};
} else {
// Apply the corrected plotWidth
axis.setAxisSize();
axis.setAxisTranslation();
}
});
}
}
}
});
addEvent(Chart, 'render', function () {
if (this.scrollablePixels) {
if (this.setUpScrolling) {
this.setUpScrolling();
}
this.applyFixed();
} else if (this.fixedDiv) { // Has been in scrollable mode
this.applyFixed();
}
});
/**
* @private
* @function Highcharts.Chart#setUpScrolling
*/
Chart.prototype.setUpScrolling = function () {
// Add the necessary divs to provide scrolling
this.scrollingContainer = H.createElement('div', {
'className': 'highcharts-scrolling'
}, {
overflowX: 'auto',
WebkitOverflowScrolling: 'touch'
}, this.renderTo);
this.innerContainer = H.createElement('div', {
'className': 'highcharts-inner-container'
}, null, this.scrollingContainer);
// Now move the container inside
this.innerContainer.appendChild(this.container);
// Don't run again
this.setUpScrolling = null;
};
/**
* @private
* @function Highcharts.Chart#applyFixed
*/
Chart.prototype.applyFixed = function () {
var container = this.container,
fixedRenderer,
scrollableWidth,
firstTime = !this.fixedDiv;
// First render
if (firstTime) {
this.fixedDiv = H.createElement(
'div',
{
className: 'highcharts-fixed'
},
{
position: 'absolute',
overflow: 'hidden',
pointerEvents: 'none',
zIndex: 2
},
null,
true
);
this.renderTo.insertBefore(
this.fixedDiv,
this.renderTo.firstChild
);
this.fixedRenderer = fixedRenderer = new H.Renderer(
this.fixedDiv,
0,
0
);
// Mask
this.scrollableMask = fixedRenderer.path()
.attr({
fill: H.color(
this.options.chart.backgroundColor || '#fff'
).setOpacity(0.85).get(),
zIndex: -1
})
.addClass('highcharts-scrollable-mask')
.add();
// These elements are moved over to the fixed renderer and stay fixed
// when the user scrolls the chart.
([
this.inverted ?
'.highcharts-xaxis' :
'.highcharts-yaxis',
this.inverted ?
'.highcharts-xaxis-labels' :
'.highcharts-yaxis-labels',
'.highcharts-contextbutton',
'.highcharts-credits',
'.highcharts-legend',
'.highcharts-subtitle',
'.highcharts-title',
'.highcharts-legend-checkbox'
]).forEach(function (className) {
[].forEach.call(
container.querySelectorAll(className),
function (elem) {
(
elem.namespaceURI === fixedRenderer.SVG_NS ?
fixedRenderer.box :
fixedRenderer.box.parentNode
).appendChild(elem);
elem.style.pointerEvents = 'auto';
}
);
});
}
// Set the size of the fixed renderer to the visible width
this.fixedRenderer.setSize(
this.chartWidth,
this.chartHeight
);
// Increase the size of the scrollable renderer and background
scrollableWidth = this.chartWidth + this.scrollablePixels;
H.stop(this.container);
this.container.style.width = scrollableWidth + 'px';
this.renderer.boxWrapper.attr({
width: scrollableWidth,
height: this.chartHeight,
viewBox: [0, 0, scrollableWidth, this.chartHeight].join(' ')
});
this.chartBackground.attr({ width: scrollableWidth });
// Set scroll position
if (firstTime) {
var options = this.options.chart.scrollablePlotArea;
if (options.scrollPositionX) {
this.scrollingContainer.scrollLeft =
this.scrollablePixels * options.scrollPositionX;
}
}
// Mask behind the left and right side
var axisOffset = this.axisOffset,
maskTop = this.plotTop - axisOffset[0] - 1,
maskBottom = this.plotTop + this.plotHeight + axisOffset[2],
maskPlotRight = this.plotLeft + this.plotWidth -
this.scrollablePixels;
this.scrollableMask.attr({
d: this.scrollablePixels ? [
// Left side
'M', 0, maskTop,
'L', this.plotLeft - 1, maskTop,
'L', this.plotLeft - 1, maskBottom,
'L', 0, maskBottom,
'Z',
// Right side
'M', maskPlotRight, maskTop,
'L', this.chartWidth, maskTop,
'L', this.chartWidth, maskBottom,
'L', maskPlotRight, maskBottom,
'Z'
] : ['M', 0, 0]
});
};