From: Jukka Kurkela Date: Thu, 21 May 2020 21:07:06 +0000 (+0300) Subject: Move font* to font.* (#7383) X-Git-Tag: v3.0.0-beta.2~134 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a83a8081110fa23654826d074393184e4282b8e;p=thirdparty%2FChart.js.git Move font* to font.* (#7383) --- diff --git a/docs/docs/axes/labelling.md b/docs/docs/axes/labelling.md index d0221f917..efae5a860 100644 --- a/docs/docs/axes/labelling.md +++ b/docs/docs/axes/labelling.md @@ -14,10 +14,7 @@ The scale label configuration is nested under the scale configuration in the `sc | `align` | `string` | `'center'` | Alignment of the axis title. Possible options are `'start'`, `'center'` and `'end'` | `labelString` | `string` | `''` | The text for the title. (i.e. "# of People" or "Response Choices"). | `lineHeight` | number|string | `1.2` | Height of an individual line of text (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height)). -| `fontColor` | `Color` | `'#666'` | Font color for scale title. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the scale title, follows CSS font-family options. -| `fontSize` | `number` | `12` | Font size for scale title. -| `fontStyle` | `string` | `'normal'` | Font style for the scale title, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit). +| `font` | `Font` | `defaults.font` | See [Fonts](fonts.md) | `padding` | number|object | `4` | Padding to apply around scale labels. Only `top` and `bottom` are implemented. ## Creating Custom Tick Formats diff --git a/docs/docs/axes/radial/linear.md b/docs/docs/axes/radial/linear.md index 5d8201b7d..4f3d468ca 100644 --- a/docs/docs/axes/radial/linear.md +++ b/docs/docs/axes/radial/linear.md @@ -108,11 +108,7 @@ The following options are used to configure the point labels that are shown on t | ---- | ---- | ------- | ----------- | `display` | `boolean` | `true` | if true, point labels are shown. | `callback` | `function` | | Callback function to transform data labels to point labels. The default implementation simply returns the current string. -| `fontColor` | Color|Color[] | `'#666'` | Font color for point labels. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family to use when rendering labels. -| `fontSize` | `number` | `10` | font size in pixels. -| `fontStyle` | `string` | `'normal'` | Font style to use when rendering point labels. -| `lineHeight` | number|string | `1.2` | Height of an individual line of text (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height)). +| `font` | `Font` | `defaults.font` | See [Fonts](fonts.md) ## Internal data format diff --git a/docs/docs/axes/styling.md b/docs/docs/axes/styling.md index 4980389d6..21a201911 100644 --- a/docs/docs/axes/styling.md +++ b/docs/docs/axes/styling.md @@ -35,25 +35,21 @@ For function arguments, the function is passed a context object that is of the f ``` ## Tick Configuration + The tick configuration is nested under the scale configuration in the `ticks` key. It defines options for the tick marks that are generated by the axis. | Name | Type | [Scriptable](../general/options.md#scriptable-options) | Default | Description | ---- | ---- | ------- | ----------- | `callback` | `function` | | | Returns the string representation of the tick value as it should be displayed on the chart. See [callback](../axes/labelling.md#creating-custom-tick-formats). | `display` | `boolean` | | `true` | If true, show tick labels. -| `fontColor` | `Color` | Yes | `'#666'` | Font color for tick labels. -| `fontFamily` | `string` | Yes | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the tick labels, follows CSS font-family options. -| `fontSize` | `number` | Yes | `12` | Font size for the tick labels. -| `fontStyle` | `string` | Yes | `'normal'` | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit). -| `lineHeight` | number|string | Yes | `1.2` | Height of an individual line of text (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height)). -| `lineWidth` | `number` | Yes | `0` | Stroke width around the text. +| `font` | `Font` | Yes | `defaults.font` | See [Fonts](fonts.md) | `major` | `object` | | `{}` | Major ticks configuration. | `padding` | `number` | | `0` | Sets the offset of the tick labels from the axis | `reverse` | `boolean` | | `false` | Reverses order of tick labels. -| `strokeStyle` | `string` | Yes | `` | The color of the stroke around the text. | `z` | `number` | `0` | | z-index of tick layer. Useful when ticks are drawn on chart area. Values <= 0 are drawn under datasets, > 0 on top. ## Major Tick Configuration + The majorTick configuration is nested under the ticks configuration in the `major` key. It defines options for the major tick marks that are generated by the axis. | Name | Type | Default | Description diff --git a/docs/docs/configuration/legend.md b/docs/docs/configuration/legend.md index 514d0411a..2d7f0a658 100644 --- a/docs/docs/configuration/legend.md +++ b/docs/docs/configuration/legend.md @@ -20,7 +20,7 @@ The legend configuration is passed into the `options.legend` namespace. The glob | `reverse` | `boolean` | `false` | Legend will show datasets in reverse order. | `labels` | `object` | | See the [Legend Label Configuration](#legend-label-configuration) section below. | `rtl` | `boolean` | | `true` for rendering the legends from right to left. -| `textDirection` | `string` | canvas' default | This will force the text direction `'rtl' or `'ltr' on the canvas for rendering the legend, regardless of the css specified on the canvas +| `textDirection` | `string` | canvas' default | This will force the text direction `'rtl'` or `'ltr'` on the canvas for rendering the legend, regardless of the css specified on the canvas | `title` | `object` | | See the [Legend Title Configuration](#legend-title-configuration) section below. ## Position @@ -49,14 +49,11 @@ The legend label configuration is nested below the legend configuration using th | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | `boxWidth` | `number` | `40` | Width of coloured box. -| `fontSize` | `number` | `12` | Font size of text. -| `fontStyle` | `string` | `'normal'` | Font style of text. -| `fontColor` | `Color` | `'#666'` | Color of text. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family of legend text. +| `font` | `Font` | `defaults.font` | See [Fonts](fonts.md) | `padding` | `number` | `10` | Padding between rows of colored boxes. | `generateLabels` | `function` | | Generates legend items for each thing in the legend. Default implementation returns the text + styling for the color box. See [Legend Item](#legend-item-interface) for details. | `filter` | `function` | `null` | Filters legend items out of the legend. Receives 2 parameters, a [Legend Item](#legend-item-interface) and the chart data. -| `usePointStyle` | `boolean` | `false` | Label style will match corresponding point style (size is based on the mimimum value between boxWidth and fontSize). +| `usePointStyle` | `boolean` | `false` | Label style will match corresponding point style (size is based on the mimimum value between boxWidth and font.size). ## Legend Title Configuration @@ -65,10 +62,7 @@ The legend title configuration is nested below the legend configuration using th | Name | Type | Default | Description | ---- | ---- | ------- | ----------- | `display` | `boolean` | `false` | Is the legend title displayed. -| `fontSize` | `number` | `12` | Font size of text. -| `fontStyle` | `string` | `'normal'` | Font style of text. -| `fontColor` | `Color` | `'#666'` | Color of text. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family of legend text. +| `font` | `Font` | `defaults.font` | See [Fonts](fonts.md) | `lineHeight` | `number` | | Line height of the text. If unset, is computed from the font size. | `padding` | number|object | `0` | Padding around the title. If specified as a number, it applies evenly to all sides. | `text` | `string` | | The string title. diff --git a/docs/docs/configuration/title.md b/docs/docs/configuration/title.md index 158e60b21..efb75289d 100644 --- a/docs/docs/configuration/title.md +++ b/docs/docs/configuration/title.md @@ -5,6 +5,7 @@ title: Title The chart title defines text to draw at the top of the chart. ## Title Configuration + The title configuration is passed into the `options.title` namespace. The global options for the chart title is defined in `Chart.defaults.title`. | Name | Type | Default | Description @@ -12,16 +13,15 @@ The title configuration is passed into the `options.title` namespace. The global | `align` | `string` | `'center'` | Alignment of the title. [more...](#align) | `display` | `boolean` | `false` | Is the title shown? | `position` | `string` | `'top'` | Position of title. [more...](#position) -| `fontSize` | `number` | `12` | Font size. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the title text. -| `fontColor` | `Color` | `'#666'` | Font color. -| `fontStyle` | `string` | `'bold'` | Font style. +| `font` | `Font` | `defaults.font` | See [Fonts](fonts.md) | `padding` | number|{top: number, bottom: number} | `10` | Adds padding above and below the title text if a single number is specified. It is also possible to change top and bottom padding separately. | `lineHeight` | number|string | `1.2` | Height of an individual line of text. See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height). | `text` | string|string[] | `''` | Title text to display. If specified as an array, text is rendered on multiple lines. ### Position + Possible title position values are: + * `'top'` * `'left'` * `'bottom'` diff --git a/docs/docs/configuration/tooltip.md b/docs/docs/configuration/tooltip.md index 0ce4c6758..cd98fdca9 100644 --- a/docs/docs/configuration/tooltip.md +++ b/docs/docs/configuration/tooltip.md @@ -17,23 +17,14 @@ The tooltip configuration is passed into the `options.tooltips` namespace. The g | `itemSort` | `function` | | Sort tooltip items. [more...](#sort-callback) | `filter` | `function` | | Filter tooltip items. [more...](#filter-callback) | `backgroundColor` | `Color` | `'rgba(0, 0, 0, 0.8)'` | Background color of the tooltip. -| `titleFontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Title font. -| `titleFontSize` | `number` | `12` | Title font size. -| `titleFontStyle` | `string` | `'bold'` | Title font style. -| `titleFontColor` | `Color` | `'#fff'` | Title font color. +| `titleFont` | `Font` | `{style: 'bold', color: '#fff'}` | See [Fonts](fonts.md). | `titleAlign` | `string` | `'left'` | Horizontal alignment of the title text lines. [more...](#alignment) | `titleSpacing` | `number` | `2` | Spacing to add to top and bottom of each title line. | `titleMarginBottom` | `number` | `6` | Margin to add on bottom of title section. -| `bodyFontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Body line font. -| `bodyFontSize` | `number` | `12` | Body font size. -| `bodyFontStyle` | `string` | `'normal'` | Body font style. -| `bodyFontColor` | `Color` | `'#fff'` | Body font color. +| `bodyFont` | `Font` | `{color: '#fff'}` | See [Fonts](fonts.md). | `bodyAlign` | `string` | `'left'` | Horizontal alignment of the body text lines. [more...](#alignment) | `bodySpacing` | `number` | `2` | Spacing to add to top and bottom of each tooltip item. -| `footerFontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Footer font. -| `footerFontSize` | `number` | `12` | Footer font size. -| `footerFontStyle` | `string` | `'bold'` | Footer font style. -| `footerFontColor` | `Color` | `'#fff'` | Footer font color. +| `footerFont` | `Font` | `{style: 'bold', color: '#fff'}` | See [Fonts](fonts.md). | `footerAlign` | `string` | `'left'` | Horizontal alignment of the footer text lines. [more...](#alignment) | `footerSpacing` | `number` | `2` | Spacing to add to top and bottom of each footer line. | `footerMarginTop` | `number` | `6` | Margin to add before drawing the footer. @@ -44,8 +35,8 @@ The tooltip configuration is passed into the `options.tooltips` namespace. The g | `cornerRadius` | `number` | `6` | Radius of tooltip corner curves. | `multiKeyBackground` | `Color` | `'#fff'` | Color to draw behind the colored boxes when multiple items are in the tooltip. | `displayColors` | `boolean` | `true` | If true, color boxes are shown in the tooltip. -| `boxWidth` | `number` | `bodyFontSize` | Width of the color box if displayColors is true. -| `boxHeight` | `number` | `bodyFontSize` | Height of the color box if displayColors is true. +| `boxWidth` | `number` | `bodyFont.size` | Width of the color box if displayColors is true. +| `boxHeight` | `number` | `bodyFont.size` | Height of the color box if displayColors is true. | `borderColor` | `Color` | `'rgba(0, 0, 0, 0)'` | Color of the border. | `borderWidth` | `number` | `0` | Size of the border. | `rtl` | `boolean` | | `true` for rendering the legends from right to left. @@ -54,6 +45,7 @@ The tooltip configuration is passed into the `options.tooltips` namespace. The g ### Position Modes Possible modes are: + * `'average'` * `'nearest'` @@ -62,6 +54,7 @@ Possible modes are: New modes can be defined by adding functions to the `Chart.Tooltip.positioners` map. Example: + ```javascript /** * Custom positioner @@ -155,6 +148,7 @@ var chart = new Chart(ctx, { ### Label Color Callback For example, to return a red box for each item in the tooltip you could do: + ```javascript var chart = new Chart(ctx, { type: 'line', @@ -275,9 +269,7 @@ var myPieChart = new Chart(ctx, { tooltipEl.style.position = 'absolute'; tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + 'px'; tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + 'px'; - tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily; - tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px'; - tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle; + tooltipEl.style.font = tooltipModel.bodyFont.string; tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px'; tooltipEl.style.pointerEvents = 'none'; } @@ -289,6 +281,7 @@ var myPieChart = new Chart(ctx, { See [samples](https://www.chartjs.org/samples/) for examples on how to get started with custom tooltips. ## Tooltip Model + The tooltip model contains parameters that can be used to render the tooltip. ```javascript @@ -322,20 +315,14 @@ The tooltip model contains parameters that can be used to render the tooltip. beforeBody: string[], // line of text that appear after the body and before the footer afterBody: string[], - bodyFontColor: Color, - _bodyFontFamily: string, - _bodyFontStyle: string, + bodyFont: Font, _bodyAlign: string, - bodyFontSize: number, bodySpacing: number, // Title // lines of text that form the title title: string[], - titleFontColor: Color, - _titleFontFamily: string, - _titleFontStyle: string, - titleFontSize: number, + titleFont: Font, _titleAlign: string, titleSpacing: number, titleMarginBottom: number, @@ -343,10 +330,7 @@ The tooltip model contains parameters that can be used to render the tooltip. // Footer // lines of text that form the footer footer: string[], - footerFontColor: Color, - _footerFontFamily: string, - _footerFontStyle: string, - footerFontSize: number, + footerFont: Font, _footerAlign: string, footerSpacing: number, footerMarginTop: number, diff --git a/docs/docs/general/fonts.md b/docs/docs/general/fonts.md index 4260ce115..3c7aaa841 100644 --- a/docs/docs/general/fonts.md +++ b/docs/docs/general/fonts.md @@ -2,12 +2,12 @@ title: Fonts --- -There are 4 special global settings that can change all of the fonts on the chart. These options are in `Chart.defaults`. The global font settings only apply when more specific options are not included in the config. +There are special global settings that can change all of the fonts on the chart. These options are in `Chart.defaults.font`. The global font settings only apply when more specific options are not included in the config. For example, in this chart the text will all be red except for the labels in the legend. ```javascript -Chart.defaults.fontColor = 'red'; +Chart.defaults.font.color = 'red'; let chart = new Chart(ctx, { type: 'line', data: data, @@ -15,7 +15,9 @@ let chart = new Chart(ctx, { legend: { labels: { // This more specific font property overrides the global property - fontColor: 'black' + font: { + color: 'black' + } } } } @@ -24,10 +26,14 @@ let chart = new Chart(ctx, { | Name | Type | Default | Description | ---- | ---- | ------- | ----------- -| `fontColor` | `Color` | `'#666'` | Default font color for all text. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Default font family for all text. -| `fontSize` | `number` | `12` | Default font size (in px) for text. Does not apply to radialLinear scale point labels. -| `fontStyle` | `string` | `'normal'` | Default font style. Does not apply to tooltip title or footer. Does not apply to chart title. +| `color` | `Color` | `'#666'` | Default font color for all text. +| `family` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Default font family for all text, follows CSS font-family options. +| `size` | `number` | `12` | Default font size (in px) for text. Does not apply to radialLinear scale point labels. +| `style` | `string` | `'normal'` | Default font style. Does not apply to tooltip title or footer. Does not apply to chart title. Follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit). +| `weight` | `string` | `undefined` | Default font weight (boldness). (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight)). +| `lineHeight` | number|string | `1.2` | Height of an individual line of text (see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height)). +| `lineWidth` | `number` | `0` | Stroke width around the text. Currently only supported by [ticks](../axes/styling.md#tick-configuration). +| `strokeStyle` | `string` | `` | The color of the stroke around the text. Currently only supported by [ticks](../axes/styling.md#tick-configuration). ## Missing Fonts diff --git a/docs/docs/getting-started/v3-migration.md b/docs/docs/getting-started/v3-migration.md index 14f2e2d21..fd70ab59c 100644 --- a/docs/docs/getting-started/v3-migration.md +++ b/docs/docs/getting-started/v3-migration.md @@ -55,11 +55,11 @@ A number of changes were made to the configuration options passed to the `Chart` * `global` namespace was removed from `defaults`. So `Chart.defaults.global` is now `Chart.defaults` * `default` prefix was removed from defaults. For example `Chart.defaults.global.defaultColor` is now `Chart.defaults.color` * `defaultColor` was renamed to `color` -* `defaultFontColor` was renamed to `fontColor` -* `defaultFontFamily` was renamed to `fontFamily` -* `defaultFontSize` was renamed to `fontSize` -* `defaultFontStyle` was renamed to `fontStyle` -* `defaultLineHeight` was renamed to `lineHeight` +* `defaultFontColor` was renamed to `font.color` +* `defaultFontFamily` was renamed to `font.family` +* `defaultFontSize` was renamed to `font.size` +* `defaultFontStyle` was renamed to `font.style` +* `defaultLineHeight` was renamed to `font.lineHeight` #### Scales @@ -82,11 +82,13 @@ options: { major: { enabled: true }, - fontStyle: function(context) { - return context.tick && context.tick.major ? 'bold' : undefined; - }, - fontColor: function(context) { - return context.tick && context.tick.major ? '#FF0000' : undefined; + font: function(context) { + if (context.tick && context.tick.major) { + return { + style: 'bold', + color: '#FF0000' + }; + } } } }], @@ -118,11 +120,13 @@ options: { major: { enabled: true }, - fontStyle: function(context) { - return context.tick && context.tick.major ? 'bold' : undefined; - }, - fontColor: function(context) { - return context.tick && context.tick.major ? '#FF0000' : undefined; + font: function(context) { + if (context.tick && context.tick.major) { + return { + style: 'bold', + color: '#FF0000' + }; + } } } }, diff --git a/samples/scales/axes-labels.html b/samples/scales/axes-labels.html index 66bad81b2..efae919a0 100644 --- a/samples/scales/axes-labels.html +++ b/samples/scales/axes-labels.html @@ -81,11 +81,13 @@ scaleLabel: { display: true, labelString: 'Month', - lineHeight: 1.2, - fontColor: '#911', - fontFamily: 'Comic Sans MS', - fontSize: 20, - fontStyle: 'bold', + font: { + color: '#911', + family: 'Comic Sans MS', + size: 20, + style: 'bold', + lineHeight: 1.2, + }, padding: {top: 20, left: 0, right: 0, bottom: 0} } }, @@ -94,11 +96,13 @@ scaleLabel: { display: true, labelString: 'Value', - lineHeight: 1.2, - fontColor: '#191', - fontFamily: 'Times', - fontSize: 20, - fontStyle: 'normal', + font: { + color: '#191', + family: 'Times', + size: 20, + style: 'normal', + lineHeight: 1.2, + }, padding: {top: 30, left: 0, right: 0, bottom: 0} } } diff --git a/samples/scales/financial.html b/samples/scales/financial.html index c92ac3368..a1c4b6686 100644 --- a/samples/scales/financial.html +++ b/samples/scales/financial.html @@ -145,8 +145,8 @@ major: { enabled: true, }, - fontStyle: function(context) { - return context.tick.major ? 'bold' : undefined; + font: function(context) { + return context.tick.major ? {style: 'bold'} : undefined; }, source: 'data', autoSkip: true, diff --git a/samples/scales/time/line-max-span.html b/samples/scales/time/line-max-span.html index d9c116899..83292c9cd 100644 --- a/samples/scales/time/line-max-span.html +++ b/samples/scales/time/line-max-span.html @@ -97,11 +97,13 @@ major: { enabled: true }, - fontStyle: function(context) { - return context.tick && context.tick.major ? 'bold' : undefined; - }, - fontColor: function(context) { - return context.tick && context.tick.major ? '#FF0000' : undefined; + font: function(context) { + if (context.tick && context.tick.major) { + return { + style: 'bold', + color: '#FF0000' + }; + } } } }, diff --git a/samples/scales/time/line-point-data.html b/samples/scales/time/line-point-data.html index 1256616f0..372891b45 100644 --- a/samples/scales/time/line-point-data.html +++ b/samples/scales/time/line-point-data.html @@ -94,11 +94,14 @@ major: { enabled: true }, - fontStyle: function(context) { - return context.tick && context.tick.major ? 'bold' : undefined; - }, - fontColor: function(context) { - return context.tick && context.tick.major ? '#FF0000' : undefined; + font: function(context) { + if (context.tick && context.tick.major) { + return { + style: 'bold', + color: '#FF0000' + }; + } + } } }, diff --git a/samples/tooltips/custom-line.html b/samples/tooltips/custom-line.html index c76226a23..f19265c23 100644 --- a/samples/tooltips/custom-line.html +++ b/samples/tooltips/custom-line.html @@ -102,9 +102,7 @@ tooltipEl.style.opacity = 1; tooltipEl.style.left = positionX + tooltip.caretX + 'px'; tooltipEl.style.top = positionY + tooltip.caretY + 'px'; - tooltipEl.style.fontFamily = tooltip._bodyFontFamily; - tooltipEl.style.fontSize = tooltip.bodyFontSize + 'px'; - tooltipEl.style.fontStyle = tooltip._bodyFontStyle; + tooltipEl.style.font = tooltip.bodyFont.string; tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px'; }; diff --git a/samples/tooltips/custom-pie.html b/samples/tooltips/custom-pie.html index cb0c76d0b..0c1b538b1 100644 --- a/samples/tooltips/custom-pie.html +++ b/samples/tooltips/custom-pie.html @@ -98,9 +98,7 @@ tooltipEl.style.opacity = 1; tooltipEl.style.left = positionX + tooltip.caretX + 'px'; tooltipEl.style.top = positionY + tooltip.caretY + 'px'; - tooltipEl.style.fontFamily = tooltip._bodyFontFamily; - tooltipEl.style.fontSize = tooltip.bodyFontSize; - tooltipEl.style.fontStyle = tooltip._bodyFontStyle; + tooltipEl.style.font = tooltip.bodyFont.string; tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px'; }; diff --git a/src/core/core.defaults.js b/src/core/core.defaults.js index 33214dac8..caacea729 100644 --- a/src/core/core.defaults.js +++ b/src/core/core.defaults.js @@ -14,11 +14,16 @@ export class Defaults { 'touchstart', 'touchmove' ]; - this.fontColor = '#666'; - this.fontFamily = "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"; - this.fontSize = 12; - this.fontStyle = 'normal'; - this.lineHeight = 1.2; + this.font = { + color: '#666', + family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + size: 12, + style: 'normal', + lineHeight: 1.2, + weight: null, + lineWidth: 0, + strokeStyle: undefined + }; this.hover = { onHover: null, mode: 'nearest', diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 5611fd654..7f8a0d5aa 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -3,7 +3,7 @@ import Element from './core.element'; import {_alignPixel, _measureText} from '../helpers/helpers.canvas'; import {callback as call, each, isArray, isFinite, isNullOrUndef, isObject, valueOrDefault} from '../helpers/helpers.core'; import {_factorize, toDegrees, toRadians} from '../helpers/helpers.math'; -import {_parseFont, resolve, toPadding} from '../helpers/helpers.options'; +import {toFont, resolve, toPadding} from '../helpers/helpers.options'; import Ticks from './core.ticks'; /** @@ -147,7 +147,7 @@ function getScaleLabelHeight(options) { return 0; } - const font = _parseFont(options); + const font = toFont(options.font); const padding = toPadding(options.padding); return font.lineHeight + padding.height; @@ -1466,8 +1466,7 @@ export default class Scale extends Element { return; } - const scaleLabelFontColor = valueOrDefault(scaleLabel.fontColor, defaults.fontColor); - const scaleLabelFont = _parseFont(scaleLabel); + const scaleLabelFont = toFont(scaleLabel.font); const scaleLabelPadding = toPadding(scaleLabel.padding); const halfLineHeight = scaleLabelFont.lineHeight / 2; const scaleLabelAlign = scaleLabel.align; @@ -1521,7 +1520,7 @@ export default class Scale extends Element { ctx.rotate(rotation); ctx.textAlign = textAlign; ctx.textBaseline = 'middle'; - ctx.fillStyle = scaleLabelFontColor; // render in correct colour + ctx.fillStyle = scaleLabelFont.color; ctx.font = scaleLabelFont.string; ctx.fillText(scaleLabel.labelString, 0, 0); ctx.restore(); @@ -1597,27 +1596,19 @@ export default class Scale extends Element { /** * @param {number} index * @return {object} - * @private + * @protected */ _resolveTickFontOptions(index) { const me = this; const options = me.options.ticks; + const ticks = me.ticks || []; const context = { chart: me.chart, scale: me, - tick: me.ticks[index], + tick: ticks[index], index }; - return Object.assign(_parseFont({ - fontFamily: resolve([options.fontFamily], context), - fontSize: resolve([options.fontSize], context), - fontStyle: resolve([options.fontStyle], context), - lineHeight: resolve([options.lineHeight], context) - }), { - color: resolve([options.fontColor, defaults.fontColor], context), - lineWidth: resolve([options.lineWidth], context), - strokeStyle: resolve([options.strokeStyle], context) - }); + return toFont(resolve([options.font], context)); } } diff --git a/src/helpers/helpers.canvas.js b/src/helpers/helpers.canvas.js index 4f4c44437..00bfc0fdf 100644 --- a/src/helpers/helpers.canvas.js +++ b/src/helpers/helpers.canvas.js @@ -1,4 +1,4 @@ -import {isArray} from './helpers.core'; +import {isArray, isNullOrUndef} from './helpers.core'; /** * @typedef { import("../core/core.controller").default } Chart @@ -15,6 +15,23 @@ const TWO_THIRDS_PI = PI * 2 / 3; * @namespace Chart.helpers.canvas */ +/** + * Converts the given font object into a CSS font string. + * @param {object} font - A font object. + * @return {string|null} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font + * @private + */ +export function toFontString(font) { + if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) { + return null; + } + + return (font.style ? font.style + ' ' : '') + + (font.weight ? font.weight + ' ' : '') + + font.size + 'px ' + + font.family; +} + /** * @private */ diff --git a/src/helpers/helpers.options.js b/src/helpers/helpers.options.js index d38bbb8b7..1335d0ae2 100644 --- a/src/helpers/helpers.options.js +++ b/src/helpers/helpers.options.js @@ -1,22 +1,6 @@ import defaults from '../core/core.defaults'; -import {isNullOrUndef, isArray, isObject, valueOrDefault} from './helpers.core'; - -/** - * Converts the given font object into a CSS font string. - * @param {object} font - A font object. - * @return {string|null} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font - * @private - */ -function toFontString(font) { - if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) { - return null; - } - - return (font.style ? font.style + ' ' : '') - + (font.weight ? font.weight + ' ' : '') - + font.size + 'px ' - + font.family; -} +import {isArray, isObject, valueOrDefault} from './helpers.core'; +import {toFontString} from './helpers.canvas'; /** * @alias Chart.helpers.options @@ -84,22 +68,26 @@ export function toPadding(value) { * Parses font options and returns the font object. * @param {object} options - A object that contains font options to be parsed. * @return {object} The font object. - * @todo Support font.* options and renamed to toFont(). * @private */ -export function _parseFont(options) { - let size = valueOrDefault(options.fontSize, defaults.fontSize); +export function toFont(options) { + const defaultFont = defaults.font; + options = options || {}; + let size = valueOrDefault(options.size, defaultFont.size); if (typeof size === 'string') { size = parseInt(size, 10); } const font = { - family: valueOrDefault(options.fontFamily, defaults.fontFamily), - lineHeight: toLineHeight(valueOrDefault(options.lineHeight, defaults.lineHeight), size), + color: valueOrDefault(options.color, defaultFont.color), + family: valueOrDefault(options.family, defaultFont.family), + lineHeight: toLineHeight(valueOrDefault(options.lineHeight, defaultFont.lineHeight), size), + lineWidth: valueOrDefault(options.lineWidth, defaultFont.lineWidth), size, - style: valueOrDefault(options.fontStyle, defaults.fontStyle), - weight: null, + style: valueOrDefault(options.style, defaultFont.style), + weight: valueOrDefault(options.weight, defaultFont.weight), + strokeStyle: valueOrDefault(options.strokeStyle, defaultFont.strokeStyle), string: '' }; diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 748f2ebcf..79f61db6e 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -3,7 +3,7 @@ import Element from '../core/core.element'; import layouts from '../core/core.layouts'; import {drawPoint} from '../helpers/helpers.canvas'; import {callback as call, mergeIf, valueOrDefault} from '../helpers/helpers.core'; -import {_parseFont, toPadding} from '../helpers/helpers.options'; +import {toFont, toPadding} from '../helpers/helpers.options'; import {getRtlAdapter, overrideTextDirection, restoreTextDirection} from '../helpers/helpers.rtl'; /** @@ -237,7 +237,7 @@ export class Legend extends Element { const display = opts.display; const ctx = me.ctx; - const labelFont = _parseFont(labelOpts); + const labelFont = toFont(labelOpts.font); const fontSize = labelFont.size; // Reset hit boxes @@ -363,8 +363,8 @@ export class Legend extends Element { me.drawTitle(); const rtlHelper = getRtlAdapter(opts.rtl, me.left, me._minSize.width); const ctx = me.ctx; - const fontColor = valueOrDefault(labelOpts.fontColor, defaults.fontColor); - const labelFont = _parseFont(labelOpts); + const labelFont = toFont(labelOpts.font); + const fontColor = labelFont.color; const fontSize = labelFont.size; let cursor; @@ -524,7 +524,7 @@ export class Legend extends Element { const me = this; const opts = me.options; const titleOpts = opts.title; - const titleFont = _parseFont(titleOpts); + const titleFont = toFont(titleOpts.font); const titlePadding = toPadding(titleOpts.padding); if (!titleOpts.display) { @@ -533,7 +533,6 @@ export class Legend extends Element { const rtlHelper = getRtlAdapter(opts.rtl, me.left, me._minSize.width); const ctx = me.ctx; - const fontColor = valueOrDefault(titleOpts.fontColor, defaults.fontColor); const position = titleOpts.position; let x, textAlign; @@ -595,8 +594,8 @@ export class Legend extends Element { // Canvas setup ctx.textAlign = rtlHelper.textAlign(textAlign); ctx.textBaseline = 'middle'; - ctx.strokeStyle = fontColor; - ctx.fillStyle = fontColor; + ctx.strokeStyle = titleFont.color; + ctx.fillStyle = titleFont.color; ctx.font = titleFont.string; ctx.fillText(titleOpts.text, x, y); @@ -607,7 +606,7 @@ export class Legend extends Element { */ _computeTitleHeight() { const titleOpts = this.options.title; - const titleFont = _parseFont(titleOpts); + const titleFont = toFont(titleOpts.font); const titlePadding = toPadding(titleOpts.padding); return titleOpts.display ? titleFont.lineHeight + titlePadding.height : 0; } diff --git a/src/plugins/plugin.title.js b/src/plugins/plugin.title.js index 21eb74a63..7ed3c5732 100644 --- a/src/plugins/plugin.title.js +++ b/src/plugins/plugin.title.js @@ -1,13 +1,15 @@ import defaults from '../core/core.defaults'; import Element from '../core/core.element'; import layouts from '../core/core.layouts'; -import {isArray, valueOrDefault, mergeIf} from '../helpers/helpers.core'; -import {toPadding, _parseFont} from '../helpers/helpers.options'; +import {isArray, mergeIf} from '../helpers/helpers.core'; +import {toPadding, toFont} from '../helpers/helpers.options'; defaults.set('title', { align: 'center', display: false, - fontStyle: 'bold', + font: { + style: 'bold', + }, fullWidth: true, padding: 10, position: 'top', @@ -119,7 +121,7 @@ export class Title extends Element { const lineCount = isArray(opts.text) ? opts.text.length : 1; me._padding = toPadding(opts.padding); - const textSize = lineCount * _parseFont(opts).lineHeight + me._padding.height; + const textSize = lineCount * toFont(opts.font).lineHeight + me._padding.height; me.width = minSize.width = isHorizontal ? me.maxWidth : textSize; me.height = minSize.height = isHorizontal ? textSize : me.maxHeight; } @@ -142,7 +144,7 @@ export class Title extends Element { return; } - const fontOpts = _parseFont(opts); + const fontOpts = toFont(opts); const lineHeight = fontOpts.lineHeight; const offset = lineHeight / 2 + me._padding.top; let rotation = 0; @@ -195,7 +197,7 @@ export class Title extends Element { ctx.save(); - ctx.fillStyle = valueOrDefault(opts.fontColor, defaults.fontColor); // render in correct colour + ctx.fillStyle = fontOpts.color; ctx.font = fontOpts.string; ctx.translate(titleX, titleY); diff --git a/src/plugins/plugin.tooltip.js b/src/plugins/plugin.tooltip.js index 6915cdda7..f4825a93b 100644 --- a/src/plugins/plugin.tooltip.js +++ b/src/plugins/plugin.tooltip.js @@ -4,8 +4,8 @@ import Element from '../core/core.element'; import plugins from '../core/core.plugins'; import {valueOrDefault, each, noop, isNullOrUndef, isArray, _elementsEqual} from '../helpers/helpers.core'; import {getRtlAdapter, overrideTextDirection, restoreTextDirection} from '../helpers/helpers.rtl'; -import {fontString} from '../helpers/helpers.extras'; import {distanceBetweenPoints} from '../helpers/helpers.math'; +import {toFont} from '../helpers/helpers.options'; /** * @typedef { import("../platform/platform.base").IEvent } IEvent @@ -18,18 +18,24 @@ defaults.set('tooltips', { position: 'average', intersect: true, backgroundColor: 'rgba(0,0,0,0.8)', - titleFontStyle: 'bold', + titleFont: { + style: 'bold', + color: '#fff', + }, titleSpacing: 2, titleMarginBottom: 6, - titleFontColor: '#fff', titleAlign: 'left', bodySpacing: 2, - bodyFontColor: '#fff', + bodyFont: { + color: '#fff', + }, bodyAlign: 'left', - footerFontStyle: 'bold', footerSpacing: 2, footerMarginTop: 6, - footerFontColor: '#fff', + footerFont: { + color: '#fff', + style: 'bold', + }, footerAlign: 'left', yPadding: 6, xPadding: 6, @@ -99,7 +105,7 @@ defaults.set('tooltips', { }; }, labelTextColor() { - return this.options.bodyFontColor; + return this.options.bodyFont.color; }, afterLabel: noop, @@ -238,20 +244,12 @@ function resolveOptions(options) { options = Object.assign({}, defaults.tooltips, options); - options.bodyFontFamily = valueOrDefault(options.bodyFontFamily, defaults.fontFamily); - options.bodyFontStyle = valueOrDefault(options.bodyFontStyle, defaults.fontStyle); - options.bodyFontSize = valueOrDefault(options.bodyFontSize, defaults.fontSize); - - options.boxHeight = valueOrDefault(options.boxHeight, options.bodyFontSize); - options.boxWidth = valueOrDefault(options.boxWidth, options.bodyFontSize); - - options.titleFontFamily = valueOrDefault(options.titleFontFamily, defaults.fontFamily); - options.titleFontStyle = valueOrDefault(options.titleFontStyle, defaults.fontStyle); - options.titleFontSize = valueOrDefault(options.titleFontSize, defaults.fontSize); + options.bodyFont = toFont(options.bodyFont); + options.titleFont = toFont(options.titleFont); + options.footerFont = toFont(options.footerFont); - options.footerFontFamily = valueOrDefault(options.footerFontFamily, defaults.fontFamily); - options.footerFontStyle = valueOrDefault(options.footerFontStyle, defaults.fontStyle); - options.footerFontSize = valueOrDefault(options.footerFontSize, defaults.fontSize); + options.boxHeight = valueOrDefault(options.boxHeight, options.bodyFont.size); + options.boxWidth = valueOrDefault(options.boxWidth, options.bodyFont.size); return options; } @@ -262,7 +260,7 @@ function resolveOptions(options) { function getTooltipSize(tooltip) { const ctx = tooltip._chart.ctx; const {body, footer, options, title} = tooltip; - const {bodyFontSize, footerFontSize, titleFontSize, boxWidth, boxHeight} = options; + const {bodyFont, footerFont, titleFont, boxWidth, boxHeight} = options; const titleLineCount = title.length; const footerLineCount = footer.length; const bodyLineItemCount = body.length; @@ -275,20 +273,20 @@ function getTooltipSize(tooltip) { combinedBodyLength += tooltip.beforeBody.length + tooltip.afterBody.length; if (titleLineCount) { - height += titleLineCount * titleFontSize + height += titleLineCount * titleFont.size + (titleLineCount - 1) * options.titleSpacing + options.titleMarginBottom; } if (combinedBodyLength) { // Body lines may include some extra height depending on boxHeight - const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFontSize) : bodyFontSize; + const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFont.size) : bodyFont.size; height += bodyLineItemCount * bodyLineHeight - + (combinedBodyLength - bodyLineItemCount) * bodyFontSize + + (combinedBodyLength - bodyLineItemCount) * bodyFont.size + (combinedBodyLength - 1) * options.bodySpacing; } if (footerLineCount) { height += options.footerMarginTop - + footerLineCount * footerFontSize + + footerLineCount * footerFont.size + (footerLineCount - 1) * options.footerSpacing; } @@ -300,11 +298,11 @@ function getTooltipSize(tooltip) { ctx.save(); - ctx.font = fontString(titleFontSize, options.titleFontStyle, options.titleFontFamily); + ctx.font = titleFont.string; each(tooltip.title, maxLineWidth); // Body width - ctx.font = fontString(bodyFontSize, options.bodyFontStyle, options.bodyFontFamily); + ctx.font = bodyFont.string; each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth); // Body lines may include some extra width due to the color box @@ -319,7 +317,7 @@ function getTooltipSize(tooltip) { widthPadding = 0; // Footer width - ctx.font = fontString(footerFontSize, options.footerFontStyle, options.footerFontFamily); + ctx.font = footerFont.string; each(tooltip.footer, maxLineWidth); ctx.restore(); @@ -730,7 +728,7 @@ export class Tooltip extends Element { const options = me.options; const title = me.title; const length = title.length; - let titleFontSize, titleSpacing, i; + let titleFont, titleSpacing, i; if (length) { const rtlHelper = getRtlAdapter(options.rtl, me.x, me.width); @@ -740,15 +738,15 @@ export class Tooltip extends Element { ctx.textAlign = rtlHelper.textAlign(options.titleAlign); ctx.textBaseline = 'middle'; - titleFontSize = options.titleFontSize; + titleFont = options.titleFont; titleSpacing = options.titleSpacing; - ctx.fillStyle = options.titleFontColor; - ctx.font = fontString(titleFontSize, options.titleFontStyle, options.titleFontFamily); + ctx.fillStyle = options.titleFont.color; + ctx.font = titleFont.string; for (i = 0; i < length; ++i) { - ctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFontSize / 2); - pt.y += titleFontSize + titleSpacing; // Line Height and spacing + ctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFont.size / 2); + pt.y += titleFont.size + titleSpacing; // Line Height and spacing if (i + 1 === length) { pt.y += options.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing @@ -764,10 +762,10 @@ export class Tooltip extends Element { const me = this; const options = me.options; const labelColors = me.labelColors[i]; - const {boxHeight, boxWidth, bodyFontSize} = options; + const {boxHeight, boxWidth, bodyFont} = options; const colorX = getAlignedX(me, 'left'); const rtlColorX = rtlHelper.x(colorX); - const yOffSet = boxHeight < bodyFontSize ? (bodyFontSize - boxHeight) / 2 : 0; + const yOffSet = boxHeight < bodyFont.size ? (bodyFont.size - boxHeight) / 2 : 0; const colorY = pt.y + yOffSet; // Fill a white rect so that colours merge nicely if the opacity is < 1 @@ -790,8 +788,8 @@ export class Tooltip extends Element { drawBody(pt, ctx) { const me = this; const {body, options} = me; - const {bodyFontSize, bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth} = options; - let bodyLineHeight = bodyFontSize; + const {bodyFont, bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth} = options; + let bodyLineHeight = bodyFont.size; let xLinePadding = 0; const rtlHelper = getRtlAdapter(options.rtl, me.x, me.width); @@ -806,12 +804,12 @@ export class Tooltip extends Element { ctx.textAlign = bodyAlign; ctx.textBaseline = 'middle'; - ctx.font = fontString(bodyFontSize, options.bodyFontStyle, options.bodyFontFamily); + ctx.font = bodyFont.string; pt.x = getAlignedX(me, bodyAlignForCalculation); // Before body lines - ctx.fillStyle = options.bodyFontColor; + ctx.fillStyle = bodyFont.color; each(me.beforeBody, fillLineOfText); xLinePadding = displayColors && bodyAlignForCalculation !== 'right' @@ -830,13 +828,13 @@ export class Tooltip extends Element { // Draw Legend-like boxes if needed if (displayColors && lines.length) { me._drawColorBox(ctx, pt, i, rtlHelper); - bodyLineHeight = Math.max(bodyFontSize, boxHeight); + bodyLineHeight = Math.max(bodyFont.size, boxHeight); } for (j = 0, jlen = lines.length; j < jlen; ++j) { fillLineOfText(lines[j]); // Reset for any lines that don't include colorbox - bodyLineHeight = bodyFontSize; + bodyLineHeight = bodyFont.size; } each(bodyItem.after, fillLineOfText); @@ -844,7 +842,7 @@ export class Tooltip extends Element { // Reset back to 0 for after body xLinePadding = 0; - bodyLineHeight = bodyFontSize; + bodyLineHeight = bodyFont.size; // After body lines each(me.afterBody, fillLineOfText); @@ -856,7 +854,7 @@ export class Tooltip extends Element { const options = me.options; const footer = me.footer; const length = footer.length; - let footerFontSize, i; + let footerFont, i; if (length) { const rtlHelper = getRtlAdapter(options.rtl, me.x, me.width); @@ -867,14 +865,14 @@ export class Tooltip extends Element { ctx.textAlign = rtlHelper.textAlign(options.footerAlign); ctx.textBaseline = 'middle'; - footerFontSize = options.footerFontSize; + footerFont = options.footerFont; - ctx.fillStyle = options.footerFontColor; - ctx.font = fontString(footerFontSize, options.footerFontStyle, options.footerFontFamily); + ctx.fillStyle = options.footerFont.color; + ctx.font = footerFont.string; for (i = 0; i < length; ++i) { - ctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFontSize / 2); - pt.y += footerFontSize + options.footerSpacing; + ctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFont.size / 2); + pt.y += footerFont.size + options.footerSpacing; } } } diff --git a/src/scales/scale.linear.js b/src/scales/scale.linear.js index 7bff82311..d84bff9d8 100644 --- a/src/scales/scale.linear.js +++ b/src/scales/scale.linear.js @@ -1,5 +1,4 @@ import {isFinite, valueOrDefault} from '../helpers/helpers.core'; -import {_parseFont} from '../helpers/helpers.options'; import LinearScaleBase from './scale.linearbase'; import Ticks from '../core/core.ticks'; @@ -44,7 +43,7 @@ export default class LinearScale extends LinearScaleBase { if (me.isHorizontal()) { return Math.ceil(me.width / 40); } - const tickFont = _parseFont(me.options.ticks); + const tickFont = me._resolveTickFontOptions(0); return Math.ceil(me.height / tickFont.lineHeight); } diff --git a/src/scales/scale.radialLinear.js b/src/scales/scale.radialLinear.js index 8f6091c8e..e31f628f9 100644 --- a/src/scales/scale.radialLinear.js +++ b/src/scales/scale.radialLinear.js @@ -4,7 +4,7 @@ import {isNumber, toDegrees, toRadians, _normalizeAngle} from '../helpers/helper import LinearScaleBase from './scale.linearbase'; import Ticks from '../core/core.ticks'; import {valueOrDefault, isArray, valueAtIndexOrDefault, isFinite, callback as callCallback, isNullOrUndef} from '../helpers/helpers.core'; -import {_parseFont, resolve} from '../helpers/helpers.options'; +import {toFont, resolve} from '../helpers/helpers.options'; const defaultConfig = { @@ -48,7 +48,9 @@ const defaultConfig = { display: true, // Number - Point label font size in pixels - fontSize: 10, + font: { + size: 10 + }, // Function - Used to convert point labels callback(label) { @@ -61,7 +63,7 @@ function getTickBackdropHeight(opts) { const tickOpts = opts.ticks; if (tickOpts.display && opts.display) { - return valueOrDefault(tickOpts.fontSize, defaults.fontSize) + tickOpts.backdropPaddingY * 2; + return valueOrDefault(tickOpts.font && tickOpts.font.size, defaults.font.size) + tickOpts.backdropPaddingY * 2; } return 0; } @@ -130,7 +132,7 @@ function fitWithPointLabels(scale) { // // https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif - const plFont = _parseFont(scale.options.pointLabels); + const plFont = toFont(scale.options.pointLabels.font); // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points @@ -220,11 +222,10 @@ function drawPointLabels(scale) { const pointLabelOpts = opts.pointLabels; const tickBackdropHeight = getTickBackdropHeight(opts); const outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max); - const plFont = _parseFont(pointLabelOpts); + const plFont = toFont(pointLabelOpts.font); ctx.save(); - ctx.font = plFont.string; ctx.textBaseline = 'middle'; for (let i = scale.chart.data.labels.length - 1; i >= 0; i--) { @@ -233,8 +234,8 @@ function drawPointLabels(scale) { const pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + 5); // Keep this in loop since we may support array properties here - const pointLabelFontColor = valueAtIndexOrDefault(pointLabelOpts.fontColor, i, defaults.fontColor); - ctx.fillStyle = pointLabelFontColor; + ctx.font = plFont.string; + ctx.fillStyle = plFont.color; const angleRadians = scale.getIndexAngle(i); const angle = toDegrees(angleRadians); @@ -505,8 +506,7 @@ export default class RadialLinearScale extends LinearScaleBase { } const startAngle = me.getIndexAngle(0); - const tickFont = _parseFont(tickOpts); - const tickFontColor = valueOrDefault(tickOpts.fontColor, defaults.fontColor); + const tickFont = toFont(tickOpts.font); let offset, width; ctx.save(); @@ -535,7 +535,7 @@ export default class RadialLinearScale extends LinearScaleBase { ); } - ctx.fillStyle = tickFontColor; + ctx.fillStyle = tickFont.color; ctx.fillText(tick.label, 0, -offset); }); diff --git a/src/scales/scale.time.js b/src/scales/scale.time.js index a4f232a77..480cd706c 100644 --- a/src/scales/scale.time.js +++ b/src/scales/scale.time.js @@ -1,5 +1,4 @@ import adapters from '../core/core.adapters'; -import defaults from '../core/core.defaults'; import {isFinite, isNullOrUndef, mergeIf, valueOrDefault} from '../helpers/helpers.core'; import {toRadians} from '../helpers/helpers.math'; import Scale from '../core/core.scale'; @@ -785,7 +784,7 @@ export default class TimeScale extends Scale { const angle = toRadians(me.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation); const cosRotation = Math.cos(angle); const sinRotation = Math.sin(angle); - const tickFontSize = valueOrDefault(ticksOpts.fontSize, defaults.fontSize); + const tickFontSize = me._resolveTickFontOptions(0).size; return { w: (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation), diff --git a/test/specs/core.controller.tests.js b/test/specs/core.controller.tests.js index 42832301c..2af65e540 100644 --- a/test/specs/core.controller.tests.js +++ b/test/specs/core.controller.tests.js @@ -75,7 +75,7 @@ describe('Chart', function() { }); var options = chart.options; - expect(options.fontSize).toBe(defaults.fontSize); + expect(options.font.size).toBe(defaults.font.size); expect(options.showLines).toBe(defaults.line.showLines); expect(options.spanGaps).toBe(true); expect(options.hover.onHover).toBe(callback); diff --git a/test/specs/helpers.options.tests.js b/test/specs/helpers.options.tests.js index 41aaa8f3c..8622d4570 100644 --- a/test/specs/helpers.options.tests.js +++ b/test/specs/helpers.options.tests.js @@ -1,11 +1,7 @@ -'use strict'; +const {toLineHeight, toPadding, toFont, resolve} = Chart.helpers.options; // from '../../src/helpers/helpers.options'; describe('Chart.helpers.options', function() { - var options = Chart.helpers.options; - describe('toLineHeight', function() { - var toLineHeight = options.toLineHeight; - it ('should support keyword values', function() { expect(toLineHeight('normal', 16)).toBe(16 * 1.2); }); @@ -28,8 +24,6 @@ describe('Chart.helpers.options', function() { }); describe('toPadding', function() { - var toPadding = options.toPadding; - it ('should support number values', function() { expect(toPadding(4)).toEqual( {top: 4, right: 4, bottom: 4, left: 4, height: 8, width: 8}); @@ -66,102 +60,102 @@ describe('Chart.helpers.options', function() { }); }); - describe('_parseFont', function() { - var parseFont = options._parseFont; + describe('toFont', function() { + it('should return a font with default values', function() { + const defaultFont = Object.assign({}, Chart.defaults.font); - it ('should return a font with default values', function() { - const fontFamily = Chart.defaults.fontFamily; - const fontSize = Chart.defaults.fontSize; - const fontStyle = Chart.defaults.fontStyle; - const lineHeight = Chart.defaults.lineHeight; - - Object.assign(Chart.defaults, { - fontFamily: 'foobar', - fontSize: 42, - fontStyle: 'xxxyyy', + Object.assign(Chart.defaults.font, { + color: 'bar', + family: 'foobar', + size: 42, + style: 'xxxyyy', lineHeight: 1.5 }); - expect(parseFont({})).toEqual({ + expect(toFont({})).toEqual({ + color: 'bar', family: 'foobar', lineHeight: 63, size: 42, string: 'xxxyyy 42px foobar', style: 'xxxyyy', - weight: null + weight: null, + lineWidth: 0, + strokeStyle: undefined }); - Object.assign(Chart.defaults, { - fontFamily, - fontSize, - fontStyle, - lineHeight - }); + Object.assign(Chart.defaults.font, defaultFont); }); it ('should return a font with given values', function() { - expect(parseFont({ - fontFamily: 'bla', + expect(toFont({ + color: 'asd', + family: 'bla', lineHeight: 8, - fontSize: 21, - fontStyle: 'zzz' + size: 21, + style: 'zzz' })).toEqual({ + color: 'asd', family: 'bla', lineHeight: 8 * 21, size: 21, string: 'zzz 21px bla', style: 'zzz', - weight: null + weight: null, + lineWidth: 0, + strokeStyle: undefined }); }); it ('should handle a string font size', function() { - expect(parseFont({ - fontFamily: 'bla', + expect(toFont({ + color: 'asd', + family: 'bla', lineHeight: 8, - fontSize: '21', - fontStyle: 'zzz' + size: '21', + style: 'zzz' })).toEqual({ + color: 'asd', family: 'bla', lineHeight: 8 * 21, size: 21, string: 'zzz 21px bla', style: 'zzz', - weight: null + weight: null, + lineWidth: 0, + strokeStyle: undefined }); }); - it('should return null as a font string if fontSize or fontFamily are missing', function() { - const fontFamily = Chart.defaults.fontFamily; - const fontSize = Chart.defaults.fontSize; - delete Chart.defaults.fontFamily; - delete Chart.defaults.fontSize; + it('should return null as a font string if size or family are missing', function() { + const fontFamily = Chart.defaults.font.family; + const fontSize = Chart.defaults.font.size; + delete Chart.defaults.font.family; + delete Chart.defaults.font.size; - expect(parseFont({ - fontStyle: 'italic', - fontSize: 12 + expect(toFont({ + style: 'italic', + size: 12 }).string).toBeNull(); - expect(parseFont({ - fontStyle: 'italic', - fontFamily: 'serif' + expect(toFont({ + style: 'italic', + family: 'serif' }).string).toBeNull(); - Chart.defaults.fontFamily = fontFamily; - Chart.defaults.fontSize = fontSize; + Chart.defaults.font.family = fontFamily; + Chart.defaults.font.size = fontSize; }); - it('fontStyle should be optional for font strings', function() { - const fontStyle = Chart.defaults.fontStyle; - delete Chart.defaults.fontStyle; + it('font.style should be optional for font strings', function() { + const fontStyle = Chart.defaults.font.style; + delete Chart.defaults.font.style; - expect(parseFont({ - fontSize: 12, - fontFamily: 'serif' + expect(toFont({ + size: 12, + family: 'serif' }).string).toBe('12px serif'); - Chart.defaults.fontStyle = fontStyle; + Chart.defaults.font.style = fontStyle; }); }); describe('resolve', function() { - var resolve = options.resolve; - it ('should fallback to the first defined input', function() { expect(resolve([42])).toBe(42); expect(resolve([42, 'foo'])).toBe(42); diff --git a/test/specs/plugin.title.tests.js b/test/specs/plugin.title.tests.js index b2f804167..b0c1c7ea8 100644 --- a/test/specs/plugin.title.tests.js +++ b/test/specs/plugin.title.tests.js @@ -10,7 +10,9 @@ describe('Title block tests', function() { position: 'top', fullWidth: true, weight: 2000, - fontStyle: 'bold', + font: { + style: 'bold' + }, padding: 10, text: '' }); @@ -74,7 +76,7 @@ describe('Title block tests', function() { options.text = ['line1', 'line2']; options.position = 'left'; options.display = true; - options.lineHeight = 1.5; + options.font.lineHeight = 1.5; var title = new Title({ chart: chart, diff --git a/test/specs/plugin.tooltip.tests.js b/test/specs/plugin.tooltip.tests.js index b352b1a98..724982f74 100644 --- a/test/specs/plugin.tooltip.tests.js +++ b/test/specs/plugin.tooltip.tests.js @@ -75,33 +75,39 @@ describe('Core.Tooltip', function() { expect(tooltip.xAlign).toEqual('left'); expect(tooltip.yAlign).toEqual('center'); + expect(tooltip.options.bodyFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: defaults.font.style, + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Body - bodyFontColor: '#fff', - bodyFontFamily: defaults.fontFamily, - bodyFontStyle: defaults.fontStyle, bodyAlign: 'left', - bodyFontSize: defaults.fontSize, bodySpacing: 2, })); + expect(tooltip.options.titleFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Title - titleFontColor: '#fff', - titleFontFamily: defaults.fontFamily, - titleFontStyle: 'bold', - titleFontSize: defaults.fontSize, titleAlign: 'left', titleSpacing: 2, titleMarginBottom: 6, })); + expect(tooltip.options.footerFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Footer - footerFontColor: '#fff', - footerFontFamily: defaults.fontFamily, - footerFontStyle: 'bold', - footerFontSize: defaults.fontSize, footerAlign: 'left', footerSpacing: 2, footerMarginTop: 6, @@ -233,33 +239,39 @@ describe('Core.Tooltip', function() { expect(tooltip.xAlign).toEqual('left'); expect(tooltip.yAlign).toEqual('center'); + expect(tooltip.options.bodyFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: defaults.font.style, + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Body - bodyFontColor: '#fff', - bodyFontFamily: defaults.fontFamily, - bodyFontStyle: defaults.fontStyle, bodyAlign: 'left', - bodyFontSize: defaults.fontSize, bodySpacing: 2, })); + expect(tooltip.options.titleFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Title - titleFontColor: '#fff', - titleFontFamily: defaults.fontFamily, - titleFontStyle: 'bold', - titleFontSize: defaults.fontSize, titleAlign: 'left', titleSpacing: 2, titleMarginBottom: 6, })); + expect(tooltip.options.footerFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Footer - footerFontColor: '#fff', - footerFontFamily: defaults.fontFamily, - footerFontStyle: 'bold', - footerFontSize: defaults.fontSize, footerAlign: 'left', footerSpacing: 2, footerMarginTop: 6, @@ -275,25 +287,22 @@ describe('Core.Tooltip', function() { displayColors: true })); - expect(tooltip).toEqual(jasmine.objectContaining({ - opacity: 1, - - // Text - title: ['Point 2'], - beforeBody: [], - body: [{ - before: [], - lines: ['Dataset 1: 20'], - after: [] - }], - afterBody: [], - footer: [], - labelTextColors: ['#fff'], - labelColors: [{ - borderColor: defaults.color, - backgroundColor: defaults.color - }] - })); + expect(tooltip.opacity).toEqual(1); + expect(tooltip.title).toEqual(['Point 2']); + expect(tooltip.beforeBody).toEqual([]); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Dataset 1: 20'], + after: [] + }]); + expect(tooltip.afterBody).toEqual([]); + expect(tooltip.footer).toEqual([]); + expect(tooltip.labelTextColors).toEqual(['#fff']); + + expect(tooltip.labelColors).toEqual([{ + borderColor: defaults.color, + backgroundColor: defaults.color + }]); expect(tooltip.x).toBeCloseToPixel(267); expect(tooltip.y).toBeCloseToPixel(312); @@ -379,33 +388,38 @@ describe('Core.Tooltip', function() { expect(tooltip.xAlign).toEqual('center'); expect(tooltip.yAlign).toEqual('top'); + expect(tooltip.options.bodyFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: defaults.font.style, + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Body - bodyFontColor: '#fff', - bodyFontFamily: defaults.fontFamily, - bodyFontStyle: defaults.fontStyle, bodyAlign: 'left', - bodyFontSize: defaults.fontSize, bodySpacing: 2, })); + expect(tooltip.options.titleFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Title - titleFontColor: '#fff', - titleFontFamily: defaults.fontFamily, - titleFontStyle: 'bold', - titleFontSize: defaults.fontSize, - titleAlign: 'left', titleSpacing: 2, titleMarginBottom: 6, })); + expect(tooltip.options.footerFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Footer - footerFontColor: '#fff', - footerFontFamily: defaults.fontFamily, - footerFontStyle: 'bold', - footerFontSize: defaults.fontSize, footerAlign: 'left', footerSpacing: 2, footerMarginTop: 6, @@ -1091,33 +1105,39 @@ describe('Core.Tooltip', function() { expect(tooltip.xAlign).toEqual('center'); expect(tooltip.yAlign).toEqual('top'); + expect(tooltip.options.bodyFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: defaults.font.style, + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Body - bodyFontColor: '#fff', - bodyFontFamily: defaults.fontFamily, - bodyFontStyle: defaults.fontStyle, bodyAlign: 'left', - bodyFontSize: defaults.fontSize, bodySpacing: 2, })); + expect(tooltip.options.titleFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Title - titleFontColor: '#fff', - titleFontFamily: defaults.fontFamily, - titleFontStyle: 'bold', - titleFontSize: defaults.fontSize, titleAlign: 'left', titleSpacing: 2, titleMarginBottom: 6, })); + expect(tooltip.options.footerFont).toEqual(jasmine.objectContaining({ + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + })); + expect(tooltip.options).toEqual(jasmine.objectContaining({ - // Footer - footerFontColor: '#fff', - footerFontFamily: defaults.fontFamily, - footerFontStyle: 'bold', - footerFontSize: defaults.fontSize, footerAlign: 'left', footerSpacing: 2, footerMarginTop: 6, @@ -1182,27 +1202,33 @@ describe('Core.Tooltip', function() { yPadding: 5, // Body - bodyFontColor: '#fff', - bodyFontFamily: defaults.fontFamily, - bodyFontStyle: defaults.fontStyle, + bodyFont: { + color: '#fff', + family: defaults.font.family, + style: defaults.font.style, + size: defaults.font.size, + }, bodyAlign: body, - bodyFontSize: defaults.fontSize, bodySpacing: 2, // Title - titleFontColor: '#fff', - titleFontFamily: defaults.fontFamily, - titleFontStyle: 'bold', - titleFontSize: defaults.fontSize, + titleFont: { + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + }, titleAlign: title, titleSpacing: 2, titleMarginBottom: 6, // Footer - footerFontColor: '#fff', - footerFontFamily: defaults.fontFamily, - footerFontStyle: 'bold', - footerFontSize: defaults.fontSize, + footerFont: { + color: '#fff', + family: defaults.font.family, + style: 'bold', + size: defaults.font.size, + }, footerAlign: footer, footerSpacing: 2, footerMarginTop: 6, diff --git a/test/specs/scale.radialLinear.tests.js b/test/specs/scale.radialLinear.tests.js index 4958cfb0d..240a2edd0 100644 --- a/test/specs/scale.radialLinear.tests.js +++ b/test/specs/scale.radialLinear.tests.js @@ -39,7 +39,9 @@ describe('Test the radial linear scale', function() { }, pointLabels: { display: true, - fontSize: 10, + font: { + size: 10, + }, callback: defaultConfig.pointLabels.callback, // make this nicer, then check explicitly below }, position: 'chartArea',