function hashCode(str) {
var hash = 0; for (var i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } return hash;
}
function intToRGB(i) {
var c = (i & 0x00FFFFFF).toString(16).toUpperCase(); return "00000".substring(0, 6 - c.length) + c;
}
function getColor(str) {
return "#" + intToRGB(hashCode(str));
}
class CallStacks extends React.Component {
constructor(props) { super(props); this.updatePath = this.updatePath.bind(this); this.state = { paths: ["root"], msThreshold: 0, enableSameWidth: false, sameWidth: 100 }; } updatePath(currentId, id) { let paths = this.state.paths; if (paths[paths.length - 1] === currentId) { paths.push(id); } else if (paths.includes(currentId)) { const idx = paths.indexOf(currentId); paths = paths.slice(0, idx + 1); paths.push(id); } this.setState({ paths: paths }); } render() { const msInput = React.createElement("input", { type: "text", size: "3", value: this.state.msThreshold, onChange: e => { this.setState({ msThreshold: e.target.value }); } }); const sameWidthInput = React.createElement("input", { type: "checkbox", value: this.state.enableSameWidth, onChange: e => { this.setState({ enableSameWidth: e.target.checked }); } }); let threshold = parseFloat(this.state.msThreshold); if (!threshold) threshold = 0; return React.createElement( "div", null, React.createElement( "div", null, "Same width for each bar ", sameWidthInput, this.state.enableSameWidth && React.createElement( "span", null, React.createElement("input", { type: "text", size: "3", value: this.state.sameWidth, onChange: e => { this.setState({ sameWidth: e.target.value }); } }), " px" ) ), React.createElement( "div", null, "Ignore method call faster than ", msInput, "ms" ), this.state.paths.map(current => { let stack; if (current === "root") { stack = this.props.stack; } else { stack = window.methodCallTable[current].children; } return React.createElement(CallStack, { key: stack[0], stack: stack, current: current, threshold: threshold, enableSameWidth: this.state.enableSameWidth, sameWidth: this.state.sameWidth, updatePath: this.updatePath }); }) ); }
}
class CallStack extends React.Component {
constructor(props) { super(props); let duration = 0; props.stack.forEach(stack => { duration += window.methodCallTable[stack].duration; }); this.defaultMsThreshold = 0; this.defaultScaleValue = 600 / duration; this.state = { scaleValue: this.defaultScaleValue }; } expand(methodID) { if (window.methodCallTable[methodID].children.length !== 0) { this.props.updatePath(this.props.current, methodID); } } render() { const scaleInput = React.createElement("input", { type: "text", size: "3", value: this.state.scaleValue, onChange: e => { this.setState({ scaleValue: e.target.value }); } }); let currentMethod, netCost; if (this.props.current === "root") { currentMethod = { tag: "root", duration: this.props.stack.reduce((accumulator, methodCall) => { return accumulator + window.methodCallTable[methodCall].duration; }, 0) }; } else { currentMethod = window.methodCallTable[this.props.current]; netCost = currentMethod.duration; currentMethod.children.forEach(id => { netCost -= window.methodCallTable[id].duration; }); } return React.createElement( "div", null, React.createElement( "div", null, currentMethod.tag, ": duration: ", parseFloat(currentMethod.duration).toFixed(4), "ms, ", netCost && React.createElement( "span", null, "net cost: ", netCost.toFixed(4), "ms" ), !this.props.enableSameWidth && React.createElement( "span", null, ", Scale: Display 1ms as ", scaleInput, "px " ) ), React.createElement( "div", null, this.props.stack.filter(ele => { const methodCall = window.methodCallTable[ele]; return methodCall.duration >= this.props.threshold; }).map(ele => { const methodCall = window.methodCallTable[ele]; let width; if (this.props.enableSameWidth) { width = parseFloat(this.props.sameWidth); if (!width) width = 100; } else { let scaleValue = parseFloat(this.state.scaleValue); if (!scaleValue) scaleValue = this.defaultScaleValue; width = methodCall.duration * scaleValue; } var tag = methodCall.tag; if (tag.length > 50) { tag = tag.substring(0, 50) + '...' } return React.createElement( "div", { key: ele, className: "call-stack", style: { backgroundColor: getColor(methodCall.tag), width: width }, duration: methodCall.duration, onClick: () => { this.expand(ele); } }, tag ); }) ) ); }
}