@syncfusion/ej2-charts
Version: 
Feature-rich chart control with built-in support for over 25 chart types, technical indictors, trendline, zooming, tooltip, selection, crosshair and trackball.
245 lines (244 loc) • 14.1 kB
JavaScript
import { RectOption, CircleOption } from '../utils/helper';
import { PathOption, Rect } from '@syncfusion/ej2-svg-base';
import { calculateScrollbarOffset } from '../../chart/index';
/**
 * Create scrollbar svg.
 *
 * @param {ScrollBar} scrollbar - The scrollbar instance.
 * @param {SvgRenderer} renderer - The SVG renderer.
 * @returns {void}
 */
export function createScrollSvg(scrollbar, renderer) {
    var rect = scrollbar.axis.rect;
    var isHorizontalAxis = scrollbar.axis.orientation === 'Horizontal';
    var enablePadding = false;
    var markerHeight = 0;
    var yMin;
    for (var _i = 0, _a = scrollbar.axis.series; _i < _a.length; _i++) {
        var tempSeries = _a[_i];
        if (tempSeries.marker.visible && tempSeries.marker.height > markerHeight) {
            markerHeight = tempSeries.marker.height;
        }
    }
    for (var _b = 0, _c = scrollbar.axis.series; _b < _c.length; _b++) {
        var tempSeries = _c[_b];
        if (tempSeries.visible) { // To avoid the console error, when the visibility of the series is false.
            yMin = tempSeries.yMin.toString();
            enablePadding = (tempSeries.yData).some(function (yData) {
                return yData === yMin;
            });
        }
        if (enablePadding) {
            break;
        }
    }
    var topOffset = (scrollbar.axis.isAxisOpposedPosition && isHorizontalAxis ? -16 :
        (enablePadding ? markerHeight : 0)) + rect.y + Math.max(0.5, scrollbar.axis.lineStyle.width / 2);
    var leftOffset = (((scrollbar.axis.isAxisOpposedPosition && !isHorizontalAxis ? 16 : 0) + rect.x) -
        (scrollbar.isVertical ? scrollbar.height : 0));
    if (!isHorizontalAxis && (scrollbar.axis.scrollbarSettings.position === 'Left' || scrollbar.axis.scrollbarSettings.position === 'Right')) {
        leftOffset = calculateScrollbarOffset(scrollbar, isHorizontalAxis);
    }
    else if (isHorizontalAxis && (scrollbar.axis.scrollbarSettings.position === 'Top' || scrollbar.axis.scrollbarSettings.position === 'Bottom')) {
        topOffset = calculateScrollbarOffset(scrollbar, isHorizontalAxis);
    }
    scrollbar.svgObject = renderer.createSvg({
        id: scrollbar.component.element.id + '_' + 'scrollBar_svg' + scrollbar.axis.name,
        width: scrollbar.isVertical ? scrollbar.height : (scrollbar.axis.scrollbarSettings.enableZoom ?
            (scrollbar.width + scrollbar.svgExtraWidth) : scrollbar.width),
        height: scrollbar.isVertical ? scrollbar.width : scrollbar.height,
        style: 'position: absolute;top: ' + topOffset + 'px;left: ' + (leftOffset - (!scrollbar.isVertical && scrollbar.axis.scrollbarSettings.enableZoom ? scrollbar.svgExtraWidth / 2 : 0)) + 'px;cursor:auto;'
    });
    scrollbar.elements.push(scrollbar.svgObject);
}
/**
 * Scrollbar elements renderer.
 *
 * @private
 */
var ScrollElements = /** @class */ (function () {
    /**
     * Constructor for scroll elements
     *
     * @param scrollObj
     * @param chart
     */
    function ScrollElements(chart) {
        this.chartId = chart.element.id + '_';
    }
    /**
     * Render scrollbar elements.
     *
     * @returns {void}
     * @private
     */
    ScrollElements.prototype.renderElements = function (scroll, renderer) {
        var isInverse = scroll.axis.isAxisInverse;
        var scrollBar = scroll.axis.scrollbarSettings;
        var scrollGroup = renderer.createGroup({
            id: this.chartId + 'scrollBar_' + scroll.axis.name,
            transform: 'translate(' + ((scroll.isVertical && isInverse) ? scroll.height : isInverse ?
                scroll.width : '0') + ',' + (scroll.isVertical && isInverse ? '0' : isInverse ?
                scroll.height : scroll.isVertical ? scroll.width : '0') + ') rotate(' + (scroll.isVertical && isInverse ?
                '90' : scroll.isVertical ? '270' : isInverse ? '180' : '0') + ')'
        });
        var backRectGroup = renderer.createGroup({
            id: this.chartId + 'scrollBar_backRect_' + scroll.axis.name
        });
        var thumbGroup = renderer.createGroup({
            id: this.chartId + 'scrollBar_thumb_' + scroll.axis.name,
            transform: 'translate(0,0)'
        });
        this.backRect(scroll, renderer, backRectGroup, scrollBar);
        this.thumb(scroll, renderer, thumbGroup, scrollBar);
        this.renderCircle(scroll, renderer, thumbGroup, scrollBar);
        this.arrows(scroll, renderer, thumbGroup, scrollBar);
        this.thumbGrip(scroll, renderer, thumbGroup, scrollBar);
        scrollGroup.appendChild(backRectGroup);
        scrollGroup.appendChild(thumbGroup);
        return scrollGroup;
    };
    /**
     * Method to render back rectangle of scrollbar
     *
     * @param scroll
     * @param renderer
     * @param parent
     * @param renderer
     * @param parent
     */
    ScrollElements.prototype.backRect = function (scroll, renderer, parent, scrollBar) {
        var style = scroll.scrollbarThemeStyle;
        var backRectEle = renderer.drawRectangle(new RectOption(this.chartId + 'scrollBarBackRect_' + scroll.axis.name, scrollBar.trackColor || style.backRect, { width: 1, color: scrollBar.trackColor || style.backRect }, 1, new Rect((scrollBar.enableZoom && !scroll.isVertical ? scroll.svgExtraWidth / 2 : 0), 0, scroll.width, scroll.height), scrollBar.trackRadius, scrollBar.trackRadius));
        parent.appendChild(backRectEle);
    };
    /**
     * Method to render arrows
     *
     * @param scroll
     * @param renderer
     * @param parent
     * @param renderer
     * @param parent
     */
    ScrollElements.prototype.arrows = function (scroll, renderer, parent, scrollBar) {
        var style = scroll.scrollbarThemeStyle;
        var option = new PathOption(this.chartId + 'scrollBar_leftArrow_' + scroll.axis.name, style.arrow, 1, style.arrow, 1, '', '');
        this.leftArrowEle = renderer.drawPath(option);
        option.id = this.chartId + 'scrollBar_rightArrow_' + scroll.axis.name;
        this.rightArrowEle = renderer.drawPath(option);
        this.setArrowDirection((this.thumbRectX + (!scroll.isVertical && scroll.axis.scrollbarSettings.enableZoom ?
            scroll.svgExtraWidth / 2 : 0)), (this.thumbRectWidth - (!scroll.isVertical &&
            (this.thumbRectWidth + this.thumbRectX > scroll.width) ?
            scroll.svgExtraWidth / 2 : 0)), scroll.height);
        if (scrollBar.enableZoom) {
            parent.appendChild(this.leftArrowEle);
            parent.appendChild(this.rightArrowEle);
        }
    };
    /**
     * Methods to set the arrow width.
     *
     * @param thumbRectX
     * @param thumbRectWidth
     * @param height
     */
    ScrollElements.prototype.setArrowDirection = function (thumbRectX, thumbRectWidth, height) {
        var circleRadius = height / 2;
        var leftDirection = 'M ' + ((thumbRectX - circleRadius / 2)) + ' ' + (height / 2) + ' ' + 'L ' +
            (thumbRectX - circleRadius / 2 + (height / 2 - circleRadius / 4)) + ' ' + (height - circleRadius / 2) + ' ' + 'L ' + (thumbRectX - circleRadius / 2 + (height / 2 - circleRadius / 4)) + ' ' + (circleRadius / 2) + ' Z';
        var rightDirection = 'M ' + ((thumbRectX + thumbRectWidth + circleRadius / 2)) + ' ' + (height / 2)
            + ' ' + 'L ' + (thumbRectX + thumbRectWidth + circleRadius / 2 - (height / 2 - circleRadius / 4)) + ' ' + (height - circleRadius / 2) + ' ' + 'L ' + (thumbRectX +
            thumbRectWidth + circleRadius / 2 - (height / 2 - circleRadius / 4)) + ' ' + (circleRadius / 2) + ' Z';
        this.leftArrowEle.setAttribute('d', leftDirection);
        this.rightArrowEle.setAttribute('d', rightDirection);
    };
    /**
     * Method to render thumb.
     *
     * @param scroll
     * @param renderer
     * @param parent
     */
    ScrollElements.prototype.thumb = function (scroll, renderer, parent, scrollBar) {
        scroll.startX = this.thumbRectX;
        var style = scroll.scrollbarThemeStyle;
        this.slider = renderer.drawRectangle(new RectOption(this.chartId + 'scrollBarThumb_' + scroll.axis.name, scrollBar.scrollbarColor || style.thumb, { width: 1, color: scrollBar.scrollbarColor || style.thumb }, 1, new Rect(scrollBar.enableZoom ? (this.thumbRectX + (!scroll.isVertical && scroll.axis.scrollbarSettings.enableZoom ?
            scroll.svgExtraWidth / 2 : 0)) : this.thumbRectX - scroll.height / 2, 0, scrollBar.enableZoom ?
            this.thumbRectWidth - (!scroll.isVertical && (this.thumbRectWidth + this.thumbRectX > scroll.width) ?
                scroll.svgExtraWidth / 2 : 0) : this.thumbRectWidth + scroll.height / 2, scroll.height), scrollBar.scrollbarRadius, scrollBar.scrollbarRadius));
        parent.appendChild(this.slider);
    };
    /**
     *  Method to render circles
     *
     * @param scroll
     * @param renderer
     * @param parent
     */
    ScrollElements.prototype.renderCircle = function (scroll, renderer, parent, scrollBar) {
        var style = scroll.scrollbarThemeStyle;
        var option = new CircleOption(this.chartId + 'scrollBar_leftCircle_' + scroll.axis.name, style.circle, { width: 1, color: style.circle }, 1, this.thumbRectX + (!scroll.isVertical && scroll.axis.scrollbarSettings.enableZoom ? scroll.svgExtraWidth / 2 : 0), scroll.height / 2, scroll.height / 2);
        var scrollShadowEle = '<filter x="-25.0%" y="-20.0%" width="150.0%" height="150.0%" filterUnits="objectBoundingBox"' +
            'id="scrollbar_shadow"><feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>' +
            '<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>' +
            '<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>' +
            '<feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.16 0" type="matrix" in="shadowBlurOuter1">' +
            '</feColorMatrix></filter>';
        var defElement = renderer.createDefs();
        var shadowGroup = renderer.createGroup({
            id: this.chartId + scroll.axis.name + '_thumb_shadow'
        });
        defElement.innerText = scrollShadowEle;
        shadowGroup.innerText = '<use fill="black" fill-opacity="1" filter="url(#scrollbar_shadow)" xlink:href="#' +
            this.chartId + 'scrollBar_leftCircle_' +
            scroll.axis.name + '"></use><use fill="black" fill-opacity="1" filter="url(#scrollbar_shadow)" xlink:href="#' +
            this.chartId + 'scrollBar_rightCircle_' + scroll.axis.name + '"></use>';
        this.leftCircleEle = renderer.drawCircle(option);
        option.id = this.chartId + 'scrollBar_rightCircle_' + scroll.axis.name;
        option.cx = (this.thumbRectX + (!scroll.isVertical && scroll.axis.scrollbarSettings.enableZoom ? scroll.svgExtraWidth / 2 : 0))
            + (this.thumbRectWidth - (!scroll.isVertical && (this.thumbRectWidth + this.thumbRectX > scroll.width) ?
                scroll.svgExtraWidth / 2 : 0));
        this.rightCircleEle = renderer.drawCircle(option);
        parent.appendChild(defElement);
        if (scrollBar.enableZoom) {
            parent.appendChild(this.leftCircleEle);
            parent.appendChild(this.rightCircleEle);
        }
        parent.appendChild(shadowGroup);
    };
    /**
     * Method to render grip elements
     *
     * @param scroll
     * @param renderer
     * @param parent
     */
    ScrollElements.prototype.thumbGrip = function (scroll, renderer, parent, scrollBar) {
        var sidePadding = (scroll.component.theme.indexOf('Fluent2') > -1 || (scroll.component.theme.indexOf('Bootstrap5')) > -1 || scroll.component.theme.indexOf('Tailwind3') > -1) ? -5 : 0;
        var topPadding = 0;
        var gripWidth = 14;
        var gripCircleDiameter = 2;
        var padding = gripWidth / 2 - gripCircleDiameter;
        var style = scroll.scrollbarThemeStyle;
        var option = new CircleOption(this.chartId + 'scrollBar_gripCircle0' + '_' + scroll.axis.name, scrollBar.gripColor || style.grip, { width: 1, color: scrollBar.gripColor || style.grip }, 1, 0, 0, 1);
        this.gripCircle = renderer.createGroup({
            id: this.chartId + 'scrollBar_gripCircle_' + scroll.axis.name,
            transform: 'translate(' + (!scrollBar.enableZoom ? ((this.thumbRectX + this.thumbRectWidth / 2) + ((scroll.isVertical ? 2 : 0) * padding) - scrollBar.height / 2) : ((this.thumbRectX + (!scroll.isVertical && scroll.axis.scrollbarSettings.enableZoom ? scroll.svgExtraWidth / 2 : 0)) + (this.thumbRectWidth - (!scroll.isVertical && scroll.axis.scrollbarSettings.enableZoom && this.thumbRectWidth + this.thumbRectX > scroll.width ? scroll.svgExtraWidth / 2 : 0)) / 2) + ((scroll.isVertical ? 1 : -1) * padding)) +
                ',' + (scroll.isVertical ? (scroll.height / 2 + padding / 2) - 0.5 : (scroll.height / 2 - padding / 2) - 0.5) + ') rotate(' + (scroll.isVertical ? '180' : '0') + ')'
        });
        for (var i = 1; i <= (scroll.component.theme.indexOf('Fluent2') > -1 || (scroll.component.theme.indexOf('Bootstrap5')) > -1 || scroll.component.theme.indexOf('Tailwind3') > -1 ? 10 : 6); i++) {
            option.id = this.chartId + 'scrollBar_gripCircle' + i + '_' + scroll.axis.name;
            option.cx = sidePadding;
            option.cy = topPadding;
            this.gripCircle.appendChild(renderer.drawCircle(option));
            sidePadding = i === (scroll.component.theme.indexOf('Fluent2') > -1 || (scroll.component.theme.indexOf('Bootstrap5')) > -1 || scroll.component.theme.indexOf('Tailwind3') > -1 ? 5 : 3) ? ((scroll.component.theme.indexOf('Fluent2') > -1 || (scroll.component.theme.indexOf('Bootstrap5')) > -1 || scroll.component.theme.indexOf('Tailwind3') > -1) ? -5 : 0) : (sidePadding + 5);
            topPadding = i >= (scroll.component.theme.indexOf('Fluent2') > -1 || (scroll.component.theme.indexOf('Bootstrap5')) > -1 || scroll.component.theme.indexOf('Tailwind3') > -1 ? 5 : 3) ? 5 : 0;
        }
        if (scrollBar.height >= 12) {
            parent.appendChild(this.gripCircle);
        }
    };
    return ScrollElements;
}());
export { ScrollElements };