-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Closed
Description
I try to use plotly.js latest v3.0.1 in my golang app(debugcharts, use plotly.js)
chrome console : Performance warning: clear() called with no buffers in bitmask
https://api.ddatsh.com/debug/charts/
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="moment.min.js"></script>
<script src="plotly-latest.min.js"></script>
</head>
<body>
<div id="container1" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<div id="container2" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<div id="container3" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<div id="container4" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<script src="main.js"></script>
</body>
</html>
const MAX_POINTS = 86400;
function formatDuration(ns) {
if (ns >= 1e9) return `${(ns / 1e9).toFixed(3)}s`;
if (ns >= 1e6) return `${(ns / 1e6).toFixed(3)}ms`;
if (ns >= 1e3) return `${(ns / 1e3).toFixed(3)}μs`;
return `${ns}ns`;
}
function stackedArea(traces) {
for (let i = 1; i < traces.length; i++) {
for (let j = 0; j < Math.min(traces[i].y.length, traces[i - 1].y.length); j++) {
traces[i].y[j] += traces[i - 1].y[j];
}
}
return traces;
}
function buildWebSocketURL() {
const loc = window.location;
const proto = loc.protocol === 'https:' ? 'wss://' : 'ws://';
const port = (loc.port && loc.port !== '80' && loc.port !== '443') ? `:${loc.port}` : '';
return `${proto}${loc.hostname}${port}/debug/charts/data-feed`;
}
document.addEventListener('DOMContentLoaded', function () {
let gcTraces, allocTraces, cpuTraces, pprofTraces;
// Replacing $.getJSON with fetch for regular HTTP request
fetch('/debug/charts/data')
.then(response => response.json())
.then(data => {
// GC Pauses
gcTraces = [{
x: [],
y: [],
text: [],
type: 'scattergl',
name: 'GC Pause',
hovertemplate: '%{text}',
}];
data.GcPauses.forEach(item => {
const t = moment(item.Ts).format('YYYY-MM-DD HH:mm:ss');
gcTraces[0].x.push(t);
gcTraces[0].y.push(item.Value);
gcTraces[0].text.push(formatDuration(item.Value)); // 添加格式化值
});
Plotly.newPlot('container1', gcTraces, {
title: {text: 'GC Pauses'},
xaxis: { type: 'date' },
yaxis: { title: 'Nanoseconds' }
});
// Bytes Allocated
allocTraces = [{
x: [],
y: [],
type: 'scattergl',
name: 'Bytes Allocated',
hovertemplate: '%{y}',
}];
data.BytesAllocated.forEach(item => {
const t = moment(item.Ts).format('YYYY-MM-DD HH:mm:ss');
allocTraces[0].x.push(t);
allocTraces[0].y.push(item.Value);
});
Plotly.newPlot('container2', allocTraces, {
title: {text: 'Memory Allocated'},
xaxis: { type: 'date' },
yaxis: { title: 'Bytes' }
});
// CPU Usage
cpuTraces = [
{ x: [], y: [null], name: 'sys', fill: 'tozeroy', type: 'scattergl', hovertemplate: '%{y}' },
{ x: [], y: [null], name: 'user', fill: 'tonexty', type: 'scattergl', hovertemplate: '%{y}' }
];
if (Array.isArray(data.CPUUsage) && data.CPUUsage.length > 0) {
data.CPUUsage.forEach(item => {
const t = moment(item.Ts).format('YYYY-MM-DD HH:mm:ss');
cpuTraces[0].x.push(t);
cpuTraces[0].y.push(item.Sys);
cpuTraces[1].x.push(t);
cpuTraces[1].y.push(item.User);
});
}
cpuTraces = stackedArea(cpuTraces);
Plotly.newPlot('container3', cpuTraces, {
title: {text: 'CPU Usage'},
xaxis: { type: 'date' },
yaxis: { title: 'Seconds' }
});
// PPROF
const pprofList = ["Block", "Goroutine", "Heap", "Mutex", "Threadcreate"];
pprofTraces = pprofList.map(name => ({
x: [],
y: [],
name: name.toLowerCase(),
type: 'scattergl',
hovertemplate: '%{y}'
}));
data.Pprof.forEach(item => {
const t = moment(item.Ts).format('YYYY-MM-DD HH:mm:ss');
pprofList.forEach((key, i) => {
pprofTraces[i].x.push(t);
pprofTraces[i].y.push(item[key]);
});
});
Plotly.newPlot('container4', pprofTraces, {
title: {text: 'PPROF'},
xaxis: { type: 'date' },
yaxis: { title: 'Count' }
});
})
.catch(error => console.error('Error fetching data:', error));
const ws = new WebSocket(buildWebSocketURL());
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
const t = moment(data.Ts).format('YYYY-MM-DD HH:mm:ss');
if (data.GcPause !== 0) {
Plotly.extendTraces('container1', { x: [[t]], y: [[data.GcPause]], text: [[formatDuration(data.GcPause)]] }, [0], MAX_POINTS);
}
Plotly.extendTraces('container2', { x: [[t]], y: [[data.BytesAllocated]] }, [0], MAX_POINTS);
Plotly.extendTraces('container3', {
x: [[t], [t]],
y: [[data.CPUSys], [data.CPUUser]]
}, [0, 1], MAX_POINTS);
Plotly.extendTraces('container4', {
x: [[t], [t], [t], [t], [t]],
y: [[data.Block], [data.Goroutine], [data.Heap], [data.Mutex], [data.Threadcreate]]
}, [0, 1, 2, 3, 4], MAX_POINTS);
};
ws.onerror = (e) => console.error('WebSocket error', e);
ws.onclose = () => console.log('WebSocket closed');
const resizeCharts = () => {
['container1', 'container2', 'container3', 'container4'].forEach(id => {
const el = document.getElementById(id);
if (el) Plotly.Plots.resize(el);
});
};
window.addEventListener('resize', resizeCharts);
window.debugRefreshCharts = resizeCharts;
});Metadata
Metadata
Assignees
Labels
No labels