linuxwindowsinboxwhatsappicloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacos
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.
208 lines
6.3 KiB
208 lines
6.3 KiB
9 years ago
|
/**
|
||
|
* 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);
|
||
|
}
|
||
|
});
|
||
|
|