123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- 'use strict';
- import H from './../../parts/Globals.js';
- import './../../parts/Chart.js';
- import './../../parts/Utilities.js';
- import './../../parts/SvgRenderer.js';
- /**
- * Options for configuring markers for annotations.
- *
- * An example of the arrow marker:
- * <pre>
- * {
- * arrow: {
- * id: 'arrow',
- * tagName: 'marker',
- * refY: 5,
- * refX: 5,
- * markerWidth: 10,
- * markerHeight: 10,
- * children: [{
- * tagName: 'path',
- * attrs: {
- * d: 'M 0 0 L 10 5 L 0 10 Z',
- * strokeWidth: 0
- * }
- * }]
- * }
- * }
- * </pre>
- * @type {Object}
- * @sample highcharts/annotations/custom-markers/
- * Define a custom marker for annotations
- * @sample highcharts/css/annotations-markers/
- * Define markers in a styled mode
- * @since 6.0.0
- * @apioption defs
- */
- var defaultMarkers = {
- arrow: {
- tagName: 'marker',
- render: false,
- id: 'arrow',
- refY: 5,
- refX: 9,
- markerWidth: 10,
- markerHeight: 10,
- children: [{
- tagName: 'path',
- d: 'M 0 0 L 10 5 L 0 10 Z', // triangle (used as an arrow)
- strokeWidth: 0
- }]
- },
- 'reverse-arrow': {
- tagName: 'marker',
- render: false,
- id: 'reverse-arrow',
- refY: 5,
- refX: 1,
- markerWidth: 10,
- markerHeight: 10,
- children: [{
- tagName: 'path',
- // reverse triangle (used as an arrow)
- d: 'M 0 5 L 10 0 L 10 10 Z',
- strokeWidth: 0
- }]
- }
- };
- H.SVGRenderer.prototype.addMarker = function (id, markerOptions) {
- var options = { id: id };
- var attrs = {
- stroke: markerOptions.color || 'none',
- fill: markerOptions.color || 'rgba(0, 0, 0, 0.75)'
- };
- options.children = markerOptions.children.map(function (child) {
- return H.merge(attrs, child);
- });
- var marker = this.definition(H.merge(true, {
- markerWidth: 20,
- markerHeight: 20,
- refX: 0,
- refY: 0,
- orient: 'auto'
- }, markerOptions, options));
- marker.id = id;
- return marker;
- };
- var createMarkerSetter = function (markerType) {
- return function (value) {
- this.attr(markerType, 'url(#' + value + ')');
- };
- };
- /**
- * @mixin
- */
- var markerMixin = {
- markerEndSetter: createMarkerSetter('marker-end'),
- markerStartSetter: createMarkerSetter('marker-start'),
- /*
- * Set markers.
- *
- * @param {Controllable} item
- */
- setItemMarkers: function (item) {
- var itemOptions = item.options,
- chart = item.chart,
- defs = chart.options.defs,
- fill = itemOptions.fill,
- color = H.defined(fill) && fill !== 'none' ?
- fill :
- itemOptions.stroke,
- setMarker = function (markerType) {
- var markerId = itemOptions[markerType],
- def,
- predefinedMarker,
- key,
- marker;
- if (markerId) {
- for (key in defs) {
- def = defs[key];
- if (
- markerId === def.id && def.tagName === 'marker'
- ) {
- predefinedMarker = def;
- break;
- }
- }
- if (predefinedMarker) {
- marker = item[markerType] = chart.renderer
- .addMarker(
- (itemOptions.id || H.uniqueKey()) + '-' +
- predefinedMarker.id,
- H.merge(predefinedMarker, { color: color })
- );
- item.attr(markerType, marker.attr('id'));
- }
- }
- };
- ['markerStart', 'markerEnd'].forEach(setMarker);
- }
- };
- // In a styled mode definition is implemented
- H.SVGRenderer.prototype.definition = function (def) {
- var ren = this;
- function recurse(config, parent) {
- var ret;
- H.splat(config).forEach(function (item) {
- var node = ren.createElement(item.tagName),
- attr = {};
- // Set attributes
- H.objectEach(item, function (val, key) {
- if (
- key !== 'tagName' &&
- key !== 'children' &&
- key !== 'textContent'
- ) {
- attr[key] = val;
- }
- });
- node.attr(attr);
- // Add to the tree
- node.add(parent || ren.defs);
- // Add text content
- if (item.textContent) {
- node.element.appendChild(
- H.doc.createTextNode(item.textContent)
- );
- }
- // Recurse
- recurse(item.children || [], node);
- ret = node;
- });
- // Return last node added (on top level it's the only one)
- return ret;
- }
- return recurse(def);
- };
- H.addEvent(H.Chart, 'afterGetContainer', function () {
- this.options.defs = H.merge(defaultMarkers, this.options.defs || {});
- H.objectEach(this.options.defs, function (def) {
- if (def.tagName === 'marker' && def.render !== false) {
- this.renderer.addMarker(def.id, def);
- }
- }, this);
- });
- export default markerMixin;
|