Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent first/last bars from being cut off in a chart with time scale

Tags:

How do I prevent the first and last bars from being cut off (showing half)?

I need to show the short month names on the x-axis. I've tried playing around with various min/max settings, but I can't seem to get it right.

Example

var graphData = {
  dates: [
    '2016-06-01',
    '2016-07-01',
    '2016-08-01',
    '2016-09-01',
    '2016-10-01',
    '2016-11-01',
    '2016-12-01',
    '2017-01-01',
    '2017-02-01',
    '2017-03-01',
    '2017-04-01',
    '2017-05-01'
  ],
  wins: [23, 5, 13, 24, 8, 11, 23, 5, 13, 24, 8, 11],
  draws: [2, 1, 2, 0, 2, 2, 3, 1, 2, 4, 0, 1],
  losses: [3, 1, 2, 10, 8, 8, 3, 1, 2, 10, 8, 8],
  winRates: [50, 40, 72, 30, 46, 80, 50, 40, 72, 30, 46, 80]
};

var winsMax = Math.max.apply(Math, graphData.wins);
var lossesMax = Math.max.apply(Math, graphData.losses);

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
  type: "bar",
  data: {
    labels: graphData.dates.map((date) => moment(date)),
    datasets: [
      {
        type: "bar",
        backgroundColor: "green",
        hoverBackgroundColor: "green",
        data: graphData.wins,
        yAxisID: "winsAndLosses"
      },
      {
        type: "bar",
        backgroundColor: "red",
        hoverBackgroundColor: "red",
        data: graphData.losses.map((i) => -i),
        yAxisID: "winsAndLosses"
      },
      {
        type: "line",
        data: graphData.winRates,
        fill: true,
        backgroundColor: "gray",
        pointRadius: 0,
        pointHoverRadius: 0,
        yAxisID: "winRate"
      }
    ]
  },
  options: {
    legend: {
      display: false
    },
    scales: {
      xAxes: [{
        type: "time",
        time: {
          unit: "month",
          displayFormats: {
            month: "MMM"
          }
        },
        stacked: true,
        gridLines: {
          display: false
        },
        ticks: {
          callback: (label) => label.toUpperCase(),
          fontSize: 10     
        }
      }],
      yAxes: [
        {
          id: "winsAndLosses",
          stacked: true,
          ticks: {
            min: (lossesMax + 10) * -1,
            max: winsMax + 10,
            callback: (label) => Math.abs(label) // TODO: Localization (number formatting).
          },
          display: false
        },
        {
          id: "winRate",
          ticks: {
            min: 0,
            max: 100,
            stepSize: 10,
            callback: (label) => label + "%", // TODO: Localization (number formatting).
            fontSize: 10
          }
        }
      ]
    }
}
});
.myChartDiv {
  max-width: 800px;
  max-height: 400px;
}
<script src="https://npmcdn.com/chart.js@latest/dist/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<html>
  <body>
    <div class="myChartDiv">
      <canvas id="myChart" width="800" height="400"></canvas>
    </div>
  </body>
</html>
like image 567
glen-84 Avatar asked May 25 '17 15:05

glen-84


People also ask

Can you use a bar graph for time?

a Bar Graph. Bar graphs are used to compare things between different groups or to track changes over time. However, when trying to measure change over time, bar graphs are best when the changes are larger.

How do you separate bars in Excel?

Select the column to the right of the column where you want to place the split, and use the Split command. You can also split on both a row and a column. by selecting the cell below and to the right of where you want the split—then click Split.

How do you customize a bar graph?

Use the Chart Styles button to quickly change the color or style of the chart. Click the chart you want to change. In the upper-right corner, next to the chart, click Chart Styles. Click Color and pick the color scheme you want, or click Style and pick the option you want.


1 Answers

There's a setting called offset which seems to work for me:

xAxes: [{
     offset: true
  }]

var graphData = {
  dates: [
    '2016-06-01',
    '2016-07-01',
    '2016-08-01',
    '2016-09-01',
    '2016-10-01',
    '2016-11-01',
    '2016-12-01',
    '2017-01-01',
    '2017-02-01',
    '2017-03-01',
    '2017-04-01',
    '2017-05-01'
  ],
  wins: [23, 5, 13, 24, 8, 11, 23, 5, 13, 24, 8, 11],
  draws: [2, 1, 2, 0, 2, 2, 3, 1, 2, 4, 0, 1],
  losses: [3, 1, 2, 10, 8, 8, 3, 1, 2, 10, 8, 8],
  winRates: [50, 40, 72, 30, 46, 80, 50, 40, 72, 30, 46, 80]
};

var winsMax = Math.max.apply(Math, graphData.wins);
var lossesMax = Math.max.apply(Math, graphData.losses);

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
  type: "bar",
  data: {
    labels: graphData.dates.map((date) => moment(date)),
    datasets: [
      {
        type: "bar",
        backgroundColor: "green",
        hoverBackgroundColor: "green",
        data: graphData.wins,
        yAxisID: "winsAndLosses"
      },
      {
        type: "bar",
        backgroundColor: "red",
        hoverBackgroundColor: "red",
        data: graphData.losses.map((i) => -i),
        yAxisID: "winsAndLosses"
      },
      {
        type: "line",
        data: graphData.winRates,
        fill: true,
        backgroundColor: "gray",
        pointRadius: 0,
        pointHoverRadius: 0,
        yAxisID: "winRate"
      }
    ]
  },
  options: {
    legend: {
      display: false
    },
    scales: {
      xAxes: [{
        type: "time",
        time: {
          unit: "month",
          displayFormats: {
            month: "MMM"
          }
        },
        stacked: true,
        gridLines: {
          display: false
        },
        ticks: {
          callback: (label) => label.toUpperCase(),
          fontSize: 10     
        },
        offset:true
      }],
      yAxes: [
        {
          id: "winsAndLosses",
          stacked: true,
          ticks: {
            min: (lossesMax + 10) * -1,
            max: winsMax + 10,
            callback: (label) => Math.abs(label) // TODO: Localization (number formatting).
          },
          display: false
        },
        {
          id: "winRate",
          ticks: {
            min: 0,
            max: 100,
            stepSize: 10,
            callback: (label) => label + "%", // TODO: Localization (number formatting).
            fontSize: 10
          }
        }
      ]
    }
}
});
.myChartDiv {
  max-width: 800px;
  max-height: 400px;
}
<script src="https://npmcdn.com/chart.js@latest/dist/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<html>
  <body>
    <div class="myChartDiv">
      <canvas id="myChart" width="800" height="400"></canvas>
    </div>
  </body>
</html>
like image 112
AMT Avatar answered Oct 16 '22 10:10

AMT