JSFiddle - React, Tailwind, and code Playground

by norbiu

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.1/Chart.min.js"></script>
<p>
    <button data-bind="click: sortBar">Sort</button>
</p>

<div class="container">
    <canvas width="" data-bind="chartType: 'Bar', chartData: sales, chartOptions: barOptions"></canvas>
</div>
    
    <br>

<div class="container">
    <canvas width="" data-bind="chartType: 'Bar', chartData: sales2, chartOptions: barOptions"></canvas>
</div>

CSS

.container {
    border: 2px solid;
    width: 500px;
}

JavaScript

ko.bindingHandlers.chartType = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        if (!allBindings.has('chartData')) {
            throw Error('chartType must be used in conjunction with chartData and (optionally) chartOptions');
        }
    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
      var ctx = element.getContext('2d'),
        type = ko.unwrap(valueAccessor()),
        data = ko.toJS(allBindings.get('chartData')),
        options = ko.unwrap(allBindings.get('chartOptions')) || {};

      if (chart) {
        console.debug(chart)
        chart.destroy();
        delete chart;
      }

      if (Object.keys(data).length != 0) {
        var chart = new Chart(ctx)[type](data, options);
      }
    }
};

ko.bindingHandlers.chartData = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        if (!allBindings.has('chartType')) {
            throw Error('chartData must be used in conjunction with chartType and (optionally) chartOptions');
        }
    }
};

ko.bindingHandlers.chartOptions = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        if (!allBindings.has('chartData') || !allBindings.has('chartType')) {
            throw Error('chartOptions must be used in conjunction with chartType and chartData');
        }
    }
};

var model = {
    barOptions: {
        responsive: true,
         maintainAspectRatio: true,
         scaleShowGridLines : true,
         scaleShowLabels: true
    },
    sales: ko.observable({
        labels: ['A really really long label', 'Another long labe', 'A third label that is long', 'Q4', 'Q5', 'Q6'],
        datasets: [{
            label: 'Helados',
            fillColor: '#152491',
            data: [70, 32, 6, 23, 63, 43]
        }]
    }),
    sales2: ko.observable({
        labels: ['A really l..', 'Another lo..', 'A third la..', 'Q4', 'Q5', 'Q6'],
    ...