Skip to content

Commit

Permalink
two maps
Browse files Browse the repository at this point in the history
  • Loading branch information
blackdotbug committed Jul 2, 2024
1 parent 942679f commit a549165
Show file tree
Hide file tree
Showing 8 changed files with 669 additions and 247 deletions.
50 changes: 50 additions & 0 deletions demo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Leaflet.IconEx v1.1.0 - 2024-06-15
*
* Copyright 2024 mfhsieh
* [email protected]
*
* Licensed under the MIT license.
*
* Demos:
* https://mfhsieh.github.io/leaflet-iconex/
*
* Source:
* [email protected]:mfhsieh/leaflet-iconex.git
*
*/
@-moz-document url-prefix() {

/* .leaflet-div-icon div:last-child,
.leaflet-iconex div:last-child, */
.leaflet-div-icon div:last-child .fa,
.leaflet-div-icon div:last-child .fab,
.leaflet-div-icon div:last-child .far,
.leaflet-div-icon div:last-child .fas,
.leaflet-iconex div:last-child .fa,
.leaflet-iconex div:last-child .fab,
.leaflet-iconex div:last-child .far,
.leaflet-iconex div:last-child .fas {
margin-top: .05rem;
margin-bottom: -.05rem;
}
}

.leaflet-div-icon {
background: transparent;
border: none;
}

.leaflet-div-icon,
.leaflet-iconex {
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
text-size-adjust: none;
-webkit-text-size-adjust: none;
-moz-text-size-adjust: none;
-ms-text-size-adjust: none;
-khtml-text-size-adjust: none;
}
252 changes: 6 additions & 246 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,252 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<base target="_top">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Bloomberg Business Oportunity Alumni Map</title>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" integrity="sha512-Zcn6bjR/8RZbLEpLIeOwNtzREBAJnUKESxces60Mpoj+2okopSAcSUIUOseddDm0cxnGQzxIR7vJgsLZbdLE3w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.js" integrity="sha512-BwHfrr4c9kmRkLw6iXFdzcdWV/PGkVgiIyIWLLlTSXzWQzxuSg4DiQUCpauz/EWjgk5TYQqX/kvn9pG1NpYfqg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/MarkerCluster.Default.css">
<script src="https://unpkg.com/[email protected]/dist/leaflet.markercluster.js"></script>
<script src="https://unpkg.com/[email protected]/dist/leaflet.featuregroup.subgroup.js"></script>
<script src="./leaflet.timeline.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
<style>
html, body {
height: 100%;
margin: 0;
}
.leaflet-container {
height: 100vh;
width: 100vw;
max-width: 100%;
max-height: 100%;
}
div.leaflet-control-layers {
visibility: hidden;
}
div.legend {
background-color: white;
padding: 0 20px 20px;
border-radius: 5px;
box-shadow: 0 0 15px rgba(0,0,0,0.2);
}
/* div.legend div.entry {
display: flex;
justify-content: space-between;
}
div.legend.cluster div.entry {
justify-content: flex-start;
}
div.activity div.entry div.swatch {
background-color: rgba(219, 5, 5, 0.56);
opacity: .5;
margin-right: 30px;
}
div.cluster div.entry div.swatch {
margin-right: 10px;
width: 20px;
height: 20px;
border-radius: 10px;
margin-bottom: 5px;
pointer-events: none;
} */
div.cluster h3 {
max-width: 130px;
}
div.cluster div.progressGroup {
display: flex;
flex-direction: row;
justify-content: space-around;
}
div.cluster div.progressGroup div.progress {
width: 50px;
height: auto;
border-bottom: 1px solid black;
border-top: 1px solid black;
display: flex;
flex-direction: column;
gap: 0;
}
div.cluster div.progressGroup div.progress div.barTick {
width: 30px;
margin: auto;
background: navy;
flex-grow: 1;
}
div.cluster div.entry div.label {
padding-top: 2px;
pointer-events: none;
}
/* div.cluster div.entry div.label.reset {
font-weight: 700;
} */
</style>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>10,000 Small Businesses Program Alumni Map</title>
</head>
<body>
<div id="map" style="width: 100vw; height: 100vh;"></div>
<script>

const map = L.map('map').setView([38.47654, -76.71313], 8);
const Stadia_AlidadeSmooth = L.tileLayer('https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.{ext}', {
minZoom: 0,
maxZoom: 20,
attribution: '&copy; <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
ext: 'png'
}).addTo(map);
d3.csv("alumni.csv").then((data) => {
console.log(data)
// const activityScale = d3.scaleLinear().range([2, 16])
// const clusterScale = d3.scaleOrdinal(d3.schemeObservable10)
// .domain(Array.from(new Set(data.features.map(m => m.properties.cluster_name))).sort((a,b)=>a.localeCompare(b)))
// function pointToClusterLayer(feature, latlng) {
// return L.circleMarker(latlng, {
// radius: 6,
// // fillColor: clusterScale(feature.properties.cluster_name),
// fillOpacity: 1,
// stroke: false
// })
// }
// function pointToActivityLayer(feature, latlng) {
// return L.circleMarker(latlng, {
// // radius: activityScale(+feature.properties.activity),
// fillColor: "#db0505",
// fillOpacity: .35,
// stroke: true,
// weight: 0.5,
// color: "white"
// })
// }
const alumni = L.markerClusterGroup();
const subgroups = [];
const gradDates = Array.from(new Set(data.map(d => d.end_date)));
const barScale = d3.scaleLinear().range([0,1])
gradDates.forEach(cohort => {
let endDate = cohort.split("/");
let gradDate = new Date(endDate[2],
endDate[0].length < 2 ? `0${endDate[0]}` : endDate[0],
endDate[1].length < 2 ? `0${endDate[1]}` : endDate[1]);
let dateStrings = gradDate.toDateString().split(" ");
let cohortLabel = `${dateStrings[1]} ${dateStrings[3]}`;
let cohortData = data.filter(d => d.end_date === cohort);
subgroups.push({
label: cohortLabel,
data: cohortData,
date: gradDate});
})
const subgroupsSorted = subgroups.slice().sort((a,b) => b.date - a.date)
const dateScale = d3.scaleTime().domain([1,0]).range(subgroupsSorted.map(m => m.date))

subgroupsSorted.forEach(group => {
let groupMarkers = [];
group.data.forEach(alum => {
groupMarkers.push(
L.circleMarker([alum.latitude, alum.longitude], {
radius: 10,
fillColor: "#db0505",
fillOpacity: .35,
stroke: true,
weight: 0.5,
color: "white"
}).bindTooltip(alum.business_name)
)
})
let cohortGroup = L.featureGroup.subGroup(alumni, groupMarkers)
cohortGroup.addTo(map);
group.layerGroup = cohortGroup;
})
// const categories = L.geoJSON(data.features, {
// pointToLayer: pointToClusterLayer
// }).bindPopup(function(layer) {
// return layer.feature.properties.stop_name;
// })
// const activity = L.geoJSON(data.features, {
// pointToLayer: pointToActivityLayer
// }).bindPopup(function(layer) {
// return layer.feature.properties.stop_name;
// })
alumni.addTo(map)
console.log(subgroupsSorted);
const overlays = {}
subgroupsSorted.forEach(g => overlays[g.label] = g.layerGroup)
const layerControl = L.control.layers(null, overlays, {collapsed: false}).addTo(map);
// const activityLegend = L.control({position: "bottomright"})
const clusterLegend = L.control({position: "bottomright"})
// activityLegend.onAdd = function(map) {
// let div = L.DomUtil.create('div', 'legend activity'),
// levels = [0, .25, .5, .75, 1];
// div.innerHTML += "<h3>Activity Levels</h3>";
// levels.forEach(level => {
// let size = 2*activityScale(level);
// div.innerHTML += `<div class="entry">
// <div class="swatch" style="width: ${size}px; height: ${size}px; border-radius: ${size/2}px; margin-bottom: ${30-size}px;" ></div>
// <div class="label">${level}</div>
// </div>`
// });
// return div;
// }
// activityLegend.addTo(map);
clusterLegend.onAdd = function(map) {
let div = L.DomUtil.create("div", 'legend cluster');
let h3 = L.DomUtil.create("h3", null, div);
h3.innerHTML = "Cohorts by Program End Date";
let pGroup = L.DomUtil.create("div", "progressGroup", div);
let pBar = L.DomUtil.create("div", "progress", pGroup);
let pLabels = L.DomUtil.create("div", "labels", pGroup);
subgroupsSorted.forEach((group, i) => {
let entry = L.DomUtil.create("div", `entry`, pLabels);
entry.innerHTML = `<div class="label index-${i}">${group.label}</div>`
let bartick = L.DomUtil.create("div", `barTick index-${i}`, pBar)
})
// div.innerHTML += `<div class="entry">
// <div class="label reset">Reset</div>
// </div>`
return div;
}
clusterLegend.addTo(map);
function handleClusterLegendClick(e) {
let i = e.target.classList.value.split("-")[1];
d3.selectAll(`div.barTick`).style("background",
(d,j) => j < i ? "transparent" : "navy"
);
d3.selectAll("div.labels div.entry div.label").style("font-weight",
(d,j) => j < i ? "300" : "500"
)
let chkbxs = document.querySelectorAll("div.leaflet-control-layers-overlays input.leaflet-control-layers-selector")
chkbxs.forEach((c,j) => {
if (j < i && c.checked) {
c.click();
} else if (j >= i && !c.checked) {
c.click();
}
})
// map.flyToBounds(alumni.getBounds());
}
d3.selectAll("div.legend.cluster div.progressGroup div.progress").on("click", handleClusterLegendClick)
function handleLegendLabelsClick(e) {
let i = e.target.querySelector(".label").classList.value.split("-")[1];
d3.selectAll(`div.barTick`).style("background",
(d,j) => j < i ? "transparent" : "navy"
);
d3.selectAll("div.labels div.entry div.label").style("font-weight",
(d,j) => j < i ? "300" : "500"
)
let chkbxs = document.querySelectorAll("div.leaflet-control-layers-overlays input.leaflet-control-layers-selector")
chkbxs.forEach((c,j) => {
if (j < i && c.checked) {
c.click();
} else if (j >= i && !c.checked) {
c.click();
}
})
// map.flyToBounds(alumni.getBounds());
}
d3.selectAll("div.legend.cluster div.progressGroup div.labels").on("click", handleLegendLabelsClick)
})
</script>
<iframe src="./progress.html" width="95%" height="790px" frameBorder="0" style="border: 0;"></iframe>
<iframe src="./industries.html" width="95%" height="790px" frameBorder="0" style="border: 0;"></iframe>
</body>
</html>
</html>
Loading

0 comments on commit a549165

Please sign in to comment.