Add Distribution Panel
This commit is contained in:
parent
e0fdeba959
commit
b9fb55eb3a
198076
heatmapData.js
198076
heatmapData.js
File diff suppressed because it is too large
Load Diff
570
index.html
570
index.html
|
@ -1,207 +1,363 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="initial-scale=1.0, user-scalable=no, width=device-width"
|
||||
/>
|
||||
<title>热力图</title>
|
||||
|
||||
<script src="./static/tailwind.min.js"></script>
|
||||
<link href="./static/remixicon/remixicon.css" rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
#container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
|
||||
<div
|
||||
class="fixed border rounded-lg shadow-xl bottom-4 left-4 right-4 bg-white"
|
||||
>
|
||||
<div class="flex flex-row flex-nowrap items-center p-4">
|
||||
<button
|
||||
class="h-7 w-7 rounded-full transition-all hover:bg-slate-200 mb-6 mx-1"
|
||||
id="play-btn"
|
||||
onclick="startOrPause()"
|
||||
>
|
||||
<i class="ri-play-line"></i>
|
||||
</button>
|
||||
<div class="grow relative mb-6 mx-1">
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="11"
|
||||
value="0"
|
||||
id="control-bar"
|
||||
class="h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-200"
|
||||
oninput="updateData(this.value)"
|
||||
/>
|
||||
<!-- 一种让 slider 下标和对应档位对齐的奇技淫巧:
|
||||
在其下方放置 flex 容器,其中放置 space-between 的若干 label。此时,由于文字宽度的影响,无法真正对齐,产生偏移。
|
||||
考虑将每个 label 实际大小设为 0,这样 label 可以实际对齐;放置其 absolute 的子元素,其中放置实际要显示的文字,
|
||||
该 span 通过指定 left 和 translate 可以实现文字中线和父元素对齐,从而实现文字和 slider 档位对齐,作为 slider 刻度。
|
||||
此外,注意 x 轴 padding 应该设为 slider 上按钮半径大小,因为 slider 实际开始位置不是该元素最左端,而是滑块在最左端时的中心点。
|
||||
-->
|
||||
<div
|
||||
class="-bottom-6 flex w-full flex-nowrap justify-between px-2 text-sm text-gray-500"
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">1</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">2</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">3</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">4</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">5</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">6</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">7</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">8</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">9</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">10</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">11</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">12</span></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: "0bc2f7560c1da34a09c921a92fce4502",
|
||||
};
|
||||
</script>
|
||||
<script src="https://webapi.amap.com/maps?v=2.0&key=13471667a960ce7a08b3dfdd9a4fb193"></script>
|
||||
<script src="./heatmapData.js"></script>
|
||||
|
||||
<script>
|
||||
var map = new AMap.Map("container", {
|
||||
resizeEnable: true,
|
||||
center: [116.418261, 39.921984], // 配置地图中心的经纬度
|
||||
zoom: 11,
|
||||
});
|
||||
|
||||
if (!isSupportCanvas()) {
|
||||
alert("您所使用的浏览器不能使用热力图功能,请换个浏览器试试~");
|
||||
}
|
||||
|
||||
// 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 isSupportCanvas() {
|
||||
var elem = document.createElement("canvas");
|
||||
return !!(elem.getContext && elem.getContext("2d"));
|
||||
}
|
||||
|
||||
function showHeatmap() {
|
||||
heatmap.show();
|
||||
}
|
||||
|
||||
function hideHeatmap() {
|
||||
heatmap.hide();
|
||||
}
|
||||
|
||||
function updateData(value) {
|
||||
heatmap.setDataSet({
|
||||
data: heatmapData[value],
|
||||
max: 100,
|
||||
});
|
||||
}
|
||||
|
||||
function startOrPause() {
|
||||
if (playing) {
|
||||
playing = false;
|
||||
let btn = document.getElementById("play-btn");
|
||||
btn.innerHTML = '<i class="ri-play-line"></i>';
|
||||
stopPlay();
|
||||
} else {
|
||||
playing = true;
|
||||
let btn = document.getElementById("play-btn");
|
||||
btn.innerHTML = '<i class="ri-pause-line"></i>';
|
||||
startPlay();
|
||||
}
|
||||
}
|
||||
|
||||
function startPlay() {
|
||||
let slider = document.getElementById("control-bar");
|
||||
intervalID = setInterval(function () {
|
||||
if (slider.value < 11) {
|
||||
slider.value++;
|
||||
updateData(slider.value);
|
||||
} else {
|
||||
startOrPause();
|
||||
}
|
||||
}, 100); // Do every 100ms
|
||||
}
|
||||
|
||||
function stopPlay() {
|
||||
clearInterval(intervalID);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="initial-scale=1.0, user-scalable=no, width=device-width"
|
||||
/>
|
||||
<title>热力图</title>
|
||||
|
||||
<script src="./static/tailwind.min.js"></script>
|
||||
<link href="./static/remixicon/remixicon.css" rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
#container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
|
||||
<button
|
||||
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"
|
||||
onclick="toggleChart()"
|
||||
>
|
||||
<i class="ri-bar-chart-line"></i>
|
||||
</button>
|
||||
<div
|
||||
id="chart-box"
|
||||
class="rounded-2xl shadow-2xl transition-all border fixed top-10 right-2 p-4 backdrop-blur-xl bg-white bg-opacity-70"
|
||||
>
|
||||
<div id="linegraph" class="w-96 h-64"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="control-box"
|
||||
class="fixed border rounded-2xl shadow-xl bottom-4 left-4 right-4 backdrop-blur-xl bg-white bg-opacity-70"
|
||||
>
|
||||
<div class="flex flex-row flex-nowrap items-center p-4">
|
||||
<button
|
||||
class="h-7 w-7 rounded-full transition-all hover:bg-slate-200 mb-6 mx-1"
|
||||
id="toggle-play-btn"
|
||||
onclick="togglePlay()"
|
||||
>
|
||||
<i class="ri-play-line"></i>
|
||||
</button>
|
||||
<div class="grow relative mb-6 mx-1">
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="23"
|
||||
value="0"
|
||||
id="control-bar"
|
||||
class="h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-200"
|
||||
oninput="updateData(this.value)"
|
||||
/>
|
||||
<!-- 一种让 slider 下标和对应档位对齐的奇技淫巧:
|
||||
在其下方放置 flex 容器,其中放置 space-between 的若干 label。此时,由于文字宽度的影响,无法真正对齐,产生偏移。
|
||||
考虑将每个 label 实际大小设为 0,这样 label 可以实际对齐;放置其 absolute 的子元素,其中放置实际要显示的文字,
|
||||
该 span 通过指定 left 和 translate 可以实现文字中线和父元素对齐,从而实现文字和 slider 档位对齐,作为 slider 刻度。
|
||||
此外,注意 x 轴 padding 应该设为 slider 上按钮半径大小,因为 slider 实际开始位置不是该元素最左端,而是滑块在最左端时的中心点。
|
||||
-->
|
||||
<div
|
||||
class="-bottom-6 flex w-full flex-nowrap justify-between px-2 text-sm text-gray-500"
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">0</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">1</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">2</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">3</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">4</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">5</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">6</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">7</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">8</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">9</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">10</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">11</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">12</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">13</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">14</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">15</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">16</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">17</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">18</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">19</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">20</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">21</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">22</span></span
|
||||
>
|
||||
<span class="relative">
|
||||
<span class="absolute left-1/2 -translate-x-1/2">23</span></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: "0bc2f7560c1da34a09c921a92fce4502",
|
||||
};
|
||||
</script>
|
||||
<script src="https://webapi.amap.com/maps?v=2.0&key=13471667a960ce7a08b3dfdd9a4fb193"></script>
|
||||
<script type="text/javascript" src="./static/echarts.min.js"></script>
|
||||
<script type="text/javascript" src="./heatmapData.js"></script>
|
||||
|
||||
<script>
|
||||
var chartEle = document.getElementById("linegraph");
|
||||
var chart = echarts.init(chartEle, null, {
|
||||
renderer: "canvas",
|
||||
useDirtyRect: false,
|
||||
});
|
||||
var app = {};
|
||||
var option = {
|
||||
title: {
|
||||
text: "Distribution of Water",
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "cross",
|
||||
},
|
||||
},
|
||||
// toolbox: {
|
||||
// show: true,
|
||||
// feature: {
|
||||
// saveAsImage: {},
|
||||
// },
|
||||
// },
|
||||
xAxis: {
|
||||
type: "category",
|
||||
boundaryGap: false,
|
||||
data: [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"15",
|
||||
"16",
|
||||
"17",
|
||||
"18",
|
||||
"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>
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue