Skip to content
Open
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Heatmap allows customizing the ordering separately from the values, by Matt Traynham ([#869](https://github.com/dc-js/dc.js/pull/869) - thanks also to Quinn Lee for [#837](https://github.com/dc-js/dc.js/pull/837))
* Front page stable version automatically read from GitHub, by Enrico Spinielli ([#865](https://github.com/dc-js/dc.js/pull/865))
* Functional-style filter handlers: instead of modifying the array of filters in-place, filter handlers must return the new filter array. This is consistent with the old documention, but a different implementation: any changes to the `filters` argument will be ignored unless they are returned. This should make filter handlers easier to reason about.
* Row chart improvements `useRightYAxis`, `xAxisLabel`, by Timothy Ruhle
* Paired row chart, by Timothy Ruhle ([#510](https://github.com/dc-js/dc.js/issues/510) / [#943](https://github.com/dc-js/dc.js/pull/943))

# 2.0 Series
## 2.0.0 beta 23
Expand Down
1 change: 1 addition & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ module.exports.jsFiles = [
'src/geo-choropleth-chart.js',
'src/bubble-overlay.js',
'src/row-chart.js',
'src/paired-row-chart.js',
'src/legend.js',
'src/scatter-plot.js',
'src/number-display.js',
Expand Down
4 changes: 4 additions & 0 deletions dc.css
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,7 @@ g.dc-legend-item.fadeout {
pointer-events: all;
cursor: pointer;
}

.dc-chart g.row text.titlerow {
fill: #000000;
}
34 changes: 34 additions & 0 deletions spec/helpers/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,39 @@ function loadColorFixture2 () {
"{\"colData\":\"6\", \"rowData\": \"6\", \"colorData\": \"8\"}" +
"]");
}

function loadGenderFixture () {
return JSON.parse("[" +
"{\"gender\":\"Male\", \"age\": \"10\"}," +
"{\"gender\":\"Male\", \"age\": \"18\"}," +
"{\"gender\":\"Male\", \"age\": \"20\"}," +
"{\"gender\":\"Male\", \"age\": \"22\"}," +
"{\"gender\":\"Male\", \"age\": \"30\"}," +
"{\"gender\":\"Male\", \"age\": \"40\"}," +
"{\"gender\":\"Male\", \"age\": \"45\"}," +
"{\"gender\":\"Male\", \"age\": \"50\"}," +
"{\"gender\":\"Male\", \"age\": \"55\"}," +
"{\"gender\":\"Male\", \"age\": \"70\"}," +
"{\"gender\":\"Male\", \"age\": \"80\"}," +
"{\"gender\":\"Male\", \"age\": \"90\"}," +
"{\"gender\":\"Male\", \"age\": \"100\"}," +
"{\"gender\":\"Male\", \"age\": \"101\"}," +
"{\"gender\":\"Female\", \"age\": \"11\"}," +
"{\"gender\":\"Female\", \"age\": \"15\"}," +
"{\"gender\":\"Female\", \"age\": \"20\"}," +
"{\"gender\":\"Female\", \"age\": \"21\"}," +
"{\"gender\":\"Female\", \"age\": \"22\"}," +
"{\"gender\":\"Female\", \"age\": \"30\"}," +
"{\"gender\":\"Female\", \"age\": \"40\"}," +
"{\"gender\":\"Female\", \"age\": \"50\"}," +
"{\"gender\":\"Female\", \"age\": \"60\"}," +
"{\"gender\":\"Female\", \"age\": \"65\"}," +
"{\"gender\":\"Female\", \"age\": \"70\"}," +
"{\"gender\":\"Female\", \"age\": \"80\"}," +
"{\"gender\":\"Female\", \"age\": \"90\"}," +
"{\"gender\":\"Female\", \"age\": \"100\"}" +
"]");
}

/* jscs:enable validateQuoteMarks, maximumLineLength */
/* jshint +W109, +W101, +W098 */
141 changes: 141 additions & 0 deletions spec/paired-row-chart-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/* global appendChartID, loadGenderFixture */
describe('dc.pairedRowChart', function () {
var id, chart;
var data, dimension, group, dummyGroup;

beforeEach(function () {
var genderFixture = loadGenderFixture();
data = crossfilter(genderFixture);
var ageRanges = ['0 - 9', '10 - 19', '20 - 29', '30 - 39', '40 - 49', '50 - 59',
'60 - 69', '70 - 79', '80 - 89', '90 - 99', '100+'];

dimension = data.dimension(function (d) {
var ageRange = (d.age <= 99) ?
ageRanges[Math.floor(d.age / 10)] :
ageRanges[10];

return [d.gender, ageRange];
});
group = dimension.group().reduceCount();

dummyGroup = {
all: function () {
// convert to object so we can easily tell if a key exists
var values = {};
group.all().forEach(function (d) {
values[d.key[0] + '.' + d.key[1]] = d.value;
});

// convert back into an array for the chart, making sure that all ageRanges exist
var g = [];
ageRanges.forEach(function (ageRange) {
g.push({
key: ['Male', ageRange],
value: values['Male.' + ageRange] || 0
});
g.push({
key: ['Female', ageRange],
value: values['Female.' + ageRange] || 0
});
});

return g;
}
};

id = 'paired-row-chart';
appendChartID(id);

chart = dc.pairedRowChart('#' + id);
chart.dimension(dimension)
.group(dummyGroup)
.width(600).height(200).gap(10)
.leftKeyFilter(function (d) {
return d.key[0] === 'Male';
})
.rightKeyFilter(function (d) {
return d.key[0] === 'Female';
})
.transitionDuration(0);
});

describe('leftChart', function () {
beforeEach(function () {
chart.render();
});

describe('useRightYAxis', function () {
it('should use right y axis', function () {
expect(chart.leftChart().useRightYAxis()).toBe(true);
});
});

describe('key filter', function () {
it('can get key filter', function () {
expect(typeof chart.leftKeyFilter()).toBe('function');
});

it('should filter data', function () {
expect(chart.leftChart().data().length < dummyGroup.all().length).toBe(true);
});
});

describe('margins', function () {
it('should manually set margins', function () {
var margins = chart.margins(),
leftMargins = chart.leftChart().margins();

expect(leftMargins.top).toBe(margins.top);
expect(leftMargins.right).toBe(0);
expect(leftMargins.bottom).toBe(margins.bottom);
expect(leftMargins.left).toBe(margins.left);
});
});

describe('calculateAxisScaleData', function () {
it('should equal the group data', function () {
expect(chart.leftChart().calculateAxisScaleData().length).toBe(dummyGroup.all().length);
});
});
});

describe('rightChart', function () {
beforeEach(function () {
chart.render();
});

describe('useRightYAxis', function () {
it('should not use right y axis', function () {
expect(chart.rightChart().useRightYAxis()).toBe(false);
});
});

describe('key filter', function () {
it('can get key filter', function () {
expect(typeof chart.rightKeyFilter()).toBe('function');
});

it('should filter data', function () {
expect(chart.rightChart().data().length < dummyGroup.all().length).toBe(true);
});
});

describe('margins', function () {
it('should manually set margins', function () {
var margins = chart.margins(),
rightMargins = chart.rightChart().margins();

expect(rightMargins.top).toBe(margins.top);
expect(rightMargins.right).toBe(margins.right);
expect(rightMargins.bottom).toBe(margins.bottom);
expect(rightMargins.left).toBe(0);
});
});

describe('calculateAxisScaleData', function () {
it('should equal the group data', function () {
expect(chart.rightChart().calculateAxisScaleData().length).toBe(dummyGroup.all().length);
});
});
});
});
59 changes: 59 additions & 0 deletions spec/row-chart-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,65 @@ describe('dc.rowChart', function () {
});
});

describe('_useRightYAxis', function () {
beforeEach(function () {
chart.group(positiveGroupHolder.group);
});

describe('is false', function () {
beforeEach(function () {
chart.useRightYAxis(false);
chart.render();
});

describe('rows', function () {
it('should not translate', function () {
expect(chart.selectAll('.row').attr('transform')).toBe('translate(0,10)');
});
});

describe('bars', function () {
it('should not translate', function () {
expect(chart.selectAll('.row rect').attr('transform')).toBe('translate(0,0)');
});
});

describe('labels', function () {
it('should position the label by the end', function () {
expect(chart.selectAll('.row text').attr('text-anchor')).toBe('start');
});
});
});

describe('is true', function () {
beforeEach(function () {
chart.useRightYAxis(true);
chart.render();
});

describe('rows', function () {
it('should translate to the width of the chart', function () {
expect(chart.selectAll('.row').attr('transform')).toBe('translate(' + chart.effectiveWidth() + ',10)');
});
});

describe('bars', function () {
it('should translate to its own width', function () {
var rect = chart.selectAll('.row rect');

expect(rect.attr('transform')).toBe('translate(-' + rect[0][0].getBBox().width + ',0)');
});
});

describe('labels', function () {
it('should position the label by the end', function () {
expect(chart.selectAll('.row text').attr('text-anchor')).toBe('end');
});
});
});

});

function itShouldBehaveLikeARowChartWithGroup (groupHolder, N) {
describe('for ' + groupHolder.groupType + ' data', function () {
beforeEach(function () {
Expand Down
Loading