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