1
votes

Take a moment to examine the bubble chart below. That is an image that I have created in Illustrator. I am now attempting to duplicate the bubble chart with dc.js.

bubble chart image

By dissecting the code for the example graphs given on this page, I have attempted to achieve the above. Here is my code:

'use strict'

// define bubble chart and get a handle
var referralsChart = dc.bubbleChart('#referrals-bubble-chart');

// load the csv data
d3.csv("data/data.csv", function (data) {
    /* since its a csv file we need to format the data a bit */
    var dateFormat   = d3.time.format("%d/%m/%Y");
    var numberFormat = d3.format(".2f");

    data.forEach(function (d) {
        d.dd    = dateFormat.parse(d.date);
    });

    // create cross-filter dimensions and groups
    // see the crossfilter api at (https://github.com/square/crossfilter/wiki/API-Reference) for reference.
    var referralsChartXFilter = crossfilter(data);
    var referralsChartXGroups = referralsChartXFilter.groupAll();

    // dimension by full date
    var dateDimension = referralsChartXFilter.dimension(function (d) {
        return d.dd.getMonth();
    });

    var diagnosisDimension = referralsChartXFilter.dimension(function (d) {
        return d.referredfor;
    });

    // dimension group
    var diagnosisDimensionGroup = diagnosisDimension.group();

    // define the referrals bubble chart attributes
    referralsChart
      .width(700)
      .height(400)
      .transitionDuration(1500) // (optional) define chart transition duration, :default = 750
      .margins({top: 10, right: 50, bottom: 30, left: 40})
      .dimension(dateDimension)
      //Bubble chart expect the groups are reduced to multiple values which would then be used
      //to generate x, y, and radius for each key (bubble) in the group
      .group(diagnosisDimensionGroup)
      .colors(colorbrewer.RdYlGn[9]) // (optional) define color function or array for bubbles
      .colorDomain([0, 100]) //(optional) define color domain to match your data domain if you want to bind data or color
      //##### Accessors
      //Accessor functions are applied to each value returned by the grouping
      //
      //* `.colorAccessor` The returned value will be mapped to an internal scale to determine a fill color
      //* `.keyAccessor` Identifies the `X` value that will be applied against the `.x()` to identify pixel location
      //* `.valueAccessor` Identifies the `Y` value that will be applied agains the `.y()` to identify pixel location
      //* `.radiusValueAccessor` Identifies the value that will be applied agains the `.r()` determine radius size, by default this maps linearly to [0,100]
      .colorAccessor(function (d) {
        return d.value / 100
      })
      .keyAccessor(function (p) {
        return p.value
      })
      .valueAccessor(function (p) {
        return p.value
      })
      .radiusValueAccessor(function (p) {
        return p.value
      })
      .maxBubbleRelativeSize(0.1)
      .x(d3.scale.linear().domain([0, 5000]))
      .y(d3.scale.linear().domain([0, 5000]))
      .r(d3.scale.linear().domain([0, 4000]))
      //##### Elastic Scaling
      //`.elasticX` and `.elasticX` determine whether the chart should rescale each axis to fit data.
      //The `.yAxisPadding` and `.xAxisPadding` add padding to data above and below their max values in the same unit domains as the Accessors.
      .elasticY(true)
      .elasticX(true)
      .yAxisPadding(100)
      .xAxisPadding(500)
      .renderHorizontalGridLines(true) // (optional) render horizontal grid lines, :default=false
      .renderVerticalGridLines(true) // (optional) render vertical grid lines, :default=false
      .xAxisLabel('Date') // (optional) render an axis label below the x axis
      .yAxisLabel('Referrals') // (optional) render a vertical axis lable left of the y axis
      //#### Labels and  Titles
      //Labels are displaed on the chart for each bubble. Titles displayed on mouseover.
      .renderLabel(true) // (optional) whether chart should render labels, :default = true
      .label(function (p) {
        return p.key;
      })
      .renderTitle(true) // (optional) whether chart should render titles, :default = false
      .title(function (p) {
          return [p.key,
                 "Referrals: " + numberFormat(p.value.absGain),
                 "Index Gain in Percentage: " + numberFormat(p.value.percentageGain) + "%",
                 "Fluctuation / Index Ratio: " + numberFormat(p.value.fluctuationPercentage) + "%"]
                 .join("\n");
      })
      //#### Customize Axis
      //Set a custom tick format. Note `.yAxis()` returns an axis object, so any additional method chaining applies to the axis, not the chart.
      .yAxis().tickFormat(function (v) {
          return v + "%";
      });

      dc.renderAll();
});

The above code works in the sense that I get Bubbles plotted, but the x-axis and y-axis show wrong scales. Here is a screenshot of what I'm getting with the above code:

code bubble chart

What I'd like is date by month plotted against the x-axis (Jan, Feb, Mar ...etc) and on the y-axis the data range for the referrals.

The csv data being passed can be found here.

I know that it is the two lines below that I need to edit, but I'm not sure how to pass my data to them.

  .x(d3.scale.linear().domain([0, 5000]))
  .y(d3.scale.linear().domain([0, 5000]))
  .r(d3.scale.linear().domain([0, 4000]))
1

1 Answers

3
votes

You will want to set .x to a d3.time.scale

https://github.com/dc-js/dc.js/blob/master/web/docs/api-latest.md#xxscale---mandatory https://github.com/mbostock/d3/wiki/Time-Scales

It looks like you also want to set .r to reflect your data.

Also, you probably don't need to set the .domain of your scale objects, since you are using .elasticX and .elasticY, which will set those automatically.

You may also want the similar .elasticRadius to size the bubbles according to the current values.

https://github.com/dc-js/dc.js/blob/master/web/docs/api-latest.md#elasticradiusboolean