UNPKG

highcharts

Version:
163 lines (162 loc) 6.2 kB
/* * * * (c) 2010-2021 Torstein Honsi * * Extensions to the SVGRenderer class to enable 3D shapes * * License: www.highcharts.com/license * * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! * * */ 'use strict'; import Color from '../../Color/Color.js'; var color = Color.parse; import SVGElement from './SVGElement.js'; import U from '../../Utilities.js'; var defined = U.defined, merge = U.merge, objectEach = U.objectEach, pick = U.pick; /* * * * Namespace * * */ var SVGElement3D; (function (SVGElement3D) { /* * * * Functions * * */ /* eslint-disable valid-jsdoc */ SVGElement3D.base = { /** * The init is used by base - renderer.Element * @private */ initArgs: function (args) { var elem3d = this, renderer = elem3d.renderer, paths = renderer[elem3d.pathType + 'Path'](args), zIndexes = paths.zIndexes; // build parts elem3d.parts.forEach(function (part) { elem3d[part] = renderer.path(paths[part]).attr({ 'class': 'highcharts-3d-' + part, zIndex: zIndexes[part] || 0 }).add(elem3d); }); elem3d.attr({ 'stroke-linejoin': 'round', zIndex: zIndexes.group }); // store original destroy elem3d.originalDestroy = elem3d.destroy; elem3d.destroy = elem3d.destroyParts; // Store information if any side of element was rendered by force. elem3d.forcedSides = paths.forcedSides; }, /** * Single property setter that applies options to each part * @private */ singleSetterForParts: function (prop, val, values, verb, duration, complete) { var elem3d = this, newAttr = {}, optionsToApply = [null, null, (verb || 'attr'), duration, complete], hasZIndexes = values && values.zIndexes; if (!values) { newAttr[prop] = val; optionsToApply[0] = newAttr; } else { // It is needed to deal with the whole group zIndexing // in case of graph rotation if (hasZIndexes && hasZIndexes.group) { this.attr({ zIndex: hasZIndexes.group }); } objectEach(values, function (partVal, part) { newAttr[part] = {}; newAttr[part][prop] = partVal; // include zIndexes if provided if (hasZIndexes) { newAttr[part].zIndex = values.zIndexes[part] || 0; } }); optionsToApply[1] = newAttr; } return elem3d.processParts.apply(elem3d, optionsToApply); }, /** * Calls function for each part. Used for attr, animate and destroy. * @private */ processParts: function (props, partsProps, verb, duration, complete) { var elem3d = this; elem3d.parts.forEach(function (part) { // if different props for different parts if (partsProps) { props = pick(partsProps[part], false); } // only if something to set, but allow undefined if (props !== false) { elem3d[part][verb](props, duration, complete); } }); return elem3d; }, /** * Destroy all parts * @private */ destroyParts: function () { this.processParts(null, null, 'destroy'); return this.originalDestroy(); } }; SVGElement3D.cuboid = merge(SVGElement3D.base, { parts: ['front', 'top', 'side'], pathType: 'cuboid', attr: function (args, val, complete, continueAnimation) { // Resolve setting attributes by string name if (typeof args === 'string' && typeof val !== 'undefined') { var key = args; args = {}; args[key] = val; } if (args.shapeArgs || defined(args.x)) { return this.singleSetterForParts('d', null, this.renderer[this.pathType + 'Path'](args.shapeArgs || args)); } return SVGElement.prototype.attr.call(this, args, void 0, complete, continueAnimation); }, animate: function (args, duration, complete) { if (defined(args.x) && defined(args.y)) { var paths = this.renderer[this.pathType + 'Path'](args), forcedSides = paths.forcedSides; this.singleSetterForParts('d', null, paths, 'animate', duration, complete); this.attr({ zIndex: paths.zIndexes.group }); // If sides that are forced to render changed, recalculate // colors. if (forcedSides !== this.forcedSides) { this.forcedSides = forcedSides; SVGElement3D.cuboid.fillSetter.call(this, this.fill); } } else { SVGElement.prototype.animate.call(this, args, duration, complete); } return this; }, fillSetter: function (fill) { var elem3d = this; elem3d.forcedSides = elem3d.forcedSides || []; elem3d.singleSetterForParts('fill', null, { front: fill, // Do not change color if side was forced to render. top: color(fill).brighten(elem3d.forcedSides.indexOf('top') >= 0 ? 0 : 0.1).get(), side: color(fill).brighten(elem3d.forcedSides.indexOf('side') >= 0 ? 0 : -0.1).get() }); // fill for animation getter (#6776) elem3d.color = elem3d.fill = fill; return elem3d; } }); /* eslint-enable valid-jsdoc */ })(SVGElement3D || (SVGElement3D = {})); export default SVGElement3D;