skypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacoslinuxwindowsinboxwhatsappicloudtweetdeckhipchattelegramhangoutsslackgmail
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
6.3 KiB
207 lines
6.3 KiB
/** |
|
* Defines a mask for a chart's series. |
|
* The 'chart' member must be set prior to rendering. |
|
* |
|
* A Mask can be used to select a certain region in a chart. |
|
* When enabled, the `select` event will be triggered when a |
|
* region is selected by the mask, allowing the user to perform |
|
* other tasks like zooming on that region, etc. |
|
* |
|
* In order to use the mask one has to set the Chart `mask` option to |
|
* `true`, `vertical` or `horizontal`. Then a possible configuration for the |
|
* listener could be: |
|
* |
|
* items: { |
|
* xtype: 'chart', |
|
* animate: true, |
|
* store: store1, |
|
* mask: 'horizontal', |
|
* listeners: { |
|
* select: { |
|
* fn: function(me, selection) { |
|
* me.setZoom(selection); |
|
* me.mask.hide(); |
|
* } |
|
* } |
|
* } |
|
* } |
|
* |
|
* In this example we zoom the chart to that particular region. You can also get |
|
* a handle to a mask instance from the chart object. The `chart.mask` element is a |
|
* `Ext.Panel`. |
|
* |
|
*/ |
|
Ext.define('Ext.chart.Mask', { |
|
mixinId: 'mask', |
|
|
|
requires: [ |
|
'Ext.chart.MaskLayer' |
|
], |
|
|
|
/** |
|
* @cfg {Boolean/String} mask |
|
* Enables selecting a region on chart. True to enable any selection, |
|
* 'horizontal' or 'vertical' to restrict the selection to X or Y axis. |
|
* |
|
* The mask in itself will do nothing but fire 'select' event. |
|
* See {@link Ext.chart.Mask} for example. |
|
*/ |
|
|
|
/** |
|
* Creates new Mask. |
|
* @param {Object} [config] Config object. |
|
*/ |
|
constructor: function(config) { |
|
var me = this; |
|
|
|
if (config) { |
|
Ext.apply(me, config); |
|
} |
|
if (me.enableMask) { |
|
me.on('afterrender', function() { |
|
//create a mask layer component |
|
var comp = new Ext.chart.MaskLayer({ |
|
renderTo: me.el, |
|
hidden: true |
|
}); |
|
comp.el.on({ |
|
'mousemove': function(e) { |
|
me.onMouseMove(e); |
|
}, |
|
'mouseup': function(e) { |
|
me.onMouseUp(e); |
|
} |
|
}); |
|
comp.initDraggable(); |
|
me.maskType = me.mask; |
|
me.mask = comp; |
|
me.maskSprite = me.surface.add({ |
|
type: 'path', |
|
path: ['M', 0, 0], |
|
zIndex: 1001, |
|
opacity: 0.6, |
|
hidden: true, |
|
stroke: '#00f', |
|
cursor: 'crosshair' |
|
}); |
|
}, me, { single: true }); |
|
} |
|
}, |
|
|
|
onMouseUp: function(e) { |
|
var me = this, |
|
bbox = me.bbox || me.chartBBox, |
|
sel; |
|
me.maskMouseDown = false; |
|
me.mouseDown = false; |
|
if (me.mouseMoved) { |
|
me.handleMouseEvent(e); |
|
me.mouseMoved = false; |
|
sel = me.maskSelection; |
|
me.fireEvent('select', me, { |
|
x: sel.x - bbox.x, |
|
y: sel.y - bbox.y, |
|
width: sel.width, |
|
height: sel.height |
|
}); |
|
} |
|
}, |
|
|
|
onMouseDown: function(e) { |
|
this.handleMouseEvent(e); |
|
}, |
|
|
|
onMouseMove: function(e) { |
|
this.handleMouseEvent(e); |
|
}, |
|
|
|
handleMouseEvent: function(e) { |
|
var me = this, |
|
mask = me.maskType, |
|
bbox = me.bbox || me.chartBBox, |
|
x = bbox.x, |
|
y = bbox.y, |
|
math = Math, |
|
floor = math.floor, |
|
abs = math.abs, |
|
min = math.min, |
|
max = math.max, |
|
height = floor(y + bbox.height), |
|
width = floor(x + bbox.width), |
|
staticX = e.getPageX() - me.el.getX(), |
|
staticY = e.getPageY() - me.el.getY(), |
|
maskMouseDown = me.maskMouseDown, |
|
path; |
|
|
|
staticX = max(staticX, x); |
|
staticY = max(staticY, y); |
|
staticX = min(staticX, width); |
|
staticY = min(staticY, height); |
|
|
|
if (e.type === 'mousedown') { |
|
// remember the cursor location |
|
me.mouseDown = true; |
|
me.mouseMoved = false; |
|
me.maskMouseDown = { |
|
x: staticX, |
|
y: staticY |
|
}; |
|
} |
|
else { |
|
// mousedown or mouseup: |
|
// track the cursor to display the selection |
|
me.mouseMoved = me.mouseDown; |
|
if (maskMouseDown && me.mouseDown) { |
|
if (mask == 'horizontal') { |
|
staticY = y; |
|
maskMouseDown.y = height; |
|
} |
|
else if (mask == 'vertical') { |
|
staticX = x; |
|
maskMouseDown.x = width; |
|
} |
|
width = maskMouseDown.x - staticX; |
|
height = maskMouseDown.y - staticY; |
|
path = ['M', staticX, staticY, 'l', width, 0, 0, height, -width, 0, 'z']; |
|
me.maskSelection = { |
|
x: (width > 0 ? staticX : staticX + width) + me.el.getX(), |
|
y: (height > 0 ? staticY : staticY + height) + me.el.getY(), |
|
width: abs(width), |
|
height: abs(height) |
|
}; |
|
me.mask.updateBox(me.maskSelection); |
|
me.mask.show(); |
|
me.maskSprite.setAttributes({ |
|
hidden: true |
|
}, true); |
|
} |
|
else { |
|
if (mask == 'horizontal') { |
|
path = ['M', staticX, y, 'L', staticX, height]; |
|
} |
|
else if (mask == 'vertical') { |
|
path = ['M', x, staticY, 'L', width, staticY]; |
|
} |
|
else { |
|
path = ['M', staticX, y, 'L', staticX, height, 'M', x, staticY, 'L', width, staticY]; |
|
} |
|
me.maskSprite.setAttributes({ |
|
path: path, |
|
'stroke-width': mask === true ? 1 : 1, |
|
hidden: false |
|
}, true); |
|
} |
|
} |
|
|
|
}, |
|
|
|
onMouseLeave: function(e) { |
|
var me = this; |
|
me.mouseMoved = false; |
|
me.mouseDown = false; |
|
me.maskMouseDown = false; |
|
me.mask.hide(); |
|
me.maskSprite.hide(true); |
|
} |
|
}); |
|
|
|
|