From 738ee34d0b4699e8797c19224ba1559cd7d54169 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Mon, 13 Jan 2020 16:33:46 -0800 Subject: [PATCH] Scriptable tick fonts (#6939) * Remove extra font parsing in Scale.fit * Implement scriptable options for tick formatting --- docs/axes/styling.md | 51 +++++++++------------------- docs/getting-started/v3-migration.md | 1 + samples/scales/time/financial.html | 4 ++- src/core/core.scale.js | 50 +++++++++++++-------------- 4 files changed, 44 insertions(+), 62 deletions(-) diff --git a/docs/axes/styling.md b/docs/axes/styling.md index 87edac46b..95e5d0eec 100644 --- a/docs/axes/styling.md +++ b/docs/axes/styling.md @@ -35,44 +35,25 @@ 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 | 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` | `'#666'` | Font color for tick labels. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the tick labels, follows CSS font-family options. -| `fontSize` | `number` | `12` | Font size for the tick labels. -| `fontStyle` | `string` | `'normal'` | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit). -| `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)). -| `reverse` | `boolean` | `false` | Reverses order of tick labels. -| `lineWidth` | `number` | `0` | Stroke width around the text. -| `minor` | `object` | `{}` | Minor ticks configuration. Omitted options are inherited from options above. -| `major` | `object` | `{}` | Major ticks configuration. Omitted options are inherited from options above. -| `padding` | `number` | `0` | Sets the offset of the tick labels from the axis -| `strokeStyle` | `string` | `` | 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. - -## Minor Tick Configuration -The minorTick configuration is nested under the ticks configuration in the `minor` key. It defines options for the minor tick marks that are generated by the axis. Omitted options are inherited from `ticks` configuration. - -| Name | Type | Default | Description +| 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). -| `fontColor` | `Color` | `'#666'` | Font color for tick labels. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the tick labels, follows CSS font-family options. -| `fontSize` | `number` | `12` | Font size for the tick labels. -| `fontStyle` | `string` | `'normal'` | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit). -| `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)). +| `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. +| `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. Omitted options are inherited from `ticks` configuration. These options are disabled by default. +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 | ---- | ---- | ------- | ----------- -| `enabled` | `boolean` | `false` | If true, major tick options are used to show major ticks. -| `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). -| `fontColor` | `Color` | `'#666'` | Font color for tick labels. -| `fontFamily` | `string` | `"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif"` | Font family for the tick labels, follows CSS font-family options. -| `fontSize` | `number` | `12` | Font size for the tick labels. -| `fontStyle` | `string` | `'normal'` | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit). -| `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)). +| `enabled` | `boolean` | `false` | If true, major ticks are generated. A major tick will affect autoskipping and `major` will be defined on ticks in the scriptable options context. diff --git a/docs/getting-started/v3-migration.md b/docs/getting-started/v3-migration.md index f280cd2b5..986d03221 100644 --- a/docs/getting-started/v3-migration.md +++ b/docs/getting-started/v3-migration.md @@ -12,6 +12,7 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released ### Ticks * `options.ticks.userCallback` was renamed to `options.ticks.callback` +* `options.ticks.major` and `options.ticks.minor` were replaced with scriptable options for tick fonts. ### Tooltip diff --git a/samples/scales/time/financial.html b/samples/scales/time/financial.html index 5183babb7..70246820c 100644 --- a/samples/scales/time/financial.html +++ b/samples/scales/time/financial.html @@ -122,7 +122,9 @@ ticks: { major: { enabled: true, - fontStyle: 'bold' + }, + fontStyle: function(context) { + return context.tick.major ? 'bold' : undefined; }, source: 'data', autoSkip: true, diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 01aa71784..2f9bfce96 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -135,26 +135,6 @@ function getScaleLabelHeight(options) { return font.lineHeight + padding.height; } -function parseFontOptions(options, nestedOpts) { - return helpers.extend(helpers.options._parseFont({ - fontFamily: valueOrDefault(nestedOpts.fontFamily, options.fontFamily), - fontSize: valueOrDefault(nestedOpts.fontSize, options.fontSize), - fontStyle: valueOrDefault(nestedOpts.fontStyle, options.fontStyle), - lineHeight: valueOrDefault(nestedOpts.lineHeight, options.lineHeight) - }), { - color: resolve([nestedOpts.fontColor, options.fontColor, defaults.fontColor]), - lineWidth: valueOrDefault(nestedOpts.lineWidth, options.lineWidth), - strokeStyle: valueOrDefault(nestedOpts.strokeStyle, options.strokeStyle) - }); -} - -function parseTickFontOptions(options) { - const minor = parseFontOptions(options, options.minor); - const major = options.major.enabled ? parseFontOptions(options, options.major) : minor; - - return {minor, major}; -} - function getEvenSpacing(arr) { const len = arr.length; let i, diff; @@ -627,13 +607,12 @@ class Scale extends Element { // Don't bother fitting the ticks if we are not showing the labels if (tickOpts.display && display) { - const tickFonts = parseTickFontOptions(tickOpts); const labelSizes = me._getLabelSizes(); const firstLabelSize = labelSizes.first; const lastLabelSize = labelSizes.last; const widestLabelSize = labelSizes.widest; const highestLabelSize = labelSizes.highest; - const lineSpace = tickFonts.minor.lineHeight * 0.4; + const lineSpace = highestLabelSize.offset * 0.8; const tickPadding = tickOpts.padding; if (isHorizontal) { @@ -756,7 +735,6 @@ class Scale extends Element { _computeLabelSizes() { const me = this; const ctx = me.ctx; - const tickFonts = parseTickFontOptions(me.options.ticks); const caches = me._longestTextCache; const sampleSize = me.options.ticks.sampleSize; const widths = []; @@ -771,7 +749,7 @@ class Scale extends Element { for (i = 0; i < length; ++i) { label = ticks[i].label; - tickFont = ticks[i].major ? tickFonts.major : tickFonts.minor; + tickFont = me._resolveTickFontOptions(i); ctx.font = fontString = tickFont.string; cache = caches[fontString] = caches[fontString] || {data: {}, gc: []}; lineHeight = tickFont.lineHeight; @@ -1104,7 +1082,6 @@ class Scale extends Element { const isMirrored = optionTicks.mirror; const isHorizontal = me.isHorizontal(); const ticks = me.ticks; - const fonts = parseTickFontOptions(optionTicks); const tickPadding = optionTicks.padding; const tl = getTickMarkLength(options.gridLines); const rotation = -helpers.math.toRadians(me.labelRotation); @@ -1148,7 +1125,7 @@ class Scale extends Element { label = tick.label; pixel = me.getPixelForTick(i) + optionTicks.labelOffset; - font = tick.major ? fonts.major : fonts.minor; + font = me._resolveTickFontOptions(i); lineHeight = font.lineHeight; lineCount = isArray(label) ? label.length : 1; @@ -1450,6 +1427,27 @@ class Scale extends Element { } return result; } + + _resolveTickFontOptions(index) { + const me = this; + const options = me.options.ticks; + const context = { + chart: me.chart, + scale: me, + tick: me.ticks[index], + index: index + }; + return helpers.extend(helpers.options._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) + }); + } } Scale.prototype._draw = Scale.prototype.draw; -- 2.47.2