Q:

Customizing Chart.js

So I've been trying to understand the documentation for Chart.js but it's not actually friendly for new people to understand how you can customize certain stuff.
I have installed the plugin but it's not customizable as I want to have it, I tried using CSS but since it's a canvas you can't really do much.
I'm trying to achieve this design and add data from my mysql database and display it on the chart, I can understand how to do the rest apart from the designing the chart.
What I'm trying to achieve.

A:

I think that the closest you can get with chart.js and rounded borders is using this answer: https://stackoverflow.com/a/43281198/10387396. 
But it doesn't work pretty well with negative values. 

Chart.helpers.drawRoundedTopRectangle = function(ctx, x, y, width, height, radius) {
  ctx.beginPath();
  ctx.moveTo(x + radius, y);
  // top right corner
  ctx.lineTo(x + width - radius, y);
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
  // bottom right   corner
  ctx.lineTo(x + width, y + height);
  // bottom left corner
  ctx.lineTo(x, y + height);
  // top left   
  ctx.lineTo(x, y + radius);
  ctx.quadraticCurveTo(x, y, x + radius, y);
  ctx.closePath();
};

Chart.elements.RoundedTopRectangle = Chart.elements.Rectangle.extend({
  draw: function() {
    var ctx = this._chart.ctx;
    var vm = this._view;
    var left, right, top, bottom, signX, signY, borderSkipped;
    var borderWidth = vm.borderWidth;

    if (!vm.horizontal) {
      // bar
      left = vm.x - vm.width / 2;
      right = vm.x + vm.width / 2;
      top = vm.y;
      bottom = vm.base;
      signX = 1;
      signY = bottom > top? 1: -1;
      borderSkipped = vm.borderSkipped || 'bottom';
    } else {
      // horizontal bar
      left = vm.base;
      right = vm.x;
      top = vm.y - vm.height / 2;
      bottom = vm.y + vm.height / 2;
      signX = right > left? 1: -1;
      signY = 1;
      borderSkipped = vm.borderSkipped || 'left';
    }

    // Canvas doesn't allow us to stroke inside the width so we can
    // adjust the sizes to fit if we're setting a stroke on the line
    if (borderWidth) {
      // borderWidth shold be less than bar width and bar height.
      var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
      borderWidth = borderWidth > barSize? barSize: borderWidth;
      var halfStroke = borderWidth / 2;
      // Adjust borderWidth when bar top position is near vm.base(zero).
      var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);
      var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);
      var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);
      var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);
      // not become a vertical line?
      if (borderLeft !== borderRight) {
        top = borderTop;
        bottom = borderBottom;
      }
      // not become a horizontal line?
      if (borderTop !== borderBottom) {
        left = borderLeft;
        right = borderRight;
      }
    }

    // calculate the bar width and roundess
    var barWidth = Math.abs(left - right);
    var roundness = this._chart.config.options.barRoundness || 0.5;
    var radius = barWidth * roundness * 0.5;

    // keep track of the original top of the bar
    var prevTop = top;

    // move the top down so there is room to draw the rounded top
    top = prevTop + radius;
    var barRadius = top - prevTop;

    ctx.beginPath();
    ctx.fillStyle = vm.backgroundColor;
    ctx.strokeStyle = vm.borderColor;
    ctx.lineWidth = borderWidth;

    // draw the rounded top rectangle
    Chart.helpers.drawRoundedTopRectangle(ctx, left, (top - barRadius + 1), barWidth, bottom - prevTop, barRadius);

    ctx.fill();
    if (borderWidth) {
      ctx.stroke();
    }

    // restore the original top value so tooltips and scales still work
    top = prevTop;
  },
});

Chart.defaults.roundedBar = Chart.helpers.clone(Chart.defaults.bar);

Chart.controllers.roundedBar = Chart.controllers.bar.extend({
  dataElementType: Chart.elements.RoundedTopRectangle
});

//*********//
const d1=  [65, 59, 80, 81,-40, 56, 55, 40 ];
const setColor = data => data < 0 ? '#ff4433': '#3377ee';

var data = {
    labels: ["January", "February", "March", "April", "May", "June", "July", "August"],
    datasets: [
        {
            label: "My First dataset",
            backgroundColor: d1.map(setColor),
            borderColor: d1.map(setColor),
            data: d1
        },
    ],
};

var options = {
    scaleBeginAtZero: false,
    responsive: true,
    barRoundness: 1,
    scales: {
      yAxes: [{
        ticks: {
          suggestedMin: -70,
          suggestedMax: 100
        }
      }]
    }
};

const ctx = "myChart";
const chart = new Chart(ctx, { type: 'roundedBar', data, options });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<canvas id="myChart" width="250" height="100"></canvas>

With Echarts it's a bit easier to do that. 

const chart = echarts.init(document.getElementById('main'));
const d1 =  [65, 59, 80, 81,-40, 56, 55, 40 ];

// specify chart configuration item and data
const option = {

  tooltip: {},
  legend: {
    data:['Sales']
  },
  xAxis: {
    data: ["January", "February", "March", "April", "May", "June", "July", "August"]
  },
  yAxis: {},
  series: [{
    name: 'Sales',
    type: 'bar',
    barWidth: 20,
    data: d1.map(item => {
      return {
        value: item,
        itemStyle: {
          color: item > 0 ? '#2196F3' : '#F44336',
          barBorderRadius: item > 0 ? [100, 100, 0 ,0] 
                                    : [0 ,0 ,100, 100]
        }
      }
    }),
  }]
};

// use configuration item and data specified to show chart
chart.setOption(option);
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.1.0/echarts.min.js"></script>
<div id="main" style="width: 100vw;height:400px;"></div>

If you don't care about rounded borders, but only styling the negative values, you can map your data in order to create an array of colors depending on its value:
const chartData = [65, 59, 80, 81,-40, 56, 55, 40 ];
const data = {
  labels: ["January", "February", "March", "April", "May", "June", "July", "August"],
  datasets: [
    {
        label: "My First dataset",
        backgroundColor: chartData.map(setColor),
        borderColor: chartData.map(setColor),
        data: chartData
    },
  ],
};
// If data < 0 return a red color.
const setColor = data => data < 0 ? '#ff4433': '#3377ee';

Result: 

const d1=  [65, 59, 80, 81,-40, 56, 55, 40 ];
const setColor = data => data < 0 ? '#ff4433': '#3377ee';

var data = {
    labels: ["January", "February", "March", "April", "May", "June", "July", "August"],
    datasets: [
        {
            label: "My First dataset",
            backgroundColor: d1.map(setColor),
            borderColor: d1.map(setColor),
            data: d1
        },
    ],
};

var options = {
    scaleBeginAtZero: false,
    responsive: true,
    scales: {
      yAxes: [{
        ticks: {
          suggestedMin: -60,
          suggestedMax: 100
        }
      }]
    }
};

const ctx = "myChart";
const chart = new Chart(ctx, { type: 'bar', data, options });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<canvas id="myChart" width="250" height="100"></canvas>

