diff --git a/js/customElements/ntpGraph.js b/js/customElements/ntpGraph.js
new file mode 100644
index 0000000000000000000000000000000000000000..177680e669930201f8627513fda8aa5e5ab2f6dc
--- /dev/null
+++ b/js/customElements/ntpGraph.js
@@ -0,0 +1,74 @@
+import chart from 'chart.js'
+
+let graphIndexCounter = 0;
+
+class NtpGraph extends HTMLElement {
+    constructor() {
+        super();
+
+        let ip = this.getAttribute("data-server-ip");
+
+        this.innerHTML = `
+            <span id="${graphIndexCounter}-Banner" data-index="${graphIndexCounter}" class="ntpBanner">${ip}</span>
+            <span id="${graphIndexCounter}-Content" class="ntpContent">
+                <a target="_blank" href="https://www.ntppool.org/scores/${ip}" class="linkToNtpPool">Server auf dem NTP Pool anzeigen</a>
+                <canvas id="${graphIndexCounter}-Delay"></canvas>
+                <canvas id="${graphIndexCounter}-Score"></canvas>
+            </span>
+        `;
+        let currentIndex = graphIndexCounter;
+        graphIndexCounter++;
+
+        let xhr = new XMLHttpRequest();
+
+        xhr.onreadystatechange = () => {
+            if(xhr.status === 200 && xhr.readyState === 4){
+                let rawData = JSON.parse(xhr.responseText);
+                let x = [];
+                let yScore = [];
+                let yDelay = [];
+                rawData["history"].forEach((entry, index) => {
+                    let date = new Date(entry["ts"] * 1000).toLocaleDateString();
+                    if(index % 10 !== 0){
+                        date = "";
+                    }
+                    x.push(date);
+                    yScore.push(entry["score"]);
+                    yDelay.push(entry["offset"]);
+                });
+
+                this.drawPlot(currentIndex + "-Delay", x, yDelay, "Delay");
+                this.drawPlot(currentIndex + "-Score", x, yScore, "Score");
+
+
+            }
+        }
+        xhr.open("GET", "https://www.ntppool.org/scores/" + ip + "/json?monitor=*&limit=800");
+        xhr.send();
+
+    }
+
+    drawPlot(elementName, x, y, title){
+        let ctx = document.getElementById(elementName).getContext('2d');
+
+        new Chart(ctx, {
+            type: 'line',
+            responsive: true,
+            scaleShowVerticalLines: false,
+            showTooltips: false,
+            data: {
+                labels: x,
+                datasets: [{
+                    label: title,
+                    data: y,
+                    borderColor: '#199a87',
+                    fill: false,
+                    radius: 0,
+                }]
+            },
+        });
+    }
+
+}
+
+customElements.define("jl-ntp-graph", NtpGraph);
\ No newline at end of file
diff --git a/js/ntpGraph.js b/js/ntpGraph.js
deleted file mode 100644
index 870bce5296f1fb1b501af7afe019204e40bffbf5..0000000000000000000000000000000000000000
--- a/js/ntpGraph.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import chart from 'chart.js'
-
-let graphIndexCounter = 0;
-let graphElements = document.querySelectorAll("jl-ntp-graph");
-
-graphElements.forEach((elememt) => {
-    let ip = elememt.getAttribute("data-server-ip");
-
-    elememt.innerHTML = `
-    <span id="${graphIndexCounter}-Banner" data-index="${graphIndexCounter}" class="ntpBanner">${ip}</span>
-    <span id="${graphIndexCounter}-Content" class="ntpContent">
-        <a target="_blank" href="https://www.ntppool.org/scores/${ip}" class="linkToNtpPool">Server auf dem NTP Pool anzeigen</a>
-        <canvas id="${graphIndexCounter}-Delay"></canvas>
-        <canvas id="${graphIndexCounter}-Score"></canvas>
-    </span>
-    `;
-    let currentIndex = graphIndexCounter;
-    graphIndexCounter++;
-
-    let xhr = new XMLHttpRequest();
-
-    xhr.onreadystatechange = function (){
-        if(xhr.status === 200 && xhr.readyState === 4){
-            let rawData = JSON.parse(this.responseText);
-            let x = [];
-            let yScore = [];
-            let yDelay = [];
-            rawData["history"].forEach((entry, index) => {
-                let date = new Date(entry["ts"] * 1000).toLocaleDateString();
-                if(index % 10 !== 0){
-                    date = "";
-                }
-                x.push(date);
-                yScore.push(entry["score"]);
-                yDelay.push(entry["offset"]);
-            });
-
-            drawPlot(currentIndex + "-Delay", x, yDelay, "Delay");
-            drawPlot(currentIndex + "-Score", x, yScore, "Score");
-
-
-        }
-    }
-    xhr.open("GET", "https://www.ntppool.org/scores/" + ip + "/json?monitor=*&limit=800");
-    xhr.send();
-});
-
-function drawPlot(elementName, x, y, title){
-    let ctx = document.getElementById(elementName).getContext('2d');
-
-    new Chart(ctx, {
-        type: 'line',
-        responsive: true,
-        scaleShowVerticalLines: false,
-        showTooltips: false,
-        data: {
-            labels: x,
-            datasets: [{
-                label: title,
-                data: y,
-                borderColor: '#199a87',
-                fill: false,
-                radius: 0,
-            }]
-        },
-    });
-}
\ No newline at end of file
diff --git a/js/script.js b/js/script.js
index 63cf079ec724e27d5e20f7d9f5936ab93789d6b4..4ae0e95d63ba1e79ac73b19d491d460ed421012f 100644
--- a/js/script.js
+++ b/js/script.js
@@ -2,10 +2,10 @@ require("./burgerMenu");
 require("./error");
 require("./imgPreview");
 require("./includeHTML");
-require("./ntpGraph");
 require("./ntpMenu");
 require("./viewPost");
 
+require("./customElements/ntpGraph");
 require("./customElements/cookie");
 require("./customElements/svgLoader");
 require("./customElements/blogFooter");