cee_four
cee_four

Reputation: 44

Can you set bar thickness to align with the x-axis scale in ChartJS?

I'd like to highlight some sections of a line chart, using a bar chart plotted on the same axes in ChartJS. The barThickness property only seems to work in pixels. Ideally I'd like to be able to say "this bar should go from yMin to yMax (this part is easy), and from 20 to 40 on the X axis".

Using ChartJS 3.5.1, the below snippet is where I'm at. I've got the line and bars in, just need to figure out how to set the bar's width.

enter image description here

const lineData = [
    { "x": 1, "y": 31 }, { "x": 2, "y": 94 }, { "x": 3, "y": 44 }, { "x": 4, "y": 4 }, { "x": 5, "y": 60 }, { "x": 6, "y": 4 }, { "x": 7, "y": 24 }, { "x": 8, "y": 20 }, { "x": 9, "y": 54 }, { "x": 10, "y": 63 }, { "x": 11, "y": 87 }, { "x": 12, "y": 59 }, { "x": 13, "y": 17 }, { "x": 14, "y": 30 }, { "x": 15, "y": 23 }, { "x": 16, "y": 72 }, { "x": 17, "y": 38 }, { "x": 18, "y": 14 }, { "x": 19, "y": 47 }, { "x": 20, "y": 28 }, { "x": 21, "y": 6 }, { "x": 22, "y": 89 }, { "x": 23, "y": 99 }, { "x": 24, "y": 30 }, { "x": 25, "y": 44 }, { "x": 26, "y": 85 }, { "x": 27, "y": 16 }, { "x": 28, "y": 55 }, { "x": 29, "y": 34 }, { "x": 30, "y": 23 }, { "x": 31, "y": 95 }, { "x": 32, "y": 5 }, { "x": 33, "y": 82 }, { "x": 34, "y": 14 }, { "x": 35, "y": 11 }, { "x": 36, "y": 82 }, { "x": 37, "y": 30 }, { "x": 38, "y": 79 }, { "x": 39, "y": 13 }, { "x": 40, "y": 4 }, { "x": 41, "y": 86 }, { "x": 42, "y": 15 }, { "x": 43, "y": 51 }, { "x": 44, "y": 70 }, { "x": 45, "y": 1 }, { "x": 46, "y": 91 }, { "x": 47, "y": 83 }, { "x": 48, "y": 90 }, { "x": 49, "y": 42 }, { "x": 50, "y": 19 }, { "x": 51, "y": 57 }, { "x": 52, "y": 32 }, { "x": 53, "y": 2 }, { "x": 54, "y": 43 }, { "x": 55, "y": 64 }, { "x": 56, "y": 76 }, { "x": 57, "y": 66 }, { "x": 58, "y": 30 }, { "x": 59, "y": 40 }, { "x": 60, "y": 10 }, { "x": 61, "y": 92 }, { "x": 62, "y": 97 }, { "x": 63, "y": 28 }, { "x": 64, "y": 17 }, { "x": 65, "y": 85 }, { "x": 66, "y": 80 }, { "x": 67, "y": 74 }, { "x": 68, "y": 91 }, { "x": 69, "y": 85 }, { "x": 70, "y": 81 }, { "x": 71, "y": 100 }, { "x": 72, "y": 10 }, { "x": 73, "y": 63 }, { "x": 74, "y": 3 }, { "x": 75, "y": 48 }, { "x": 76, "y": 95 }, { "x": 77, "y": 2 }, { "x": 78, "y": 51 }, { "x": 79, "y": 56 }, { "x": 80, "y": 50 }, { "x": 81, "y": 25 }, { "x": 82, "y": 23 }, { "x": 83, "y": 41 }, { "x": 84, "y": 61 }, { "x": 85, "y": 27 }, { "x": 86, "y": 38 }, { "x": 87, "y": 81 }, { "x": 88, "y": 16 }, { "x": 89, "y": 82 }, { "x": 90, "y": 73 }, { "x": 91, "y": 34 }, { "x": 92, "y": 47 }, { "x": 93, "y": 84 }, { "x": 94, "y": 15 }, { "x": 95, "y": 47 }, { "x": 96, "y": 82 }, { "x": 97, "y": 16 }, { "x": 98, "y": 31 }, { "x": 99, "y": 99 }, { "x": 100, "y": 57 }
];

const barData = [
    { x: 30, y: 200 }, { x: 70, y: 200 }
];

const data = {
    datasets: [
        {
            label: 'Overlay',
            type: 'bar',
            backgroundColor: "rgba( 0, 0, 255, 0.4 )",
            data: barData
        }, {
            label: 'Line',
            data: lineData,
            borderColor: '#FFDE03',
            backgroundColor: '#FFDE03',
            borderWidth: 2,
            pointRadius: 0,
            fill: false
        }]
}

const config = {
    type: 'line',
    data: data,
    options: {
        parsing: false,
        normalized: true,
        scales: {
            xAxes: {
                type: 'linear',
                gridLines: {
                    display: true,
                    color: "#555"
                },
                position: 'bottom'
            },
            yAxis: {
                min: 0,
                max: lineData.reduce(function (prev, curr) { return prev.y > curr.y ? prev : curr; })["y"],
                gridLines: {
                    display: true,
                    color: "#555"
                }
            }
        }
    }
};

var myChart = new Chart(
    document.getElementById('myChart'),
    config
);
<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    <canvas id="myChart"></canvas>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</body>

</html>

Thanks for any help.

Upvotes: 0

Views: 350

Answers (1)

LeeLenalee
LeeLenalee

Reputation: 31361

You need to set the barPercentage and categoryPercentage in the bar dataset to 1:

const lineData = [
    { "x": 1, "y": 31 }, { "x": 2, "y": 94 }, { "x": 3, "y": 44 }, { "x": 4, "y": 4 }, { "x": 5, "y": 60 }, { "x": 6, "y": 4 }, { "x": 7, "y": 24 }, { "x": 8, "y": 20 }, { "x": 9, "y": 54 }, { "x": 10, "y": 63 }, { "x": 11, "y": 87 }, { "x": 12, "y": 59 }, { "x": 13, "y": 17 }, { "x": 14, "y": 30 }, { "x": 15, "y": 23 }, { "x": 16, "y": 72 }, { "x": 17, "y": 38 }, { "x": 18, "y": 14 }, { "x": 19, "y": 47 }, { "x": 20, "y": 28 }, { "x": 21, "y": 6 }, { "x": 22, "y": 89 }, { "x": 23, "y": 99 }, { "x": 24, "y": 30 }, { "x": 25, "y": 44 }, { "x": 26, "y": 85 }, { "x": 27, "y": 16 }, { "x": 28, "y": 55 }, { "x": 29, "y": 34 }, { "x": 30, "y": 23 }, { "x": 31, "y": 95 }, { "x": 32, "y": 5 }, { "x": 33, "y": 82 }, { "x": 34, "y": 14 }, { "x": 35, "y": 11 }, { "x": 36, "y": 82 }, { "x": 37, "y": 30 }, { "x": 38, "y": 79 }, { "x": 39, "y": 13 }, { "x": 40, "y": 4 }, { "x": 41, "y": 86 }, { "x": 42, "y": 15 }, { "x": 43, "y": 51 }, { "x": 44, "y": 70 }, { "x": 45, "y": 1 }, { "x": 46, "y": 91 }, { "x": 47, "y": 83 }, { "x": 48, "y": 90 }, { "x": 49, "y": 42 }, { "x": 50, "y": 19 }, { "x": 51, "y": 57 }, { "x": 52, "y": 32 }, { "x": 53, "y": 2 }, { "x": 54, "y": 43 }, { "x": 55, "y": 64 }, { "x": 56, "y": 76 }, { "x": 57, "y": 66 }, { "x": 58, "y": 30 }, { "x": 59, "y": 40 }, { "x": 60, "y": 10 }, { "x": 61, "y": 92 }, { "x": 62, "y": 97 }, { "x": 63, "y": 28 }, { "x": 64, "y": 17 }, { "x": 65, "y": 85 }, { "x": 66, "y": 80 }, { "x": 67, "y": 74 }, { "x": 68, "y": 91 }, { "x": 69, "y": 85 }, { "x": 70, "y": 81 }, { "x": 71, "y": 100 }, { "x": 72, "y": 10 }, { "x": 73, "y": 63 }, { "x": 74, "y": 3 }, { "x": 75, "y": 48 }, { "x": 76, "y": 95 }, { "x": 77, "y": 2 }, { "x": 78, "y": 51 }, { "x": 79, "y": 56 }, { "x": 80, "y": 50 }, { "x": 81, "y": 25 }, { "x": 82, "y": 23 }, { "x": 83, "y": 41 }, { "x": 84, "y": 61 }, { "x": 85, "y": 27 }, { "x": 86, "y": 38 }, { "x": 87, "y": 81 }, { "x": 88, "y": 16 }, { "x": 89, "y": 82 }, { "x": 90, "y": 73 }, { "x": 91, "y": 34 }, { "x": 92, "y": 47 }, { "x": 93, "y": 84 }, { "x": 94, "y": 15 }, { "x": 95, "y": 47 }, { "x": 96, "y": 82 }, { "x": 97, "y": 16 }, { "x": 98, "y": 31 }, { "x": 99, "y": 99 }, { "x": 100, "y": 57 }
];

const barData = [
    { x: 30, y: 200 }, { x: 70, y: 200 }
];

const data = {
  datasets: [{
    label: 'Overlay',
    type: 'bar',
    backgroundColor: "rgba( 0, 0, 255, 0.4 )",
    data: barData,
    barPercentage: 1,
    categoryPercentage: 1
  }, {
    label: 'Line',
    data: lineData,
    borderColor: '#FFDE03',
    backgroundColor: '#FFDE03',
    borderWidth: 2,
    pointRadius: 0,
    fill: false
  }]
}

const config = {
  type: 'line',
  data: data,
  options: {
    parsing: false,
    normalized: true,
    scales: {
      xAxes: {
        type: 'linear',
        gridLines: {
          display: true,
          color: "#555"
        },
        position: 'bottom'
      },
      yAxis: {
        min: 0,
        max: lineData.reduce(function(prev, curr) {
          return prev.y > curr.y ? prev : curr;
        })["y"],
        gridLines: {
          display: true,
          color: "#555"
        }
      }
    }
  }
};

var myChart = new Chart(
  document.getElementById('myChart'),
  config
);
<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
  <canvas id="myChart"></canvas>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</body>

</html>

EDIT:

From your comment you can best make use of the annotation plugin

Example:

const lineData = [
    { "x": 1, "y": 31 }, { "x": 2, "y": 94 }, { "x": 3, "y": 44 }, { "x": 4, "y": 4 }, { "x": 5, "y": 60 }, { "x": 6, "y": 4 }, { "x": 7, "y": 24 }, { "x": 8, "y": 20 }, { "x": 9, "y": 54 }, { "x": 10, "y": 63 }, { "x": 11, "y": 87 }, { "x": 12, "y": 59 }, { "x": 13, "y": 17 }, { "x": 14, "y": 30 }, { "x": 15, "y": 23 }, { "x": 16, "y": 72 }, { "x": 17, "y": 38 }, { "x": 18, "y": 14 }, { "x": 19, "y": 47 }, { "x": 20, "y": 28 }, { "x": 21, "y": 6 }, { "x": 22, "y": 89 }, { "x": 23, "y": 99 }, { "x": 24, "y": 30 }, { "x": 25, "y": 44 }, { "x": 26, "y": 85 }, { "x": 27, "y": 16 }, { "x": 28, "y": 55 }, { "x": 29, "y": 34 }, { "x": 30, "y": 23 }, { "x": 31, "y": 95 }, { "x": 32, "y": 5 }, { "x": 33, "y": 82 }, { "x": 34, "y": 14 }, { "x": 35, "y": 11 }, { "x": 36, "y": 82 }, { "x": 37, "y": 30 }, { "x": 38, "y": 79 }, { "x": 39, "y": 13 }, { "x": 40, "y": 4 }, { "x": 41, "y": 86 }, { "x": 42, "y": 15 }, { "x": 43, "y": 51 }, { "x": 44, "y": 70 }, { "x": 45, "y": 1 }, { "x": 46, "y": 91 }, { "x": 47, "y": 83 }, { "x": 48, "y": 90 }, { "x": 49, "y": 42 }, { "x": 50, "y": 19 }, { "x": 51, "y": 57 }, { "x": 52, "y": 32 }, { "x": 53, "y": 2 }, { "x": 54, "y": 43 }, { "x": 55, "y": 64 }, { "x": 56, "y": 76 }, { "x": 57, "y": 66 }, { "x": 58, "y": 30 }, { "x": 59, "y": 40 }, { "x": 60, "y": 10 }, { "x": 61, "y": 92 }, { "x": 62, "y": 97 }, { "x": 63, "y": 28 }, { "x": 64, "y": 17 }, { "x": 65, "y": 85 }, { "x": 66, "y": 80 }, { "x": 67, "y": 74 }, { "x": 68, "y": 91 }, { "x": 69, "y": 85 }, { "x": 70, "y": 81 }, { "x": 71, "y": 100 }, { "x": 72, "y": 10 }, { "x": 73, "y": 63 }, { "x": 74, "y": 3 }, { "x": 75, "y": 48 }, { "x": 76, "y": 95 }, { "x": 77, "y": 2 }, { "x": 78, "y": 51 }, { "x": 79, "y": 56 }, { "x": 80, "y": 50 }, { "x": 81, "y": 25 }, { "x": 82, "y": 23 }, { "x": 83, "y": 41 }, { "x": 84, "y": 61 }, { "x": 85, "y": 27 }, { "x": 86, "y": 38 }, { "x": 87, "y": 81 }, { "x": 88, "y": 16 }, { "x": 89, "y": 82 }, { "x": 90, "y": 73 }, { "x": 91, "y": 34 }, { "x": 92, "y": 47 }, { "x": 93, "y": 84 }, { "x": 94, "y": 15 }, { "x": 95, "y": 47 }, { "x": 96, "y": 82 }, { "x": 97, "y": 16 }, { "x": 98, "y": 31 }, { "x": 99, "y": 99 }, { "x": 100, "y": 57 }
];

const barData = [
    { x: 30, y: 200 }, { x: 70, y: 200 }
];

const data = {
  datasets: [{
    label: 'Line',
    data: lineData,
    borderColor: '#FFDE03',
    backgroundColor: '#FFDE03',
    borderWidth: 2,
    pointRadius: 0,
    fill: false
  }]
}

const config = {
  type: 'line',
  data: data,
  options: {
    parsing: false,
    normalized: true,
    scales: {
      xAxes: {
        type: 'linear',
        gridLines: {
          display: true,
          color: "#555"
        },
        position: 'bottom'
      },
      yAxis: {
        min: 0,
        max: lineData.reduce(function(prev, curr) {
          return prev.y > curr.y ? prev : curr;
        })["y"],
        gridLines: {
          display: true,
          color: "#555"
        }
      }
    },
    plugins: {
        annotation: {
        annotations: {
          box1: {
            type: 'box',
            drawTime: 'beforeDraw',
            xScaleID: 'xAxes',
            yScaleID: 'yAxis',
            backgroundColor: 'rgba( 0, 0, 255, 0.4 )',
            xMin: 10,
            xMax: 50,
            yMin: 0,
            yMax: 100,
          }
        }
      }
    }
  }
};

var myChart = new Chart(
  document.getElementById('myChart'),
  config
);
<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
  <canvas id="myChart"></canvas>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/1.0.2/chartjs-plugin-annotation.js"></script>
</body>

</html>

Upvotes: 1

Related Questions