magix-inspector
Version:
magix项目调试分析工具
507 lines (497 loc) • 21.3 kB
JavaScript
//#snippet;
//#exclude(loader)
let Graphics = {
'@{captureItmes}'() {
let g = Graphics;
g.list = [];
delete g['@{view.last}'];
UI['@{onMousemove}'] = e => {
let loop, one, dis;
if (g['@{view.last}']) {
one = g['@{view.last}'];
dis = Math.pow(Math.pow(one.center.x - e.x, 2) + Math.pow(one.center.y - e.y, 2), 1 / 2);
if (dis > one.radius) {
g['@{onHoverItem}']({
item: one,
action: 'leave'
});
delete g['@{view.last}'];
loop = true;
}
} else {
loop = true;
}
if (loop) {
for (let i = g.list.length - 1; i >= 0; i--) {
one = g.list[i];
dis = Math.pow(Math.pow(one.center.x - e.x, 2) + Math.pow(one.center.y - e.y, 2), 1 / 2);
if (dis <= one.radius) {
if (g['@{view.last}'] != one) {
g['@{view.last}'] = one;
g['@{onHoverItem}']({
item: one,
action: 'enter'
});
}
break;
}
}
}
};
UI['@{onCanvasClick}'] = g['@{onClickItem}'];
},
'@{captureManagerItmes}'() {
let g = Graphics;
g.managerList = [];
delete g['@{manager.last}'];
UI['@{onManagerMousemove}'] = e => {
let loop, one, rect;
if (g['@{manager.last}']) {
one = g['@{manager.last}'];
rect = one.rect;
if (e.x < rect[0] || e.y < rect[1] || e.x > (rect[0] + rect[2]) || e.y > (rect[1] + rect[3])) {
g['@{onHoverManagerItem}']({
item: one,
action: 'leave'
});
delete g['@{manager.last}'];
loop = true;
}
} else {
loop = true;
}
if (loop) {
for (let i = g.managerList.length - 1; i >= 0; i--) {
one = g.managerList[i];
rect = one.rect;
if (e.x >= rect[0] && e.y >= rect[1] && e.x <= (rect[0] + rect[2]) && e.y <= (rect[1] + rect[3])) {
if (g['@{manager.last}'] != one) {
g['@{manager.last}'] = one;
g['@{onHoverManagerItem}']({
item: one,
action: 'enter'
});
}
}
}
}
};
},
'@{getBestParams}'(tree, width, height) {
let maxChildren = 0,
deep = 0,
deepMap = {};
let walk = (item, level) => {
item.deep = level;
if (level > deep) {
deep = level;
}
if (!deepMap[level]) {
deepMap[level] = 0;
}
item.leftCount = deepMap[level];
deepMap[level]++;
if (deepMap[level] > maxChildren) {
maxChildren = deepMap[level];
}
for (let i = 0, one; i < item.children.length; i++) {
one = item.children[i];
walk(item.children[i], item.deep + 1);
}
};
tree.deepMap = deepMap;
walk(tree, 1, 0);
maxChildren = Math.max(maxChildren, tree.isolated.length + 1);
let hRadius = width / maxChildren - Consts['@{circleMargin}'];
let vRadius = height / deep - Consts['@{circleMargin}'];
let tw = width;
let dMinRadius = 2 * Consts['@{minCircleRadius}'];
if (hRadius < dMinRadius) {
hRadius = dMinRadius;
tw = dMinRadius * maxChildren + (maxChildren + 1) * Consts['@{circleMargin}'];
if (tw > 30000) {
tw = 30000;
}
UI['@{updateVOMCanvansWidth}'](tw);
} else {
UI['@{updateVOMCanvansWidth}'](tw);
}
let radius = Math.floor(Math.min(vRadius, hRadius) / 2);
let band = (radius / 20).toFixed(1);
return {
width: tw,
margin: Consts['@{circleMargin}'],
radius: radius,
band: band
};
},
'@{drawTree}'(tree, active) {
if (tree.id) {
let width = Consts['@{width}'],
height = Consts['@{canvasHeight}'],
g = Graphics;
g['@{captureItmes}']();
let params = g['@{getBestParams}'](tree, width, height);
width = params.width;
let ctx = getNode('@{mx_view_canvas}').getContext('2d');
ctx.clearRect(0, 0, width, height);
let max = params.radius * 2 - 2 * (params.band + 1) - 1;
if (!g['@{text.cache}']) g['@{text.cache}'] = {};
let getWidth = text => {
if (!g['@{text.cache}'][text]) {
ctx.font = 'normal 12px Arial';
g['@{text.cache}'][text] = ctx.measureText(text).width;
}
return g['@{text.cache}'][text];
};
let cutText = text => {
let len = 1,
width = 0;
while (len <= text.length) {
width += getWidth(text.substring(len - 1, len));
if (width < max) {
len += 1;
} else {
return text.substring(0, len - 3) + '..';
}
}
return text;
};
let linecolorIndex = 0;
let drawLine = (item, pos, ppos, lineColor) => {
if (ppos) {
ctx.beginPath();
let deg = Math.atan((pos.y - ppos.y) / (pos.x - ppos.x)) * 180 / Math.PI;
if (deg < 0) {
deg += 180;
}
let tx = Math.round(ppos.x + params.radius * Math.cos(deg * Math.PI / 180));
let ty = Math.round(ppos.y + params.radius * Math.sin(deg * Math.PI / 180));
ctx.moveTo(tx, ty); // 设置路径起点,坐标为(20,20)
ctx.lineTo(pos.x, pos.y); // 绘制一条到(200,20)的直线
ctx.lineWidth = params.band / 1.5; // 设置线宽
ctx.strokeStyle = lineColor;
ctx.stroke(); // 进行线的着色,这时整条线才变得可见
}
let count = tree.deepMap[item.deep + 1];
if (count) {
let space = (width - (count * params.radius * 2 + (count - 1) * params.margin)) / 2;
let lcolor = '#' + Lines[linecolorIndex++ % Lines.length]; // Lines[Math.floor(Math.random() * (Lines.length - 1))];
for (let i = 0, one; i < item.children.length; i++) {
one = item.children[i];
drawLine(one, {
x: space + one.leftCount * (params.radius * 2 + params.margin) + params.radius,
y: pos.y + params.margin + 2 * params.radius
}, pos, lcolor);
}
}
};
let drawCircle = (item, pos) => {
ctx.moveTo(pos.x, pos.y);
ctx.beginPath();
ctx.arc(pos.x, pos.y, params.radius, 0, Math.PI * 2, true);
ctx.fillStyle = item.status;
if (item.id == active) {
if (item.flag) {
ctx.fillStyle = Status['@{active}'];
} else {
ctx.fillStyle = item.status;
}
item.flag = !item.flag;
}
ctx.fill();
//bottom small cicle
let radius = Math.max(0.5, params.radius / 10);
let ly = pos.y + params.radius / 2;
let lx = pos.x - params.radius / 2 + radius;
//left
if (item.event) {
ctx.beginPath();
ctx.arc(lx, ly, radius, 0, Math.PI * 2, true);
ctx.fillStyle = item.event;
ctx.fill();
}
//center
if (item.location) {
ctx.beginPath();
ctx.arc(pos.x, ly + radius, radius, 0, Math.PI * 2, true);
ctx.fillStyle = item.location;
ctx.fill();
}
// center left top
if (item.mixins) {
let x1 = lx,
y1 = ly,
x2 = pos.x,
y2 = ly + radius;
let x3 = (x1 + x2 + Math.sqrt(3) * (y2 - y1)) / 2 - (x2 - x1) / 10;
let y3 = (y1 + y2 - Math.sqrt(3) * (x2 - x1)) / 2 + (x2 - x1) / 3;
ctx.beginPath();
ctx.arc(x3, y3, radius, 0, Math.PI * 2, true);
ctx.fillStyle = item.mixins;
ctx.fill();
}
//right
if (item.shared) {
let rx = pos.x + params.radius / 2 - radius;
ctx.beginPath();
ctx.arc(rx, ly, radius, 0, Math.PI * 2, true);
ctx.fillStyle = item.shared;
ctx.fill();
}
// center right top
if (item.state) {
let x1 = pos.x,
y1 = ly + radius,
x2 = pos.x + params.radius / 2 - radius,
y2 = ly;
let x3 = (x1 + x2 + Math.sqrt(3) * (y2 - y1)) / 2 + (x2 - x1) / 10;
let y3 = (y1 + y2 - Math.sqrt(3) * (x2 - x1)) / 2 + (x2 - x1) / 3;
ctx.beginPath();
ctx.arc(x3, y3, radius, 0, Math.PI * 2, true);
ctx.fillStyle = item.state;
ctx.fill();
}
if (item.inline) {
ctx.beginPath();
let r = params.radius - params.band - 1;
let d60 = -2 * Math.PI / 360 * 60;
let d120 = -2 * Math.PI / 360 * 120;
let x1 = pos.x + r * Math.cos(d60);
let y1 = pos.y + r * Math.sin(d60);
let x2 = pos.x + r * Math.cos(d120);
let y2 = pos.y + r * Math.sin(d120);
ctx.moveTo(x1, y1);
ctx.quadraticCurveTo(pos.x, pos.y - r / 2, x2, y2);
ctx.moveTo(x1, y1);
ctx.quadraticCurveTo(pos.x, pos.y - params.radius - params.band, x2, y2);
ctx.fillStyle = '#fff';
ctx.fill();
}
ctx.moveTo(pos.x, pos.y);
ctx.beginPath();
//white slot
ctx.arc(pos.x, pos.y, params.radius - params.band - 1, 0, Math.PI * 2, true);
ctx.lineWidth = params.band;
ctx.strokeStyle = '#fff';
ctx.stroke();
g.list.push({
id: item.id,
center: pos,
il: item.il,
radius: params.radius
});
//text
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
ctx.font = 'normal 12px Arial';
ctx.fillStyle = '#eee';
let id = cutText(item.id);
let textWidth = Math.round(ctx.measureText(id).width);
let left = (2 * params.radius - textWidth) / 2;
ctx.fillText(id, pos.x + left - params.radius, pos.y + 4);
let count = tree.deepMap[item.deep + 1];
if (count) {
let space = (width - (count * params.radius * 2 + (count - 1) * params.margin)) / 2;
for (let i = 0, one; i < item.children.length; i++) {
one = item.children[i];
drawCircle(one, {
x: space + one.leftCount * (params.radius * 2 + params.margin) + params.radius,
y: pos.y + params.margin + 2 * params.radius
});
}
}
};
let temp = tree.isolated;
let space = width / 2;
if (temp.length) {
space = (width - (temp.length + 1) * params.radius * 2 + temp.length * params.margin) / 2;
for (let i = 0; i < temp.length; i++) {
drawCircle(temp[i], {
x: space + (i + 1) * (params.radius * 2 + params.margin) + params.radius,
y: params.margin + params.radius
});
}
space += params.radius;
}
drawLine(tree, {
x: space,
y: params.margin + params.radius
});
drawCircle(tree, {
x: space,
y: params.margin + params.radius
});
UI['@{showTotal}'](tree, params);
}
},
'@{drawManagerTree}'(tree) {
let gs = Graphics;
gs['@{captureManagerItmes}']();
let height = Consts['@{managerMargin}'] * (tree.rows + 1) + tree.rows * Consts['@{managerHeight}'] + (Consts['@{managerGroupSpace}'] + Consts['@{managerMargin}']) * tree.groups.length;
UI['@{updateManagerCanvasHeight}'](height);
let ctx = getNode('@{mx_manager_canvas}').getContext('2d');
ctx.clearRect(0, 0, Consts['@{canvasWidth}'], height);
let margin = Consts['@{managerMargin}'];
let managerWidth = ((Consts['@{canvasWidth}'] - (1 + Consts['@{managerCols}']) * Consts['@{managerMargin}']) / Consts['@{managerCols}']) | 0;
let oneWidth = (() => {
ctx.font = 'normal 14px Arial';
let width = ctx.measureText('M').width;
return width;
})();
let drawRect = (ctx, rect, one, pname) => {
ctx.beginPath();
ctx.moveTo(rect[0], rect[1]);
ctx.fillStyle = one.color;
ctx.fillRect(rect[0], rect[1], rect[2], rect[3]);
//text
ctx.beginPath();
ctx.moveTo(rect[0], rect[1] + 10);
ctx.font = 'normal 14px Arial';
ctx.fillStyle = '#282828';
let id = one.id,
tail;
while ((id.length - 3) * oneWidth > rect[2]) {
id = id.slice(0, -1);
tail = true;
}
if (tail) {
id = id.slice(0, -3) + '...';
}
ctx.fillText(id, rect[0] + 5, rect[1] + 25);
one.package = pname;
one.rect = rect;
gs.managerList.push(one);
};
let draw = groups => {
/* mc-uncheck */
for (let i = 0; i < groups.length; i++) {
let g = groups[i];
let left = Consts['@{managerMargin}'];
let pad = false;
ctx.beginPath();
ctx.moveTo(left, margin);
ctx.font = 'normal 14px Arial';
ctx.fillStyle = '#282828';
ctx.fillText(g.name, left + 5, margin + 25);
margin += Consts['@{managerGroupSpace}'];
let u, one;
let max = Math.max(g.maxLeft, g.maxRight);
let maps = {};
let linecolorIndex = 0;
let leftTopSpace = ((max - g.maxLeft) / 2) * (Consts['@{managerHeight}'] + Consts['@{managerMargin}']);
let rightTopSpace = ((max - g.maxRight) / 2) * (Consts['@{managerHeight}'] + Consts['@{managerMargin}']);
for (u = 0; u < max; u++) {
let lo = g.cleans.left[u];
let ro = g.cleans.right[u];
if (lo) {
drawRect(ctx, [
left,
margin + leftTopSpace,
150,
Consts['@{managerHeight}']
], lo, g.name);
maps[lo.id] = lo;
}
if (ro) {
drawRect(ctx, [
Consts['@{canvasWidth}'] - Consts['@{managerMargin}'] - 150,
margin + rightTopSpace,
150,
Consts['@{managerHeight}']
], ro, g.name);
maps[ro.id] = ro;
ro.lineColor = Lines[linecolorIndex++ % Lines.length];
}
margin += Consts['@{managerMargin}'] + Consts['@{managerHeight}'];
}
for (let p in maps) {
one = maps[p];
if (one.cleans) {
let beginPos = {
x: one.rect[0] + one.rect[2],
y: one.rect[1] + (one.rect[3] / 2 | 0)
};
let a = (one.cleans + '').split(',');
for (let x = a.length - 1; x >= 0; x--) {
let endOne = maps[a[x]];
let endPos = {
x: endOne.rect[0],
y: endOne.rect[1] + (endOne.rect[3] / 2 | 0)
};
ctx.beginPath();
ctx.moveTo(beginPos.x, beginPos.y); // 设置路径起点,坐标为(20,20)
ctx.lineTo(endPos.x, endPos.y); // 绘制一条到(200,20)的直线
ctx.lineWidth = 1.0; // 设置线宽
ctx.strokeStyle = '#' + (endOne.lineColor || '996699');
ctx.stroke();
}
}
}
for (u = 0; u < g.caches.length; u++) {
drawRect(ctx, [left, margin, managerWidth, Consts['@{managerHeight}']], g.caches[u], g.name);
if ((u + 1) % Consts['@{managerCols}'] === 0) {
left = Consts['@{managerMargin}'];
margin += Consts['@{managerMargin}'] + Consts['@{managerHeight}'];
pad = false;
} else {
left += managerWidth + Consts['@{managerMargin}'];
pad = true;
}
}
left = Consts['@{managerMargin}'];
if (pad) {
margin += Consts['@{managerMargin}'] + Consts['@{managerHeight}'];
}
for (u = 0; u < g.items.length; u++) {
one = g.items[u];
drawRect(ctx, [left, margin, managerWidth, Consts['@{managerHeight}']], one, g.name);
if ((u + 1) % Consts['@{managerCols}'] === 0) {
left = Consts['@{managerMargin}'];
margin += Consts['@{managerMargin}'] + Consts['@{managerHeight}'];
pad = false;
} else {
left += managerWidth + Consts['@{managerMargin}'];
pad = true;
}
}
left = Consts['@{managerMargin}'];
if (pad) {
margin += Consts['@{managerGroupSpace}'];
}
}
};
draw(tree.groups);
UI['@{showManagerTotal}'](tree);
},
'@{onHoverItem}'(e) {
let env = Inspector['@{getEnv}']();
let vom = env['@{getVOM}']();
if (e.action == 'enter') {
Graphics['@{lastVOM}'] = vom.get(e.item.id);
UI['@{showMoreInfo}'](vom.get(e.item.id), e.item);
} else {
Graphics['@{lastVOM}'] = null;
UI['@{hideMoreInfo}']();
}
},
'@{onHoverManagerItem}'(e) {
if (e.action == 'enter') {
UI['@{showManagerMoreInfo}'](e.item);
} else {
UI['@{hideManagerMoreInfo}']();
}
},
'@{onClickItem}'(e) {
var lastVOM = Graphics['@{lastVOM}'];
if(!lastVOM) {
return;
}
var path = (lastVOM.view && lastVOM.view.path) || lastVOM.path;
if(!path) {
return;
}
var base = (W.Site && W.Site.onlineHostname) || W.location.hostname;
IdePort['@{connectAllPromise}'](base, path + '.js', path + '.html');
}
};