diff --git a/demo/package-lock.json b/demo/package-lock.json
index 0745570f08df7e81b284b2a4809709799408cd4a..d7d99b693777755d6ce19fde5d3483480feca866 100644
--- a/demo/package-lock.json
+++ b/demo/package-lock.json
@@ -29,7 +29,7 @@
     },
     "..": {
       "name": "@polaris/dashboard-sdk",
-      "version": "1.0.4",
+      "version": "1.0.8",
       "license": "ISC",
       "dependencies": {
         "d3": "^7.7.0"
diff --git a/demo/src/bar_chart_test.js b/demo/src/bar_chart_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..8b82add8390b35b27b88bdf79c1f77cb0ae74a83
--- /dev/null
+++ b/demo/src/bar_chart_test.js
@@ -0,0 +1,52 @@
+import * as d3 from "d3";
+import { BarChartWidget, ChartJSWidget } from "@polaris/dashboard-sdk";
+
+const dict = {
+    "accessed": 98,
+    "started": 7,
+    "graded": 7,
+    "submitted": 7,
+    "answered": 38,
+    "leftUnanswered": 4
+}
+
+const data = Object.keys(dict).map(key => ({column1: key, column2: dict[key]}));
+
+export const barChartDef = { "barchart-widget" :
+    new BarChartWidget(
+        "A sample bar chart",
+        "sample description",
+        data,
+        {
+            showLegend: true,
+            xAxisLabel: "Status",
+            yAxisLabel: "Count"
+        })
+}
+
+
+const chartjs_data = {datasets: [{data: Object.keys(dict).map(key => dict[key])}], labels: Object.keys(dict)};
+
+export const chartJSBarChartDef = { "chartjs-barchart-widget" :
+    new ChartJSWidget(
+        "A sample ChartJS bar chart",
+        "sample description",
+        chartjs_data,
+        {
+            scales: {
+                x: {
+                    title: {
+                        display: true,
+                        text: "Status"
+                    }
+                },
+                y: {
+                    title: {
+                        display: true,
+                        text: "Count"
+                    }
+                }
+            }
+        }
+    )
+}
diff --git a/demo/src/grouped_bar_chart_test.js b/demo/src/grouped_bar_chart_test.js
index 90b9e010c6127207ff9398260fb734be4c2c6a53..0398dff0ec0526c19fd0ac0ae2c1530b944ff152 100644
--- a/demo/src/grouped_bar_chart_test.js
+++ b/demo/src/grouped_bar_chart_test.js
@@ -59,4 +59,4 @@ export const simpleGroupedBarChartDef = { "simple-grouped-barchart-widget" :
         "A sample grouped bar chart",
         "sample description",
         dict)
-}
\ No newline at end of file
+}
diff --git a/demo/src/heatmap_test.js b/demo/src/heatmap_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..6178a0315748ce312d8dbd5303aadb782b243277
--- /dev/null
+++ b/demo/src/heatmap_test.js
@@ -0,0 +1,117 @@
+import * as d3 from "d3";
+import { HeatMapWidget } from "@polaris/dashboard-sdk";
+
+const data = [
+    {
+        group: "A",
+        variable: "v1",
+        value: 12
+    },
+    {
+        group: "A",
+        variable: "v2",
+        value: 1
+    },
+    {
+        group: "A",
+        variable: "v3",
+        value: 26
+    },
+    {
+        group: "A",
+        variable: "v4",
+        value: 86
+    },
+    {
+        group: "A",
+        variable: "v5",
+        value: 10
+    },
+    {
+        group: "B",
+        variable: "v1",
+        value: 82
+    },
+    {
+        group: "B",
+        variable: "v2",
+        value: 65
+    },
+    {
+        group: "B",
+        variable: "v3",
+        value: 51
+    },
+    {
+        group: "B",
+        variable: "v4",
+        value: 2
+    },
+    {
+        group: "B",
+        variable: "v5",
+        value: 15
+    },
+    {
+        group: "C",
+        variable: "v1",
+        value: 23
+    },
+    {
+        group: "C",
+        variable: "v2",
+        value: 35
+    },
+    {
+        group: "C",
+        variable: "v3",
+        value: 45
+    },
+    {
+        group: "C",
+        variable: "v4",
+        value: 36
+    },
+    {
+        group: "C",
+        variable: "v5",
+        value: 19
+    },
+    {
+        group: "D",
+        variable: "v1",
+        value: 89
+    },
+    {
+        group: "D",
+        variable: "v2",
+        value: 64
+    },
+    {
+        group: "D",
+        variable: "v3",
+        value: 4
+    },
+    {
+        group: "D",
+        variable: "v4",
+        value: 39
+    },
+    {
+        group: "D",
+        variable: "v5",
+        value: 75
+    },
+]
+
+export const heatMapDef = { "heatmap-widget" :
+    new HeatMapWidget(
+        "A sample heat map",
+        "sample description",
+        data,
+        {
+            showLegend: false,
+            xAxisLabel: "Days",
+            yAxisLabel: "Students"
+        })
+}
diff --git a/demo/src/js/app.js b/demo/src/js/app.js
index 14852f40bf325767b644b2eaabf6d3e1f84015d1..d277dec7e081b41bf1c49c97f508287fa40961d5 100644
--- a/demo/src/js/app.js
+++ b/demo/src/js/app.js
@@ -6,12 +6,15 @@ import {
   AreaChartWidget,
   PieChartWidget,
   StackedBarChartWidget,
+  ChartJSWidget,
+  HeatMapWidget
 } from "@polaris/dashboard-sdk/dist/bundle";
 import { CourseRatingChart } from "./custom-charts/courseRatingChart";
 import {groupedBarChartDef, simpleGroupedBarChartDef} from "../grouped_bar_chart_test";
-
+import { barChartDef, chartJSBarChartDef } from "../bar_chart_test";
+import { heatMapDef } from "../heatmap_test";
 /**
- * JWT Token - hardcoded for demotrastion
+ * JWT Token - hardcoded for demontrastion
  * This jwt token is generated in the backend.
  */
 let token =
@@ -28,7 +31,7 @@ const subGrid = [
 /**
  * Setup initial widget position and sizes
  */
-const widgets_confgg = [
+const widgets_config = [
   {
     x: 4,
     y: 0,
@@ -100,6 +103,27 @@ const widgets_confgg = [
     h: 6,
     widgetId: "simple-grouped-barchart-widget",
   },
+  {
+    x: 0,
+    y: 13,
+    w: 5,
+    h: 5,
+    widgetId: "chartjs-barchart-widget",
+  },
+  {
+    x: 5,
+    y: 13,
+    w: 5,
+    h: 5,
+    widgetId: "barchart-widget",
+  },
+  {
+    x: 0,
+    y: 14,
+    w: 5,
+    h: 5,
+    widgetId: "heatmap-widget",
+  },
 ];
 
 /**
@@ -235,6 +259,9 @@ const buildWidgets = (data) => {
         onShowDesc,
       }
     ),
+    ...heatMapDef,
+    ...barChartDef,
+    ...chartJSBarChartDef,
     ...groupedBarChartDef,
     ...simpleGroupedBarChartDef
   };
@@ -248,7 +275,7 @@ const setupGrid = (data) => {
   const widgets = buildWidgets(data);
 
   // Initialize grid with widgets at configured positions
-  grid = initGrid(widgets, widgets_confgg);
+  grid = initGrid(widgets, widgets_config);
 
   // Handle toggle button click
   const toggleBtn = document.getElementById("toggle-sidebar-btn");
@@ -288,7 +315,8 @@ const onInit = () => {
       showErrorModal(err.message);
     });
     */
-    setupGrid([])
+
+  setupGrid([])
 };
 
 const handleSaveSettingsClick = () => {
diff --git a/index.js b/index.js
index 128f549ccc503e5d3bd8decb3c5866b065f7f383..42a8cd7b21e8f5a5d58b1a280b8bce2de7780565 100644
--- a/index.js
+++ b/index.js
@@ -8,6 +8,8 @@ import { AreaChartWidget } from "./src/js/charts/areachart";
 import { StackedBarChartWidget } from "./src/js/charts/stacked_barchart";
 import { GroupedBarChartWidget } from "./src/js/charts/grouped_barchart";
 import { SimpleGroupedBarChartWidget } from "./src/js/charts/simple_grouped_barchart";
+import { ChartJSWidget } from "./src/js/charts/chartjs";
+import { HeatMapWidget } from "./src/js/charts/heatmap";
 
 export {
   getResult,
@@ -19,5 +21,7 @@ export {
   StackedBarChartWidget,
   BaseChartWidget,
   GroupedBarChartWidget,
-  SimpleGroupedBarChartWidget
+  SimpleGroupedBarChartWidget,
+  ChartJSWidget,
+  HeatMapWidget
 };
diff --git a/package-lock.json b/package-lock.json
index bdc7d319f864a130693b957949e01cb4c4408093..70af6fd96a8a96f3bf21077a6a0d988578ab99c1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,14 +1,15 @@
 {
   "name": "@polaris/dashboard-sdk",
-  "version": "1.0.4",
+  "version": "1.0.8",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "@polaris/dashboard-sdk",
-      "version": "1.0.4",
+      "version": "1.0.8",
       "license": "ISC",
       "dependencies": {
+        "chart.js": "^4.3.1",
         "d3": "^7.7.0"
       },
       "devDependencies": {
@@ -1766,6 +1767,11 @@
         "@jridgewell/sourcemap-codec": "1.4.14"
       }
     },
+    "node_modules/@kurkle/color": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
+      "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
+    },
     "node_modules/@leichtgewicht/ip-codec": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz",
@@ -2923,6 +2929,17 @@
         "node": ">=4"
       }
     },
+    "node_modules/chart.js": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.3.1.tgz",
+      "integrity": "sha512-QHuISG3hTJ0ftq0I0f5jqH9mNVO9bqG8P+zvMOVslgKajQVvFEX7QAhYNJ+QEmw+uYTwo8XpTimaB82oeTWjxw==",
+      "dependencies": {
+        "@kurkle/color": "^0.3.0"
+      },
+      "engines": {
+        "pnpm": ">=7"
+      }
+    },
     "node_modules/chokidar": {
       "version": "3.5.3",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
diff --git a/package.json b/package.json
index 3c3f7fb6d91c0be06743de1830c965af8a838833..5e7f77f7a9065cf0ee0153fd41676ce004bed610 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
     "webpack-dev-server": "^4.11.1"
   },
   "dependencies": {
+    "chart.js": "^4.3.1",
     "d3": "^7.7.0"
   },
   "peerDependencies": {
diff --git a/src/js/charts/areachart.js b/src/js/charts/areachart.js
index 8f2e25b424a724f46cdfe96e348cbd6f90785450..acb3cbad1e286e5b1619526fd9c20b5269c1e183 100644
--- a/src/js/charts/areachart.js
+++ b/src/js/charts/areachart.js
@@ -8,7 +8,7 @@ export class AreaChartWidget extends BaseChartWidget {
     super(title, description, data, options);
   }
 
-  plot(divWidth, divHeight) {
+  plot(divWidth, divHeight, el) {
     const [width, height] = this.clearAndScaleSvg(divWidth, divHeight);
     this.drawTitle();
 
diff --git a/src/js/charts/barchart.js b/src/js/charts/barchart.js
index d318a352cc3886db5129069d8d34ff4b19a985eb..14f7b2d58a516b3bc2dde8fd575edb63309e3eb6 100644
--- a/src/js/charts/barchart.js
+++ b/src/js/charts/barchart.js
@@ -8,7 +8,7 @@ export class BarChartWidget extends BaseChartWidget {
     super(title, description, data, options);
   }
 
-  plot(divWidth, divHeight) {
+  plot(divWidth, divHeight, el) {
     const [width, height] = this.clearAndScaleSvg(divWidth, divHeight);
     this.drawTitle();
 
diff --git a/src/js/charts/chartjs.js b/src/js/charts/chartjs.js
new file mode 100644
index 0000000000000000000000000000000000000000..aaef34b29f9d9d8a2402bbae1df6bb6f9667fe94
--- /dev/null
+++ b/src/js/charts/chartjs.js
@@ -0,0 +1,50 @@
+import Chart from 'chart.js/auto';
+
+export class ChartJSWidget {
+    constructor(title, description, data, options = {}, type="bar") {
+    this.title = title;
+    this.description = description;
+    this.data = data;
+    this.options = options;
+
+    if(document.querySelector(".chart-title") == null)
+    {
+      let temp_child = document.createElement("div");
+      temp_child.classList.add('chart-title');
+      document.body.appendChild(temp_child);
+    }
+    let temp_child = document.querySelector(".chart-title");
+    let style = window.getComputedStyle(temp_child);
+    let font_weight = style.getPropertyValue('font-weight');
+    let font_size = style.getPropertyValue('font-size');
+    let font_family = style.getPropertyValue('font-family');
+    let title_object = {title: {display: true, text: this.title, font: {weight: font_weight, size: font_size, family: font_family}}};
+
+    if("plugins" in this.options)
+    {
+      this.options = Object.assign(title_object, this.options.plugins)
+    }
+    else {
+      this.options = Object.assign({plugins: title_object}, this.options)
+    }
+
+    this.type = type;
+    this.dataIsValid = Array.isArray(data) ? data.length > 0 : !!data;
+  }
+
+
+  plot(divWidth, divHeight, element) {
+      this.canvas = document.createElement("canvas");
+      this.canvas.id = self.crypto.randomUUID();
+      element.appendChild(this.canvas);
+
+      this.chart = new Chart(this.canvas.id, {
+        type: this.type,
+        data: this.data,
+        options: this.options
+      });
+
+      return null;
+  }
+
+}
diff --git a/src/js/charts/grouped_barchart.js b/src/js/charts/grouped_barchart.js
index b4c28e2537a8f7143e3bc9594a4d484bb90e2738..91199d9cc9631ba371442a2c032f711fdbaccf23 100644
--- a/src/js/charts/grouped_barchart.js
+++ b/src/js/charts/grouped_barchart.js
@@ -71,7 +71,7 @@ export class GroupedBarChartWidget extends BaseChartWidget {
     this.svg = d3.select(this.wrapper).append("svg");
   }
 
-  plot(divWidth, divHeight) {
+  plot(divWidth, divHeight, el) {
     let [w, h] = this.clearAndScaleSvg(divWidth, divHeight);
    // this.drawTitle();
 
@@ -193,4 +193,4 @@ export class GroupedBarChartWidget extends BaseChartWidget {
 
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/js/charts/heatmap.js b/src/js/charts/heatmap.js
new file mode 100644
index 0000000000000000000000000000000000000000..2987b3f3900c17d1ef401d44ae622a406e2d4064
--- /dev/null
+++ b/src/js/charts/heatmap.js
@@ -0,0 +1,65 @@
+import * as d3 from "d3";
+import { BaseChartWidget } from "./base";
+
+export class HeatMapWidget extends BaseChartWidget {
+  constructor(title, description, data, options) {
+    if (options.transform) data = (data ?? []).map(options.transform);
+
+    super(title, description, data, options);
+  }
+
+  plot(divWidth, divHeight, el) {
+    const [width, height] = this.clearAndScaleSvg(divWidth, divHeight);
+    this.drawTitle();
+
+    if (!this.dataIsValid) {
+      this.showErrorMessage(divWidth, divHeight);
+      return this.wrapper.innerHTML;
+    }
+    const groups = d3.map(this.data, function(d){return d.group;})
+    const vars = d3.map(this.data, function(d){return d.variable;})
+
+    const xScale = d3.scaleBand().range([0, width]).padding(0.1);
+    const yScale = d3.scaleBand().range([height, 0]).padding(0.1);
+
+    xScale.domain(groups);
+    yScale.domain(vars);
+
+    this.g.append("g")
+    .style("font-size", 15)
+    .attr("transform", "translate(0," + height + ")")
+    .call(d3.axisBottom(xScale).tickSize(0))
+    .select(".domain").remove();
+
+    this.g.append("g")
+    .style("font-size", 15)
+    .call(d3.axisLeft(yScale).tickSize(0))
+    .select(".domain").remove()
+    //this.appendXAxis(xScale, height);
+    //this.appendXAxisLabel(width, height);
+    //this.appendYAxisLabel();
+
+    //this.g.append("g").attr("transform", "translate(0, 0)").call(d3.axisLeft(yScale));
+
+    const max = d3.max(this.data, (d) => d.value);
+
+    const colorScale = d3.scaleSequential().interpolator(d3.interpolateInferno).domain([0,max])
+
+    this.g.selectAll()
+    .data(this.data, function(d) {return d.group+':'+d.variable;})
+    .enter()
+    .append("rect")
+      .attr("x", function(d) { return xScale(d.group) })
+      .attr("y", function(d) { return yScale(d.variable) })
+      .attr("rx", 4)
+      .attr("ry", 4)
+      .attr("width", xScale.bandwidth() )
+      .attr("height", yScale.bandwidth() )
+      .style("fill", function(d) { return colorScale(d.value)} )
+      .style("stroke-width", 4)
+      .style("stroke", "none")
+      .style("opacity", 0.8);
+
+    return this.wrapper.innerHTML;
+  }
+}
diff --git a/src/js/charts/linechart.js b/src/js/charts/linechart.js
index f09b82ce607c022ebc63c665783169640eb1666c..c2673448d71946a5ca2d495fcf4d7b094adb3c02 100644
--- a/src/js/charts/linechart.js
+++ b/src/js/charts/linechart.js
@@ -8,7 +8,7 @@ export class LineChartWidget extends BaseChartWidget {
     super(title, description, data, options);
   }
 
-  plot(divWidth, divHeight) {
+  plot(divWidth, divHeight, el) {
     const [width, height] = this.clearAndScaleSvg(divWidth, divHeight);
     this.drawTitle();
 
diff --git a/src/js/charts/piechart.js b/src/js/charts/piechart.js
index 6dc850f00a5e3c15ce6ca0e511399e4df515bc47..53693adccc4da308fea34cd2a42568384ae065fb 100644
--- a/src/js/charts/piechart.js
+++ b/src/js/charts/piechart.js
@@ -8,7 +8,7 @@ export class PieChartWidget extends BaseChartWidget {
     super(title, description, data, options);
   }
 
-  plot(divWidth, divHeight) {
+  plot(divWidth, divHeight, el) {
     const translateX = divWidth / 2,
       translateY = divHeight / 2;
 
diff --git a/src/js/charts/simple_grouped_barchart.js b/src/js/charts/simple_grouped_barchart.js
index 8cc50206db5bc6c9ea6848a5b1d702f347384ee9..071e7c8c8115b86f503a271c62d09953e229ef9b 100644
--- a/src/js/charts/simple_grouped_barchart.js
+++ b/src/js/charts/simple_grouped_barchart.js
@@ -75,7 +75,7 @@ export class SimpleGroupedBarChartWidget extends BaseChartWidget {
     this.svg = d3.select(this.wrapper).append("svg");
   }
 
-  plot(divWidth, divHeight) {
+  plot(divWidth, divHeight, el) {
     let [w, h] = this.clearAndScaleSvg(divWidth, divHeight);
    // this.drawTitle();
 
@@ -197,4 +197,4 @@ export class SimpleGroupedBarChartWidget extends BaseChartWidget {
 
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/js/charts/stacked_barchart.js b/src/js/charts/stacked_barchart.js
index d65161319a275d4b678884079aee65fdf1fab2b1..7b16de1f8501ea8696cee4108b1161b67b103ea4 100644
--- a/src/js/charts/stacked_barchart.js
+++ b/src/js/charts/stacked_barchart.js
@@ -9,7 +9,7 @@ export class StackedBarChartWidget extends BaseChartWidget {
     this.groups = groups;
   }
 
-  plot(divWidth, divHeight) {
+  plot(divWidth, divHeight, el) {
     const [width, height] = this.clearAndScaleSvg(divWidth, divHeight);
     this.drawTitle();
 
diff --git a/src/js/utils.js b/src/js/utils.js
index 459a474615989bca985094921f915dd0949fb783..fa62915fc650c9658ab9330a2c8e5bfd41f4a035 100644
--- a/src/js/utils.js
+++ b/src/js/utils.js
@@ -52,7 +52,11 @@ function plot(node, widget) {
   const content = node.el.querySelector(".grid-stack-item-content");
   const width = content.offsetWidth;
   const height = content.offsetHeight;
-  content.innerHTML = widget.plot(width, height);
+  const generated = widget.plot(width, height, content);
+  if(generated != null)
+  {
+    content.innerHTML = widget.plot(width, height);
+  }
 }
 
 /**