Q: Trying to put a chartjs chart on top of an image As stated in the subject, I have a chart.js chart that I'm trying to render on top of an image but it just doesn't seem to be working.  Either no image at all shows up, or it shows up somewhere else.  No javascript errors that I'm seeing either.  I'm seeing a lot of people using .png files for this, but I'm using .jpg files, hopefully that's not the issue.  Been trying to use pointStyle and have that point to an img tag id defined in the html.
Below is the code thanks in advance!


<!doctype html>
<html>

<head>
    <title>Gauge Chart</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
    <script>
    Chart.defaults.gauge = Chart.defaults.doughnut;

var gauge = Chart.controllers.doughnut.extend({
    draw: function(ease) {
        //Chart.controllers.doughnut.prototype.draw.call(this, ease);
        var meta = this.getMeta();
        var pt0 = meta.data[0];

        var ctx = this.chart.chart.ctx;
        ctx.save();

        var cx = pt0._view.x;
        var cy = pt0._view.y;
        var innerRadius = pt0._view.innerRadius;
        var outerRadius = pt0._view.outerRadius;
        var config = this.chart.chart.config;
        var current = config.data.current;
        var max = config.options.panel.max;
        var min = config.options.panel.min;
        var needle = config.options.needle;
        var panel = config.options.panel;
        if (current >= max) {
            current = max;
        }
        if (current <= min) {
            current = min;
        }
        var needleAngle = config.options.circumference * (current - min) / (max - min) + config.options.rotation;
        var radius = outerRadius * needle.lengthRadius / 100;
        var textRadius = outerRadius * panel.scaleTextRadius / 100;
        
        ctx.translate(cx, cy);
        ctx.font = "" + panel.scaleTextSize + "px, Helvetica, Arial, sans-serif";
        ctx.fillStyle = panel.scaleTextColor || 'rgba(255, 255, 255, 1)';
        panel.scales.forEach(function(value, index, arr) {
            var textWidth = ctx.measureText("" + value).width;
            var textAngle = config.options.circumference * index / (arr.length - 1) + config.options.rotation;
            var dy = textRadius * Math.sin(textAngle);
            var dx = textRadius * Math.cos(textAngle);
            ctx.fillText("" + value, dx - (textWidth / 2), dy);
            var oy = (outerRadius * panel.scaleOuterRadius / 100) * Math.sin(textAngle);
            var ox = (outerRadius * panel.scaleOuterRadius / 100) * Math.cos(textAngle);
            var iy = (outerRadius * panel.scaleInnerRadius / 100) * Math.sin(textAngle);
            var ix = (outerRadius * panel.scaleInnerRadius / 100) * Math.cos(textAngle);
            ctx.strokeStyle = panel.scaleColor || 'rgba(0, 0, 0, 1)';
            ctx.beginPath();
            ctx.moveTo(ix, iy);
            ctx.lineTo(ox, oy);
            ctx.stroke();
        });
        ctx.restore();

        ctx.save();
        ctx.translate(cx, cy);
        ctx.strokeStyle = panel.tickColor || 'rgba(0, 0, 0, 1)';
        ctx.beginPath();
        this.chart.chart.config.data.datasets[0].values.forEach(function(value, index, arr) {
            var textWidth = ctx.measureText("" + value).width;
            var textAngle = config.options.circumference * (value - min) / (max - min) + config.options.rotation;
            var oy = (outerRadius * panel.tickOuterRadius / 100) * Math.sin(textAngle);
            var ox = (outerRadius * panel.tickOuterRadius / 100) * Math.cos(textAngle);
            var iy = (outerRadius * panel.tickInnerRadius / 100) * Math.sin(textAngle);
            var ix = (outerRadius * panel.tickInnerRadius / 100) * Math.cos(textAngle);
            ctx.moveTo(ix, iy);
            ctx.lineTo(ox, oy);
        });
        ctx.stroke();
        ctx.restore();

        ctx.save();
        ctx.translate(cx, cy);
        ctx.rotate(needleAngle);
        ctx.beginPath();
        ctx.moveTo(0, -needle.width);
        ctx.lineTo(radius, 0);
        ctx.lineTo(0, needle.width);
        ctx.fillStyle = needle.color || 'rgba(180, 0, 0, 0.8)';
        ctx.fill();
        ctx.rotate(-needleAngle);
        ctx.translate(-cx, -cy);
        ctx.beginPath();
        ctx.fillStyle = needle.circleColor || 'rgba(188, 188, 188, 1)';
        ctx.arc(cx, cy, needle.circleRadius, 0, Math.PI * 2);
        ctx.fill();
        ctx.restore();
    },

    initialize: function(chart, datasetIndex) {
        var panel = chart.chart.config.options.panel;
        var data = [100];
        var backgroundColor = [panel.scaleBackgroundColor || "rgb(120, 120, 120)"];
        var hoverBackgroundColor = [panel.scaleBackgroundColor || "rgb(120, 120, 120)"];
        var pointStyle = [panel.pointStyle];
        
        var values = [];
        for (var v = panel.min; v <= panel.max; v += panel.tickInterval) {
            values.push(v);
        }

        chart.chart.config.data.datasets[0].data = data;
        chart.chart.config.data.datasets[0].backgroundColor = backgroundColor;
        chart.chart.config.data.datasets[0].hoverBackgroundColor = hoverBackgroundColor;
        chart.chart.config.data.datasets[0].pointStyle = pointStyle;
        chart.chart.config.data.datasets[0].values = values;

        Chart.controllers.doughnut.prototype.initialize.call(this, chart, datasetIndex);
    }
});

Chart.controllers.gauge = gauge;
    
    </script>
</head>

<body>
    <div id="canvas-holder">
        <canvas id="chart-speed"></canvas>
        <img id="source" src="http://example.com/image.jpg";>
    </div>


    <script>
                Chart.defaults.global.animation.duration = 0;
        Chart.defaults.global.defaultFontSize = 12;

        var image = document.getElementById('source');

        var configSpeed = {
            "type": "gauge",
            "data": {
                "datasets": [
                    {
                        "data": [],
                        "backgroundColor": [],
                        "borderWidth": 9,
                        "hoverBackgroundColor": [],
                        "hoverBorderWidth": 0,
                        "pointStyle": image
                    }
                ],
                "current": 135,
            },
            "options": {
                "panel": {
                    "min": 0,
                    "max": 240,
                    "tickInterval": 1,
                    "tickColor": "rgb(0, 0, 0)",
                    "tickOuterRadius": 99,
                    "tickInnerRadius": 99,
                    "scales": [],
                    "scaleColor": "rgb(0, 0, 0)",
                    "scaleBackgroundColor": "rgb(105, 125, 151)",
                    "scaleTextRadius": 80,
                    "scaleTextSize": 8,
                    "scaleTextColor": "rgba(0, 0, 0, 1)",
                    "scaleOuterRadius": 99,
                    "scaleInnerRadius": 99,
                },
                "needle": {
                    "lengthRadius": 100,
                    "circleColor": "rgba(188, 188, 188, 1)",
                    "color": "rgba(180, 0, 0, 0.8)",
                    "circleRadius": 7,
                    "width": 5,
                },
                "cutoutPercentage": 90,
                "rotation": (1/2+1/3)*Math.PI,
                "circumference": 2*Math.PI*2/3,
                "legend": {
                    "display": false,
                    "text": "legend"
                },
                "tooltips": {
                    "enabled": false
                },
                "title": {
                    "display": false,
                    "text": "speed",
                    "position": "bottom"
                },
                "animation": {
                    "animateRotate": true,
                    "animateScale": false
                },
                "hover": {
                    "mode": null
                }
            }
        };



        window.onload = function() {
            var ctx = document.getElementById('chart-speed').getContext('2d');
            window.speed = new Chart(ctx, configSpeed);
        };



    </script>
</body>
</html>


