Add Distribution Panel

This commit is contained in:
SkyWT 2023-12-14 21:01:36 +08:00
parent e0fdeba959
commit b9fb55eb3a
3 changed files with 192458 additions and 6233 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,207 +1,363 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta <meta
name="viewport" name="viewport"
content="initial-scale=1.0, user-scalable=no, width=device-width" content="initial-scale=1.0, user-scalable=no, width=device-width"
/> />
<title>热力图</title> <title>热力图</title>
<script src="./static/tailwind.min.js"></script> <script src="./static/tailwind.min.js"></script>
<link href="./static/remixicon/remixicon.css" rel="stylesheet" /> <link href="./static/remixicon/remixicon.css" rel="stylesheet" />
<style> <style>
html, html,
body, body,
#container { #container {
margin: 0; margin: 0;
padding: 0; padding: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="container"></div> <div id="container"></div>
<div <button
class="fixed border rounded-lg shadow-xl bottom-4 left-4 right-4 bg-white" id="toggle-chart-btn"
> class="h-7 w-7 rounded-full border shadow-xl transition-all hover:bg-slate-200 mb-6 mx-1 fixed right-2 top-2 bg-white"
<div class="flex flex-row flex-nowrap items-center p-4"> onclick="toggleChart()"
<button >
class="h-7 w-7 rounded-full transition-all hover:bg-slate-200 mb-6 mx-1" <i class="ri-bar-chart-line"></i>
id="play-btn" </button>
onclick="startOrPause()" <div
> id="chart-box"
<i class="ri-play-line"></i> class="rounded-2xl shadow-2xl transition-all border fixed top-10 right-2 p-4 backdrop-blur-xl bg-white bg-opacity-70"
</button> >
<div class="grow relative mb-6 mx-1"> <div id="linegraph" class="w-96 h-64"></div>
<input </div>
type="range"
min="0" <div
max="11" id="control-box"
value="0" class="fixed border rounded-2xl shadow-xl bottom-4 left-4 right-4 backdrop-blur-xl bg-white bg-opacity-70"
id="control-bar" >
class="h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-200" <div class="flex flex-row flex-nowrap items-center p-4">
oninput="updateData(this.value)" <button
/> class="h-7 w-7 rounded-full transition-all hover:bg-slate-200 mb-6 mx-1"
<!-- 一种让 slider 下标和对应档位对齐的奇技淫巧: id="toggle-play-btn"
在其下方放置 flex 容器,其中放置 space-between 的若干 label。此时由于文字宽度的影响无法真正对齐产生偏移。 onclick="togglePlay()"
考虑将每个 label 实际大小设为 0这样 label 可以实际对齐;放置其 absolute 的子元素,其中放置实际要显示的文字, >
该 span 通过指定 left 和 translate 可以实现文字中线和父元素对齐,从而实现文字和 slider 档位对齐,作为 slider 刻度。 <i class="ri-play-line"></i>
此外,注意 x 轴 padding 应该设为 slider 上按钮半径大小,因为 slider 实际开始位置不是该元素最左端,而是滑块在最左端时的中心点。 </button>
--> <div class="grow relative mb-6 mx-1">
<div <input
class="-bottom-6 flex w-full flex-nowrap justify-between px-2 text-sm text-gray-500" type="range"
> min="0"
<span class="relative"> max="23"
<span class="absolute left-1/2 -translate-x-1/2">1</span></span value="0"
> id="control-bar"
<span class="relative"> class="h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-200"
<span class="absolute left-1/2 -translate-x-1/2">2</span></span oninput="updateData(this.value)"
> />
<span class="relative"> <!-- 一种让 slider 下标和对应档位对齐的奇技淫巧:
<span class="absolute left-1/2 -translate-x-1/2">3</span></span 在其下方放置 flex 容器,其中放置 space-between 的若干 label。此时由于文字宽度的影响无法真正对齐产生偏移。
> 考虑将每个 label 实际大小设为 0这样 label 可以实际对齐;放置其 absolute 的子元素,其中放置实际要显示的文字,
<span class="relative"> 该 span 通过指定 left 和 translate 可以实现文字中线和父元素对齐,从而实现文字和 slider 档位对齐,作为 slider 刻度。
<span class="absolute left-1/2 -translate-x-1/2">4</span></span 此外,注意 x 轴 padding 应该设为 slider 上按钮半径大小,因为 slider 实际开始位置不是该元素最左端,而是滑块在最左端时的中心点。
> -->
<span class="relative"> <div
<span class="absolute left-1/2 -translate-x-1/2">5</span></span class="-bottom-6 flex w-full flex-nowrap justify-between px-2 text-sm text-gray-500"
> >
<span class="relative"> <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">6</span></span <span class="absolute left-1/2 -translate-x-1/2">0</span></span
> >
<span class="relative"> <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">7</span></span <span class="absolute left-1/2 -translate-x-1/2">1</span></span
> >
<span class="relative"> <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">8</span></span <span class="absolute left-1/2 -translate-x-1/2">2</span></span
> >
<span class="relative"> <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">9</span></span <span class="absolute left-1/2 -translate-x-1/2">3</span></span
> >
<span class="relative"> <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">10</span></span <span class="absolute left-1/2 -translate-x-1/2">4</span></span
> >
<span class="relative"> <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">11</span></span <span class="absolute left-1/2 -translate-x-1/2">5</span></span
> >
<span class="relative"> <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">12</span></span <span class="absolute left-1/2 -translate-x-1/2">6</span></span
> >
</div> <span class="relative">
</div> <span class="absolute left-1/2 -translate-x-1/2">7</span></span
</div> >
</div> <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">8</span></span
<script type="text/javascript"> >
window._AMapSecurityConfig = { <span class="relative">
securityJsCode: "0bc2f7560c1da34a09c921a92fce4502", <span class="absolute left-1/2 -translate-x-1/2">9</span></span
}; >
</script> <span class="relative">
<script src="https://webapi.amap.com/maps?v=2.0&key=13471667a960ce7a08b3dfdd9a4fb193"></script> <span class="absolute left-1/2 -translate-x-1/2">10</span></span
<script src="./heatmapData.js"></script> >
<span class="relative">
<script> <span class="absolute left-1/2 -translate-x-1/2">11</span></span
var map = new AMap.Map("container", { >
resizeEnable: true, <span class="relative">
center: [116.418261, 39.921984], // 配置地图中心的经纬度 <span class="absolute left-1/2 -translate-x-1/2">12</span></span
zoom: 11, >
}); <span class="relative">
<span class="absolute left-1/2 -translate-x-1/2">13</span></span
if (!isSupportCanvas()) { >
alert("您所使用的浏览器不能使用热力图功能,请换个浏览器试试~"); <span class="relative">
} <span class="absolute left-1/2 -translate-x-1/2">14</span></span
>
// heatmap.js document: <span class="relative">
// http://www.patrick-wied.at/static/heatmapjs/docs.html <span class="absolute left-1/2 -translate-x-1/2">15</span></span
/* visible 热力图是否显示, 默认为 true >
* opacity 热力图的透明度, 分别对应 heatmap.js的minOpacity和maxOpacity <span class="relative">
* radius 热力图的每个点的半径大小 <span class="absolute left-1/2 -translate-x-1/2">16</span></span
* gradient {JSON} 热力图的渐变区间 . gradient如下所示 >
* { <span class="relative">
.2:'rgb(0, 255, 255)', <span class="absolute left-1/2 -translate-x-1/2">17</span></span
.5:'rgb(0, 110, 255)', >
.8:'rgb(100, 0, 255)' <span class="relative">
} <span class="absolute left-1/2 -translate-x-1/2">18</span></span
其中 key 表示插值的位置, 0-1 >
value 为颜色值 <span class="relative">
*/ <span class="absolute left-1/2 -translate-x-1/2">19</span></span
var heatmap; >
var playing = false; <span class="relative">
map.plugin(["AMap.HeatMap"], function () { <span class="absolute left-1/2 -translate-x-1/2">20</span></span
heatmap = new AMap.HeatMap(map, { >
radius: 25, //给定半径 <span class="relative">
opacity: [0, 0.8], <span class="absolute left-1/2 -translate-x-1/2">21</span></span
/*, >
gradient:{ <span class="relative">
0.5: 'blue', <span class="absolute left-1/2 -translate-x-1/2">22</span></span
0.65: 'rgb(117,211,248)', >
0.7: 'rgb(0, 255, 0)', <span class="relative">
0.9: '#ffea00', <span class="absolute left-1/2 -translate-x-1/2">23</span></span
1.0: 'red' >
} </div>
*/ </div>
}); </div>
heatmap.setDataSet({ </div>
max: 100,
data: heatmapData[0], <script type="text/javascript">
}); window._AMapSecurityConfig = {
}); securityJsCode: "0bc2f7560c1da34a09c921a92fce4502",
};
function isSupportCanvas() { </script>
var elem = document.createElement("canvas"); <script src="https://webapi.amap.com/maps?v=2.0&key=13471667a960ce7a08b3dfdd9a4fb193"></script>
return !!(elem.getContext && elem.getContext("2d")); <script type="text/javascript" src="./static/echarts.min.js"></script>
} <script type="text/javascript" src="./heatmapData.js"></script>
function showHeatmap() { <script>
heatmap.show(); var chartEle = document.getElementById("linegraph");
} var chart = echarts.init(chartEle, null, {
renderer: "canvas",
function hideHeatmap() { useDirtyRect: false,
heatmap.hide(); });
} var app = {};
var option = {
function updateData(value) { title: {
heatmap.setDataSet({ text: "Distribution of Water",
data: heatmapData[value], },
max: 100, tooltip: {
}); trigger: "axis",
} axisPointer: {
type: "cross",
function startOrPause() { },
if (playing) { },
playing = false; // toolbox: {
let btn = document.getElementById("play-btn"); // show: true,
btn.innerHTML = '<i class="ri-play-line"></i>'; // feature: {
stopPlay(); // saveAsImage: {},
} else { // },
playing = true; // },
let btn = document.getElementById("play-btn"); xAxis: {
btn.innerHTML = '<i class="ri-pause-line"></i>'; type: "category",
startPlay(); boundaryGap: false,
} data: [
} "0",
"1",
function startPlay() { "2",
let slider = document.getElementById("control-bar"); "3",
intervalID = setInterval(function () { "4",
if (slider.value < 11) { "5",
slider.value++; "6",
updateData(slider.value); "7",
} else { "8",
startOrPause(); "9",
} "10",
}, 100); // Do every 100ms "11",
} "12",
"13",
function stopPlay() { "14",
clearInterval(intervalID); "15",
} "16",
</script> "17",
</body> "18",
</html> "19",
"20",
"21",
"22",
"23",
"24",
],
},
yAxis: {
type: "value",
axisLabel: {
formatter: "{value} T",
},
axisPointer: {
snap: true,
},
},
visualMap: {
show: false,
dimension: 0,
pieces: [{ gt: 0, lte: 24, color: "green" }],
padding: 0,
},
series: [
{
name: "Water",
type: "line",
smooth: true,
data: [
30000, 28000, 25000, 26000, 27000, 30000, 55000, 50000, 40000,
39000, 38000, 39000, 27000, 25000, 30000, 32000, 31000, 25000,
23000, 10000, 12000, 12300, 25000, 26000, 30000,
],
markArea: {
itemStyle: { color: "rgba(255, 173, 177, 0.4)" },
data: [[{ name: "Now", xAxis: "0" }, { xAxis: "1" }]],
},
},
],
grid: {
left: "15%",
right: 0,
bottom: "10%",
},
};
chart.setOption(option);
var map = new AMap.Map("container", {
resizeEnable: true,
center: [116.418261, 39.921984], // 配置地图中心的经纬度
zoom: 11,
});
// heatmap.js document:
// http://www.patrick-wied.at/static/heatmapjs/docs.html
/* visible 热力图是否显示, 默认为 true
* opacity 热力图的透明度, 分别对应 heatmap.js的minOpacity和maxOpacity
* radius 热力图的每个点的半径大小
* gradient {JSON} 热力图的渐变区间 . gradient如下所示
* {
.2:'rgb(0, 255, 255)',
.5:'rgb(0, 110, 255)',
.8:'rgb(100, 0, 255)'
}
其中 key 表示插值的位置, 0-1
value 为颜色值
*/
var heatmap;
var playing = false;
map.plugin(["AMap.HeatMap"], function () {
heatmap = new AMap.HeatMap(map, {
radius: 25, //给定半径
opacity: [0, 0.8],
/*,
gradient:{
0.5: 'blue',
0.65: 'rgb(117,211,248)',
0.7: 'rgb(0, 255, 0)',
0.9: '#ffea00',
1.0: 'red'
}
*/
});
heatmap.setDataSet({
max: 100,
data: heatmapData[0],
});
});
function showHeatmap() {
heatmap.show();
}
function hideHeatmap() {
heatmap.hide();
}
function updateData(value) {
option.series[0].markArea.data = [
[
{
name: "Now",
xAxis: value.toString(),
},
{ xAxis: (parseInt(value) + 1).toString() },
],
];
chart.setOption(option);
heatmap.setDataSet({
data: heatmapData[value],
max: 100,
});
}
function togglePlay() {
let btn = document.getElementById("toggle-play-btn");
if (playing) {
playing = false;
btn.innerHTML = '<i class="ri-play-line"></i>';
stopPlay();
} else {
playing = true;
btn.innerHTML = '<i class="ri-pause-line"></i>';
startPlay();
}
}
function startPlay() {
let slider = document.getElementById("control-bar");
intervalID = setInterval(function () {
if (slider.value < 23) {
slider.value++;
} else {
slider.value = 0;
}
updateData(slider.value);
}, 100); // Do every 100ms
}
function stopPlay() {
clearInterval(intervalID);
}
var temp;
function toggleChart() {
let chartBox = document.getElementById("chart-box");
if (chartBox.style.display !== "none") {
temp = chartBox.style.display;
chartBox.style.display = "none";
} else {
chartBox.style.display = temp;
}
}
</script>
</body>
</html>

45
static/echarts.min.js vendored Normal file

File diff suppressed because one or more lines are too long