/*
* Copyright 2016 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @private
* This class is a cartesian chart which enables to draw over it.
* Inspired by http://examples.sencha.com/extjs/6.0.1/examples/kitchensink/?charts=true#free-paint
*/
Ext.define('Ametys.plugins.admin.jvmstatus.MonitoringTool.DrawableCartesianChart', function () {
function smoothList(points) {
if (points.length < 3) {
return ['M', points[0], points[1]];
}
var dx = [], dy = [], result = ['M'],
i, ln = points.length;
for (i = 0; i < ln; i += 2) {
dx.push(points[i]);
dy.push(points[i + 1]);
}
dx = Ext.draw.Draw.spline(dx);
dy = Ext.draw.Draw.spline(dy);
result.push(dx[0], dy[0], 'C');
for (i = 1, ln = dx.length; i < ln; i++) {
result.push(dx[i], dy[i]);
}
return result;
}
return {
extend: 'Ext.chart.CartesianChart',
xtype: 'drawable-cartesian',
draw: false,
sprite: undefined,
lastEventX: undefined,
lastEventY: undefined,
list: [],
listeners: {
element: 'element',
// The type of events that are supported for each framework and platform are...
// - ExtJS on Desktop Machine: Mouse events
// - ExtJS on Touch Device: Mouse events + Touch events
// - Sencha Touch: Touch events + Drag events
//
// Mouse events = mousedown / mousemove / mouseup
// Touch events = touchstart / touchmove / touchend
// Drag events = dragstart / drag / dragend
//
// Since this is an ExtJS example, we can listen to Mouse events only.
//
// If we wanted the example to run on Sencha Touch also, we would have
// to listen to both Mouse events and Drag events (listening to Mouse
// events and Touch events would work as well but with the drawback
// that ExtJS on Touch Device would send duplicate events.
mousedown: function(e) {
var targetElement = this,
me = Ext.getCmp(targetElement.id),
surface = me.getSurface('chart');
if (me.draw && !me.sprite) {
var xy = surface.getEventXY(e),
x = xy[0],
y = xy[1];
me.list = [x, y, x, y];
me.lastEventX = x;
me.lastEventY = y;
me.sprite = surface.add({
type: 'path',
path: ['M', me.list[0], me.list[1], 'L', me.list[0] + 1e-1, me.list[1] + 1e-1],
lineWidth: 4,
lineCap: 'round',
lineJoin: 'round',
strokeStyle: new Ext.draw.Color(50, 50, 50),
zIndex: 1
});
surface.renderFrame();
}
},
mousemove: function(e) {
var targetElement = this,
me = Ext.getCmp(targetElement.id),
surface = me.getSurface('chart');
if (me.draw && me.sprite) {
var xy = surface.getEventXY(e),
x = xy[0],
y = xy[1],
dx = me.lastEventX - x,
dy = me.lastEventY - y,
D = 10;
if (dx * dx + dy * dy < D * D) {
me.list.length -= 2;
me.list.push(x, y);
} else {
me.list.length -= 2;
me.list.push(me.lastEventX = x, me.lastEventY = y);
me.list.push(me.lastEventX + 1, me.lastEventY + 1);
}
var path = smoothList(me.list);
me.sprite.setAttributes({
path: path
});
if (Ext.os.is.Android) {
Ext.draw.Animator.schedule(function () {
surface.renderFrame();
}, me);
} else {
surface.renderFrame();
}
}
}
},
initEvents: function () {
this.callParent(arguments);
this.on({
element: 'element',
mouseup: this.onMouseUp,
mouseleave: this.onMouseUp
});
},
onMouseUp: function(e) {
var targetElement = this,
me = Ext.getCmp(targetElement.id);
me.sprite = null;
},
onResize: function() {
var size = this.element.getSize();
this.getSurface('chart').setRect([0, 0, size.width, size.height]);
this.renderFrame();
},
/**
* Set the drawing mode active.
* @param {Boolean} active True to set the drawing mode active, false otherwise.
*/
setDraw: function(active)
{
this.draw = Ext.isBoolean(active) ? active : false;
}
};
});