diff --git a/html/leaderboard.html b/html/leaderboard.html
index cb18d17c4dd7b9463534dfbb7a1408ba45a03c7e..1a50e3666e47803e404c317566253d4ee0f5f748 100644
--- a/html/leaderboard.html
+++ b/html/leaderboard.html
@@ -1,89 +1,15 @@
 {{ template "header" . }}
-<main class="flexcell gridcontainer-leader">
-  <div id="table" class="col-0 row-0" style="width: 20%;">
+<main class="leaderboard-main">
+  <div id="table" class="flexcell">
     <table>
       <tbody>
-      <tr>
-        <th>Name</th>
-        <th>Points</th>
-      </tr>
-      {{ range .AllUsers }}
-      <tr>
-      <td>{{ .DisplayName }}</td>
-      <td>{{ .Points }}</td>
-      </tr>
-      {{ end }}
       </tbody>
     </table>
   </div>
-  <div class="col-1 row-0">
+  <div style="min-width: 0; flex-basis: 80%; margin-right: 24px;" class="flexcell">
   <canvas id="graph"></canvas>
   </div>
     <script src="static/Chart.bundle.min.js" type="text/javascript"></script>
-  <script>
-      var score = {name: [{{ range .AllUsers }}{{ .DisplayName }},{{end}}], points: [ { label: "Points", data: [{{ range .AllUsers }}{{ .Points }},{{end}}]}] };
-      var chart;
-
-    (function(){
-      var c = document.getElementById("graph").getContext('2d');
-      c.height = 800;
-
-
-      chart = new Chart(c, {
-        type: 'horizontalBar',
-        data: {
-          labels: score.name,
-          datasets: score.points
-        },
-        options: {
-          scales: {
-            xAxes: [{
-              ticks: {
-                min: 0,
-                stepSize: 1
-              }
-            }]
-          },
-          legend: {
-              display: false,
-          },
-          mantainAspectRatio: false,
-          responsive: true,
-        },
-    });
-
-      ws = new WebSocket("ws://"+window.location.host+"/ws");
-ws.onopen = function() {
-
-   // Web Socket is connected, send data uting send()
-  console.log("ws connected");
-};
-ws.onclose = function() {
-   alert("WS Disconnected, reload the page")
-};
-
-ws.onmessage = (evt)=>{
-  var rec = evt.data;
-  console.log(evt.data);
-  score = JSON.parse(rec);
-  chart.data = {
-    labels: score.name,
-    datasets: [{data: score.points, label: "Solved Challenges" }]
-  };
-  chart.update();
-  table = document.getElementsByTagName("tbody")[0];
-  table.innerHTML = "<tr><th>Name</th><th>Points</th></tr>";
-  for(i=0; i < score.name.length; i++){
-          row = table.insertRow();
-          namecell = row.insertCell();
-          namecell.innerHTML = score.name[i];
-          pointcell = row.insertCell();
-          pointcell.innerHTML = score.points[i];
-
-  }
-
-};
-    })();
-  </script>
+    <script src="static/leaderboard.js" type="text/javascript"></script>
 </main>
 {{ template "footer" . }}
diff --git a/html/static/leaderboard.js b/html/static/leaderboard.js
new file mode 100644
index 0000000000000000000000000000000000000000..b2ff9f6ae16f7ef85ebca0b66213d5ba12307b96
--- /dev/null
+++ b/html/static/leaderboard.js
@@ -0,0 +1,73 @@
+var chart;
+(function() {
+  var c = document.getElementById("graph").getContext("2d");
+
+  chart = new Chart(c, {
+    type: "line",
+    options: {
+      scales: {
+        xAxes: [
+          {
+            type: "time",
+            time: {
+              unit: "minute",
+              max: Date.now()
+            }
+          }
+        ],
+        yAxes: [
+          {
+            ticks: {
+              beginAtZero: true
+            }
+          }
+        ]
+      },
+      elements: {
+        line: {
+          tension: 0,
+          fill: false
+        }
+      },
+      legend: {
+        display: false
+      },
+      mantainAspectRatio: false,
+      responsive: true,
+      showScale: false
+    }
+  });
+
+  ws = new WebSocket("ws://" + window.location.host + "/ws");
+  ws.onopen = function() {
+    // Web Socket is connected, send data uting send()
+    console.log("ws connected");
+  };
+  ws.onclose = function() {
+    alert("WS Disconnected, reload the page");
+  };
+
+  ws.onmessage = evt => {
+    var rec = evt.data;
+    console.log(evt.data);
+    score = JSON.parse(rec);
+
+    chart.data = {
+      datasets: score.chart
+    };
+    chart.update();
+
+    table = document.getElementsByTagName("tbody")[0];
+    table.innerHTML = "<tr><th>Name</th><th>Points</th></tr>";
+    for (i = 0; i < score.table.name.length; i++) {
+      row = table.insertRow();
+      namecell = row.insertCell();
+      namecell.innerHTML = score.table.name[i];
+      pointcell = row.insertCell();
+      pointcell.innerHTML = score.table.points[i];
+    }
+  };
+  window.addEventListener("resize", function() {
+    chart.update();
+  });
+})();
diff --git a/html/static/style.css b/html/static/style.css
index c41a4559bca7a41f74c4756b826080979ddd16b8..4ee89b6a5d8bcdd52a40f66c162eb4c42ae2852b 100644
--- a/html/static/style.css
+++ b/html/static/style.css
@@ -4,6 +4,20 @@
     border-style: solid;
 }*/
 
+.leaderboard-table {
+    flex-grow: 1;
+    flex-shrink: 1;
+    flex-basis: 20%;
+    margin-right: 24px;
+}
+
+.leaderboard-main {
+    margin-top: 96px;
+    justify-content: space-between;
+    align-items: strech;
+    display: flex;
+}
+
 .button {
     border: none;
     color: white;
@@ -210,7 +224,7 @@ img {
 
 .gridcontainer-leader {
     display: grid;
-    width: auto;
+    width: 100%;
     height: 100%;
 }
 
diff --git a/internal/liveScoreboard.go b/internal/liveScoreboard.go
index c281441bbb9f3d5b8c7ea245fa7991552c09e9c6..535808d9ac8a2bfc9577138edc3bd516f3c71c30 100644
--- a/internal/liveScoreboard.go
+++ b/internal/liveScoreboard.go
@@ -2,11 +2,19 @@ package wtfd
 
 import (
 	"encoding/json"
+	"fmt"
 	"github.com/gorilla/websocket"
+	"hash/crc32"
 	"log"
 	"net/http"
+	"time"
 )
 
+type tableData struct {
+	Names  []string `json:"name"`
+	Points []int    `json:"points"`
+}
+
 var (
 	serverChan  = make(chan chan string, 4)
 	messageChan = make(chan string, 1)
@@ -52,6 +60,7 @@ func leaderboardWS(w http.ResponseWriter, r *http.Request) {
 	}
 	client := make(chan string, 1)
 	serverChan <- client // i have no idea what this go magic is
+	updateScoreboard()
 
 	for {
 		select {
@@ -64,31 +73,72 @@ func leaderboardWS(w http.ResponseWriter, r *http.Request) {
 
 }
 
-func updateScoreboard() error {
-	log.Printf("Scoreboard Update\n")
-	type userNamePoints struct {
-		Name   []string `json:"name"`
-		Points []int    `json:"points"`
-	}
-	var name []string
-	var points []int
+func generateTableData() (tableData, error) {
 	allu, err := ormAllUsersSortedByPoints()
 	if err != nil {
-		log.Printf("Scoreboard Update Error: %v\n", err)
-		return err
+		return tableData{}, err
 	}
+	var name []string
+	var points []int
+
 	for _, u := range allu {
 		name = append(name, u.DisplayName)
 		points = append(points, u.Points)
 	}
+        return tableData{Names: name, Points: points}, nil
+}
+
+func updateScoreboard() error {
+	type chartDataPoint struct {
+		T string `json:"t"`
+		//	Label string    `json:"label"`
+		Y int `json:"y"`
+	}
+	type chartData struct {
+		Label  string           `json:"label"`
+		Data   []chartDataPoint `json:"data"`
+		Color  string           `json:"backgroundColor"`
+		Pcolor string           `json:"borderColor"`
+	}
+	type leaderboardData struct {
+		TableData tableData `json:"table"`
+		ChartData []chartData `json:"chart"`
+	}
+
+	log.Printf("Scoreboard Update\n")
+	users, err := ormAllUsersSortedByPoints()
+	datas := make([]chartData, len(users))
+	for _, u := range users {
+		solves := ormGetSolvesWithTime(u.Name)
+		data := make([]chartDataPoint, len(solves)+1)
+		sum := 0
+		data[0] = chartDataPoint{T: u.Created.Format(time.RFC3339), Y: sum} //, Label: s.ChallengeName}
+		for i, s := range solves {
+			chall, err := challs.Find(s.ChallengeName)
+			if err != nil {
+				log.Printf("Scoreboard Update Error: %v, %v\n", err, s.ChallengeName)
+				return err
+			}
+			sum += chall.Points
+			data[i+1] = chartDataPoint{T: s.Created.Format(time.RFC3339), Y: sum} //, Label: s.ChallengeName}
+		}
+		a := fmt.Sprintf("#%X", crc32.ChecksumIEEE([]byte(u.DisplayName)))[0:7]
+		datas = append(datas, chartData{Pcolor: a, Color: a, Label: u.DisplayName, Data: data})
+
+	}
 
-	json, err := json.Marshal(&userNamePoints{Name: name, Points: points})
+        td, err := generateTableData()
+	if err != nil {
+		log.Printf("Scoreboard Update Error: %v\n", err)
+		return err
+	}
+        ld := leaderboardData{TableData: td, ChartData: datas}
+	jsona, err := json.Marshal(&ld)
 	if err != nil {
 		log.Printf("Scoreboard Update Error: %v\n", err)
 		return err
 	}
-	messageChan <- string(json)
-        log.Printf("Scoreboard Update String: %s\n", string(json))
+	messageChan <- string(jsona)
 
 	return nil
 }
diff --git a/internal/orm.go b/internal/orm.go
index 2a3b36bd9fde8b661b908266b4d11013edf12285..c8727d0d424b0066aa840863fa2b1136b4091ffa 100644
--- a/internal/orm.go
+++ b/internal/orm.go
@@ -3,10 +3,11 @@ package wtfd
 import (
 	"errors"
 	"fmt"
-	"golang.org/x/crypto/bcrypt"
 	"github.com/go-xorm/xorm"
 	_ "github.com/mattn/go-sqlite3" // needed for xorm
+	"golang.org/x/crypto/bcrypt"
 	"os"
+	"time"
 	"xorm.io/core"
 )
 
@@ -25,13 +26,15 @@ var (
 type _ORMUser struct {
 	Name        string `xorm:"unique"`
 	DisplayName string `xorm:"unique"`
+	Created       time.Time `xorm:"created" json:"time"`
 	Hash        []byte
 	Points      int
 }
 
 type _ORMChallengesByUser struct {
-	UserName      string // Foregin keys don't exist
-	ChallengeName string
+	UserName      string    `json:"username"` // Foregin keys don't exist
+	Created       time.Time `xorm:"created" json:"time"`
+	ChallengeName string    `json:"name"`
 }
 
 func (u _ORMUser) TableName() string {
@@ -77,6 +80,7 @@ func NewUser(name, password, displayname string) (User, error) {
 	return User{Name: name, Hash: hash, DisplayName: displayname}, nil
 
 }
+
 // Contains looks if a username is in the datenbank
 func Contains(username, displayname string) bool {
 	count, _ := ormUserExists(User{Name: username, DisplayName: displayname})
@@ -146,6 +150,18 @@ func ormNewUser(user User) error {
 	return err
 }
 
+// ormGetSolveCount returns the number of solves for the Challenge chall
+func ormGetSolvesWithTime(u string) []_ORMChallengesByUser {
+
+	var a []_ORMChallengesByUser
+	if err := engine.Where("UserName = ?", u).Find(&a); err != nil {
+          fmt.Printf("ORM Error: %v\n", err)
+		return []_ORMChallengesByUser{}
+	}
+	return a
+
+}
+
 // ormGetSolveCount returns the number of solves for the Challenge chall
 func ormGetSolveCount(chall Challenge) int64 {