]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Scale: refactor drawTitle, add tests (#8598)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Tue, 9 Mar 2021 13:35:43 +0000 (15:35 +0200)
committerGitHub <noreply@github.com>
Tue, 9 Mar 2021 13:35:43 +0000 (08:35 -0500)
* Scale: refactor drawTitle, add tests
* CC, lint
* update

15 files changed:
src/core/core.scale.js
test/fixtures/core.scale/title-multi-line.js [deleted file]
test/fixtures/core.scale/title-multi-line.png [deleted file]
test/fixtures/core.scale/title/align-end.js [new file with mode: 0644]
test/fixtures/core.scale/title/align-end.png [new file with mode: 0644]
test/fixtures/core.scale/title/align-start.js [new file with mode: 0644]
test/fixtures/core.scale/title/align-start.png [new file with mode: 0644]
test/fixtures/core.scale/title/default.js [new file with mode: 0644]
test/fixtures/core.scale/title/default.png [new file with mode: 0644]
test/fixtures/core.scale/title/multi-line/align-end.js [new file with mode: 0644]
test/fixtures/core.scale/title/multi-line/align-end.png [new file with mode: 0644]
test/fixtures/core.scale/title/multi-line/align-start.js [new file with mode: 0644]
test/fixtures/core.scale/title/multi-line/align-start.png [new file with mode: 0644]
test/fixtures/core.scale/title/multi-line/default.js [new file with mode: 0644]
test/fixtures/core.scale/title/multi-line/default.png [new file with mode: 0644]

index ca7b278ddd45c0f0afd8e338b58fbe9bbe2e99a2..684916e7fee8519be6f42a877a4db2dc6d58afc8 100644 (file)
@@ -2,10 +2,14 @@ import defaults from './core.defaults';
 import Element from './core.element';
 import {_alignPixel, _measureText, renderText, clipArea, unclipArea} from '../helpers/helpers.canvas';
 import {callback as call, each, finiteOrDefault, isArray, isFinite, isNullOrUndef, isObject, valueOrDefault} from '../helpers/helpers.core';
-import {_factorize, toDegrees, toRadians, _int16Range, HALF_PI, _limitValue} from '../helpers/helpers.math';
+import {_factorize, toDegrees, toRadians, _int16Range, _limitValue, HALF_PI} from '../helpers/helpers.math';
+import {_alignStartEnd, _toLeftRightCenter} from '../helpers/helpers.extras';
 import {toFont, toPadding} from '../helpers/helpers.options';
 import Ticks from './core.ticks';
 
+const reverseAlign = (align) => align === 'left' ? 'right' : align === 'right' ? 'left' : align;
+const offsetFromEdge = (scale, edge, offset) => edge === 'top' || edge === 'left' ? scale[edge] + offset : scale[edge] - offset;
+
 /**
  * @typedef { import("./core.controller").default } Chart
  * @typedef {{value:number | string, label?:string, major?:boolean, $context?:any}} Tick
@@ -317,6 +321,31 @@ function createTickContext(parent, index, tick) {
   });
 }
 
+function titleAlign(align, position, reverse) {
+  let ret = _toLeftRightCenter(align);
+  if ((reverse && position !== 'right') || (!reverse && position === 'right')) {
+    ret = reverseAlign(ret);
+  }
+  return ret;
+}
+
+function titleArgs(scale, offset, position, align) {
+  const {top, left, bottom, right} = scale;
+  let rotation = 0;
+  let maxWidth, titleX, titleY;
+
+  if (scale.isHorizontal()) {
+    titleX = _alignStartEnd(align, left, right);
+    titleY = offsetFromEdge(scale, position, offset);
+    maxWidth = right - left;
+  } else {
+    titleX = offsetFromEdge(scale, position, offset);
+    titleY = _alignStartEnd(align, bottom, top);
+    rotation = position === 'left' ? -HALF_PI : HALF_PI;
+  }
+  return {titleX, titleY, maxWidth, rotation};
+}
+
 export default class Scale extends Element {
 
   // eslint-disable-next-line max-statements
@@ -1661,69 +1690,34 @@ export default class Scale extends Element {
   /**
         * @protected
         */
-  drawTitle(chartArea) { // eslint-disable-line no-unused-vars
-    const me = this;
-    const ctx = me.ctx;
-    const options = me.options;
-    const title = options.title;
+  drawTitle() {
+    const {ctx, options: {position, title, reverse}} = this;
 
     if (!title.display) {
       return;
     }
 
-    const titleFont = toFont(title.font);
-    const titlePadding = toPadding(title.padding);
-    const halfLineHeight = titleFont.lineHeight / 2;
-    const titleAlign = title.align;
-    const position = options.position;
-    const isReverse = me.options.reverse;
-    let rotation = 0;
-    /** @type CanvasTextAlign */
-    let textAlign;
-    let titleX, titleY;
+    const font = toFont(title.font);
+    const padding = toPadding(title.padding);
+    const align = title.align;
+    let offset = font.lineHeight / 2;
 
-    if (me.isHorizontal()) {
-      switch (titleAlign) {
-      case 'start':
-        titleX = me.left + (isReverse ? me.width : 0);
-        textAlign = isReverse ? 'right' : 'left';
-        break;
-      case 'end':
-        titleX = me.left + (isReverse ? 0 : me.width);
-        textAlign = isReverse ? 'left' : 'right';
-        break;
-      default:
-        titleX = me.left + me.width / 2;
-        textAlign = 'center';
+    if (position === 'bottom') {
+      offset += padding.bottom;
+      if (isArray(title.text)) {
+        offset += font.lineHeight * (title.text.length - 1);
       }
-      titleY = position === 'top'
-        ? me.top + halfLineHeight + titlePadding.top
-        : me.bottom - halfLineHeight - titlePadding.bottom;
     } else {
-      const isLeft = position === 'left';
-      titleX = isLeft
-        ? me.left + halfLineHeight + titlePadding.top
-        : me.right - halfLineHeight - titlePadding.top;
-      switch (titleAlign) {
-      case 'start':
-        titleY = me.top + (isReverse ? 0 : me.height);
-        textAlign = isReverse === isLeft ? 'right' : 'left';
-        break;
-      case 'end':
-        titleY = me.top + (isReverse ? me.height : 0);
-        textAlign = isReverse === isLeft ? 'left' : 'right';
-        break;
-      default:
-        titleY = me.top + me.height / 2;
-        textAlign = 'center';
-      }
-      rotation = isLeft ? -HALF_PI : HALF_PI;
+      offset += padding.top;
     }
 
-    renderText(ctx, title.text, 0, 0, titleFont, {
+    const {titleX, titleY, maxWidth, rotation} = titleArgs(this, offset, position, align);
+
+    renderText(ctx, title.text, 0, 0, font, {
       color: title.color,
+      maxWidth,
       rotation,
-      textAlign,
+      textAlign: titleAlign(align, position, reverse),
       textBaseline: 'middle',
       translation: [titleX, titleY],
     });
diff --git a/test/fixtures/core.scale/title-multi-line.js b/test/fixtures/core.scale/title-multi-line.js
deleted file mode 100644 (file)
index d116254..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-module.exports = {
-  config: {
-    type: 'line',
-    data: {
-      datasets: [{
-        data: [1, -1, 3],
-      }],
-      labels: ['Label1', 'Label2', 'Label3']
-    },
-    options: {
-      scales: {
-        y: {
-          title: {
-            display: true,
-            text: [
-              'Line 1',
-              'Line 2',
-              'Line 3',
-            ]
-          }
-        }
-      }
-    }
-  },
-  options: {
-    spriteText: true,
-    canvas: {
-      height: 256,
-      width: 512
-    }
-  }
-};
diff --git a/test/fixtures/core.scale/title-multi-line.png b/test/fixtures/core.scale/title-multi-line.png
deleted file mode 100644 (file)
index 291bb28..0000000
Binary files a/test/fixtures/core.scale/title-multi-line.png and /dev/null differ
diff --git a/test/fixtures/core.scale/title/align-end.js b/test/fixtures/core.scale/title/align-end.js
new file mode 100644 (file)
index 0000000..81059cf
--- /dev/null
@@ -0,0 +1,77 @@
+module.exports = {
+  config: {
+    type: 'line',
+    options: {
+      events: [],
+      scales: {
+        top: {
+          type: 'linear',
+          position: 'top',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'end',
+            text: 'top'
+          }
+        },
+        left: {
+          type: 'linear',
+          position: 'left',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'end',
+            text: 'left'
+          }
+        },
+        bottom: {
+          type: 'linear',
+          position: 'bottom',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'end',
+            text: 'bottom'
+          }
+        },
+        right: {
+          type: 'linear',
+          position: 'right',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'end',
+            text: 'right'
+          }
+        },
+      }
+    }
+  },
+  options: {
+    spriteText: true,
+    canvas: {
+      height: 256,
+      width: 256
+    },
+  }
+};
diff --git a/test/fixtures/core.scale/title/align-end.png b/test/fixtures/core.scale/title/align-end.png
new file mode 100644 (file)
index 0000000..f52a7bf
Binary files /dev/null and b/test/fixtures/core.scale/title/align-end.png differ
diff --git a/test/fixtures/core.scale/title/align-start.js b/test/fixtures/core.scale/title/align-start.js
new file mode 100644 (file)
index 0000000..385f172
--- /dev/null
@@ -0,0 +1,77 @@
+module.exports = {
+  config: {
+    type: 'line',
+    options: {
+      events: [],
+      scales: {
+        top: {
+          type: 'linear',
+          position: 'top',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'start',
+            text: 'top'
+          }
+        },
+        left: {
+          type: 'linear',
+          position: 'left',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'start',
+            text: 'left'
+          }
+        },
+        bottom: {
+          type: 'linear',
+          position: 'bottom',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'start',
+            text: 'bottom'
+          }
+        },
+        right: {
+          type: 'linear',
+          position: 'right',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'start',
+            text: 'right'
+          }
+        },
+      }
+    }
+  },
+  options: {
+    spriteText: true,
+    canvas: {
+      height: 256,
+      width: 256
+    },
+  }
+};
diff --git a/test/fixtures/core.scale/title/align-start.png b/test/fixtures/core.scale/title/align-start.png
new file mode 100644 (file)
index 0000000..7a1317e
Binary files /dev/null and b/test/fixtures/core.scale/title/align-start.png differ
diff --git a/test/fixtures/core.scale/title/default.js b/test/fixtures/core.scale/title/default.js
new file mode 100644 (file)
index 0000000..9570d89
--- /dev/null
@@ -0,0 +1,73 @@
+module.exports = {
+  config: {
+    type: 'line',
+    options: {
+      events: [],
+      scales: {
+        top: {
+          type: 'linear',
+          position: 'top',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            text: 'top'
+          }
+        },
+        left: {
+          type: 'linear',
+          position: 'left',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            text: 'left'
+          }
+        },
+        bottom: {
+          type: 'linear',
+          position: 'bottom',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            text: 'bottom'
+          }
+        },
+        right: {
+          type: 'linear',
+          position: 'right',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            text: 'right'
+          }
+        },
+      }
+    }
+  },
+  options: {
+    spriteText: true,
+    canvas: {
+      height: 256,
+      width: 256
+    },
+  }
+};
diff --git a/test/fixtures/core.scale/title/default.png b/test/fixtures/core.scale/title/default.png
new file mode 100644 (file)
index 0000000..3dc2270
Binary files /dev/null and b/test/fixtures/core.scale/title/default.png differ
diff --git a/test/fixtures/core.scale/title/multi-line/align-end.js b/test/fixtures/core.scale/title/multi-line/align-end.js
new file mode 100644 (file)
index 0000000..b6d980b
--- /dev/null
@@ -0,0 +1,77 @@
+module.exports = {
+  config: {
+    type: 'line',
+    options: {
+      events: [],
+      scales: {
+        top: {
+          type: 'linear',
+          position: 'top',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'end',
+            text: ['top', 'line2', 'line3']
+          }
+        },
+        left: {
+          type: 'linear',
+          position: 'left',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'end',
+            text: ['left', 'line2', 'line3']
+          }
+        },
+        bottom: {
+          type: 'linear',
+          position: 'bottom',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'end',
+            text: ['bottom', 'line2', 'line3']
+          }
+        },
+        right: {
+          type: 'linear',
+          position: 'right',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'end',
+            text: ['right', 'line2', 'line3']
+          }
+        },
+      }
+    }
+  },
+  options: {
+    spriteText: true,
+    canvas: {
+      height: 256,
+      width: 256
+    },
+  }
+};
diff --git a/test/fixtures/core.scale/title/multi-line/align-end.png b/test/fixtures/core.scale/title/multi-line/align-end.png
new file mode 100644 (file)
index 0000000..155da25
Binary files /dev/null and b/test/fixtures/core.scale/title/multi-line/align-end.png differ
diff --git a/test/fixtures/core.scale/title/multi-line/align-start.js b/test/fixtures/core.scale/title/multi-line/align-start.js
new file mode 100644 (file)
index 0000000..c0e97cb
--- /dev/null
@@ -0,0 +1,77 @@
+module.exports = {
+  config: {
+    type: 'line',
+    options: {
+      events: [],
+      scales: {
+        top: {
+          type: 'linear',
+          position: 'top',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'start',
+            text: ['top', 'line2', 'line3']
+          }
+        },
+        left: {
+          type: 'linear',
+          position: 'left',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'start',
+            text: ['left', 'line2', 'line3']
+          }
+        },
+        bottom: {
+          type: 'linear',
+          position: 'bottom',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'start',
+            text: ['bottom', 'line2', 'line3']
+          }
+        },
+        right: {
+          type: 'linear',
+          position: 'right',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            align: 'start',
+            text: ['right', 'line2', 'line3']
+          }
+        },
+      }
+    }
+  },
+  options: {
+    spriteText: true,
+    canvas: {
+      height: 256,
+      width: 256
+    },
+  }
+};
diff --git a/test/fixtures/core.scale/title/multi-line/align-start.png b/test/fixtures/core.scale/title/multi-line/align-start.png
new file mode 100644 (file)
index 0000000..dcba460
Binary files /dev/null and b/test/fixtures/core.scale/title/multi-line/align-start.png differ
diff --git a/test/fixtures/core.scale/title/multi-line/default.js b/test/fixtures/core.scale/title/multi-line/default.js
new file mode 100644 (file)
index 0000000..c320d0f
--- /dev/null
@@ -0,0 +1,73 @@
+module.exports = {
+  config: {
+    type: 'line',
+    options: {
+      events: [],
+      scales: {
+        top: {
+          type: 'linear',
+          position: 'top',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            text: ['top', 'line2', 'line3']
+          }
+        },
+        left: {
+          type: 'linear',
+          position: 'left',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            text: ['left', 'line2', 'line3']
+          }
+        },
+        bottom: {
+          type: 'linear',
+          position: 'bottom',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            text: ['bottom', 'line2', 'line3']
+          }
+        },
+        right: {
+          type: 'linear',
+          position: 'right',
+          ticks: {
+            display: false
+          },
+          gridLines: {
+            display: false
+          },
+          title: {
+            display: true,
+            text: ['right', 'line2', 'line3']
+          }
+        },
+      }
+    }
+  },
+  options: {
+    spriteText: true,
+    canvas: {
+      height: 256,
+      width: 256
+    },
+  }
+};
diff --git a/test/fixtures/core.scale/title/multi-line/default.png b/test/fixtures/core.scale/title/multi-line/default.png
new file mode 100644 (file)
index 0000000..f53f33e
Binary files /dev/null and b/test/fixtures/core.scale/title/multi-line/default.png differ