@@ -24,24 +24,23 @@ import Charts from "./Charts";
2424import EventHandler from "./EventHandler" ;
2525import TimeAxis from "./TimeAxis" ;
2626import TimeMarker from "./TimeMarker" ;
27+ import Label from "./Label" ;
2728
2829const defaultTimeAxisStyle = {
29- label : {
30- labelColor : "#8B7E7E" , // Default label color
31- labelWeight : 100 ,
32- labelSize : 12
33- } ,
34- values : {
35- valueColor : "#8B7E7E" ,
36- valueWeight : 100 ,
37- valueSize : 11
38- } ,
3930 axis : {
40- axisColor : "#C0C0C0" ,
41- axisWidth : 1
31+ fill : "none" ,
32+ stroke : "#C0C0C0" ,
33+ pointerEvents : "none"
4234 }
4335} ;
4436
37+ const defaultTitleStyle = {
38+ fontWeight : 100 ,
39+ fontSize : 14 ,
40+ font : '"Goudy Bookletter 1911", sans-serif"' ,
41+ fill : "#C0C0C0"
42+ } ;
43+
4544/**
4645 * The `<ChartContainer>` is the outer most element of a chart and is
4746 * responsible for generating and arranging its sub-elements. Specifically,
@@ -118,8 +117,14 @@ export default class ChartContainer extends React.Component {
118117 //
119118
120119 render ( ) {
121- const { padding } = this . props ;
120+ const { padding = 0 } = this . props ;
122121 const { paddingLeft = padding , paddingRight = padding } = this . props ;
122+ const { paddingTop = padding , paddingBottom = padding } = this . props ;
123+
124+ let { titleHeight = 28 } = this . props ;
125+ if ( _ . isUndefined ( this . props . title ) ) {
126+ titleHeight = 0 ;
127+ }
123128
124129 const chartRows = [ ] ;
125130 const leftAxisWidths = [ ] ;
@@ -230,8 +235,34 @@ export default class ChartContainer extends React.Component {
230235 . domain ( this . props . timeRange . toJSON ( ) )
231236 . range ( [ 0 , timeAxisWidth ] ) ) ;
232237
238+ const chartsWidth = this . props . width - leftWidth - rightWidth - paddingLeft - paddingRight ;
239+
233240 let i = 0 ;
234- let yPosition = 0 ;
241+ let yPosition = paddingTop ;
242+
243+ // Chart title
244+ const transform = `translate(${ leftWidth + paddingLeft } ,${ yPosition } )` ;
245+ const titleStyle = merge (
246+ true ,
247+ defaultTitleStyle ,
248+ this . props . titleStyle ? this . props . titleStyle : { }
249+ ) ;
250+ const title = this . props . title ? (
251+ < g transform = { transform } >
252+ < Label
253+ align = "center"
254+ label = { this . props . title }
255+ style = { { label : titleStyle , box : { fill : "none" , stroke : "none" } } }
256+ width = { chartsWidth }
257+ height = { titleHeight }
258+ />
259+ </ g >
260+ ) : (
261+ < g />
262+ ) ;
263+
264+ //yPosition += titleHeight;
265+ let chartsHeight = 0 ;
235266 React . Children . forEach ( this . props . children , child => {
236267 if ( areComponentsEqual ( child . type , ChartRow ) ) {
237268 const chartRow = child ;
@@ -250,6 +281,7 @@ export default class ChartContainer extends React.Component {
250281 transition : this . props . transition ,
251282 enablePanZoom : this . props . enablePanZoom ,
252283 minDuration : this . props . minDuration ,
284+ showGrid : this . props . showGrid ,
253285 timeFormat : this . props . format ,
254286 trackerShowTime : firstRow ,
255287 trackerTime : this . props . trackerPosition ,
@@ -265,15 +297,14 @@ export default class ChartContainer extends React.Component {
265297 </ g >
266298 ) ;
267299
268- yPosition += parseInt ( child . props . height , 10 ) ;
300+ const height = parseInt ( child . props . height , 10 ) ;
301+ yPosition += height ;
302+ chartsHeight += height ;
269303 }
270304 }
271305 i += 1 ;
272306 } ) ;
273307
274- const chartsHeight = yPosition ;
275- const chartsWidth = this . props . width - leftWidth - rightWidth - paddingLeft - paddingRight ;
276-
277308 // Hover tracker line
278309 let tracker ;
279310 if (
@@ -284,7 +315,7 @@ export default class ChartContainer extends React.Component {
284315 < g
285316 key = "tracker-group"
286317 style = { { pointerEvents : "none" } }
287- transform = { `translate(${ leftWidth + paddingLeft } ,0 )` }
318+ transform = { `translate(${ leftWidth + paddingLeft } ,${ paddingTop + titleHeight } )` }
288319 >
289320 < TimeMarker
290321 width = { chartsWidth }
@@ -305,27 +336,24 @@ export default class ChartContainer extends React.Component {
305336 // TimeAxis
306337 //
307338
308- const axisStyle = merge (
339+ const timeAxisStyle = merge (
309340 true ,
310341 defaultTimeAxisStyle . axis ,
311342 this . props . timeAxisStyle . axis ? this . props . timeAxisStyle . axis : { }
312343 ) ;
313344
314- const xStyle = {
315- stroke : axisStyle . axisColor ,
316- strokeWidth : axisStyle . axisWidth ,
317- fill : "none" ,
318- pointerEvents : "none"
319- } ;
320-
321345 const timeAxis = (
322- < g transform = { `translate(${ leftWidth + paddingLeft } ,${ chartsHeight } )` } >
346+ < g
347+ transform = { `translate(${ leftWidth + paddingLeft } ,${ paddingTop +
348+ titleHeight +
349+ chartsHeight } )`}
350+ >
323351 < line
324352 x1 = { - leftWidth }
325353 y1 = { 0.5 }
326354 x2 = { chartsWidth + rightWidth }
327355 y2 = { 0.5 }
328- style = { xStyle }
356+ style = { timeAxisStyle }
329357 />
330358 < TimeAxis
331359 scale = { timeScale }
@@ -345,7 +373,7 @@ export default class ChartContainer extends React.Component {
345373 //
346374
347375 const rows = (
348- < g transform = { `translate(${ leftWidth + paddingLeft } ,${ 0 } )` } >
376+ < g transform = { `translate(${ leftWidth + paddingLeft } ,${ paddingTop + titleHeight } )` } >
349377 < EventHandler
350378 key = "event-handler"
351379 width = { chartsWidth }
@@ -372,17 +400,24 @@ export default class ChartContainer extends React.Component {
372400 //
373401
374402 const svgWidth = this . props . width ;
375- const svgHeight = yPosition + timeAxisHeight ;
403+ const svgHeight = chartsHeight + timeAxisHeight + paddingTop + paddingBottom + titleHeight ;
404+
405+ const svgStyle = merge (
406+ true ,
407+ { display : "block" } ,
408+ this . props . style ? this . props . style : { }
409+ ) ;
376410
377411 return this . props . showGridPosition === "over" ? (
378412 < svg
379413 width = { svgWidth }
380414 height = { svgHeight }
381- style = { { display : "block" } }
415+ style = { svgStyle }
382416 ref = { c => {
383417 this . svg = c ;
384418 } }
385419 >
420+ { title }
386421 { rows }
387422 { tracker }
388423 { timeAxis }
@@ -396,6 +431,7 @@ export default class ChartContainer extends React.Component {
396431 this . svg = c ;
397432 } }
398433 >
434+ { title }
399435 { timeAxis }
400436 { rows }
401437 { tracker }
@@ -532,10 +568,21 @@ ChartContainer.propTypes = {
532568 * };
533569 * ```
534570 */
535- timeAxisStyle : PropTypes . shape ( {
536- label : PropTypes . object , // eslint-disable-line
571+ /**
572+ * Object specifying the CSS by which the Time Axis can be styled. The object can contain:
573+ * "values" (the time labels), "axis" (the main horizontal line) and "ticks" (which may
574+ * optionally extend the height of all chart rows using the `showGrid` prop. Each of these
575+ * is an inline CSS style applied to the axis label, axis values, axis line and ticks
576+ * respectively.
577+ *
578+ * Note that "ticks" and "values" are passed into d3's styles, so they are regular CSS property names
579+ * and not React's camel case names (e.g. "stroke-dasharray" not strokeDasharray). "axis" is a
580+ * regular React rendered SVG line, so it uses camel case.
581+ */
582+ style : PropTypes . shape ( {
583+ axis : PropTypes . object ,
537584 values : PropTypes . object ,
538- axis : PropTypes . object
585+ ticks : PropTypes . object
539586 } ) ,
540587
541588 /**
@@ -563,8 +610,8 @@ ChartContainer.propTypes = {
563610 PropTypes . string ,
564611 PropTypes . arrayOf (
565612 PropTypes . shape ( {
566- label : PropTypes . string , // eslint-disable-line
567- value : PropTypes . string // eslint-disable-line
613+ label : PropTypes . string ,
614+ value : PropTypes . string
568615 } )
569616 )
570617 ] ) ,
0 commit comments