From 3846844529f13dfe496a214dd9abc6152b86b20b Mon Sep 17 00:00:00 2001 From: yanofsky Date: Thu, 17 Sep 2015 08:01:07 -0700 Subject: [PATCH 1/3] add subtitle --- src/js/components/ChartMetadata.jsx | 1 + src/js/components/RendererWrapper.jsx | 15 ++++++++++++++- src/styl/chart-renderer.styl | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/js/components/ChartMetadata.jsx b/src/js/components/ChartMetadata.jsx index 87492ce8..d9fccd60 100644 --- a/src/js/components/ChartMetadata.jsx +++ b/src/js/components/ChartMetadata.jsx @@ -41,6 +41,7 @@ var chart_sizes = [ var text_input_values = [ { name: "title", content: "Title" }, + { name: "subtitle", content: "Subtitle"}, { name: "credit", content: "Credit" }, { name: "source", content: "Source" } ]; diff --git a/src/js/components/RendererWrapper.jsx b/src/js/components/RendererWrapper.jsx index 0975296e..2c5dee91 100644 --- a/src/js/components/RendererWrapper.jsx +++ b/src/js/components/RendererWrapper.jsx @@ -257,7 +257,7 @@ var RendererWrapper = React.createClass({ var margin = this.state.chartConfig.display.margin; var metadataSvg = []; - var title; + var title,subtitle; var translate = { top: margin.top, @@ -280,6 +280,19 @@ var RendererWrapper = React.createClass({ metadataSvg.push(title); } + if (metadata.subtitle && metadata.subtitle !== "") { + subtitle = ( + + ); + metadataSvg.push(subtitle); + } + metadataSvg.push( Date: Thu, 17 Sep 2015 08:02:10 -0700 Subject: [PATCH 2/3] magic number spacing --- src/js/components/RendererWrapper.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/components/RendererWrapper.jsx b/src/js/components/RendererWrapper.jsx index 2c5dee91..585d8a07 100644 --- a/src/js/components/RendererWrapper.jsx +++ b/src/js/components/RendererWrapper.jsx @@ -272,7 +272,7 @@ var RendererWrapper = React.createClass({ From 6baf13f47952e2a09c50875031e28b14240010c3 Mon Sep 17 00:00:00 2001 From: golfecholima Date: Tue, 26 Jan 2016 17:30:26 -0500 Subject: [PATCH 3/3] adds optional subtitle --- .../charts/cb-chart-grid/chart-grid-config.js | 11 +++++---- .../cb-chart-grid/chart-grid-dimensions.js | 2 ++ src/js/charts/cb-xy/xy-config.js | 11 +++++---- src/js/components/ChartMetadata.jsx | 7 +++--- src/js/components/RendererWrapper.jsx | 21 ++++++++-------- .../components/chart-grid/ChartGridBars.jsx | 5 +++- .../chart-grid/ChartGridRenderer.jsx | 24 +++++++++++++++++++ src/js/components/chart-grid/ChartGridXY.jsx | 4 +++- src/js/components/chart-xy/XYRenderer.jsx | 23 ++++++++++++++---- src/styl/chart-renderer.styl | 6 ++--- 10 files changed, 83 insertions(+), 31 deletions(-) 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 6bed5168..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,7 +41,7 @@ var chart_sizes = [ var text_input_values = [ { name: "title", content: "Title" }, - { name: "subtitle", content: "Subtitle"}, + { name: "sub", content: "Sub" }, { name: "credit", content: "Credit" }, { name: "source", content: "Source" } ]; @@ -64,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, @@ -105,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 81a35f6a..d97b1a8c 100644 --- a/src/js/components/RendererWrapper.jsx +++ b/src/js/components/RendererWrapper.jsx @@ -242,7 +242,8 @@ var RendererWrapper = React.createClass({ var margin = this.state.chartConfig.display.margin; var metadataSvg = []; - var title,subtitle; + var title; + var sub; var translate = { top: margin.top, @@ -257,7 +258,7 @@ var RendererWrapper = React.createClass({ @@ -265,17 +266,17 @@ var RendererWrapper = React.createClass({ metadataSvg.push(title); } - if (metadata.subtitle && metadata.subtitle !== "") { - subtitle = ( + if (metadata.sub && metadata.sub !== "") { + sub = ( ); - metadataSvg.push(subtitle); + metadataSvg.push(sub); } metadataSvg.push( @@ -329,4 +330,4 @@ var RendererWrapper = React.createClass({ }); -module.exports = RendererWrapper; +module.exports = RendererWrapper; \ No newline at end of file diff --git a/src/js/components/chart-grid/ChartGridBars.jsx b/src/js/components/chart-grid/ChartGridBars.jsx index 9e27f378..d5bd7ee3 100644 --- a/src/js/components/chart-grid/ChartGridBars.jsx +++ b/src/js/components/chart-grid/ChartGridBars.jsx @@ -93,7 +93,10 @@ var ChartGridBars = React.createClass({ /* Height of each grid block */ dimensionsPerGrid.height = (dimensions.height) / chartProps._grid.rows; - if (this.props.hasTitle) { + if (this.props.hasBoth) { + extraPadding.top = extraPadding.top + displayConfig.afterTitle + displayConfig.afterSub; + dimensionsPerGrid.height -= displayConfig.afterTitle + displayConfig.afterSub; + } else if (this.props.hasTitle) { extraPadding.top = extraPadding.top + displayConfig.afterTitle; dimensionsPerGrid.height -= displayConfig.afterTitle; } diff --git a/src/js/components/chart-grid/ChartGridRenderer.jsx b/src/js/components/chart-grid/ChartGridRenderer.jsx index 91f16467..b4aad62a 100644 --- a/src/js/components/chart-grid/ChartGridRenderer.jsx +++ b/src/js/components/chart-grid/ChartGridRenderer.jsx @@ -94,6 +94,30 @@ var ChartGridRenderer = React.createClass({ /> ); } + + /* 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 f69ef799..5fbcea79 100644 --- a/src/styl/chart-renderer.styl +++ b/src/styl/chart-renderer.styl @@ -139,9 +139,9 @@ svg fill $color-body-text font-family $font-sans font-size $em_size - &.svg-text-subtitle - fill $color-body-text - font-family $font-sans + &.svg-text-sub + fill $color-chart-axis-text + font-family $font-sans-light font-size $em_size .svg-source-pipe