#javascript #arrays #object
#javascript #массивы #объект
Вопрос:
У меня есть карта с 3 странами, при нажатии на которые отображается всплывающее окно со ссылками и их названием. Я бы хотел избежать всплывающего окна для страны без отображаемых ссылок.
Как я могу проверить пустой массив и предотвратить всплывающее окно только для стран, у которых нет никакой информации ни в "link"
or "linkName"
?
Всплывающее окно происходит здесь:
let polygonTemplate = series.mapPolygons.template;
polygonTemplate.tooltipHTML = '<b>{country}</b>';
polygonTemplate.events.on("hit", function (ev) {
chart.closeAllPopups();
// Map countries and link encoding
const popupContent = `
<strong>${ev.target.dataItem.dataContext.country}</strong><br />
${ev.target.dataItem.dataContext.link.map((url,urlIndex)=>`
<a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>
`).join('')}
`;
chart.openPopup(popupContent);
});
Я пытался написать if
условие, но что-то не работает должным образом. Пожалуйста, проверьте это ниже:
if (Array.isArray(ev.target.dataItem.dataContext.link) amp;amp; !ev.target.dataItem.dataContext.link.length) {
let polygonTemplate = series.mapPolygons.template;
polygonTemplate.tooltipHTML = '<b>{country}</b>';
polygonTemplate.events.on("hit", function (ev) {
chart.closeAllPopups();
// Map countries and link encoding
const popupContent = `
<strong>${ev.target.dataItem.dataContext.country}</strong><br />
${ev.target.dataItem.dataContext.link.map((url, urlIndex) => `
<a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>
`).join('')}
`;
chart.openPopup(popupContent);
});
} else {
console.log("something is wrong");
}
});
am4core.ready(function () {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// Create map instance
let chart = am4core.create("map", am4maps.MapChart);
// Responsiveness enabled
chart.responsive.enabled = true;
// Set map definition
chart.geodata = am4geodata_worldHigh;
// Set projection
chart.projection = new am4maps.projections.Miller();
// Zoom control
chart.zoomControl = new am4maps.ZoomControl();
let homeButton = new am4core.Button();
homeButton.events.on("hit", function () {
chart.goHome();
});
homeButton.icon = new am4core.Sprite();
homeButton.padding(7, 5, 7, 5);
homeButton.width = 30;
homeButton.icon.path = "M16,8 L14,8 L14,16 L10,16 L10,10 L6,10 L6,16 L2,16 L2,8 L0,8 L8,0 L16,8 Z M16,8";
homeButton.marginBottom = 10;
homeButton.parent = chart.zoomControl;
homeButton.insertBefore(chart.zoomControl.plusButton);
// Center on the groups by default
chart.homeZoomLevel = 3.5;
chart.homeGeoPoint = {
longitude: 10,
latitude: 54
};
let groupData = [{
"color": chart.colors.getIndex(0),
"data": [{
"country": "Germany",
"id": "DE",
"link": ["https://www.example1.com"],
"linkName": ["Name 1"]
}, {
"country": "France",
"id": "FR",
"link": ["https://www.example2.com", "https://www.example3.com"],
"linkName": ["Name 2", "Name 3"]
}, {
"country": "Belgium",
"id": "BE",
"link": [""],
"linkName": [""]
}]
}];
// This array will be populated with country IDs to exclude from the world series
let excludedCountries = ["AQ"];
// Create a series for each group, and populate the above array
groupData.forEach(function (group) {
let series = chart.series.push(new am4maps.MapPolygonSeries());
series.name = group.name;
series.useGeodata = true;
let includedCountries = [];
group.data.forEach(function (country) {
includedCountries.push(country.id);
excludedCountries.push(country.id);
});
let polygonTemplate = series.mapPolygons.template;
polygonTemplate.tooltipHTML = '<b>{country}</b>';
polygonTemplate.events.on("hit", function (ev) {
chart.closeAllPopups();
// Map countries and link encoding
const popupContent = `
<strong>${ev.target.dataItem.dataContext.country}</strong><br />
${ev.target.dataItem.dataContext.link.map((url,urlIndex)=>`
<a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>
`).join('')}
`;
chart.openPopup(popupContent);
});
series.include = includedCountries;
series.fill = am4core.color(group.color);
series.setStateOnChildren = true;
series.calculateVisualCenter = true;
series.tooltip.label.interactionsEnabled = false; //disable tooltip click
series.tooltip.keepTargetHover = true;
// Country shape properties amp; behaviors
let mapPolygonTemplate = series.mapPolygons.template;
mapPolygonTemplate.fill = am4core.color("#c4a5e8");
mapPolygonTemplate.fillOpacity = 0.8;
mapPolygonTemplate.nonScalingStroke = true;
mapPolygonTemplate.tooltipPosition = "fixed";
mapPolygonTemplate.events.on("over", function (event) {
series.mapPolygons.each(function (mapPolygon) {
mapPolygon.isHover = false;
})
event.target.isHover = false;
event.target.isHover = true;
})
mapPolygonTemplate.events.on("out", function (event) {
series.mapPolygons.each(function (mapPolygon) {
mapPolygon.isHover = false;
})
})
// States
let hoverState = mapPolygonTemplate.states.create("hover");
hoverState.properties.fill = am4core.color("#FFCC00");
series.data = JSON.parse(JSON.stringify(group.data));
});
// The rest of the world.
let worldSeries = chart.series.push(new am4maps.MapPolygonSeries());
let worldSeriesName = "world";
worldSeries.name = worldSeriesName;
worldSeries.useGeodata = true;
worldSeries.exclude = excludedCountries;
worldSeries.fillOpacity = 0.5;
worldSeries.hiddenInLegend = true;
worldSeries.mapPolygons.template.nonScalingStroke = true;
});
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#map {
width: 100%;
height: 600px;
overflow: hidden;
}
#map a,
b {
cursor: pointer;
color: #003399;
text-align: center;
}
#map a:hover {
color: #023432;
}
.ampopup-content {
/* width: 40%; */
text-align: center;
}
.ampopup-header {
background-color: #003399 !important;
}
.ampopup-close {
filter: invert(1);
}
.ampopup-inside {
background-color: rgb(255, 255, 255);
}
.ampopup-inside a {
color: #28a86c !important;
}
.ampopup-inside a:hover {
color: #023432 !important;
}
.ampopup-curtain {
display: block !important;
background-color: rgba(7, 22, 51, 0.7) !important;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Countries popup with links</title>
<link rel="stylesheet" href="css/style.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-12">
<div id="map"></div>
</div>
</div>
</div>
<!-- Scripts for loading AmCharts Map -->
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/maps.js"></script>
<script src="https://cdn.amcharts.com/lib/4/geodata/worldHigh.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<script src="js/custom2.js"></script>
<!-- Bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
</body>
</html>
Комментарии:
1. Объявите оператор if и посмотрите, есть ли свойство??
Ответ №1:
Вам нужно изменить эти строки:
const popupContent = `
<strong>${ev.target.dataItem.dataContext.country}</strong><br />
${ev.target.dataItem.dataContext.link.map((url,urlIndex)=>`
<a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>
`).join('')}
`;
с:
popupContent = ev.target.dataItem.dataContext.link.map((url,urlIndex)=>
`${(url.length) ? `<a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>` : ''} `
).join('');
if (popupContent.trim().length != 0) { // if popup contains something....
popupContent = `<strong >${ev.target.dataItem.dataContext.country} </strong><br />` popupContent;
chart.openPopup(popupContent);
}
Фрагмент:
am4core.ready(function () {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// Create map instance
let chart = am4core.create("map", am4maps.MapChart);
// Responsiveness enabled
chart.responsive.enabled = true;
// Set map definition
chart.geodata = am4geodata_worldHigh;
// Set projection
chart.projection = new am4maps.projections.Miller();
// Zoom control
chart.zoomControl = new am4maps.ZoomControl();
let homeButton = new am4core.Button();
homeButton.events.on("hit", function () {
chart.goHome();
});
homeButton.icon = new am4core.Sprite();
homeButton.padding(7, 5, 7, 5);
homeButton.width = 30;
homeButton.icon.path = "M16,8 L14,8 L14,16 L10,16 L10,10 L6,10 L6,16 L2,16 L2,8 L0,8 L8,0 L16,8 Z M16,8";
homeButton.marginBottom = 10;
homeButton.parent = chart.zoomControl;
homeButton.insertBefore(chart.zoomControl.plusButton);
// Center on the groups by default
chart.homeZoomLevel = 3.5;
chart.homeGeoPoint = {
longitude: 10,
latitude: 54
};
let groupData = [{
"color": chart.colors.getIndex(0),
"data": [{
"country": "Germany",
"id": "DE",
"link": ["https://www.example1.com"],
"linkName": ["Name 1"]
}, {
"country": "France",
"id": "FR",
"link": ["https://www.example2.com", "https://www.example3.com"],
"linkName": ["Name 2", "Name 3"]
}, {
"country": "Belgium",
"id": "BE",
"link": [""],
"linkName": [""]
}]
}];
// This array will be populated with country IDs to exclude from the world series
let excludedCountries = ["AQ"];
// Create a series for each group, and populate the above array
groupData.forEach(function (group) {
let series = chart.series.push(new am4maps.MapPolygonSeries());
series.name = group.name;
series.useGeodata = true;
let includedCountries = [];
group.data.forEach(function (country) {
includedCountries.push(country.id);
excludedCountries.push(country.id);
});
let polygonTemplate = series.mapPolygons.template;
polygonTemplate.tooltipHTML = '<b>{country}</b>';
polygonTemplate.events.on("hit", function (ev) {
chart.closeAllPopups();
// Map countries and link encoding
popupContent = ev.target.dataItem.dataContext.link.map((url,urlIndex)=>
`${(url.length) ? `<a href="${encodeURI(url)}">${ev.target.dataItem.dataContext.linkName[urlIndex]}</a><br>` : ''} `
).join('');
if (popupContent.trim().length != 0) {
popupContent = `<strong >${ev.target.dataItem.dataContext.country} </strong><br />` popupContent;
chart.openPopup(popupContent);
}
});
series.include = includedCountries;
series.fill = am4core.color(group.color);
series.setStateOnChildren = true;
series.calculateVisualCenter = true;
series.tooltip.label.interactionsEnabled = false; //disable tooltip click
series.tooltip.keepTargetHover = true;
// Country shape properties amp; behaviors
let mapPolygonTemplate = series.mapPolygons.template;
mapPolygonTemplate.fill = am4core.color("#c4a5e8");
mapPolygonTemplate.fillOpacity = 0.8;
mapPolygonTemplate.nonScalingStroke = true;
mapPolygonTemplate.tooltipPosition = "fixed";
mapPolygonTemplate.events.on("over", function (event) {
series.mapPolygons.each(function (mapPolygon) {
mapPolygon.isHover = false;
})
event.target.isHover = false;
event.target.isHover = true;
})
mapPolygonTemplate.events.on("out", function (event) {
series.mapPolygons.each(function (mapPolygon) {
mapPolygon.isHover = false;
})
})
// States
let hoverState = mapPolygonTemplate.states.create("hover");
hoverState.properties.fill = am4core.color("#FFCC00");
series.data = JSON.parse(JSON.stringify(group.data));
});
// The rest of the world.
let worldSeries = chart.series.push(new am4maps.MapPolygonSeries());
let worldSeriesName = "world";
worldSeries.name = worldSeriesName;
worldSeries.useGeodata = true;
worldSeries.exclude = excludedCountries;
worldSeries.fillOpacity = 0.5;
worldSeries.hiddenInLegend = true;
worldSeries.mapPolygons.template.nonScalingStroke = true;
});
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#map {
width: 100%;
height: 600px;
overflow: hidden;
}
#map a,
b {
cursor: pointer;
color: #003399;
text-align: center;
}
#map a:hover {
color: #023432;
}
.ampopup-content {
/* width: 40%; */
text-align: center;
}
.ampopup-header {
background-color: #003399 !important;
}
.ampopup-close {
filter: invert(1);
}
.ampopup-inside {
background-color: rgb(255, 255, 255);
}
.ampopup-inside a {
color: #28a86c !important;
}
.ampopup-inside a:hover {
color: #023432 !important;
}
.ampopup-curtain {
display: block !important;
background-color: rgba(7, 22, 51, 0.7) !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/maps.js"></script>
<script src="https://cdn.amcharts.com/lib/4/geodata/worldHigh.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div class="container">
<div class="row">
<div class="col-12">
<div id="map"></div>
</div>
</div>
</div>
Комментарии:
1. Большое вам спасибо за ваше решение! Я пробовал какой-то другой метод, немного более сложный, чем ваш, но он не удался с
Array.isArray()