diff --git a/src/js/charts/cb-chart-grid/chart-grid-config.js b/src/js/charts/cb-chart-grid/chart-grid-config.js index 615f7f8d..bfb52ab0 100644 --- a/src/js/charts/cb-chart-grid/chart-grid-config.js +++ b/src/js/charts/cb-chart-grid/chart-grid-config.js @@ -10,6 +10,7 @@ var ChartConfig = require("../ChartConfig"); * @static * @memberof chart_grid_config * @property {Nem|number} afterTitle - Distance btwn top of title and top of legend or chart +* @property {Nem|number} afterSub - Distance btwn top of sub and top of legend or chart * @property {Nem|number} afterLegend - Distance btwn top of legend and top of chart * @property {Nem|number} blockerRectOffset - Distance btwn text of axis and its background blocker * @property {Nem|number} paddingBerBar - Space btwn two bars in a bar grid @@ -24,7 +25,8 @@ var ChartConfig = require("../ChartConfig"); * @property {object} padding - Distances btwn inner chart elements and container */ var display = { - afterTitle: "1.25em", // distance between top of title and top of legend or chart + afterTitle: "1.25em", // distance between top of title and top of sub, legend or chart + afterSub: "1em", // distance between top of sub and top of legend or chart afterLegend: "0.5em", // distance between top of legend and top of chart blockerRectOffset: 6, // distance between text and background blocker rect paddingPerBar: "0.7em", // extra space around bars @@ -36,9 +38,9 @@ var display = { xy: require("../cb-xy/xy-config").display, margin: { top: "0.8em", - right: "0.25em", - bottom: "0.15em", - left: "0.25em" + right: "0.5em", + bottom: "0.5em", + left: "0.5em" }, padding: { top: "0.5em", @@ -111,6 +113,7 @@ var defaultProps = { id: null, chartType: "chartgrid", title: "", + sub: "", source: "", credit: "Made with Chartbuilder", size: "auto" diff --git a/src/js/charts/cb-chart-grid/chart-grid-dimensions.js b/src/js/charts/cb-chart-grid/chart-grid-dimensions.js index 64242e39..bf0e05c3 100644 --- a/src/js/charts/cb-chart-grid/chart-grid-dimensions.js +++ b/src/js/charts/cb-chart-grid/chart-grid-dimensions.js @@ -27,6 +27,8 @@ function chartGridDimensions(width, opts) { if (model.metadata.title.length > 0 && opts.showMetadata) { height += opts.displayConfig.afterTitle; + } else if (model.metadata.sub.length > 0 && opts.showMetadata) { + height += opts.displayConfig.afterTitle + opts.displayConfig.afterSub; } else if (!opts.showMetadata) { height -= opts.displayConfig.padding.bottom; } diff --git a/src/js/charts/cb-xy/xy-config.js b/src/js/charts/cb-xy/xy-config.js index 8bdde504..3f3ee657 100644 --- a/src/js/charts/cb-xy/xy-config.js +++ b/src/js/charts/cb-xy/xy-config.js @@ -14,7 +14,8 @@ var ChartConfig = require("../ChartConfig"); * @property {Nem|number} labelTextMargin - Horiz distance btwn label rect and text * @property {Nem|number} labelRowHeight - Vert distance btwn rows of labels * items with colors the appropriate indexed CSS class -* @property {Nem|number} afterTitle - Distance btwn top of title and top of legend or chart +* @property {Nem|number} afterTitle - Distance btwn top of title and top of legend, sub or chart +* @property {Nem|number} afterSub - Distance btwn top of sub and top of legend or chart * @property {Nem|number} afterLegend - Distance btwn top of legend and top of chart * @property {Nem|number} blockerRectOffset - Distance btwn text of axis and its background blocker * @property {Nem|number} columnPaddingCoefficient - Distance relative to @@ -35,6 +36,7 @@ var display = { labelTextMargin: "0.3em", labelRowHeight: "1.2em", afterTitle: "1.6em", + afterSub: "1em", afterLegend: "1.6em", blockerRectOffset: "0.3em", columnPaddingCoefficient: 0.3, @@ -47,9 +49,9 @@ var display = { }, margin: { top: "0.8em", - right: "0.25em", - bottom: "0.15em", - left: "0.25em" + right: "0.5em", + bottom: "0.5em", + left: "0.5em" }, padding: { top: 0, @@ -128,6 +130,7 @@ var defaultProps = { metadata: { chartType: 'xy', title: "", + sub: "", source: "", credit: "Made with Chartbuilder", size: "auto" diff --git a/src/js/components/ChartMetadata.jsx b/src/js/components/ChartMetadata.jsx index 55ff7052..87676c4a 100644 --- a/src/js/components/ChartMetadata.jsx +++ b/src/js/components/ChartMetadata.jsx @@ -1,5 +1,5 @@ // Component that handles global metadata, ie data that is universal regardless -// of chart type. Eg title, source, credit, size. +// of chart type. Eg title, sub, source, credit, size. var React = require("react"); var PropTypes = React.PropTypes; @@ -41,6 +41,7 @@ var chart_sizes = [ var text_input_values = [ { name: "title", content: "Title" }, + { name: "sub", content: "Sub" }, { name: "credit", content: "Credit" }, { name: "source", content: "Source" } ]; @@ -63,6 +64,7 @@ var ChartMetadata = React.createClass({ size: PropTypes.string.isRequired, source: PropTypes.string, credit: PropTypes.string, + sub: PropTypes.string, title: PropTypes.string }), stepNumber: PropTypes.string, @@ -104,7 +106,7 @@ var ChartMetadata = React.createClass({

{this.props.stepNumber} - Set title, source, credit and size + Set title, sub, source, credit and size

{textInputs} {this.props.additionalComponents} diff --git a/src/js/components/RendererWrapper.jsx b/src/js/components/RendererWrapper.jsx index cdc98098..d97b1a8c 100644 --- a/src/js/components/RendererWrapper.jsx +++ b/src/js/components/RendererWrapper.jsx @@ -243,6 +243,7 @@ var RendererWrapper = React.createClass({ var margin = this.state.chartConfig.display.margin; var metadataSvg = []; var title; + var sub; var translate = { top: margin.top, @@ -265,6 +266,19 @@ var RendererWrapper = React.createClass({ metadataSvg.push(title); } + if (metadata.sub && metadata.sub !== "") { + sub = ( + + ); + metadataSvg.push(sub); + } + metadataSvg.push( ); } + + /* Pass a boolean that detects whether there is a title and sub*/ + var hasBoth = (this.props.metadata.title.length > 0 && this.props.metadata.sub.length > 0 && this.props.showMetadata); + + /* Choose between grid of bars and grid of XY, and transfer all props to + * relevant component + */ + if (this.props.chartProps._grid.type == "bar") { + gridTypeRenderer = ( + + ); + } else { + gridTypeRenderer = ( + + ); + } return gridTypeRenderer; } }); diff --git a/src/js/components/chart-grid/ChartGridXY.jsx b/src/js/components/chart-grid/ChartGridXY.jsx index d3e52588..499b2ad8 100644 --- a/src/js/components/chart-grid/ChartGridXY.jsx +++ b/src/js/components/chart-grid/ChartGridXY.jsx @@ -94,7 +94,9 @@ var ChartGridXY = React.createClass({ var dimensions = clone(this.props.dimensions); - if (this.props.hasTitle) { + if (this.props.hasBoth) { + extraPadding.top = extraPadding.top + displayConfig.afterTitle + displayConfig.afterSub; + } else if (this.props.hasTitle) { extraPadding.top = extraPadding.top + displayConfig.afterTitle; } diff --git a/src/js/components/chart-xy/XYRenderer.jsx b/src/js/components/chart-xy/XYRenderer.jsx index 2319b082..fc2ad28d 100644 --- a/src/js/components/chart-xy/XYRenderer.jsx +++ b/src/js/components/chart-xy/XYRenderer.jsx @@ -130,10 +130,11 @@ var XYRenderer = React.createClass({ // apply `chartSettings` to data var dataWithSettings = this._applySettingsToData(_chartProps); - // compute margin based on existence of labels and title, based on default + // compute margin based on existence of labels and titles, based on default // margin set in config var labels = _chartProps._annotations.labels; var hasTitle = (this.props.metadata.title.length > 0 && this.props.showMetadata); + var hasBoth = (this.props.metadata.title.length > 0 && this.props.metadata.sub.length > 0 && this.props.showMetadata); // compute the max tick width for each scale each(scaleNames, function(scaleKey) { @@ -194,6 +195,7 @@ var XYRenderer = React.createClass({ key="xy-chart" chartProps={_chartProps} hasTitle={hasTitle} + hasBoth={hasBoth} displayConfig={this.props.displayConfig} styleConfig={this.props.styleConfig} data={dataWithSettings} @@ -213,6 +215,7 @@ var XYRenderer = React.createClass({ chartAreaDimensions={chartAreaDimensions} data={dataWithSettings} hasTitle={hasTitle} + hasBoth={hasBoth} scale={scale} editable={this.props.editable} maxTickWidth={this.state.maxTickWidth} @@ -233,6 +236,7 @@ var XYRenderer = React.createClass({ * propTypes: { * chartProps: PropTypes.object.isRequired, * hasTitle: PropTypes.bool.isRequired, + * hasBoth: PropTypes.bool.isRequired, * displayConfig: PropTypes.object.isRequired, * styleConfig: PropTypes.object.isRequired, * data: PropTypes.arrayOf(PropTypes.object).isRequired, @@ -255,6 +259,7 @@ var XYChart = React.createClass({ propTypes: { chartProps: PropTypes.object.isRequired, hasTitle: PropTypes.bool.isRequired, + hasBoth: PropTypes.bool.isRequired, displayConfig: PropTypes.object.isRequired, styleConfig: PropTypes.object.isRequired, data: PropTypes.arrayOf(PropTypes.object).isRequired, @@ -303,7 +308,9 @@ var XYChart = React.createClass({ componentWillReceiveProps: function(nextProps) { var yOffset; - if (nextProps.hasTitle) { + if (nextProps.hasBoth) { + yOffset = nextProps.displayConfig.margin.top + nextProps.displayConfig.afterTitle + nextProps.displayConfig.afterSub; + } else if (nextProps.hasTitle) { yOffset = nextProps.displayConfig.margin.top + nextProps.displayConfig.afterTitle; } else { yOffset = nextProps.displayConfig.margin.top; @@ -359,6 +366,7 @@ var XYChart = React.createClass({ * propTypes: { * chartProps: PropTypes.object.isRequired, * hasTitle: PropTypes.bool.isRequired, + * hasBoth: PropTypes.bool.isRequired, * displayConfig: PropTypes.object.isRequired, * styleConfig: PropTypes.object.isRequired, * data: PropTypes.arrayOf(PropTypes.object).isRequired, @@ -382,6 +390,7 @@ var XYLabels = React.createClass({ propTypes: { chartProps: PropTypes.object.isRequired, hasTitle: PropTypes.bool.isRequired, + hasBoth: PropTypes.bool.isRequired, displayConfig: PropTypes.object.isRequired, styleConfig: PropTypes.object.isRequired, data: PropTypes.arrayOf(PropTypes.object).isRequired, @@ -412,7 +421,9 @@ var XYLabels = React.createClass({ // Determine how far down vertically the labels should be placed, depending // on presence (or not) of a title var yOffset; - if (nextProps.hasTitle) { + if (nextProps.hasBoth) { + yOffset = nextProps.displayConfig.margin.top + nextProps.displayConfig.afterTitle + nextProps.displayConfig.afterSub; + } else if (nextProps.hasTitle) { yOffset = nextProps.displayConfig.margin.top + nextProps.displayConfig.afterTitle; } else { yOffset = nextProps.displayConfig.margin.top; @@ -832,9 +843,11 @@ function computePadding(props, chartHeight) { var displayConfig = props.displayConfig; var _top = (props.labelYMax * props.chartAreaDimensions.height) + displayConfig.afterLegend; - if (props.hasTitle) { + if (props.hasBoth) { + _top += displayConfig.afterTitle + displayConfig.afterSub; + } else if (props.hasTitle) { _top += displayConfig.afterTitle; - } + } // Maintain space between legend and chart area unless all legend labels // have been dragged diff --git a/src/styl/chart-renderer.styl b/src/styl/chart-renderer.styl index 46c882a8..5fbcea79 100644 --- a/src/styl/chart-renderer.styl +++ b/src/styl/chart-renderer.styl @@ -139,6 +139,10 @@ svg fill $color-body-text font-family $font-sans font-size $em_size + &.svg-text-sub + fill $color-chart-axis-text + font-family $font-sans-light + font-size $em_size .svg-source-pipe stroke $color-chart-meta