@@ -29,7 +29,8 @@ dc.compositeChart = function (parent, chartGroup) {
29
29
var _childOptions = { } ;
30
30
31
31
var _shareColors = false ,
32
- _shareTitle = true ;
32
+ _shareTitle = true ,
33
+ _alignYAxes = false ;
33
34
34
35
var _rightYAxis = d3 . svg . axis ( ) ,
35
36
_rightYAxisLabel = 0 ,
@@ -80,8 +81,12 @@ dc.compositeChart = function (parent, chartGroup) {
80
81
} ;
81
82
82
83
_chart . _prepareYAxis = function ( ) {
83
- if ( leftYAxisChildren ( ) . length !== 0 ) { prepareLeftYAxis ( ) ; }
84
- if ( rightYAxisChildren ( ) . length !== 0 ) { prepareRightYAxis ( ) ; }
84
+ var left = ( leftYAxisChildren ( ) . length !== 0 ) ;
85
+ var right = ( rightYAxisChildren ( ) . length !== 0 ) ;
86
+ var ranges = calculateYAxesRanges ( left , right ) ;
87
+
88
+ if ( left ) { prepareLeftYAxis ( ranges ) ; }
89
+ if ( right ) { prepareRightYAxis ( ranges ) ; }
85
90
86
91
if ( leftYAxisChildren ( ) . length > 0 && ! _rightAxisGridLines ) {
87
92
_chart . _renderHorizontalGridLinesForAxis ( _chart . g ( ) , _chart . y ( ) , _chart . yAxis ( ) ) ;
@@ -102,12 +107,57 @@ dc.compositeChart = function (parent, chartGroup) {
102
107
}
103
108
} ;
104
109
105
- function prepareRightYAxis ( ) {
110
+ function calculateYAxesRanges ( left , right ) {
111
+ var lyAxisMin , lyAxisMax , ryAxisMin , ryAxisMax ;
112
+
113
+ if ( left ) {
114
+ lyAxisMin = yAxisMin ( ) ;
115
+ lyAxisMax = yAxisMax ( ) ;
116
+ }
117
+
118
+ if ( right ) {
119
+ ryAxisMin = rightYAxisMin ( ) ;
120
+ ryAxisMax = rightYAxisMax ( ) ;
121
+ }
122
+
123
+ if ( _chart . alignYAxes ( ) && left && right && ( lyAxisMin < 0 || ryAxisMin < 0 ) ) {
124
+ // both y axis are linear and at least one doesn't start at zero
125
+ var leftYRatio , rightYRatio ;
126
+
127
+ if ( lyAxisMin < 0 ) {
128
+ leftYRatio = lyAxisMax / lyAxisMin ;
129
+ }
130
+
131
+ if ( ryAxisMin < 0 ) {
132
+ rightYRatio = ryAxisMax / ryAxisMin ;
133
+ }
134
+
135
+ if ( lyAxisMin < 0 && ryAxisMin < 0 ) {
136
+ if ( leftYRatio < rightYRatio ) {
137
+ ryAxisMax = ryAxisMin * leftYRatio ;
138
+ } else {
139
+ lyAxisMax = lyAxisMin * rightYRatio ;
140
+ }
141
+ } else if ( lyAxisMin < 0 ) {
142
+ ryAxisMin = ryAxisMax / leftYRatio ;
143
+ } else {
144
+ lyAxisMin = lyAxisMax / ( ryAxisMax / ryAxisMin ) ;
145
+ }
146
+ }
147
+ return {
148
+ lyAxisMin : lyAxisMin ,
149
+ lyAxisMax : lyAxisMax ,
150
+ ryAxisMin : ryAxisMin ,
151
+ ryAxisMax : ryAxisMax
152
+ } ;
153
+ }
154
+
155
+ function prepareRightYAxis ( ranges ) {
106
156
if ( _chart . rightY ( ) === undefined || _chart . elasticY ( ) ) {
107
157
if ( _chart . rightY ( ) === undefined ) {
108
158
_chart . rightY ( d3 . scale . linear ( ) ) ;
109
159
}
110
- _chart . rightY ( ) . domain ( [ rightYAxisMin ( ) , rightYAxisMax ( ) ] ) . rangeRound ( [ _chart . yAxisHeight ( ) , 0 ] ) ;
160
+ _chart . rightY ( ) . domain ( [ ranges . ryAxisMin , ranges . ryAxisMax ] ) . rangeRound ( [ _chart . yAxisHeight ( ) , 0 ] ) ;
111
161
}
112
162
113
163
_chart . rightY ( ) . range ( [ _chart . yAxisHeight ( ) , 0 ] ) ;
@@ -116,12 +166,12 @@ dc.compositeChart = function (parent, chartGroup) {
116
166
_chart . rightYAxis ( ) . orient ( 'right' ) ;
117
167
}
118
168
119
- function prepareLeftYAxis ( ) {
169
+ function prepareLeftYAxis ( ranges ) {
120
170
if ( _chart . y ( ) === undefined || _chart . elasticY ( ) ) {
121
171
if ( _chart . y ( ) === undefined ) {
122
172
_chart . y ( d3 . scale . linear ( ) ) ;
123
173
}
124
- _chart . y ( ) . domain ( [ yAxisMin ( ) , yAxisMax ( ) ] ) . rangeRound ( [ _chart . yAxisHeight ( ) , 0 ] ) ;
174
+ _chart . y ( ) . domain ( [ ranges . lyAxisMin , ranges . lyAxisMax ] ) . rangeRound ( [ _chart . yAxisHeight ( ) , 0 ] ) ;
125
175
}
126
176
127
177
_chart . y ( ) . range ( [ _chart . yAxisHeight ( ) , 0 ] ) ;
@@ -339,6 +389,23 @@ dc.compositeChart = function (parent, chartGroup) {
339
389
return _chart ;
340
390
} ;
341
391
392
+ /**
393
+ * Get or set alignment between left and right y axes. A line connecting '0' on both y axis
394
+ * will be parallel to x axis.
395
+ * @name alignYAxes
396
+ * @memberof dc.compositeChart
397
+ * @instance
398
+ * @param {Boolean } [alignYAxes=false]
399
+ * @return {Chart }
400
+ */
401
+ _chart . alignYAxes = function ( alignYAxes ) {
402
+ if ( ! arguments . length ) {
403
+ return _alignYAxes ;
404
+ }
405
+ _alignYAxes = alignYAxes ;
406
+ return _chart ;
407
+ } ;
408
+
342
409
function leftYAxisChildren ( ) {
343
410
return _children . filter ( function ( child ) {
344
411
return ! child . useRightYAxis ( ) ;
0 commit comments