Skip to content

[WIP] Reworked dashboard with Chart.JS and offline support #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 2 additions & 24 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,26 +1,4 @@
target/
.module-cache
node_modules
bower_components
work/
.idea
.DS_Store
.project
.settings
.project
.classpath
.vagrant
/bin
_site
*.iws
*.ipr
*.iml
npm-debug.log
src/main/webapp/js/*dotci.js
src/main/webapp/js/*.svg
src/main/webapp/js/*dotci.js.map
_book
src/main/webapp/webcomponent-imports-vulcanized.html
src/main/webapp/css/dotci.css
site/
src/main/webapp/js/homepage.js
src/main/webapp/css
/target
Original file line number Diff line number Diff line change
@@ -1,109 +1,11 @@
<?jelly escape-by-default='false'?>
<!DOCTYPE html>
<html lang="en">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler"
xmlns:l="/lib/layout">
<head>
<st:contentType value="text/html;charset=UTF-8"/>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="description" content="Docker Swarm Status"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"/>
<title>Docker Swarm Status</title>

<meta name="mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<meta name="apple-mobile-web-app-title" content="Docker Swarm Status"/>
<meta name="msapplication-TileColor" content="#3372DF"/>
<j:set var="dbrd" value="${it.dashboard}" />

<link rel="stylesheet" href="https://unpkg.com/@clr/ui/clr-ui.min.css" />
<link rel="stylesheet" href="https://unpkg.com/@clr/icons/clr-icons.min.css" />
<script src="https://unpkg.com/@webcomponents/custom-elements/custom-elements.min.js"></script>
<script src="https://unpkg.com/@clr/icons/clr-icons.min.js"></script>

<style>
#main-panel {
margin-left: 0px !important;
padding: 0px !important;
}
#side-panel {
width: 0px !important;
}
footer {
visibility: hidden;
}

.info-block .card-header {
background-color: #DDDDDD;
}
.flex {
display: flex;
}
.node {
width: 350px;
margin: 5px;
display: inline-block;
}
.chart-small-container {
text-align: center;
}
.chart-small-text {
font-size: 0.5em;
}
/* Fix to remove the margin of the first entry in the queue */
.list-unstyled > li:first-child > div {
margin-top: 0 !important;
}
.goog-tooltip {
z-index: 1000;
}
</style>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script>
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawCharts);
function drawCharts() {
// restore Array.prototype.entries native behaviour (see JENKINS-49319)
Array.prototype.entries = function() {
return Object.entries(this).map(([key,value]) => [+key, value])[Symbol.iterator]();
}
drawCpuChart();
drawMemoryChart();
}
function drawCpuChart() {
var data = google.visualization.arrayToDataTable(${dbrd.cpuUsage});
var options = {
title: 'CPU Usage',
width: '100%',
legend: { position: 'top', alignment: 'start', maxLines: '4' }
};
var chart = new
google.visualization.PieChart(document.getElementById('cpu-usage-chart'));
chart.draw(data, options);
}
function drawMemoryChart() {
var data = google.visualization.arrayToDataTable(${dbrd.memoryUsage});
var options = {
title: 'Memory Usage',
width: '100%',
legend: { position: 'top', alignment: 'start', maxLines: '4' }
};
var chart = new
google.visualization.PieChart(document.getElementById('mem-usage-chart'));
chart.draw(data, options);
}

window.addEventListener("resize", function(){
drawCpuChart();
drawMemoryChart();
});
</script>
</head>
<body>
<l:layout>
<l:main-panel>
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler"
xmlns:l="/lib/layout">
<l:layout title="Docker Swarm Status" type="one-column">
<j:set var="dbrd" value="${it.dashboard}" />
<l:main-panel>
<div id="contentDiv">
<div class="content-container">
<div class="clr-row">
<div class="clr-col-4">
<div class="card info-block">
Expand All @@ -114,10 +16,14 @@
<div class="card-text">
<div class="clr-row">
<div class="clr-col-6">
<div id="cpu-usage-chart" style="min-height: 250px;"></div>
<div class="chart-container" style="min-height: 250px;">
<canvas id="cpu-usage-chart"></canvas>
</div>
</div>
<div class="clr-col-6">
<div id="mem-usage-chart" style="min-height: 250px;"></div>
<div class="chart-container" style="min-height: 250px;">
<canvas id="mem-usage-chart"></canvas>
</div>
</div>
</div>
</div>
Expand All @@ -131,8 +37,68 @@
<st:include page="swarm-status.jelly"/>
</div>
</div>
</l:main-panel>
</l:layout>
</body>
</j:jelly>
</html>
</div>
</div>
<div id="shadowElement">
</div>
<script>
// Build and attach the shadowDOM
const header = document.getElementById('shadowElement');
const shadowRoot = header.attachShadow({mode: 'open'});

// Get the html that should be added to the shadow dom
var contentDiv = document.getElementById('contentDiv');
var html = contentDiv.innerHTML;
contentDiv.remove();

// Add the base elements to the shadowDOM
var shadowHtmlElement = document.createElement('html');
var shadowBodyElement = document.createElement('body');
shadowBodyElement.innerHTML = html;
shadowHtmlElement.appendChild(shadowBodyElement);

// Add styles to the shadowDOM
addCss(shadowRoot, '${resURL}/plugin/docker-swarm/css/clr-ui.min.css');
addCss(shadowRoot, '${resURL}/plugin/docker-swarm/css/clr-icons.min.css');
addCss(shadowRoot, '${resURL}/plugin/docker-swarm/css/custom-styles.css');

// Append the content element to the shadowDOM
shadowRoot.appendChild(shadowHtmlElement);

// Add scripts to the shadowDOM
addScript(shadowRoot, '${resURL}/plugin/docker-swarm/js/clr-icons.min.js');
addScript(shadowRoot, '${resURL}/plugin/docker-swarm/js/Chart.min.js');
addScript(shadowRoot, '${resURL}/plugin/docker-swarm/js/chartjs-plugin-datalabels.js');
const lastScript = addScript(shadowRoot, '${resURL}/plugin/docker-swarm/js/custom-script.js');

// Wait until the script is loaded and then draw the charts
lastScript.addEventListener('load', () => {
// Draw the charts
drawCpuChart(shadowRoot, ${dbrd.cpuUsage});
drawMemoryChart(shadowRoot, ${dbrd.memoryUsage});
<j:forEach items="${dbrd.nodes}" var="node">
drawNodeCpuChart(shadowRoot, '${node.name}', ${node.cpuUsageJson});
drawNodeMemoryChart(shadowRoot, '${node.name}', ${node.memoryUsageJson});
</j:forEach>
});

function addCss(element, url) {
let link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', url);
element.appendChild(link);
return link;
}

function addScript(element, url) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
script.async = false;
element.appendChild(script);
return script;
}
</script>
</l:main-panel>
</l:layout>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
</div>
<div class="clr-col-auto flex">
<span class="chart-small-container">
<div id="cpu${node.name}"></div>
<canvas id="cpu-${node.name}" width="30" height="30"></canvas>
<span class="chart-small-text">CPU</span>
</span>
<span class="chart-small-container">
<div id="memory${node.name}"></div>
<canvas id="memory-${node.name}" width="30" height="30"></canvas>
<span class="chart-small-text">Memory</span>
</span>
</div>
Expand All @@ -26,10 +26,9 @@
<div class="card-block">
<div class="card-text">

<script defer="true">
<script>
(function() {
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawCharts);
//drawCharts();

function drawCharts() {
drawMemoryChart();
Expand All @@ -51,17 +50,81 @@
}

function drawMemoryChart() {
var memoryData = google.visualization.arrayToDataTable(${node.memoryUsageJson});
var memoryChart = new google.visualization.PieChart(document.getElementById('memory${node.name}'));
var options = buildChartOptions('memory');
memoryChart.draw(memoryData, options);
var data = ${node.memoryUsageJson};

// Remove the first entry (header)
data.shift();

// Build a list of labels
var labels = data.map(function(x) {
return x[0];
});
// Build a list of values
var values = data.map(function(x) {
return x[1];
});

// Build the config and draw the chart
var config = {
type: 'pie',
data: {
datasets: [{
data: values,
backgroundColor: ['red', 'green'],
borderWidth: 1
}],
labels: labels
},
options: {
responsive: false,
maintainAspectRatio: false,
title: {
display: false,
text: 'memory',
padding: 0
},
legend: {
display: false,
labels: {
usePointStyle: true,
},
},
tooltips: {
enabled: false,
},
plugins: {
datalabels: {
backgroundColor: function(context) {
return context.dataset.backgroundColor;
},
color: 'white',
padding: 2,
display: false,
font: {
weight: 'bold'
},
formatter: (value, ctx) => {
let sum = 0;
let dataArr = ctx.chart.data.datasets[0].data;
dataArr.map(data => {
sum += data;
});
let percentage = (value*100 / sum).toFixed(1) + '%';
return percentage;
}
}
}
}
};
var ctx = document.getElementById('memory-${node.name}').getContext('2d');
var myPie = new Chart(ctx, config);
}

function drawCpuChart() {
var cpuData = google.visualization.arrayToDataTable(${node.cpuUsageJson});
var cpuChart = new google.visualization.PieChart(document.getElementById('cpu${node.name}'));
var options = buildChartOptions('cpu');
cpuChart.draw(cpuData, options);
//var cpuData = google.visualization.arrayToDataTable(${node.cpuUsageJson});
//var cpuChart = new google.visualization.PieChart(document.getElementById('cpu-${node.name}'));
//var options = buildChartOptions('cpu');
//cpuChart.draw(cpuData, options);
}
})()
</script>
Expand Down
Loading