Category scale on Y-axis and time on x-axis in bubble chart in Chartjs
Asked Answered
R

2

6

Is is possible to have a category scale on y-axis in Bubble chart? I am trying to create a bubble chart where on y-axis-> days of the week and x-axis-> time in "hh:mm a" format. (only because Chart.js allows timescale only on the x axis). Please suggest how I can change this question to be more helpful to more people.

<body><canvas id="bubble" width="400" height="400"></canvas></body>

<script>


$(function() {
  Chart.defaults.global.defaultFontColor = '#fff'
  var bubbleBackgroundColor = function() {
            return 'rgba(255, 206, 86, 0.2)'
  };
  var bubbleBorderColor = function() {
            return 'rgba(255, 206, 86, 1)'
  };

  var bubbleChartData = {
    animation: {
      duration: 10000
    },
    // Documentation says the tick values tick.min & tick.max must be in the Labels array. So thats what I have below
    labels: ["Mon", "Tue", "wed", "Thu"],
    datasets: [{
      label: "Requests and bookings",
      fill: false,
      lineTension: 0.1,
      backgroundColor: bubbleBackgroundColor(),
      borderColor: bubbleBorderColor(),
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: "rgba(75,192,192,1)",
      pointBackgroundColor: "#fff",
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: "rgba(153, 102, 155, 0.2)",
      pointHoverBorderColor: "rgba(153, 102, 155, 1)",
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      // how would the data change ...how can the numbers for y be replaced with strings
      data:[{x: 2,y: 0,r: 15},{x: 3,y: 1,r: 19}, {x: 5,y: 2,r: 15}, {x: 4, y: 3,r: 18}]
    }]
  };


  var ctx = document.getElementById('bubble');
  var bubble = new Chart(ctx, {
    type: 'bubble',
    data: bubbleChartData,
    options: {
      responsive: true,
      title: {
        display: true,
        text:'Weekly activity'
      },
      options: {
        scales: {
          yAxes: [{
              // will this create y-axis with days of week?
              type: 'Category',
              position: 'bottom',
              ticks: {
                ticks.min: "Mon",
                ticks.max: "Thu"
              }
          }],
          xAxes: [{
              type: 'time',
              time: {
                  displayFormats: {
                      minute: 'hh:mm a'
                  }
              }
          }]
        }
      }
    }
  });
});
</script>
Romain answered 4/7, 2016 at 9:37 Comment(0)
A
2

This is possible in ChartJS, and will work with the given code once a couple issues are fixed:

  1. The options config, containing the scales, is within another options object. This means the options in this second layer will not take effect.

Changing this

options: {
  responsive: true,
  title: {
    display: true,
    text:'Weekly activity'
  },
  options: {
    scales: {
      yAxes: [{
          // will this create y-axis with days of week?
          type: 'Category',
          position: 'bottom',
          ticks: {
            ticks.min: "Mon",
            ticks.max: "Thu"
          }
      }],
      xAxes: [{
          type: 'time',
          time: {
              displayFormats: {
                  minute: 'hh:mm a'
              }
          }
      }]
    }
  }
}

to this (by removing the excess options block)

options: {
  responsive: true,
  title: {
  display: true,
  text:'Weekly activity'
  },
  scales: {
    yAxes: [{
        // will this create y-axis with days of week?
        type: 'Category',
        position: 'bottom',
        ticks: {
          ticks.min: "Mon",
          ticks.max: "Thu"
        }
    }],
    xAxes: [{
        type: 'time',
        time: {
            displayFormats: {
                minute: 'hh:mm a'
            }
        }
    }]
  }
}

remedies this issue.

  1. The scale type of the x-axis is Category, which is not a recognized ChartJS scale type only because of the capital letter. Renaming the type to its lowercase partner, category, allows it to be recognized by ChartJS.

  2. The tick options are set incorrectly, and are also invalid property names, which stops ChartJS from functioning.

Documentation says the tick values tick.min & tick.max must be in the Labels array.

As of now, ticks.min and ticks.max are optional for category scales. However, if you would like to continue to use ticks.min and ticks.max, you could do this:

Change

ticks: {
  ticks.min: "Mon",
  ticks.max: "Thu"
}

to

ticks: {
  min: "Mon",
  max: "Thu"
}

Although it was not as clear as it could have been in the official documentation, this is what is meant when the options ticks.min and ticks.max are specified - instead of having the previous ticks.ticks.min, we can now access our settings at ticks.min.

  1. The labels set for the category axis currently affect all axes instead of only the y (category) axis. We can fix this by setting yLabels instead of labels, as shown in the documentation.

Change

labels: ["Mon", "Tue", "wed", "Thu"],

to

yLabels: ["Mon", "Tue", "wed", "Thu"],
  1. Having both the x and y axes on the bottom produces a garbled chart. This can be remedied by moving the y-axis back to the left.

Change

type: 'category',
position: 'bottom',
ticks: {

to

type: 'category',
position: 'left',
ticks: {

It now looks something like this:

Picture of the codepen sample

We now have a working bubble chart! The y-axis shows days of the week, and the x-axis shows a time value formatted in 'hh:mm a'. Here is the sample completed codepen: http://codepen.io/albinodrought/pen/VmNwoj


In response to the reasoning for this way of graphing,

(only because Chart.js allows timescale only on the x axis)

There also seems to be workarounds for plotting timescale values on the y-axis: ChartJS issue #2791

Mainly, setting the y-value of your datapoints to a time-formattable value (epoch), and then changing the callback of your y-axis to format those values. See the ChartJS docs for setting tick callbacks.

Ayer answered 21/12, 2016 at 19:12 Comment(3)
for some reason i currently do not understand, the above mentioned solutions has one drawback: The data is not being matched based on the y-axis, the weekdays. When you go to codepen.io and change just the first data object from {x: 2,y: 0,r: 15} to {x: 2,y: 4,r: 15} the data point will remain in the first "row" near Monday, but it should change to Thursday. I am currently coping with this issue, too, and didn't find any workaround.Stagy
@AlbinoDrought: Hi, thanks for your solution, is there anyway to use x: moment(something) ? I didn't manage to have the proper x data altough my moment object is right.Cate
In the codepen example if the y is changed to the string equivalent it works for me. ie {x: 2,y: 'Mon',r: 15}Hesitation
H
0

Please try data:

[ {x: '2016-05-11 12:00:00', y: 'Mon', r: 15}, {x: '2016-05-11 20:00:00', y: 'Sat', r: 20}, {x: '2016-05-11 05:00:00', y: 'Wed', r: 5} ]

Instead of data:

[{x: 2,y: 0,r: 15},{x: 3,y: 1,r: 19}, {x: 5,y: 2,r: 15}, {x: 4, y: 3,r: 18}]
Hierogram answered 18/6, 2018 at 10:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.