Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using d3.svg.axis instead of custom axis implementation on heatmap #919

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions spec/bubble-chart-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ describe('dc.bubbleChart', function () {
}
describe('column filtering with straight crossfilter', function () {
beforeEach(function () {
var axisLabel = d3.select(heatMap.selectAll('.cols.axis text')[0][3]);
var axisLabel = d3.select(heatMap.selectAll('.cols.axis g')[0][3]);
axisLabel.on('click')(axisLabel.datum());
d3.timer.flush();
});
Expand All @@ -713,7 +713,7 @@ describe('dc.bubbleChart', function () {
beforeEach(function () {
chart.group(clone_group(sepalGroup));
chart.render();
var axisLabel = d3.select(heatMap.selectAll('.cols.axis text')[0][3]);
var axisLabel = d3.select(heatMap.selectAll('.cols.axis g')[0][3]);
axisLabel.on('click')(axisLabel.datum());
d3.timer.flush();
});
Expand Down
24 changes: 10 additions & 14 deletions spec/heatmap-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,9 @@ describe('dc.heatmap', function () {
});

it('should position the y-axis labels with their associated rows', function () {
var yaxisTexts = chart.selectAll('.rows.axis text');
expect(+yaxisTexts[0][0].getAttribute('y')).toEqual(150);
expect(+yaxisTexts[0][0].getAttribute('x')).toEqual(0);
expect(+yaxisTexts[0][1].getAttribute('y')).toEqual(50);
expect(+yaxisTexts[0][1].getAttribute('x')).toEqual(0);
var yaxisTicks = chart.selectAll('.rows.axis .tick');
expect(yaxisTicks[0][0].getAttribute('transform')).toMatchTranslate(0, 150);
expect(yaxisTicks[0][1].getAttribute('transform')).toMatchTranslate(0, 50);
});

it('should have labels on the y-axis corresponding to the row values', function () {
Expand All @@ -90,11 +88,9 @@ describe('dc.heatmap', function () {
});

it('should position the x-axis labels with their associated columns', function () {
var xaxisTexts = chart.selectAll('.cols.axis text');
expect(+xaxisTexts[0][0].getAttribute('y')).toEqual(200);
expect(+xaxisTexts[0][0].getAttribute('x')).toEqual(50);
expect(+xaxisTexts[0][1].getAttribute('y')).toEqual(200);
expect(+xaxisTexts[0][1].getAttribute('x')).toEqual(150);
var xaxisTexts = chart.selectAll('.cols.axis .tick');
expect(xaxisTexts[0][0].getAttribute('transform')).toMatchTranslate(50, 0);
expect(xaxisTexts[0][1].getAttribute('transform')).toMatchTranslate(150, 0);
});

it('should have labels on the x-axis corresponding to the row values', function () {
Expand Down Expand Up @@ -355,13 +351,13 @@ describe('dc.heatmap', function () {

describe('with nothing previously filtered', function () {
it('should filter all cells on that axis', function () {
chart.selectAll('.cols.axis text').each(function (d) {
chart.selectAll('.cols.axis g').each(function (d) {
var axisLabel = d3.select(this);
axisLabel.on('click')(d);
assertOnlyThisAxisIsFiltered(chart, 0, d);
axisLabel.on('click')(d);
});
chart.selectAll('.rows.axis text').each(function (d) {
chart.selectAll('.rows.axis g').each(function (d) {
var axisLabel = d3.select(this);
axisLabel.on('click')(d);
assertOnlyThisAxisIsFiltered(chart, 1, d);
Expand All @@ -380,7 +376,7 @@ describe('dc.heatmap', function () {

var xVal = box.datum().key[0];

var columns = chart.selectAll('.cols.axis text');
var columns = chart.selectAll('.cols.axis g');
var column = columns.filter(function (columnData) {
return columnData === xVal;
});
Expand All @@ -404,7 +400,7 @@ describe('dc.heatmap', function () {

assertOnlyThisAxisIsFiltered(chart, 0, xVal);

var columns = chart.selectAll('.cols.axis text');
var columns = chart.selectAll('.cols.axis g');
var column = columns.filter(function (columnData) {
return columnData === xVal;
});
Expand Down
87 changes: 42 additions & 45 deletions src/heatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ dc.heatMap = function (parent, chartGroup) {
var _rowOrdering = d3.ascending;
var _colScale = d3.scale.ordinal();
var _rowScale = d3.scale.ordinal();
var _colAxis = d3.svg.axis().orient('bottom');
var _rowAxis = d3.svg.axis().orient('left');

var _xBorderRadius = DEFAULT_BORDER_RADIUS;
var _yBorderRadius = DEFAULT_BORDER_RADIUS;
Expand Down Expand Up @@ -185,6 +187,13 @@ dc.heatMap = function (parent, chartGroup) {
.append('g')
.attr('class', 'heatmap')
.attr('transform', 'translate(' + _chart.margins().left + ',' + _chart.margins().top + ')');
_chartBody.append('g')
.attr('class', 'cols axis')
.attr('transform', 'translate(0,' + _chart.effectiveHeight() + ')');
_chartBody.append('g')
.attr('class', 'rows axis');
_colScale.rangeRoundBands([0, _chart.effectiveWidth()]);
_rowScale.rangeRoundBands([_chart.effectiveHeight(), 0]);

return _chart._doRedraw();
};
Expand All @@ -202,17 +211,39 @@ dc.heatMap = function (parent, chartGroup) {
rows = _rowScale.domain(rows);
cols = _colScale.domain(cols);

var rowCount = rows.domain().length,
colCount = cols.domain().length,
boxWidth = Math.floor(_chart.effectiveWidth() / colCount),
boxHeight = Math.floor(_chart.effectiveHeight() / rowCount);
// Update axis
_colAxis.scale(cols)
.tickFormat(_chart.colsLabel());
var _colAxisTransition = dc.transition(_chartBody.select('g.cols.axis'), _chart.transitionDuration(), _chart.transitionDelay())
.call(_colAxis);
_rowAxis.scale(rows)
.tickFormat(_chart.rowsLabel());
var _rowAxisTransition = dc.transition(_chartBody.select('g.rows.axis'), _chart.transitionDuration(), _chart.transitionDelay())
.call(_rowAxis);
// We need the clicks added after the transition. Unfortunately, this is handled differently
// for selection/transition
if (_colAxisTransition.duration || _rowAxisTransition.duration) {
_colAxisTransition.each('end', function () {
d3.select(this)
.selectAll('g')
.on('click', _chart.xAxisOnClick());
});
_rowAxisTransition.each('end', function () {
d3.select(this)
.selectAll('g')
.on('click', _chart.yAxisOnClick());
});
} else {
_colAxisTransition.selectAll('g').on('click', _chart.xAxisOnClick());
_rowAxisTransition.selectAll('g').on('click', _chart.yAxisOnClick());
}

cols.rangeRoundBands([0, _chart.effectiveWidth()]);
rows.rangeRoundBands([_chart.effectiveHeight(), 0]);
// Update boxes
var boxes = _chartBody.selectAll('g.box-group')
.data(_chart.data(), function (d, i) {
return _chart.keyAccessor()(d, i) + '\0' + _chart.valueAccessor()(d, i);
});

var boxes = _chartBody.selectAll('g.box-group').data(_chart.data(), function (d, i) {
return _chart.keyAccessor()(d, i) + '\0' + _chart.valueAccessor()(d, i);
});
var gEnter = boxes.enter().append('g')
.attr('class', 'box-group');

Expand All @@ -232,45 +263,11 @@ dc.heatMap = function (parent, chartGroup) {
.attr('rx', _xBorderRadius)
.attr('ry', _yBorderRadius)
.attr('fill', _chart.getColor)
.attr('width', boxWidth)
.attr('height', boxHeight);
.attr('width', _colScale.rangeBand())
.attr('height', _rowScale.rangeBand());

boxes.exit().remove();

var gCols = _chartBody.select('g.cols');
if (gCols.empty()) {
gCols = _chartBody.append('g').attr('class', 'cols axis');
}
var gColsText = gCols.selectAll('text').data(cols.domain());
gColsText.enter().append('text')
.attr('x', function (d) { return cols(d) + boxWidth / 2; })
.style('text-anchor', 'middle')
.attr('y', _chart.effectiveHeight())
.attr('dy', 12)
.on('click', _chart.xAxisOnClick())
.text(_chart.colsLabel());
dc.transition(gColsText, _chart.transitionDuration(), _chart.transitionDelay())
.text(_chart.colsLabel())
.attr('x', function (d) { return cols(d) + boxWidth / 2; })
.attr('y', _chart.effectiveHeight());
gColsText.exit().remove();
var gRows = _chartBody.select('g.rows');
if (gRows.empty()) {
gRows = _chartBody.append('g').attr('class', 'rows axis');
}
var gRowsText = gRows.selectAll('text').data(rows.domain());
gRowsText.enter().append('text')
.attr('dy', 6)
.style('text-anchor', 'end')
.attr('x', 0)
.attr('dx', -2)
.on('click', _chart.yAxisOnClick())
.text(_chart.rowsLabel());
dc.transition(gRowsText, _chart.transitionDuration(), _chart.transitionDelay())
.text(_chart.rowsLabel())
.attr('y', function (d) { return rows(d) + boxHeight / 2; });
gRowsText.exit().remove();

if (_chart.hasFilter()) {
_chart.selectAll('g.box-group').each(function (d) {
if (_chart.isSelectedNode(d)) {
Expand Down
12 changes: 9 additions & 3 deletions style/dc.scss
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,15 @@ div.dc-chart {
fill-opacity: 0.5;
fill: $color_celeste;
}
g.axis text {
pointer-events: all;
cursor: pointer;
g.axis {
text {
pointer-events: all;
cursor: pointer;
}
.domain,
.tick line {
opacity: 0;
}
}
}
.empty-chart .pie-slice {
Expand Down