Commit 60ab8f24 authored by Sven Schneider's avatar Sven Schneider
Browse files

made the Chart.js line chart working inclusive zoom and pan functionality,...

made the Chart.js line chart working inclusive zoom and pan functionality, added new plots using the Plotly library using 3d Surface Ribbonplot and 2dheatmaps and histogram plots. in development...
parent 37b8232f
......@@ -11,8 +11,7 @@
<meta name="author" content="" />
<title>Dashboard - iCity Bosch</title>
<link href="css/styles.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.css" rel="stylesheet" />
<link
href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css"
rel="stylesheet"
......@@ -31,8 +30,6 @@
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://code.highcharts.com/stock/modules/export-data.js"></script>
<!-- chart.js library -->
<!-- <script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> -->
<!-- Apexcharts lib -->
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<link rel="stylesheet" href="css/styles.css" />
......@@ -59,16 +56,36 @@
<!-- chart.js library -->
<!-- <script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script> -->
<!-- chart.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<!-- for gesture recogintion -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/0.7.7/chartjs-plugin-zoom.min.js"></script>
<!-- chart.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<!-- for gesture recogintion -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<!-- chart.js library -->
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.css" integrity="sha512-/zs32ZEJh+/EO2N1b0PEdoA10JkdC3zJ8L5FTiQu82LR9S/rOQNfQN7U59U9BC12swNeRAz3HSzIL2vpp4fv3w==" crossorigin="anonymous" referrerpolicy="no-referrer" /> -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js" integrity="sha512-d9xgZrVZpmmQlfonhQUvTR7lMPtO7NkZMkA0ABN3PHCbKA5nqylQ/yWlFAyY6hYgdF1Qh6nYiuADWwKB4C2WSw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/0.7.7/chartjs-plugin-zoom.min.js" integrity="sha512-8E9fPF4pjWxI0dpprpn4WYeciAMo2kh6xN0COFxvTfurMttjZzih/sBp+Fxu49Zr6IUSp4sqWY6KLecnqOCwxA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.min.js"
integrity="sha512-VMsZqo0ar06BMtg0tPsdgRADvl0kDHpTbugCBBrL55KmucH6hP9zWdLIWY//OTfMnzz6xWQRxQqsUFefwHuHyg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.0.0-rc/chartjs-plugin-zoom.min.js"
integrity="sha512-Vo3Q1pGza0B8qnI5DYBIV1o09d+S5W0gDu5azuXVIZsGPnFLUb+McK8dExyuqITZlgoS9ueRs98KDcwng/b4sw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script defer src="js/appCesium.js"></script>
<script defer src="js/appChart.js"></script>
<!-- <script defer src="js/testzoom.js"></script> -->
<script defer src="js/createPlotlyPlots.js"></script>
</head>
<body class="sb-nav-fixed">
<nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark">
......@@ -118,18 +135,26 @@
</div>
</div>
</div>
<div class="row">
<div class="col-xl-6">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-line mr-1"></i>
Line Chart Example
<i class="fas fa-chart-area mr-1"></i>
Inflow with Chart.JS and Zoom Plugin
</div>
<div class="card-body">
<div id="chart-apex-line" width="100%" height="40"></div>
<canvas
id="inflowChartCanvas"
style="max-width: 100%; max-height: 600px"
></canvas>
<button id="reset_zoom" class="btn btn-light">
Reset zoom
</button>
</div>
</div>
</div>
<div class="col-xl-6">
<div class="card mb-4">
<div class="card-header">
......@@ -137,51 +162,62 @@
Area Chart Example
</div>
<div class="card-body">
<div id="chart-apex-heatmap" width="100%" height="40"></div>
<div
id="chart-apex-heatmap"
width="100%"
height="40"
style="max-width: 100%; max-height: 500px"
></div>
</div>
</div>
</div>
</div>
<!-- end row -->
<div class="col-xl-6">
<div class="row">
<div class="col-xl-12">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-area mr-1"></i>
Test Chart.js
<i class="fas fa-globe mr-1"></i>
PLotly Ribbon plot
</div>
<div class="card-body">
<canvas id="lineChart" width="400" height="400"></canvas>
<button id="reset_zoom_line">Reset zoom</button>
<button id="disable_zoom_line">Disable zoom</button>
<button id="enable_zoom_line">Enable zoom</button>
<div
id="RibbonPlot"
width="100%"
height="40"
>
<!-- Plotly chart will be drawn inside this DIV -->
</div>
</div>
</div>
</div>
</div>
<!-- end row -->
<!-- <div class="col-xl-6">
<div class="row">
<div class="col-xl-6">
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-chart-area mr-1"></i>
Test Scatter Chart.js
2d heatmap
</div>
<div class="card-body" >
<canvas id="scatterChart" width="400" height="400"></canvas>
<button id="reset_zoom">Reset zoom</button>
<button id="disable_zoom">Disable zoom</button>
<button id="enable_zoom">Enable zoom</button>
<div class="card-body">
<div
id="heatmap2d"
width="100%"
height="40"
style="max-width: 100%; max-height: 600px"
>
<!-- Plotly chart will be drawn inside this DIV -->
</div>
</div>
</div>
</div> -->
</div>
</div>
<!-- end row -->
<!-- </div> -->
</div>
</main>
<footer class="py-4 bg-light mt-auto">
......
......@@ -441,7 +441,8 @@ followNextLink(
// drawHeatMapAC2(observationArr);
///////////// use chart.js for line chart
///// check this out : https://stackoverflow.com/questions/57343566/zoom-function-for-chart-js
////////////////////////////////
function renameKey(obj, oldKey, newKey) {
obj[newKey] = obj[oldKey];
......@@ -463,135 +464,237 @@ followNextLink(
let jsonFromArr2 = jsonFromArr;
jsonFromArr2.forEach((obj) => renameKey(obj, "1", "y"));
var ctx = document.getElementById("lineChart").getContext("2d");
var lineChart = new Chart(ctx, {
type: "line",
data: {
datasets: [
{
label: "Inflow (Vorlauf)",
data: [12, 19, 3, 5, 2, 3],
borderColor: ["rgba(255, 99, 132, 0.2)"],
fill: false,
},
],
},
options: {
scales: {
y: {
beginAtZero: false,
},
},
///////////////////////////////////////////////////
function prep2dHistogramData(jsonData) {
var resList = [];
const L = jsonData.length;
var startVal = 1;
var currentDay = 1;
var hourInMonth = 0;
var x = [];
var y = [];
var z = [];
for (var d = 0; d < L; d++) {
let tmpDate = new Date(jsonData[d].x);
// let datum = tmpDate.getDate(); // gets the day of the month 1...31
let hour = tmpDate.getHours();
let day = tmpDate.getUTCDate();
let month = tmpDate.getUTCMonth(); // gets the month as numeric value
if (currentDay == day) {
x.push([startVal, startVal + 1]);
y.push([hourInMonth,hourInMonth]);
z.push([jsonData[d].y, jsonData[d].y]);
hourInMonth++;
} else {
resList.push({x:x, y:y, z:z } );
var x = [];
var y = [];
var z = [];
currentMonth += 1;
startVal += 2;
hourInMonth = 0;
x.push([startVal, startVal + 1]);
y.push([hourInMonth,hourInMonth]);
z.push([jsonData[d].y, jsonData[d].y]);
}
// pan: {
// enabled: true,
// mode: "x",
// speed: 10,
// threshold: 10,
// },
// zoom: {
// enabled: true,
// drag: false,
// mode: "y",
// speed: 0.5,
// // sensitivity: 0.1,
// // limits: {
// // max: 10,
// // min: 0.5,
// // },
// },
},
});
} // end of for loop
// add results for last month as else statement will not be reached for the december
// as the condition d < L will be true before the condition currentMonth === month can be evaluated
// re-activate following line when i have more than one data point for the next month
// resList.push({x:x, y:y, z:z } );
return resList;
}
$('#reset_zoom_line').click(function(){
lineChart.resetZoom();
console.log(lineChart);
});
$('#disable_zoom_line').click(function(){
lineChart.ctx.canvas.removeEventListener('wheel', lineChart._wheelHandler);
});
$('#enable_zoom_line').click(function(){
lineChart.ctx.canvas.addEventListener('wheel', lineChart._wheelHandler);
});
///////////////////////////////////////////////////
function prepRibbonData(jsonData) {
var resList = [];
const L = jsonData.length;
var startVal = 2;
var currentMonth = 0;
var hourInMonth = 0;
var x = [];
var y = [];
var z = [];
for (var d = 0; d < L; d++) {
let tmpDate = new Date(jsonData[d].x);
// let datum = tmpDate.getDate(); // gets the day of the month 1...31
let hour = tmpDate.getHours();
let month = tmpDate.getUTCMonth(); // gets the month as numeric value
if (currentMonth == month) {
x.push([startVal, startVal + 1]);
y.push([hourInMonth,hourInMonth]);
z.push([jsonData[d].y, jsonData[d].y]);
hourInMonth++;
} else {
resList.push({x:x, y:y, z:z } );
var x = [];
var y = [];
var z = [];
currentMonth += 1;
startVal += 2;
hourInMonth = 0;
x.push([startVal, startVal + 1]);
y.push([hourInMonth,hourInMonth]);
z.push([jsonData[d].y, jsonData[d].y]);
}
} // end of for loop
// add results for last month as else statement will not be reached for the december
// as the condition d < L will be true before the condition currentMonth === month can be evaluated
// re-activate following line when i have more than one data point for the next month
// resList.push({x:x, y:y, z:z } );
return resList;
}
///////////////////////////////////////////////////
let datx=[];
let daty=[];
const MONTH = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
for (var u = 0; u<jsonFromArr.length ; u++){
daty.push(jsonFromArr2[u].y);
let date = new Date(jsonFromArr2[u].x);
let datum = date.getDate();
let month = MONTH[date.getMonth()];
let hour = date.getHours() + ":00";
let newDateStr = datum + "/" + month + "-" + hour;
datx.push(newDateStr);
}
/////////////////////////////////////////
// var ctx_scatterChart = document.getElementById("scatterChart");
// var scatterChart = new Chart(ctx_scatterChart, {
// type: 'bar',
// data: {
// labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
// datasets: [{
// label: '# of Votes',
// data: [12, 19, 3, 5, 2, 3],
// backgroundColor: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
// borderColor: ["Blue", "Yellow", "Green", "Purple", "Orange", "Red"],
// borderWidth: 1,
// }]
// },
// options: {
// scales: {
// yAxes: [{
// ticks: {
// beginAtZero:false
// }
// }]
// },
// // Container for pan options
// pan: {
// // Boolean to enable panning
// enabled: true,
// // Panning directions. Remove the appropriate direction to disable
// // Eg. 'y' would only allow panning in the y direction
// mode: 'xy',
// speed: 10
// },
// // Container for zoom options
// zoom: {
// // Boolean to enable zooming
// enabled: true,
// // Zooming directions. Remove the appropriate direction to disable
// // Eg. 'y' would only allow zooming in the y direction
// mode: 'x',
// }
// }
// });
// $('#reset_zoom').click(function(){
// scatterChart.resetZoom();
// console.log(scatterChart);
// });
// $('#disable_zoom').click(function(){
// scatterChart.ctx.canvas.removeEventListener('wheel', scatterChart._wheelHandler);
// });
// $('#enable_zoom').click(function(){
// scatterChart.ctx.canvas.addEventListener('wheel', scatterChart._wheelHandler);
// });
// $('#reset_zoom').click(function(){
// scatterChart.resetZoom();
// console.log(scatterChart);
// });
// $('#disable_zoom').click(function(){
// scatterChart.ctx.canvas.removeEventListener('wheel', scatterChart._wheelHandler);
// });
// $('#enable_zoom').click(function(){
// scatterChart.ctx.canvas.addEventListener('wheel', scatterChart._wheelHandler);
// });
//////////////////////////////////////////
// const chart1LineTitle = "Inlet flow (Vorlauf)";
// const chart1LineYAxisTitle = "Temperature (°C)";
//////////////////////////////////////////
const inflowChart = new Chart('inflowChartCanvas', {
type: 'line',
data: {
labels: datx,
datasets: [{
label: 'Inflow Temperature in °C',
data: daty,
fill: false,
borderColor: 'rgb(75, 192, 192,0.3)',
backgroundColor: 'rgba(153, 102, 255, 0.2)',
// tension: 0.1
}]
},
options: {
// responsive: true,
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
},
plugins: {
// title: {
// display: true,
// text: 'Inlet Flow Temperature'
// },
zoom: {
pan: {
// Boolean to enable panning
enabled: true,
// Panning directions. Remove the appropriate direction to disable
// Eg. 'y' would only allow panning in the y direction
mode: "xy",
speed: 1,
},
zoom: {
wheel: {
enabled: true,
},
pinch: {
enabled: false
},
mode: 'x',
}
}
} // end of plugins
} // end of options
});
$('#reset_zoom').click(function(){
inflowChart.resetZoom();
});
// drawHeatMapAC2(observationArr);
var loadJS = function(url, implementationCode, location){
//url is URL of external file, implementationCode is the code
//to be called from the file, location is the location to
//insert the <script> element
var scriptTag = document.createElement('script');
scriptTag.src = url;
scriptTag.onload = implementationCode;
scriptTag.onreadystatechange = implementationCode;
location.appendChild(scriptTag);
};
var preppedData = prepRibbonData(jsonFromArr2);
loadJS('js/createPlotlyPlots.js', makeRibbonPlot(preppedData), document.body);
loadJS('js/createPlotlyPlots.js', makeHeatmap(preppedData), document.body);
///////////////////////////////////////
}); // this closes the followLink.then ({ .... })
function makeRibbonPlot(dat) {
// https://plotly.com/javascript/ribbon-plots/
var trace1 = {
x: dat[0].x,
y: dat[0].y,
z: dat[0].z,
name: "January",
// colorscale: dat[0].colorscale,
type: "surface",
showscale: false,
};
var trace2 = {
name: "Feburary",
x: dat[1].x,
y: dat[1].y,
z: dat[1].z,
// colorscale: dat[1].colorscale,
type: "surface",
showscale: false,
};
var trace3 = {
name: "March",
x: dat[2].x,
y: dat[2].y,
z: dat[2].z,
// colorscale: dat[2].colorscale,
type: "surface",
showscale: false,
};
var trace4 = {
name: "April",
x: dat[3].x,
y: dat[3].y,
z: dat[3].z,
// colorscale: dat[3].colorscale,
type: "surface",
showscale: false,
};
var trace5 = {
name: "May",
x: dat[4].x,
y: dat[4].y,
z: dat[4].z,
// colorscale: dat[4].colorscale,
type: "surface",
showscale: false,
};
var trace6 = {
name: "June",
x: dat[5].x,
y: dat[5].y,
z: dat[5].z,
// colorscale: dat[5].colorscale,
type: "surface",
showscale: false,
};
var data = [trace1, trace2, trace3, trace4, trace5, trace6];
var layout = {
title: "Inlet flow (per month)",
showlegend: true,
autosize: true,
width: 1400,
height: 800,
xaxis: {
tickmode: "array",
tickvals: [2.5, 4.5, 6.5, 8.5, 10.5, 12.5],
ticktext: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
},
hoverlabel: {
bgcolor: "black",
},
scene: {
xaxis: {
title: "Month ",
tickmode: "array",
tickvals: [2.5, 4.5, 6.5, 8.5, 10.5, 12.5],
ticktext: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
},
yaxis: { title: "Hours in a month" },
zaxis: { title: "Temperature (°C)" },
},
};
Plotly.newPlot("RibbonPlot", data, layout);
function make2dHistogram(dat) {
//////////////////////////////
// make heatmap or 2d histogram plot
var x = [];
var y = [];
for (var i = 0; i < 500; i++) {
x[i] = Math.random();
y[i] = Math.random() + 1;
}
var data = [
{
x: x,
y: y,
z: x,
type: "histogram2d", // try this type as well 'histogram2dcontour' or this one 'histogram2d'
},
];
Plotly.newPlot("heatmap2d", data);
}
/////////////////////////////////////
function makeHeatmap(dat) {
var data = [
{
z: [
[1, null, 30, 50, 1],
[20, 1, 60, 80, 30],
[30, 60, 1, -10, 20],
],
x: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
y: ["Morning", "Afternoon", "Evening"],
type: "heatmap",
hoverongaps: false,
},
];
Plotly.newPlot("heatmap2d", data);
}
}
function prepRibbonData(jsonData) {
let resList = [];
let resJson = {
x: [],
y: [],
z: [],
};
const L = jsonData.length;
var startVal = 2;
var currentMonth = 0;
for (var d = 0; d < L; d++) {
let tmpDate = new Date(jsonData[d].x);
// let datum = tmpDate.getDate(); // gets the day of the month 1...31
let month = date.getMonth(); // gets the month as numeric value
if (currentMonth === month) {
resJson.x.push([startVal, startVal + 1]);
resJson.y.push([tmpDate, tmpDate]);
resJson.z.push([jsonData[d].y, jsonData[d].y]);
} else {
resList.push(resJson);
resJson.x = [];
resJson.y = [];
resJson.z = [];
currentMonth += 1;
startVal += 2;
}
} // end of for loop
// add results for last month as else statement will not be reached for the december
// as the condition d < L will be true before the condition currentMonth === month can be evaluated
// resList.push(resJson);
return resList;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- chart.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<script src="https://npmcdn.com/Chart.Zoom.js@0.3.0/Chart.Zoom.min.js"></script>
<!-- <script defer src="js/testzoom.js"></script> -->
<title>Document</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js'></script>
<script src='js/test.js'></script>
</head>
<body>
<h1>test</h1>
<h1>test</h1>
<h1>test</h1>
<div style="max-width: 600px; max-height: 400px;" class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
<button id="reset_zoom">
Reset zoom
</button>
<button id="disable_zoom">
Disable zoom
</button>
<button id="enable_zoom">
Enable zoom
</button>
<h1>test</h1>
<script defer src="js/testzoom.js"></script>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
</html>
</html>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment