abstract-chart 10.0.10 → 10.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abstract-chart",
3
- "version": "10.0.10",
3
+ "version": "10.0.12",
4
4
  "description": "Drawing charts using multiple unit of measure axes as coordinate system",
5
5
  "repository": "https://github.com/dividab/abstract-visuals/tree/master/packages/abstract-chart",
6
6
  "main": "lib/index.js",
@@ -18,8 +18,8 @@
18
18
  "README.md"
19
19
  ],
20
20
  "dependencies": {
21
- "abstract-image": "^11.0.2",
21
+ "abstract-image": "^11.0.4",
22
22
  "ts-exhaustive-check": "^1.0.0"
23
23
  },
24
- "gitHead": "fb930ea31c7f94e451ec42da24a0405803a39797"
24
+ "gitHead": "2b28beae0303be1d261b3b91a7bd946986ba334a"
25
25
  }
package/src/chart.ts CHANGED
@@ -1,7 +1,16 @@
1
1
  /* eslint-disable max-lines */
2
- import * as AI from "abstract-image";
3
- import * as Axis from "./axis.js";
4
2
  import { exhaustiveCheck } from "ts-exhaustive-check";
3
+ import * as AI from "abstract-image";
4
+ import {
5
+ Axis,
6
+ AxisBase,
7
+ inverseTransformValue,
8
+ getTicks,
9
+ createLinearAxis,
10
+ transformValue,
11
+ transformPoint,
12
+ DiscreteAxisPoint,
13
+ } from "./axis.js";
5
14
 
6
15
  // tslint:disable:max-file-line-count
7
16
 
@@ -22,10 +31,10 @@ export interface Chart {
22
31
  readonly chartDataAxisesTop: Array<ChartDataAxis>;
23
32
  readonly chartDataAxisesLeft: Array<ChartDataAxis>;
24
33
  readonly chartDataAxisesRight: Array<ChartDataAxis>;
25
- readonly xAxisesBottom: ReadonlyArray<Axis.Axis>;
26
- readonly xAxisesTop: ReadonlyArray<Axis.Axis>;
27
- readonly yAxisesLeft: ReadonlyArray<Axis.Axis>;
28
- readonly yAxisesRight: ReadonlyArray<Axis.Axis>;
34
+ readonly xAxisesBottom: ReadonlyArray<Axis>;
35
+ readonly xAxisesTop: ReadonlyArray<Axis>;
36
+ readonly yAxisesLeft: ReadonlyArray<Axis>;
37
+ readonly yAxisesRight: ReadonlyArray<Axis>;
29
38
  readonly backgroundColor: AI.Color;
30
39
  readonly xGrid: ChartGrid;
31
40
  readonly yGrid: ChartGrid;
@@ -230,7 +239,7 @@ export function createChartStack(props: ChartStackProps): ChartStack {
230
239
  return { points, xAxis, yAxis, config };
231
240
  }
232
241
 
233
- export type ChartDataAxis = Axis.AxisBase & {
242
+ export type ChartDataAxis = AxisBase & {
234
243
  readonly points: Array<AI.Point>;
235
244
  };
236
245
 
@@ -268,13 +277,8 @@ export function inverseTransformPoint(point: AI.Point, chart: Chart, xAxis: XAxi
268
277
  const xMax = chart.width - padding.right;
269
278
  const yMin = chart.height - padding.bottom;
270
279
  const yMax = padding.top;
271
- const x = Axis.inverseTransformValue(
272
- point.x,
273
- xMin,
274
- xMax,
275
- xAxis === "top" ? chart.xAxisesTop[0] : chart.xAxisesBottom[0]
276
- );
277
- const y = Axis.inverseTransformValue(
280
+ const x = inverseTransformValue(point.x, xMin, xMax, xAxis === "top" ? chart.xAxisesTop[0] : chart.xAxisesBottom[0]);
281
+ const y = inverseTransformValue(
278
282
  point.y,
279
283
  yMin,
280
284
  yMax,
@@ -461,7 +465,7 @@ export function generateBackground(xMin: number, xMax: number, yMin: number, yMa
461
465
  export function xAxises(
462
466
  xAxis: XAxis,
463
467
  xNumTicks: number,
464
- axises: ReadonlyArray<Axis.Axis>,
468
+ axises: ReadonlyArray<Axis>,
465
469
  xMin: number,
466
470
  xMax: number,
467
471
  yMin: number,
@@ -476,7 +480,7 @@ export function xAxises(
476
480
  const [dirFactor, axisWidth] = xAxis === "bottom" ? [1, chart.axisWidth.bottom] : [-1, chart.axisWidth.top];
477
481
  for (const [ix, axis] of axises.entries()) {
478
482
  const fullGrid = ix === 0 && xAxis === "bottom";
479
- const xTicks = Axis.getTicks(xNumTicks, axis);
483
+ const xTicks = getTicks(xNumTicks, axis);
480
484
  if (chart.xGrid && !axis.noTicks) {
481
485
  gridLineComponents.push(
482
486
  generateXAxisGridLines(xMin, xMax, lineY + dirFactor * 10, fullGrid ? yMax : lineY, xTicks, axis, chart.xGrid)
@@ -533,7 +537,7 @@ export function xAxises(
533
537
  export function yAxises(
534
538
  yAxis: YAxis,
535
539
  yNumTicks: number,
536
- axises: ReadonlyArray<Axis.Axis>,
540
+ axises: ReadonlyArray<Axis>,
537
541
  xMin: number,
538
542
  xMax: number,
539
543
  yMin: number,
@@ -549,7 +553,7 @@ export function yAxises(
549
553
 
550
554
  for (const [ix, axis] of axises.entries()) {
551
555
  const fullGrid = ix === 0 && yAxis === "left";
552
- const yTicks = Axis.getTicks(yNumTicks, axis);
556
+ const yTicks = getTicks(yNumTicks, axis);
553
557
  if (chart.yGrid && !axis.noTicks) {
554
558
  gridLineComponents.push(
555
559
  generateYAxisLines(
@@ -624,7 +628,7 @@ export function generateDataAxisesX(
624
628
  for (const axis of axises) {
625
629
  const min = Math.min(...axis.points.map((p) => p.y));
626
630
  const max = Math.max(...axis.points.map((p) => p.y));
627
- const linear = Axis.createLinearAxis(
631
+ const linear = createLinearAxis(
628
632
  min,
629
633
  max,
630
634
  axis.label,
@@ -653,12 +657,12 @@ export function generateDataAxisesX(
653
657
  }
654
658
  return axis.points[axis.points.length - 1]?.x ?? 0;
655
659
  };
656
- const yValues = Axis.getTicks(numTicks, linear).map((t) => t.value);
660
+ const yValues = getTicks(numTicks, linear).map((t) => t.value);
657
661
  const lineY2 = lineY;
658
662
  components.push(
659
663
  ...yValues.flatMap((y) => {
660
664
  const tickX = findX(y);
661
- const x = Axis.transformValue(tickX, xMin, xMax, chart.xAxisesBottom[0]);
665
+ const x = transformValue(tickX, xMin, xMax, chart.xAxisesBottom[0]);
662
666
  const start = AI.createPoint(x, lineY2);
663
667
  const end = AI.createPoint(x, lineY2 + dirFactor * 10);
664
668
  const textPos = AI.createPoint(x, lineY2 + dirFactor * 12);
@@ -734,7 +738,7 @@ export function generateDataAxisesY(
734
738
  for (const axis of axises) {
735
739
  const min = Math.min(...axis.points.map((p) => p.y));
736
740
  const max = Math.max(...axis.points.map((p) => p.y));
737
- const linear = Axis.createLinearAxis(
741
+ const linear = createLinearAxis(
738
742
  min,
739
743
  max,
740
744
  axis.label,
@@ -763,12 +767,12 @@ export function generateDataAxisesY(
763
767
  }
764
768
  return axis.points[axis.points.length - 1]?.x ?? 0;
765
769
  };
766
- const yValues = Axis.getTicks(numTicks, linear).map((t) => t.value);
770
+ const yValues = getTicks(numTicks, linear).map((t) => t.value);
767
771
  const lineX2 = lineX;
768
772
  components.push(
769
773
  ...yValues.flatMap((y) => {
770
774
  const tickY = findX(y);
771
- const yPx = Axis.transformValue(tickY, yMin, yMax, chart.yAxisesLeft[0]);
775
+ const yPx = transformValue(tickY, yMin, yMax, chart.yAxisesLeft[0]);
772
776
  const start = AI.createPoint(lineX2, yPx);
773
777
  const end = AI.createPoint(lineX2 + dirFactor * 10, yPx);
774
778
  const textPos = AI.createPoint(lineX2 + dirFactor * 12, yPx);
@@ -864,7 +868,7 @@ function generateUnsignedStack(xMin: number, xMax: number, yMin: number, yMax: n
864
868
  let sumY = 0;
865
869
  const points = stackPoints.ys.map((y) => {
866
870
  sumY += y;
867
- return Axis.transformPoint(AI.createPoint(stackPoints.x, sumY), xMin, xMax, yMin, yMax, xAxis, yAxis);
871
+ return transformPoint(AI.createPoint(stackPoints.x, sumY), xMin, xMax, yMin, yMax, xAxis, yAxis);
868
872
  });
869
873
  return points;
870
874
  });
@@ -880,7 +884,7 @@ function generateUnsignedStack(xMin: number, xMax: number, yMin: number, yMax: n
880
884
 
881
885
  const polygons: Array<AI.Polygon> = [];
882
886
  let lastLine = chart.chartStack.points.map((stackPoint) =>
883
- Axis.transformPoint(AI.createPoint(stackPoint.x, 0), xMin, xMax, yMin, yMax, xAxis, yAxis)
887
+ transformPoint(AI.createPoint(stackPoint.x, 0), xMin, xMax, yMin, yMax, xAxis, yAxis)
884
888
  );
885
889
  lines.forEach((line, index) => {
886
890
  const config = chart.chartStack.config[index];
@@ -903,7 +907,7 @@ export function generateLines(xMin: number, xMax: number, yMin: number, yMax: nu
903
907
  }
904
908
  const xAxis = l.xAxis === "top" ? chart.xAxisesTop[0] : chart.xAxisesBottom[0];
905
909
  const yAxis = l.yAxis === "right" ? chart.yAxisesRight[0] : chart.yAxisesLeft[0];
906
- const points = l.points.map((p) => Axis.transformPoint(p, xMin, xMax, yMin, yMax, xAxis, yAxis));
910
+ const points = l.points.map((p) => transformPoint(p, xMin, xMax, yMin, yMax, xAxis, yAxis));
907
911
  const segments = getLineSegmentsInsideChart(xMin, xMax, yMin, yMax, points);
908
912
  const components = [];
909
913
  const outlineColor = l.textOutlineColor ?? chart.textOutlineColor;
@@ -1020,7 +1024,7 @@ export function generatePoints(xMin: number, xMax: number, yMin: number, yMax: n
1020
1024
  const points = chart.chartPoints.map((p) => {
1021
1025
  const xAxis = p.xAxis === "top" ? chart.xAxisesTop[0] : chart.xAxisesBottom[0];
1022
1026
  const yAxis = p.yAxis === "right" ? chart.yAxisesRight[0] : chart.yAxisesLeft[0];
1023
- const position = Axis.transformPoint(p.position, xMin, xMax, yMin, yMax, xAxis, yAxis);
1027
+ const position = transformPoint(p.position, xMin, xMax, yMin, yMax, xAxis, yAxis);
1024
1028
  const outlineColor = p.textOutlineColor ?? chart.textOutlineColor;
1025
1029
  const components = [
1026
1030
  generatePointShape(p, position, undefined),
@@ -1090,9 +1094,9 @@ export function generateBars(xMin: number, xMax: number, yMin: number, yMax: num
1090
1094
  AI.createPoint(barPos, (b.max + (b.min ?? yMinValue)) / 2),
1091
1095
  AI.createPoint(barPos + bars.width / 2, b.min ?? yMinValue),
1092
1096
  ];
1093
- const pos = Axis.transformPoint(middle, xMin, xMax, yMin, yMax, xAxis, yAxis);
1094
- const topLeft = Axis.transformPoint(tl, xMin, xMax, yMin, yMax, xAxis, yAxis);
1095
- const bottomRight = Axis.transformPoint(br, xMin, xMax, yMin, yMax, xAxis, yAxis);
1097
+ const pos = transformPoint(middle, xMin, xMax, yMin, yMax, xAxis, yAxis);
1098
+ const topLeft = transformPoint(tl, xMin, xMax, yMin, yMax, xAxis, yAxis);
1099
+ const bottomRight = transformPoint(br, xMin, xMax, yMin, yMax, xAxis, yAxis);
1096
1100
  components.push(
1097
1101
  AI.createRectangle(
1098
1102
  topLeft,
@@ -1164,12 +1168,12 @@ export function generateXAxisGridLines(
1164
1168
  xMax: number,
1165
1169
  yMin: number,
1166
1170
  yMax: number,
1167
- xTicks: ReadonlyArray<Axis.DiscreteAxisPoint>,
1168
- xAxis: Axis.Axis,
1171
+ xTicks: ReadonlyArray<DiscreteAxisPoint>,
1172
+ xAxis: Axis,
1169
1173
  xGrid: { readonly color: AI.Color; readonly thickness: number }
1170
1174
  ): AI.Component {
1171
1175
  const xLines = xTicks.map((l) => {
1172
- const x = Axis.transformValue(l.value, xMin, xMax, xAxis);
1176
+ const x = transformValue(l.value, xMin, xMax, xAxis);
1173
1177
  const start = AI.createPoint(x, yMin);
1174
1178
  const end = AI.createPoint(x, yMax);
1175
1179
  return AI.createLine(start, end, xGrid.color, xGrid.thickness);
@@ -1183,8 +1187,8 @@ export function generateXAxisLabels(
1183
1187
  xMax: number,
1184
1188
  y: number,
1185
1189
  growVertical: AI.GrowthDirection,
1186
- ticks: ReadonlyArray<Axis.DiscreteAxisPoint>,
1187
- axis: Axis.Axis,
1190
+ ticks: ReadonlyArray<DiscreteAxisPoint>,
1191
+ axis: Axis,
1188
1192
  chart: Chart
1189
1193
  ): AI.Component {
1190
1194
  const rotation = axis.labelRotation ?? 0;
@@ -1200,7 +1204,7 @@ export function generateXAxisLabels(
1200
1204
  }
1201
1205
  })();
1202
1206
  const xLabels = ticks.map((l) => {
1203
- const position = AI.createPoint(Axis.transformValue(l.value, xMin, xMax, axis), y);
1207
+ const position = AI.createPoint(transformValue(l.value, xMin, xMax, axis), y);
1204
1208
  return AI.createText(
1205
1209
  position,
1206
1210
  l.label ?? formatNumber(l.value),
@@ -1225,7 +1229,7 @@ export function generateXAxisLabel(
1225
1229
  y: number,
1226
1230
  horizontalGrowthDirection: AI.GrowthDirection,
1227
1231
  verticalGrowthDirection: AI.GrowthDirection,
1228
- axis: Axis.Axis,
1232
+ axis: Axis,
1229
1233
  chart: Chart
1230
1234
  ): AI.Component {
1231
1235
  const position = AI.createPoint(x, y);
@@ -1252,13 +1256,13 @@ export function generateYAxisLines(
1252
1256
  xMax: number,
1253
1257
  yMin: number,
1254
1258
  yMax: number,
1255
- yTicks: ReadonlyArray<Axis.DiscreteAxisPoint>,
1256
- yAxis: Axis.Axis,
1259
+ yTicks: ReadonlyArray<DiscreteAxisPoint>,
1260
+ yAxis: Axis,
1257
1261
  yGrid: { readonly color: AI.Color; readonly thickness: number },
1258
1262
  xGrid: { readonly color: AI.Color; readonly thickness: number }
1259
1263
  ): AI.Component {
1260
1264
  const yLines = yTicks.map((l) => {
1261
- const y = Axis.transformValue(l.value, yMin, yMax, yAxis);
1265
+ const y = transformValue(l.value, yMin, yMax, yAxis);
1262
1266
  const start = AI.createPoint(xMin - xGrid.thickness / 2, y);
1263
1267
  const end = AI.createPoint(xMax + xGrid.thickness / 2, y);
1264
1268
  return AI.createLine(start, end, yGrid.color, yGrid.thickness);
@@ -1271,8 +1275,8 @@ export function generateYAxisLabels(
1271
1275
  yMin: number,
1272
1276
  yMax: number,
1273
1277
  growHorizontal: AI.GrowthDirection,
1274
- yTicks: ReadonlyArray<Axis.DiscreteAxisPoint>,
1275
- yAxis: Axis.Axis,
1278
+ yTicks: ReadonlyArray<DiscreteAxisPoint>,
1279
+ yAxis: Axis,
1276
1280
  chart: Chart
1277
1281
  ): AI.Component {
1278
1282
  const rotation = yAxis.labelRotation ?? 0;
@@ -1288,7 +1292,7 @@ export function generateYAxisLabels(
1288
1292
  })();
1289
1293
 
1290
1294
  const yLabels = yTicks.map((l) => {
1291
- const position = AI.createPoint(x, Axis.transformValue(l.value, yMin, yMax, yAxis));
1295
+ const position = AI.createPoint(x, transformValue(l.value, yMin, yMax, yAxis));
1292
1296
  return AI.createText(
1293
1297
  position,
1294
1298
  l.label ?? formatNumber(l.value),
@@ -1314,7 +1318,7 @@ export function generateYAxisLabel(
1314
1318
  rotation: number,
1315
1319
  horizontalGrowthDirection: AI.GrowthDirection,
1316
1320
  verticalGrowthDirection: AI.GrowthDirection,
1317
- axis: Axis.Axis,
1321
+ axis: Axis,
1318
1322
  chart: Chart
1319
1323
  ): AI.Component {
1320
1324
  const position = AI.createPoint(x, y);