Skip to content

feat(coordinateGridMixin): useTopXAxis #1816

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

Closed
wants to merge 7 commits into from
Closed
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
14 changes: 14 additions & 0 deletions docs/api-latest.md
Original file line number Diff line number Diff line change
Expand Up @@ -5415,6 +5415,7 @@ concrete chart types, e.g. bar chart, line chart, and bubble chart.
* [.xAxisPaddingUnit([unit])](#CoordinateGridMixin+xAxisPaddingUnit) ⇒ <code>String</code> \| [<code>CoordinateGridMixin</code>](#CoordinateGridMixin)
* [.xUnitCount()](#CoordinateGridMixin+xUnitCount) ⇒ <code>Number</code>
* [.useRightYAxis([useRightYAxis])](#CoordinateGridMixin+useRightYAxis) ⇒ <code>Boolean</code> \| [<code>CoordinateGridMixin</code>](#CoordinateGridMixin)
* [.useTopXAxis([useTopXAxis])](#CoordinateGridMixin+useTopXAxis) ⇒ <code>Boolean</code> \| [<code>CoordinateGridMixin</code>](#CoordinateGridMixin)
* [.isOrdinal()](#CoordinateGridMixin+isOrdinal) ⇒ <code>Boolean</code>
* [.xAxisLabel([labelText], [padding])](#CoordinateGridMixin+xAxisLabel) ⇒ <code>String</code>
* [.yAxisLabel([labelText], [padding])](#CoordinateGridMixin+yAxisLabel) ⇒ <code>String</code> \| [<code>CoordinateGridMixin</code>](#CoordinateGridMixin)
Expand Down Expand Up @@ -5687,6 +5688,19 @@ chart.
| --- | --- | --- |
| [useRightYAxis] | <code>Boolean</code> | <code>false</code> |

<a name="CoordinateGridMixin+useTopXAxis"></a>

### coordinateGridMixin.useTopXAxis([useTopXAxis]) ⇒ <code>Boolean</code> \| [<code>CoordinateGridMixin</code>](#CoordinateGridMixin)
Gets or sets whether the chart should be drawn with a top axis instead of a bottom axis. When
used with a chart in a composite chart, allows both top and bottom X axes to be shown on a
chart.

**Kind**: instance method of [<code>CoordinateGridMixin</code>](#CoordinateGridMixin)

| Param | Type | Default |
| --- | --- | --- |
| [useTopXAxis] | <code>Boolean</code> | <code>false</code> |

<a name="CoordinateGridMixin+isOrdinal"></a>

### coordinateGridMixin.isOrdinal() ⇒ <code>Boolean</code>
Expand Down
49 changes: 42 additions & 7 deletions src/base/coordinate-grid-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {schemeCategory10} from 'd3-scale-chromatic';
import {timeDay} from 'd3-time';
import {max, min} from 'd3-array';
import {scaleBand, scaleLinear, scaleOrdinal} from 'd3-scale';
import {axisBottom, axisLeft, axisRight} from 'd3-axis';
import {axisTop, axisBottom, axisLeft, axisRight} from 'd3-axis';
import {zoom, zoomIdentity} from 'd3-zoom';
import {brushX} from 'd3-brush';

Expand Down Expand Up @@ -45,7 +45,7 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
this._x = undefined;
this._origX = undefined; // Will hold original scale in case of zoom
this._xOriginalDomain = undefined;
this._xAxis = axisBottom();
this._xAxis = null;
this._xUnits = units.integers;
this._xAxisPadding = 0;
this._xAxisPaddingUnit = timeDay;
Expand Down Expand Up @@ -93,6 +93,7 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
this._fRangeBandPadding = 0;

this._useRightYAxis = false;
this._useTopXAxis = false;
}

/**
Expand Down Expand Up @@ -322,6 +323,9 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
*/
xAxis (xAxis) {
if (!arguments.length) {
if (!this._xAxis) {
this._xAxis = this._createXAxis();
}
return this._xAxis;
}
this._xAxis = xAxis;
Expand Down Expand Up @@ -429,6 +433,29 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
return this;
}

/**
* Gets or sets whether the chart should be drawn with a top axis instead of a bottom axis. When
* used with a chart in a composite chart, allows both top and bottom X axes to be shown on a
* chart.
* @param {Boolean} [useTopXAxis=false]
* @returns {Boolean|CoordinateGridMixin}
*/
useTopXAxis (useTopXAxis) {
if (!arguments.length) {
return this._useTopXAxis;
}

// We need to warn if value is changing after self._yAxis was created
if (this._useTopXAxis !== useTopXAxis && this._xAxis) {
logger.warn('Value of useTopXAxis has been altered, after xAxis was created. ' +
'You might get unexpected yAxis behavior. ' +
'Make calls to useTopXAxis sooner in your chart creation process.');
}

this._useTopXAxis = useTopXAxis;
return this;
}

/**
* Returns true if the chart is using ordinal xUnits ({@link units.ordinal units.ordinal}, or false
* otherwise. Most charts behave differently with ordinal data and use the result of this method to
Expand All @@ -448,6 +475,11 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
return groups.map(this.keyAccessor());
}

_createXAxis () {
return this._useTopXAxis ? axisTop() : axisBottom();
}

// eslint-disable-next-line complexity
_prepareXAxis (g, render) {
if (!this.isOrdinal()) {
if (this.elasticX()) {
Expand Down Expand Up @@ -488,6 +520,10 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
this._x.range([0, this.xAxisLength()]);
}

if (!this._xAxis) {
this._xAxis = this._createXAxis()
}

this._xAxis = this._xAxis.scale(this.x());

this._renderVerticalGridLines(g);
Expand All @@ -503,11 +539,11 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
}

let axisXLab = g.select(`text.${X_AXIS_LABEL_CLASS}`);
const axisXLabY = this._useTopXAxis ? this._xAxisLabelPadding : (this.height() - this._xAxisLabelPadding);
if (axisXLab.empty() && this.xAxisLabel()) {
axisXLab = g.append('text')
.attr('class', X_AXIS_LABEL_CLASS)
.attr('transform', `translate(${this.margins().left + this.xAxisLength() / 2},${
this.height() - this._xAxisLabelPadding})`)
.attr('transform', `translate(${this.margins().left + this.xAxisLength() / 2},${axisXLabY})`)
.attr('text-anchor', 'middle');
}
if (this.xAxisLabel() && axisXLab.text() !== this.xAxisLabel()) {
Expand All @@ -518,8 +554,7 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
.attr('transform', `translate(${this.margins().left},${this._xAxisY()})`)
.call(this._xAxis);
transition(axisXLab, this.transitionDuration(), this.transitionDelay())
.attr('transform', `translate(${this.margins().left + this.xAxisLength() / 2},${
this.height() - this._xAxisLabelPadding})`);
.attr('transform', `translate(${this.margins().left + this.xAxisLength() / 2},${axisXLabY})`);
}

_renderVerticalGridLines (g) {
Expand Down Expand Up @@ -564,7 +599,7 @@ export class CoordinateGridMixin extends ColorMixin(MarginMixin) {
}

_xAxisY () {
return (this.height() - this.margins().bottom);
return this._useTopXAxis ? this.margins().top : this.height() - this.margins().bottom;
}

xAxisLength () {
Expand Down
53 changes: 53 additions & 0 deletions web-src/examples/scatter-top.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>dc.js - Scatter Plot Top X Axis Example</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../css/dc.css"/>
</head>
<body>

<div class="container">
<script type="text/javascript" src="header.js"></script>
<div id="test"></div>

<script type="text/javascript" src="../js/d3.js"></script>
<script type="text/javascript" src="../js/crossfilter.js"></script>
<script type="text/javascript" src="../js/dc.js"></script>
<script type="text/javascript">

var chart = new dc.ScatterPlot("#test");
d3.csv("morley.csv").then(function(experiments) {

experiments.forEach(function(x) {
x.Speed = +x.Speed;
});

var ndx = crossfilter(experiments),
runDimension = ndx.dimension(function(d) {return [+d.Run, -d.Speed]; }),
speedSumGroup = runDimension.group();

chart
.width(768)
.height(480)
.margins({top: 30, right: 0, bottom: 10, left: 30})
.x(d3.scaleLinear().domain([6,20]))
.useTopXAxis(true)
.xAxisLabel("This is the X Axis!")
.brushOn(false)
.symbolSize(8)
.clipPadding(10)
.yAxisLabel("This is the Y Axis!")
.dimension(runDimension)
.group(speedSumGroup);

chart.render();

});

</script>

</div>
</body>
</html>