Search code examples
javascriptangularjscanvasdonut-chart

html canvas - enlarge stroke width on donut chart


I followed a jsfiddle: http://jsfiddle.net/RgLAU/1/

and made a donut chart. Right now the donut chart has really tiny strokes in white separating each segment of the donut. For instance, in the picture below, you can see (barely) that there are 6 sections to the donut, delineated by white strokes.

enter image description here

My problem is that I want to increase the thickness of those lines without increasing the thickness of the chart overall, such that the breaks look a little more like this:

enter image description here

Here's my JS. Any help greatly appreciated.:

var donutVm = this;

donutVm.donutHeight = donutVm.donutHeightConfig || 150;
donutVm.donutWidth = donutVm.donutWidthConfig || 150;
donutVm.donutRadius = donutVm.donutRadiusConfig || 50;

if (CommunityConfig.conversionContestActionId) {
    ActionService.get({ id: CommunityConfig.conversionContestActionId, type: 'action' }).$promise.then(function (response) {
        if (CommunityConfig.conversionContestConversionCountTarget) donutVm.totalConversions = CommunityConfig.conversionContestConversionCountTarget;
        var action = response;
        if (action.linkReference) {
            action.getContextFromLinkReference(action.linkReference, function (error, context) {
                var conversionsMade = context.conversionCount;

                var canvas  = document.getElementById("chart");
                var chart = canvas.getContext("2d");

                function drawDonutChart(canvas)
                {
                    donutVm.x, donutVm.y, donutVm.radius, donutVm.lineWidth, donutVm.strokeStyle, donutVm.from, donutVm.to = null;
                    donutVm.set = function( x, y, radius, from, to, lineWidth, strokeStyle) {
                        donutVm.x = x;
                        donutVm.y = y;
                        donutVm.radius = radius;
                        donutVm.from = from;
                        donutVm.to = to;
                        donutVm.lineWidth = lineWidth;
                        donutVm.strokeStyle = strokeStyle;
                    };

                    donutVm.draw = function(data) {
                        canvas.beginPath();
                        canvas.lineWidth = donutVm.lineWidth;
                        canvas.strokeStyle = donutVm.strokeStyle;
                        canvas.arc(donutVm.x, donutVm.y, donutVm.radius, donutVm.from, donutVm.to);
                        canvas.stroke();
                        var numberOfParts = data.numberOfParts;
                        var parts = data.parts.pt;
                        var colors = data.colors.cs;
                        var df = 1.5 * Math.PI;

                        for(var i = 0; i < numberOfParts; i++) {
                            canvas.beginPath();
                            canvas.strokeStyle = colors[i];
                            canvas.arc(donutVm.x, donutVm.y, donutVm.radius, df, df + (Math.PI * 2) * (parts[i] / 100));
                            canvas.stroke();
                            df += (Math.PI * 2) * (parts[i] / 100);
                        }
                    }
                }

                var sections = {"pt": []};
                var sectionColors = {"cs": []};
                var emptyColor = "lightgrey";
                var madeColor = CommunityConfig.styles.buttonColor;
                var sectionPercentage = 100/donutVm.totalConversions;

                if (conversionsMade == donutVm.totalConversions) {
                    for (var y = 0; y < conversionsMade; y++) {
                        sectionColors.cs.push(emptyColor);
                    }
                } else {
                    for (var y = 0; y < conversionsMade; y++) {
                        sectionColors.cs.push(madeColor);
                    }

                    while (sectionColors.cs.length < donutVm.totalConversions) {
                        sectionColors.cs.push(emptyColor);
                    }
                }

                for (var i = 0; i < donutVm.totalConversions; i++){
                    sections.pt.push(sectionPercentage);
                }

                var data = {
                    numberOfParts: donutVm.totalConversions,
                    parts: sections,
                    colors: sectionColors
                };

                var drawDonut = new drawDonutChart(chart);
                donutVm.set(canvas.width / 2, canvas.height / 2, donutVm.donutRadius, 0, Math.PI*2, 10, "#fff");
                donutVm.draw(data);
                donutVm.donutFinished = true;

Solution

  • Something like this should work:

    var donutVm = this;
    
    donutVm.donutHeight = donutVm.donutHeightConfig || 150;
    donutVm.donutWidth = donutVm.donutWidthConfig || 150;
    donutVm.donutRadius = donutVm.donutRadiusConfig || 50;
    
    if (CommunityConfig.conversionContestActionId) {
        ActionService.get({ id: CommunityConfig.conversionContestActionId, type: 'action' }).$promise.then(function (response) {
            if (CommunityConfig.conversionContestConversionCountTarget) donutVm.totalConversions = CommunityConfig.conversionContestConversionCountTarget;
            var action = response;
            if (action.linkReference) {
                action.getContextFromLinkReference(action.linkReference, function (error, context) {
                    var conversionsMade = context.conversionCount;
    
                    var canvas  = document.getElementById("chart");
                    var chart = canvas.getContext("2d");
    
                    function drawDonutChart(canvas)
                    {
                        donutVm.x, donutVm.y, donutVm.radius, donutVm.lineWidth, donutVm.strokeStyle, donutVm.from, donutVm.to = null;
                        donutVm.set = function( x, y, radius, from, to, lineWidth, strokeStyle) {
                            donutVm.x = x;
                            donutVm.y = y;
                            donutVm.radius = radius;
                            donutVm.from = from;
                            donutVm.to = to;
                            donutVm.lineWidth = lineWidth;
                            donutVm.strokeStyle = strokeStyle;
                        };
    
                        donutVm.draw = function(data) {
                            canvas.beginPath();
                            canvas.lineWidth = donutVm.lineWidth;
                            canvas.strokeStyle = donutVm.strokeStyle;
                            canvas.arc(donutVm.x, donutVm.y, donutVm.radius, donutVm.from, donutVm.to);
                            canvas.stroke();
                            var numberOfParts = data.numberOfParts;
                            var parts = data.parts.pt;
                            var colors = data.colors.cs;
                            var spacer = 2 * 0.05
                            var df = (1.5 + spacer) * Math.PI;
    
                            for(var i = 0; i < numberOfParts; i++) {
                                canvas.beginPath();
                                canvas.strokeStyle = colors[i];
                                canvas.arc(donutVm.x, donutVm.y, donutVm.radius, df, df + (Math.PI * 2) * (parts[i] / 100) - (2 * spacer);
                                canvas.stroke();
                                df += (Math.PI * 2) * ((parts[i] / 100) + (2 * spacer));
                            }
                        }
                    }
    
                    var sections = {"pt": []};
                    var sectionColors = {"cs": []};
                    var emptyColor = "lightgrey";
                    var madeColor = CommunityConfig.styles.buttonColor;
                    var sectionPercentage = 100/donutVm.totalConversions;
    
                    if (conversionsMade == donutVm.totalConversions) {
                        for (var y = 0; y < conversionsMade; y++) {
                            sectionColors.cs.push(emptyColor);
                        }
                    } else {
                        for (var y = 0; y < conversionsMade; y++) {
                            sectionColors.cs.push(madeColor);
                        }
    
                        while (sectionColors.cs.length < donutVm.totalConversions) {
                            sectionColors.cs.push(emptyColor);
                        }
                    }
    
                    for (var i = 0; i < donutVm.totalConversions; i++){
                        sections.pt.push(sectionPercentage);
                    }
    
                    var data = {
                        numberOfParts: donutVm.totalConversions,
                        parts: sections,
                        colors: sectionColors
                    };
    
                    var drawDonut = new drawDonutChart(chart);
                    donutVm.set(canvas.width / 2, canvas.height / 2, donutVm.donutRadius, 0, Math.PI*2, 10, "#fff");
                    donutVm.draw(data);
                    donutVm.donutFinished = true;