blob: d544d62958341943f84aa984bc43c8941e919be0 [file]
import * as d3 from 'd3';
/* eslint-disable */
const type = {
MQ: '#bf99f8',
Http: '#72a5fd',
Database: '#ff6732',
Unknown: '#ffc107',
Cache: '#00bcd4',
RPCFramework: '#ee4395',
};
const trace = (data,width,row,vm) => {
d3.select('svg').remove();
let i = 0,
root;
const margin = { top: 30, right: 20, bottom: 30, left: 20 };
const diagonal = d3.linkHorizontal().x(d => d.y).y(d => d.x);
const svg = d3.select('#svg').append('svg').attr('width', width-margin.right).append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
const min = d3.min(row.map(i => i.startTime));
const max = d3.max(row.map(i => i.endTime - min));
const list = Array.from(new Set(row.map(i => i.applicationCode)));
const sequentialScale = d3.scaleSequential()
.domain([0, list.length])
.interpolator(d3.interpolateWarm);
const xScale = d3.scaleLinear().range([0,width*0.387]).domain([0, max]);
const xAxis = d3.axisTop(xScale).tickFormat(d => {
if(d === 0) return 0;
if(d>=1000) return d/1000 + 's';
return d + ' ms'
});
d3.select('svg').append('g').attr('transform',`translate(${width*0.618-margin.right-margin.right},30)`).call(xAxis);
root = d3.hierarchy(data);
root.x0 = 0;
root.y0 = 0;
update(root);
function update(source) {
const nodes = root.descendants();
const height = Math.max( 500, nodes.length * 48 + margin.top + margin.bottom);
d3.select('svg').transition().duration(400).attr('height', height);
d3.select(self.frameElement).transition().duration(400).style('height', height + 'px');
let index = -1;
root.eachBefore(n => {
n.x = ++index * 48;
n.y = n.depth * 20;
});
const node = svg.selectAll('.trace-node').data(nodes, d => d.id || (d.id = ++i));
const nodeEnter = node.enter().append('g').attr('class', 'trace-node')
.attr('transform',d => 'translate(' + source.y0 + ',' + source.x0 + ')')
.style('opacity', 0);
nodeEnter.append('rect').attr('class', 'trace-node-container').attr('rx',4).attr('ry',4).attr('y', -18).attr('height', 48).attr('width', '100%').on('click', click);
nodeEnter.append('text').attr('dy', 2).attr('dx', 25)
.text(d => d.data.label.length > 45 ? `${d.data.label.slice(0, 45)}...` : `${d.data.label}`);
nodeEnter.append('text').attr('dy', 2).attr('dx', 12)
.style('fill', d => d.data.isError? '#f1483f' : '')
.text(d => d.data.isError? 'x' : '');
nodeEnter.append('text').style('fill', d => type[d.data.layer]).style('stroke', d => type[d.data.layer]).style('stroke-width', '0.6').style('font-size', '11px').attr('dy', 2)
.attr('dx', d => d.data.label.length > 50 ? 320 : 45 + d.data.label.length * 6.9)
.text(d => d.data.layer);
nodeEnter.append('text').attr('dy', 20).attr('dx', 30).style('fill', '#acacac').style('font-size', '11px')
.text(d => `${d.data.applicationCode? d.data.applicationCode : ''} ${d.data.component? `> ${d.data.component}` : ''}`);
nodeEnter.append('rect').attr('height', 4)
.attr('width', (d) => {
if ( !d.data.endTime || !d.data.startTime) return 0
return xScale(d.data.endTime-d.data.startTime)+1;
})
.attr('rx', 2).attr('ry', 2)
.attr('x', d => ( !d.data.endTime || !d.data.startTime) ? 0: width*0.618-margin.right-margin.left-margin.right - d.y + xScale(d.data.startTime-min))
.attr('y', -3)
.style('fill', d => `${sequentialScale(list.indexOf(d.data.applicationCode))}`);
nodeEnter.append('text')
.style('font-size', '10px')
.style('fill', '#888')
.attr('x', d => ( !d.data.endTime || !d.data.startTime) ? 0: width*0.618-margin.right-margin.left-margin.right - d.y + xScale(d.data.startTime-min))
.attr('y', 15)
.text(d =>
d.data.endTime ? `${d.data.endTime - d.data.startTime} ms` : '');
nodeEnter.transition().duration(400).attr('transform', d => 'translate(' + d.y + ',' + d.x + ')').style('opacity', 1);
node.transition().duration(400)
.attr('transform', d => 'translate(' + d.y + ',' + d.x + ')')
.style('opacity', 1)
.select('rect');
node
.exit()
.transition()
.duration(400)
.attr('transform', function(d) {
return 'translate(' + source.y + ',' + source.x + ')';
})
.style('opacity', 0)
.remove();
// Update the links…
var link = svg.selectAll('.trace-link').data(root.links(), function(d) {
return d.target.id;
});
link.enter().insert('path', 'g').attr('class', 'trace-link')
.attr('d', d => {
const o = { x: source.x0, y: source.y0 };
return diagonal({ source: o, target: o });
})
.transition()
.duration(400)
.attr('d', diagonal);
link.transition().duration(400).attr('d', diagonal);
link.exit().transition().duration(400)
.attr('d', d => {
const o = { x: source.x, y: source.y };
return diagonal({ source: o, target: o });
})
.remove();
root.each(d => {
d.x0 = d.x;
d.y0 = d.y;
});
}
function click(d) {
if (!d.data.type) return;
// if (d.children) {
// d._children = d.children;
// d.children = null;
// } else {
// d.children = d._children;
// d._children = null;
// }
// update(d);
vm.$emit('show', d);
}
};
export default trace;