Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using it's URL and the proper URL extention.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                       <div class="bar">
            <div class="Row">
                <div class="ColumnSmall"><span id="title"></span><span id="year"></span></div>
            </div>
            <div class="Row">
                <div class="Column slidercolumn">
                    <span id="opacityLabel"></span><input type="range" id="opacityslider">
                    <span id="borderLabel"></span><input type="range" id="borderslider">
                    <button id="colorbtn"></button>
                </div>
                <div class="Column">
                    <div class="select-dropdown">
                        <select id="selectmap"></select>
                    </div>
                </div>
            </div>
            <div class="Row">
                <div class="ColumnSmall" id="rangeMin"></div>
                <div class="Column"><input type="range" class="slider" id="yearRange"><br><span id="kilde"> </span>
                </div>
                <div class="ColumnSmall" id="rangeMax"></div>
            </div>
        </div>
        <div id="map"></div>
              
            
!

CSS

              
                * {
    font-family: 'Montserrat';
}

html,
body {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
}

.Row {
    display: table;
    width: 100%;
    padding: 0;
    margin: 0;
}

.Column {
    display: table-cell;
    width: 92%;
}

.ColumnSmall {
    display: table-cell;
    padding: 0px;
    font-size: 24px;
    margin: 0;
    padding-left: 10px;
    
}


#map {
    
    height: 100%;
    width: 100%;


}

.red {
    background-color: darkred;
    border-radius: 4px;
    padding: 2px;
    border: solid 1px gray;
    font-weight: bold;

}

.label {
    background-color: beige;
    border-radius: 4px;
    padding: 1.5px;
    border: solid 1px gray;

}


#title {
    margin-left: 70px;
}

#header { 
    margin-left: 70px;
    margin-top: 5px;
    margin-bottom: 2px;
    font-size: 26px;
}

.infowindow {
    color: #333;
    margin: 15px;
}

.infoheader {
    font-size: 18px;
    font-weight: bold;
}

.infotext {
    font-size: 14px;
}

.slidercolumn {
    /* float:right; 
    width: 800px; */
}
.opacityslider  {
    opacity: 0.8;
    margin-right:15px;

    }

.slider {
    -webkit-appearance: none;
    width: 100%;
    height: 20px;
    background: lightblue;
    outline: none;
    opacity: 0.7;
    -webkit-transition: .2s;
    transition: opacity .2s;
}

.slider:hover {
    opacity: 1;
}

.slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    border-radius: 40%;
    appearance: none;
    width: 20px;
    height: 20px;
    background: orangered;
    cursor: pointer;
}

.slider::-moz-range-thumb {
    width: 25px;
    height: 25px;
    background: orangered;
    cursor: pointer;
}

.bar {
    overflow: hidden;
    color: #fff;
    background-color:  #336695;
    position: fixed;
    padding:5px;
    width: 100%;
    /* height: 9.8%;
    min-height: 85px; */
    z-index: 999;
}

.waitMessage {
    color: yellow;
    font-style: italic;
}

#colorbtn{
    background-color:lightblue;
    border-radius: 6px;
}

.select-dropdown,
.select-dropdown * {
    margin: 0;
    margin-top: 2px;
    padding: 0;
    /* position: relative; */
    border-radius: 4px;
    box-sizing: border-box;

}

.select-dropdown {
     position: relative; 
    border-radius: 1px;
    margin-right: 5px;
    
}

.select-dropdown select {
    font-size: 0.8rem;
    font-weight: normal;
    max-width: 100%;
    padding: 8px 24px 8px 10px;
    border: none;
    background-color: lightblue;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

.select-dropdown select:active,
.select-dropdown select:focus {
    outline: none;
    box-shadow: none;
}

.select-dropdown:after {
    content: "";
    position: absolute;
    top: 50%;
    right: 8px;
    width: 0;
    height: 0;
    margin-top: -2px;
    border-top: 5px solid #aaa;
    border-right: 5px solid transparent;
    border-left: 5px solid transparent;
}
#kilde {
    font-size:10px;
    float:left;
    color:lavender
}
#kilde a {
    color:white;
}

              
            
!

JS

              
                            //Konstanter
            const copyright = "Indeholder data fra Styrelsen for Dataforsyning og Effektivisering, Digitalt atlas over Danmarks historisk-administrative geografi (DigDag), hentet marts 2022. (<a href='https://euromind.com/digdag' target='_blank'>Læs mere</a></b>)";
            const waitMessage = "Indlæser kort, vent...";
            const geoJSONPath = "https://lindsoe.net/digdag/";
            const centerDK = new google.maps.LatLng(56.36392, 9.917850);
            const initialZoom = 7.7;
            const initialBorderWidth = 1.5;
            const initialOpacity = 0.4;
            const labelCoordinate = "Interior"; //Interior eller Centroid
            const labelFontSize = "11px";
 

            var dataLayer = new window.google.maps.Data();
            var featuresCount = 0;
            var counter = 0;
            var colorArray = [];
            var mapLoaded = false;
            var infowindow;
            var map;

            google.maps.event.addDomListener(window, 'load', initMap);


            function initMap() {
                // Initialiser kort    
                var mapElement = document.getElementById('map');
                map = new google.maps.Map(mapElement, {
                    zoom: initialZoom,
                    center: centerDK,
                    maxZoom: 14, // Begræns zoom ind
                    minZoom: 7,  // Begræns Zoom ud
                    restriction: { // Begræns bevægelsesrummet til ca. Danmark
                        latLngBounds: { north: 59, south: 53, west: 7, east: 16 },
                      },
                    fullscreenControl: true,
                    fullscreenControlOptions: {
                        position: google.maps.ControlPosition.RIGHT_BOTTOM
                    }, 
                    mapTypeControl: true,
                    mapTypeControlOptions: {
                        style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
                        position: google.maps.ControlPosition.LEFT_BOTTOM,
                    }
                    
                });

                // Sæt event-listener    
                google.maps.event.addListener(map, 'bounds_changed', manageLabels);
                google.maps.event.addListener(map, "click", onClickMap);
                dataLayer.addListener('mouseover', onMouseoverLayer);
                dataLayer.addListener('mouseout', onMouseoutLayer);
                dataLayer.addListener('click', onClickLayer);
                document.getElementById("borderslider").oninput = onOpacityBorderChange;
                document.getElementById("opacityslider").oninput = onOpacityBorderChange;
                document.getElementById("colorbtn").onclick = onColorBtnClick;

                loadSelectedMap();
            }


            function loadSelectedMap() {
                setWaitMessage();
                cfg = Config[document.getElementById("selectmap").selectedIndex];
                dataLayer.loadGeoJson(
                    geoJSONPath + cfg.geojson, {},
                    function (features) {
                        featuresCount = features.length;
                        dataLayer.forEach(function (feature) {
                                // For hver Feature: sæt farve, Label og og Click-Event for label, hvor Featurens infowindow åbner 
                                // feature udvides med properties for color og label
                                if (!colorArray[feature.getProperty("navn")]) {
                                    _color = getRandomColor();
                                    colorArray[feature.getProperty("navn")] = _color;
                                }
                                else {
                                    _color = colorArray[feature.getProperty("navn")];
                                }
                                feature.setProperty("color", _color)
                                feature.setProperty("label", CreateLabel(feature));
                                google.maps.event.addListener(feature.getProperty("label"), 'click', function (e) {
                                if (infowindow) infowindow.close();
                                infowindow = CreateInfo(feature);
                            });
                        })
                        setHeaderText(cfg);
                        dataLayer.setMap(map);
                        
                    }
                );
            };


            dataLayer.setStyle(function (feature) {
                counter++;
                var label = feature.getProperty("label");
                if (label) {
                    var showLabelAtLevel = Config[document.getElementById("selectmap").selectedIndex].showLabelAtZoomLevel;
                    var isInViewport = map.getBounds().contains(label.getPosition());
                    var showIt = (isSelectedYear(feature) && (map.getZoom() >= showLabelAtLevel) && (isInViewport));
                    label.setOptions({ visible: showIt });
              }
              if (counter==featuresCount){
                document.getElementById("title").classList.remove('waitMessage');
                document.getElementById("title").innerHTML = Config[document.getElementById("selectmap").selectedIndex].title + " ";
                document.getElementById("year").innerHTML =  document.getElementById("yearRange").value;
                counter=0;
              }   
              return {
                    fillColor: feature.getProperty("color"),
                    fillOpacity: opacityslider.value,
                    strokeWeight: borderslider.value,
                    strokeColor: 'black',
                    visible: isSelectedYear(feature)
                }
            });



            function onOpacityBorderChange() {
                dataLayer.forEach(function (feature) {
                    dataLayer.overrideStyle(feature, { fillOpacity: opacityslider.value, strokeWeight: borderslider.value });
                })
            };

            function onColorBtnClick() {
                colorArray = [];
                dataLayer.forEach(function (feature) {
                    _color = getRandomColor();
                    if (!colorArray[feature.getProperty("navn")])
                        colorArray[feature.getProperty("navn")] = _color;
                    _color = colorArray[feature.getProperty("navn")];
                    feature.setProperty("color", _color)
                    dataLayer.overrideStyle(feature, { fillColor: _color });
                });
            }

            function manageLabels() {
                var showLabelAtLevel = Config[document.getElementById("selectmap").selectedIndex].showLabelAtZoomLevel;
                var zoomLevel = map.getZoom();
                dataLayer.forEach(function (feature) {
                    var label = feature.getProperty("label");
                    var isInViewport = map.getBounds().contains(label.getPosition());
                    var showIt = (isSelectedYear(feature) && (zoomLevel >= showLabelAtLevel) && (isInViewport));
                    label.setOptions({ visible: showIt });
                });
            }
           function onMouseoverLayer(e) {
                var template = `     
      ${e.feature.getProperty("navn").toUpperCase()}
      Gyldig fra: ${ChangeDateFormat(e.feature.getProperty("fra"))}
      Gyldig til: ${ChangeDateFormat(e.feature.getProperty("til"))}
      Areal: ${e.feature.getProperty("SHAPE_Area")} km\u00B2
      Omkreds: ${e.feature.getProperty("SHAPE_Leng")} km
      `;
                var label = e.feature.getProperty('label');
                var _label = label.getLabel();
                _label.className = "red";
                _label.color = "white";
                label.setLabel(_label);
                dataLayer.overrideStyle(e.feature, { fillOpacity: 0, strokeWeight: 2 });
                map.getDiv().setAttribute('title', template);
            };

            function onMouseoutLayer(e) {
                dataLayer.revertStyle();
                var label = e.feature.getProperty('label');
                var _label = label.getLabel();
                _label.className = "label";
                _label.color = "black";
                label.setLabel(_label);
                map.getDiv().removeAttribute('title');
            }


            // Event - Klik på polygon: Åbn infowindow og luk andet, hvis åben
            function onClickLayer(e) {
                if (infowindow) infowindow.close();
                //                   infowindow= CreateInfo(e.feature);
            }

            // Klip på kortet udenfor polygoner: luk Infowindow hvis åben
            function onClickMap(e) {
                if (infowindow) infowindow.close();
            }



            function isSelectedYear(feature) {
                var year = document.getElementById("yearRange").value;
                if ((feature.getProperty("fra") == feature.getProperty("til")) && (feature.getProperty("fra").substring(0, 4) == year)) return true;
                year = year + "-01-02";
                return ((feature.getProperty("fra") <= year) && (feature.getProperty("til") >= year));
            }


            // Find en tilfældig farve
            function getRandomColor() {
                var letters = '0123456789abcdef';
                var color = '#';
                for (var i = 0; i < 6; i++) {
                    color += letters[Math.floor(Math.random() * 16)];
                }
                return color;
            }

            // Skift dato-format fra 2022-12-28 -> 28-12-2022 
            function ChangeDateFormat(dato) {
                return dato.substring(8, 10) + "-" + dato.substring(5, 7) + "-" + dato.substring(0, 4);
            }

            function setWaitMessage() {
                document.getElementById("title").classList.add('waitMessage');
                document.getElementById("title").innerHTML = waitMessage;
                document.getElementById("year").innerHTML = "";
                document.getElementById("rangeMin").innerHTML = "";
                document.getElementById("rangeMax").innerHTML = "";

            }

            function setHeaderText(cfg) {
                document.getElementById("title").classList.remove('waitMessage');
                document.getElementById("title").innerHTML = cfg.title + " ";
                document.getElementById("year").innerHTML = (cfg.startYear != cfg.endYear) ? cfg.startYear + "-" + cfg.endYear : cfg.startYear
                document.getElementById("rangeMin").innerHTML = cfg.startYear;
                document.getElementById("rangeMax").innerHTML = cfg.endYear;
                document.getElementById("yearRange").min = cfg.startYear;
                document.getElementById("yearRange").max = cfg.endYear;
                document.getElementById("yearRange").step = cfg.yearStep;
                document.getElementById("yearRange").value = cfg.initialYear;
            }


            function CreateInfo(feat) {
                var template = `<div class="infowindow">
                        <span class="infoheader">${feat.getProperty("navn")}</span><p>
                        <div class="infotext">
                            <span><b>Gyldig fra: 
                                </b>${(feat.getProperty("fra") == '1000-01-01') ? "(før år 1500)" : ChangeDateFormat(feat.getProperty("fra"))}</span><br>
                            <span><b>Gyldig til: 
                                </b>${ChangeDateFormat(feat.getProperty("til"))}</span><br>
                            <span><b>Areal: </b>${feat.getProperty("SHAPE_Area")} km<sup>2</sup></span><br>
                            <span><b>Omkreds: </b>${feat.getProperty("SHAPE_Leng")} km</span><p>
                            <span style="font-size:12px">
                            <span><b>Type: </b>${feat.getGeometry().getType()} (${feat.getGeometry().getArray().length}) </span><br>
                            <span><b>Interiorpoint: </b>${feat.getProperty("Interior")}</span><br> 
                            <span><b>Centroid: </b>${feat.getProperty("Centroid")}</span><br>
                            <span><b>Boundingbox: </b>${feat.getProperty("Envelope")}</span><br>
                            </span>
                        </div>
                    </div>`;
                return new google.maps.InfoWindow(
                    {
                        map: map,
                        content: template,
                        position: new google.maps.LatLng(feat.getProperty(labelCoordinate)[0], feat.getProperty(labelCoordinate)[1]),
                        shouldFocus: false
                    });
            }

            function CreateLabel(feat) {
                return new google.maps.Marker({
                    position: new google.maps.LatLng(feat.getProperty(labelCoordinate)[0], feat.getProperty(labelCoordinate)[1]),
                    map: map,
                    icon: " ",
                    anchorPoint: new google.maps.Point(20, 10),
                    label: {
                        text: feat.getProperty("navn"),
                        className: "label",
                        fontSize: labelFontSize
                    }
                });
            }


            var slider = document.getElementById("yearRange");

            slider.oninput = function () {
                document.getElementById("year").innerHTML = slider.value;

            };

            slider.onchange = function () {
                document.getElementById("title").classList.add('waitMessage');
                document.getElementById("title").innerHTML = waitMessage;
                document.getElementById("year").innerHTML = "";
                counter = 0;
                setTimeout(function(){
                    dataLayer.setMap(map);
                },10);
            };



            var dropdown = document.getElementById("selectmap");
            dropdown.addEventListener("change", function (e) {

                colorArray = [];
                dataLayer.forEach(function (feature) {
                    feature.getProperty("label").setMap(null);
                    dataLayer.remove(feature);
                });

                var _center = Config[document.getElementById("selectmap").selectedIndex].center;
                var _zoom = Config[document.getElementById("selectmap").selectedIndex].zoom;

                if (!_zoom) _zoom = initialZoom;
                var delay = (_zoom == map.getZoom()) ? 60 : 1000;

                if (_center) {
                    map.setZoom(_zoom);
                    map.panTo(new google.maps.LatLng(_center[0], _center[1]));
                } else {
                    map.setZoom(initialZoom);
                    map.panTo(centerDK);
                }
                setTimeout(function () {
                    loadSelectedMap(e.target.value);
                }, delay);
            });



            document.getElementById("opacityLabel").innerHTML =  "Farvestyrke:";
            document.getElementById("borderLabel").innerHTML =  "Grænselinje:";
            document.getElementById("colorbtn").textContent =  "Nye Farvevalg";
            document.getElementById("opacityslider").min = 0;
            document.getElementById("opacityslider").max = 1;
            document.getElementById("opacityslider").step = 0.1;
            document.getElementById("opacityslider").value = initialOpacity;
            document.getElementById("borderslider").min = 0;
            document.getElementById("borderslider").max = 4;
            document.getElementById("borderslider").value = initialBorderWidth;
            document.getElementById("borderslider").step = 0.1;
            document.getElementById("kilde").innerHTML = copyright;



            // Sorter Config på group->title og fyld Dropdown
            Config.sort(function (a, b) {
                return a.group.localeCompare(b.group) || a.title.localeCompare(b.title);
            });
            var group;
            Config.forEach(function (e, idx) {
                // Hvis der er ny gruppe, så set optgroup    
                if (group != e.group) {
                    var optgroup = document.createElement("optgroup");
                    optgroup.label = e.group;
                    group = e.group;
                    dropdown.add(optgroup);
                }
                // Sæt option med value og text    
                var option = document.createElement("option");
                option.value = idx;
                option.text = (e.startYear == e.endYear)
                    ? e.title + " (" + e.startYear + ")"
                    : e.title + " (" + e.startYear + "-" + e.endYear + ")";
                dropdown.add(option);
            });



              
            
!
999px

Console