/** * Mixin that provides the functionality to place markers. */Ext.define('Ext.chart.MarkerHolder', { extend: 'Ext.Mixin', requires: [ 'Ext.chart.Markers' ], mixinConfig: { id: 'markerHolder', after: { constructor: 'constructor', preRender: 'preRender' }, before: { destroy: 'destroy' } }, isMarkerHolder: true, // The combined transformation applied to the sprite by its parents. // Does not include the transformation matrix of the sprite itself. surfaceMatrix: null, // The inverse of the above transformation to go back to the original state. inverseSurfaceMatrix: null, deprecated: { 6: { methods: { /** * Returns the markers bound to the given name. * @param {String} name The name of the marker (e.g., "items", "labels", etc.). * @return {Ext.chart.Markers[]} * @method getBoundMarker * @deprecated 6.0 Use {@link #getMarker} instead. */ getBoundMarker: { message: "Please use the 'getMarker' method instead.", fn: function(name) { var marker = this.boundMarkers[name]; return marker ? [marker] : marker; } } } } }, constructor: function() { this.boundMarkers = {}; this.cleanRedraw = false; }, /** * Registers the given marker with the marker holder under the specified name. * @param {String} name The name of the marker (e.g., "items", "labels", etc.). * @param {Ext.chart.Markers} marker */ bindMarker: function(name, marker) { var me = this, markers = me.boundMarkers; if (marker && marker.isMarkers) { //<debug> if (markers[name] && markers[name] === marker) { Ext.log.warn(me.getId(), " (MarkerHolder): the Markers instance '", marker.getId(), "' is already bound under the name '", name, "'."); } //</debug> me.releaseMarker(name); markers[name] = marker; marker.on('destroy', me.onMarkerDestroy, me); } }, onMarkerDestroy: function(marker) { this.releaseMarker(marker); }, /** * Unregisters the given marker or a marker with the given name. * Providing a name of the marker is more efficient as it avoids lookup. * @param marker {String/Ext.chart.Markers} * @return {Ext.chart.Markers} Released marker or null. */ releaseMarker: function(marker) { var markers = this.boundMarkers, name; if (marker && marker.isMarkers) { for (name in markers) { if (markers[name] === marker) { delete markers[name]; break; } } } else { name = marker; marker = markers[name]; delete markers[name]; } return marker || null; }, /** * Returns the marker bound to the given name (or null). See {@link #bindMarker}. * @param {String} name The name of the marker (e.g., "items", "labels", etc.). * @return {Ext.chart.Markers} */ getMarker: function(name) { return this.boundMarkers[name] || null; }, preRender: function(surface, ctx, rect) { var me = this, id = me.getId(), boundMarkers = me.boundMarkers, parent = me.getParent(), name, marker, matrix; if (me.surfaceMatrix) { matrix = me.surfaceMatrix.set(1, 0, 0, 1, 0, 0); } else { matrix = me.surfaceMatrix = new Ext.draw.Matrix(); } me.cleanRedraw = !me.attr.dirty; if (!me.cleanRedraw) { for (name in boundMarkers) { marker = boundMarkers[name]; if (marker) { marker.clear(id); } } } // Parent can be either a sprite (like a composite or instancing) // or a surface. First, climb up and apply transformations of the // parent sprites. while (parent && parent.attr && parent.attr.matrix) { matrix.prependMatrix(parent.attr.matrix); parent = parent.getParent(); } // Finally, apply the transformation used by the surface. matrix.prependMatrix(parent.matrix); me.surfaceMatrix = matrix; me.inverseSurfaceMatrix = matrix.inverse(me.inverseSurfaceMatrix); }, putMarker: function(name, attr, index, bypassNormalization, keepRevision) { var marker = this.boundMarkers[name]; if (marker) { marker.putMarkerFor(this.getId(), attr, index, bypassNormalization, keepRevision); } }, getMarkerBBox: function(name, index, isWithoutTransform) { var marker = this.boundMarkers[name]; if (marker) { return marker.getMarkerBBoxFor(this.getId(), index, isWithoutTransform); } }, destroy: function() { var boundMarkers = this.boundMarkers, name, marker; for (name in boundMarkers) { marker = boundMarkers[name]; marker.destroy(); } }});