Chart.js 传单中的弹出窗口?
Chart.js inside popup on leaflet?
也许这是一个愚蠢的问题,但我无法在地图上包含每个点的图表。
我正在从一个 JSON 收集数据,我在弹出窗口中打印这些数据,每个数据都有它的 class .scoreA, .scoreB...我想从这个数据为每个点创建一个图表,就像我拥有的那样。我宁愿从弹出窗口的内容(.scoreA,.scoreB)中获取它们,而不是从 JSON 中获取它们,以防结构发生变化。可能吗?
var mymap = L.map('mapid').setView([39.46975, -0.37739], 8 );
L.tileLayer('https://api.mapbox.com/styles/v1/jamaldols/cktwljkom0vzo18l9ggtnky83/tiles/256/{z}/{x}/{y}@2x?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 12,
minZoom: 8,
id: 'mapbox/standard',
tileSize: 512,
zoomOffset: -1,
// maxNativeZoom: 16,
accessToken: ''
}).addTo(mymap);
$.getJSON('data.geo.json', function (geojson) {
L.geoJson(geojson, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng);
},
onEachFeature: function (feature, layer) {
const coordinates = feature.geometry.coordinates;
const normalizedCoordinates = feature.geometry.coordinates.sort(function(a,b){return a.typeid-b.typeid});
console.log( `Coordinates: ${coordinates}`);
console.log( `Coordinates N: ${normalizedCoordinates}`);
const content =
`
<p id="heading">${feature.properties.name}</p>
<p class="scoreA"><strong>ScoreA: </strong>${feature.properties.scoreA}</p>
<p class="scoreB"><strong>ScoreB: </strong>${feature.properties.scoreB}</p>
<p class="scoreC"><strong>ScoreC: </strong>${feature.properties.scoreC}</p>
<p class="scoreD"><strong>ScoreD: </strong>${feature.properties.scoreD}</p>
<div class="popup__chart">chart</div>
`;
layer.on('click', function (e) {
document.getElementById("popup__content").innerHTML = content;
$(".popup").fadeOut(10);
$(".popup").fadeIn("slow");
console.log( `Click on ${feature.properties.name}`);
const maxZoom = mymap.getMaxZoom();
console.log(maxZoom)
mymap.flyTo(this.getLatLng(), maxZoom, {easeLinearity: 0.12, duration:1});
});
}
}).addTo(mymap);
});
//Chart
var marksCanvas = document.getElementById("marksChart");
var marksData = {
labels: ["Score A", "Score B", "Score C", "Score D"],
datasets: [{
label: "City",
backgroundColor: "rgba(200,0,0,1)",
data: [65, 60, 90, 80]
},]
};
var radarChart = new Chart(marksCanvas, {
type: 'radar',
data: marksData
});
$(document).ready(function(){
$(".popup__bar__close").click(function(){
$('.popup').css('display', 'none');
mymap.flyTo([39.46975, -0.37739], 8, {easeLinearity: 0.12, duration:1});
});
});
html,
body {
height: 100%;
font-family: 'Montserrat', sans-serif;
}
.popup-fixed {
position: fixed;
top: auto;
bottom: 0 !important;
left: 0 !important;
right: 0 !important;
transform: none !important;
margin: 0;
border-radius: 0;
}
.leaflet-popup-tip-container {
display: none;
}
.leaflet-popup-content-wrapper {
border-radius: 0;
}
.popup {
width: 300px;
padding-bottom: 50px;
background: white;
position: absolute;
top: 50px;
right: 50px;
border: none;
display:none;
z-index: 1000;
}
#heading {
font-size: 35px;
color:black;
text-transform: uppercase;
margin: 15px 0;
}
#main {
display: flex;
overflow: hidden;
}
.popup {
}
.popup__bar {
width: 100%;
height: 50px;
position: relative;
display: flex;
align-items: center;
background: black;
}
.popup__bar__close {
background-image: url(img/close.svg);
background-size: 30px;
background-repeat: no-repeat;
background-position: center;
position: absolute;
height: 30px;
width: 30px;
right: 15px;
transform: rotate(45deg);
cursor: pointer;
}
.popup__chart {
}
.popup__chart img{
max-width: 100%;
height: auto;
}
#popup__content {
padding: 0 30px;
}
#info {
}
#footer {
font-family: 'Roboto Condensed', sans-serif;
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
letter-spacing: 6px;
height: 70px;
position: absolute;
background: white;
bottom: 0;
width: calc(100% - 90px);
right: 0;
}
#marksChart {
display: block;
box-sizing: border-box;
height: 250px;
width: 250px;
position: absolute;
top: 100px;
left: 90px;
background: white;
z-index: 200000;
border-radius: 12px;
padding: 20px;
}
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js" integrity="sha512-Wt1bJGtlnMtGP0dqNFH1xlkLBNpEodaiQ8ZN5JLA5wpc1sUlk/O5uuOMNgvzddzkpvZ9GLyYNa8w2s7rqiTk5Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<style>
#mapid {
height: calc(100vh - 70px);
width: calc(100vw - 90px);
}
body {
padding: 0;
margin: 0;
}
</style>
<main id="main">
<div id="mapid"></div>
</main>
<div class="chart-container" style="max-width: 200px;">
<canvas id="marksChart" width="200" height="400"></canvas>
</div>
<script>
</script>
<div class="popup">
<div class="popup__bar">
<div class="popup__bar__close"></div>
</div>
<div id="popup__content"></div>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<!-- <script type="text/javascript" src="data.geo.json"></script> -->
<script type="text/javascript" src="main.js"></script>
</body>
将您的 javascript 更改为以下内容:
$.getJSON('data.geo.json', function (geojson) {
L.geoJson(geojson, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng);
},
onEachFeature: function (feature, layer) {
const coordinates = feature.geometry.coordinates;
const normalizedCoordinates = feature.geometry.coordinates.sort(function(a,b){return a.typeid-b.typeid});
console.log( `Coordinates: ${coordinates}`);
console.log( `Coordinates N: ${normalizedCoordinates}`);
const content =
`
<p id="heading">${feature.properties.name}</p>
<p class="scoreA"><strong>ScoreA: </strong><span>${feature.properties.scoreA}</span></p>
<p class="scoreB"><strong>ScoreB: </strong><span>${feature.properties.scoreB}</span></p>
<p class="scoreC"><strong>ScoreC: </strong><span>${feature.properties.scoreC}</span></p>
<p class="scoreD"><strong>ScoreD: </strong><span>${feature.properties.scoreD}</span></p>
<div class="popup__chart">chart</div>
`;
layer.on('click', function (e) {
var popupElm = document.getElementById("popup__content");
popupElm.innerHTML = content;
$(".popup").fadeOut(10);
$(".popup").fadeIn("slow");
console.log( `Click on ${feature.properties.name}`);
const maxZoom = mymap.getMaxZoom();
console.log(maxZoom)
mymap.flyTo(this.getLatLng(), maxZoom, {easeLinearity: 0.12, duration:1});
var marksData = {
labels: ["Score A", "Score B", "Score C", "Score D"],
datasets: [{
label: "City",
backgroundColor: "rgba(200,0,0,1)",
data: [
popupElm.querySelectorAll('.scoreA span')[0].innerHTML,
popupElm.querySelectorAll('.scoreB span')[0].innerHTML,
popupElm.querySelectorAll('.scoreC span')[0].innerHTML,
popupElm.querySelectorAll('.scoreD span')[0].innerHTML
],
},]
};
if(radarChart){
radarChart.destroy();
}
radarChart = new Chart(marksCanvas, {
type: 'radar',
data: marksData
});
});
}
}).addTo(mymap);
});
//Chart
var marksCanvas = document.getElementById("marksChart");
var radarChart = null;
$(document).ready(function(){
$(".popup__bar__close").click(function(){
$('.popup').css('display', 'none');
mymap.flyTo([39.46975, -0.37739], 8, {easeLinearity: 0.12, duration:1});
});
});
改变了什么:
在分值a的Popup中添加span
,方便读出
<p class="scoreA"><strong>ScoreA: </strong><span>${feature.properties.scoreA}</span></p>
将图表生成移动到点击函数中,但保留全局变量
销毁现有图表,否则抛出错误radarChart.destroy();
从弹出窗口中获取值并将其用于 data
数组。它搜索 class .scoreA
然后它得到子 span
元素
popupElm.querySelectorAll('.scoreA span')[0].innerHTML,
顺便说一句。您还可以从单击的图层中获取值:
data: [
layer.feature.properties.scoreA,
layer.feature.properties.scoreB,
layer.feature.properties.scoreC,
layer.feature.properties.scoreD,
]
也许这是一个愚蠢的问题,但我无法在地图上包含每个点的图表。
我正在从一个 JSON 收集数据,我在弹出窗口中打印这些数据,每个数据都有它的 class .scoreA, .scoreB...我想从这个数据为每个点创建一个图表,就像我拥有的那样。我宁愿从弹出窗口的内容(.scoreA,.scoreB)中获取它们,而不是从 JSON 中获取它们,以防结构发生变化。可能吗?
var mymap = L.map('mapid').setView([39.46975, -0.37739], 8 );
L.tileLayer('https://api.mapbox.com/styles/v1/jamaldols/cktwljkom0vzo18l9ggtnky83/tiles/256/{z}/{x}/{y}@2x?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 12,
minZoom: 8,
id: 'mapbox/standard',
tileSize: 512,
zoomOffset: -1,
// maxNativeZoom: 16,
accessToken: ''
}).addTo(mymap);
$.getJSON('data.geo.json', function (geojson) {
L.geoJson(geojson, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng);
},
onEachFeature: function (feature, layer) {
const coordinates = feature.geometry.coordinates;
const normalizedCoordinates = feature.geometry.coordinates.sort(function(a,b){return a.typeid-b.typeid});
console.log( `Coordinates: ${coordinates}`);
console.log( `Coordinates N: ${normalizedCoordinates}`);
const content =
`
<p id="heading">${feature.properties.name}</p>
<p class="scoreA"><strong>ScoreA: </strong>${feature.properties.scoreA}</p>
<p class="scoreB"><strong>ScoreB: </strong>${feature.properties.scoreB}</p>
<p class="scoreC"><strong>ScoreC: </strong>${feature.properties.scoreC}</p>
<p class="scoreD"><strong>ScoreD: </strong>${feature.properties.scoreD}</p>
<div class="popup__chart">chart</div>
`;
layer.on('click', function (e) {
document.getElementById("popup__content").innerHTML = content;
$(".popup").fadeOut(10);
$(".popup").fadeIn("slow");
console.log( `Click on ${feature.properties.name}`);
const maxZoom = mymap.getMaxZoom();
console.log(maxZoom)
mymap.flyTo(this.getLatLng(), maxZoom, {easeLinearity: 0.12, duration:1});
});
}
}).addTo(mymap);
});
//Chart
var marksCanvas = document.getElementById("marksChart");
var marksData = {
labels: ["Score A", "Score B", "Score C", "Score D"],
datasets: [{
label: "City",
backgroundColor: "rgba(200,0,0,1)",
data: [65, 60, 90, 80]
},]
};
var radarChart = new Chart(marksCanvas, {
type: 'radar',
data: marksData
});
$(document).ready(function(){
$(".popup__bar__close").click(function(){
$('.popup').css('display', 'none');
mymap.flyTo([39.46975, -0.37739], 8, {easeLinearity: 0.12, duration:1});
});
});
html,
body {
height: 100%;
font-family: 'Montserrat', sans-serif;
}
.popup-fixed {
position: fixed;
top: auto;
bottom: 0 !important;
left: 0 !important;
right: 0 !important;
transform: none !important;
margin: 0;
border-radius: 0;
}
.leaflet-popup-tip-container {
display: none;
}
.leaflet-popup-content-wrapper {
border-radius: 0;
}
.popup {
width: 300px;
padding-bottom: 50px;
background: white;
position: absolute;
top: 50px;
right: 50px;
border: none;
display:none;
z-index: 1000;
}
#heading {
font-size: 35px;
color:black;
text-transform: uppercase;
margin: 15px 0;
}
#main {
display: flex;
overflow: hidden;
}
.popup {
}
.popup__bar {
width: 100%;
height: 50px;
position: relative;
display: flex;
align-items: center;
background: black;
}
.popup__bar__close {
background-image: url(img/close.svg);
background-size: 30px;
background-repeat: no-repeat;
background-position: center;
position: absolute;
height: 30px;
width: 30px;
right: 15px;
transform: rotate(45deg);
cursor: pointer;
}
.popup__chart {
}
.popup__chart img{
max-width: 100%;
height: auto;
}
#popup__content {
padding: 0 30px;
}
#info {
}
#footer {
font-family: 'Roboto Condensed', sans-serif;
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
letter-spacing: 6px;
height: 70px;
position: absolute;
background: white;
bottom: 0;
width: calc(100% - 90px);
right: 0;
}
#marksChart {
display: block;
box-sizing: border-box;
height: 250px;
width: 250px;
position: absolute;
top: 100px;
left: 90px;
background: white;
z-index: 200000;
border-radius: 12px;
padding: 20px;
}
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js" integrity="sha512-Wt1bJGtlnMtGP0dqNFH1xlkLBNpEodaiQ8ZN5JLA5wpc1sUlk/O5uuOMNgvzddzkpvZ9GLyYNa8w2s7rqiTk5Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<style>
#mapid {
height: calc(100vh - 70px);
width: calc(100vw - 90px);
}
body {
padding: 0;
margin: 0;
}
</style>
<main id="main">
<div id="mapid"></div>
</main>
<div class="chart-container" style="max-width: 200px;">
<canvas id="marksChart" width="200" height="400"></canvas>
</div>
<script>
</script>
<div class="popup">
<div class="popup__bar">
<div class="popup__bar__close"></div>
</div>
<div id="popup__content"></div>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<!-- <script type="text/javascript" src="data.geo.json"></script> -->
<script type="text/javascript" src="main.js"></script>
</body>
将您的 javascript 更改为以下内容:
$.getJSON('data.geo.json', function (geojson) {
L.geoJson(geojson, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng);
},
onEachFeature: function (feature, layer) {
const coordinates = feature.geometry.coordinates;
const normalizedCoordinates = feature.geometry.coordinates.sort(function(a,b){return a.typeid-b.typeid});
console.log( `Coordinates: ${coordinates}`);
console.log( `Coordinates N: ${normalizedCoordinates}`);
const content =
`
<p id="heading">${feature.properties.name}</p>
<p class="scoreA"><strong>ScoreA: </strong><span>${feature.properties.scoreA}</span></p>
<p class="scoreB"><strong>ScoreB: </strong><span>${feature.properties.scoreB}</span></p>
<p class="scoreC"><strong>ScoreC: </strong><span>${feature.properties.scoreC}</span></p>
<p class="scoreD"><strong>ScoreD: </strong><span>${feature.properties.scoreD}</span></p>
<div class="popup__chart">chart</div>
`;
layer.on('click', function (e) {
var popupElm = document.getElementById("popup__content");
popupElm.innerHTML = content;
$(".popup").fadeOut(10);
$(".popup").fadeIn("slow");
console.log( `Click on ${feature.properties.name}`);
const maxZoom = mymap.getMaxZoom();
console.log(maxZoom)
mymap.flyTo(this.getLatLng(), maxZoom, {easeLinearity: 0.12, duration:1});
var marksData = {
labels: ["Score A", "Score B", "Score C", "Score D"],
datasets: [{
label: "City",
backgroundColor: "rgba(200,0,0,1)",
data: [
popupElm.querySelectorAll('.scoreA span')[0].innerHTML,
popupElm.querySelectorAll('.scoreB span')[0].innerHTML,
popupElm.querySelectorAll('.scoreC span')[0].innerHTML,
popupElm.querySelectorAll('.scoreD span')[0].innerHTML
],
},]
};
if(radarChart){
radarChart.destroy();
}
radarChart = new Chart(marksCanvas, {
type: 'radar',
data: marksData
});
});
}
}).addTo(mymap);
});
//Chart
var marksCanvas = document.getElementById("marksChart");
var radarChart = null;
$(document).ready(function(){
$(".popup__bar__close").click(function(){
$('.popup').css('display', 'none');
mymap.flyTo([39.46975, -0.37739], 8, {easeLinearity: 0.12, duration:1});
});
});
改变了什么:
在分值a的Popup中添加
span
,方便读出<p class="scoreA"><strong>ScoreA: </strong><span>${feature.properties.scoreA}</span></p>
将图表生成移动到点击函数中,但保留全局变量
销毁现有图表,否则抛出错误
radarChart.destroy();
从弹出窗口中获取值并将其用于
data
数组。它搜索 class.scoreA
然后它得到子span
元素popupElm.querySelectorAll('.scoreA span')[0].innerHTML,
顺便说一句。您还可以从单击的图层中获取值:
data: [
layer.feature.properties.scoreA,
layer.feature.properties.scoreB,
layer.feature.properties.scoreC,
layer.feature.properties.scoreD,
]