Chartjs-Merge Jquery Knob Functionality in Chart Js

1πŸ‘

βœ…

It would be better to use that control. That said, you could do it Chart.js too. Here is a fair approximation (note that I’ve used jQuery for some parts, but you could do the same using plain javascript).

CSS

<style>
    .myChartWrapper {
        position: relative;
        display: inline-block;
    }

    .myChartValue {
        border: none;
        font-family: 'Helvetica';
        font-size: 20px;
        overflow: visible;
        width: 2em;
        white-space: nowrap;
        text-align: center;
        position: absolute;
        background-color: transparent;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
    }

        .myChartValue::-ms-clear {
            display: none;
        }
</style>

HTML

<div class="myChartWrapper">
    <canvas id="myChart"></canvas>
    <input id="myChartValue" class="myChartValue" />
</div>

Javascript

var value = 20;


var MAX = 200;
var STEP = 1;
var HALFSETCOLOR = "rgba(154, 225, 254, 1)";
var SETCOLOR = "rgba(134, 205, 234, 1)";
var UNSETCOLOR = "rgba(237, 237, 237, 1)";


var data = [];
for (var i = 0; i < MAX; i = i + STEP) {
    data.push({
        value: STEP,
        color: (i < value) ? SETCOLOR : UNSETCOLOR,
        label: i
    })
}


var canvas = document.getElementById("myChart");
var ctx = canvas.getContext("2d");
var myDoughnutChart = new Chart(ctx).Doughnut(data, {
    animation: false,
    segmentShowStroke: false,
    showTooltips: false
});

$("#myChartValue").val(value);


// half set the sectors
canvas.onmousedown = function (evt) {
    var activeSegments = myDoughnutChart.getSegmentsAtEvent(evt);
    if (activeSegments.length) {
        var value = Number(activeSegments[0].label);

        var crossed = false;
        myDoughnutChart.segments.forEach(function (segment) {
            if (Number(segment.label) >= value)
                crossed = true;

            if (!crossed && segment.fillColor !== SETCOLOR)
                segment.fillColor = HALFSETCOLOR;
            else if (crossed && segment.fillColor !== UNSETCOLOR)
                segment.fillColor = HALFSETCOLOR;
        })
        myDoughnutChart.update()
        myDoughnutChart.value = value;

        $("#myChartValue").val(value);
    }
};

canvas.onmousemove = function (evt) {
    if (myDoughnutChart.value !== undefined) {
        canvas.onmousedown(evt)
    }
}

// set / unset sectors
canvas.onmouseup = function () {
    var value = myDoughnutChart.value;
    if (value !== undefined) {
        var crossed = false;

        myDoughnutChart.segments.forEach(function (segment, i) {
            if (Number(segment.label) >= value)
                crossed = true;

            if (!crossed)
                segment.fillColor = SETCOLOR;
            else if (crossed)
                segment.fillColor = UNSETCOLOR;
        })

        myDoughnutChart.value = undefined;
        myDoughnutChart.update()
    }
};

$("#myChartValue").on("change", function () {
    myDoughnutChart.value = Number($("#myChartValue").val());
    canvas.onmouseup();
})

It could do with a bit of cleanup (like handling change in direction without lifting the mouse), but comes pretty close to the knob functionality without too much effort.


Fiddle – http://jsfiddle.net/rxrxLo33/


enter image description here

Leave a comment