@baron1996/klinecharts-adapter 0.9.22 → 0.9.23

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.
@@ -0,0 +1,7 @@
1
+ import type { AxisCreateTicksParams, AxisTick } from 'klinecharts';
2
+ /** Positive candle prices: fixed log lattice, shared by ticks and grid lines. */
3
+ export declare function createLogPriceTicks({ range, bounding, defaultTicks }: AxisCreateTicksParams, reverse: boolean, presentation?: {
4
+ textHeight?: number;
5
+ formatText?: (text: string) => string;
6
+ }): AxisTick[];
7
+ //# sourceMappingURL=log-price-ticks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-price-ticks.d.ts","sourceRoot":"","sources":["../../src/conversion/log-price-ticks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAwBnE,iFAAiF;AACjF,wBAAgB,mBAAmB,CAClC,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,qBAAqB,EACxD,OAAO,EAAE,OAAO,EAChB,YAAY,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAAO,GAC/E,QAAQ,EAAE,CA2BZ"}
@@ -0,0 +1,52 @@
1
+ const MIN_TICK_SPACING = 48;
2
+ /** Choose density in log space, independent of the translated price bounds. */
3
+ function logStep(span, height, textHeight) {
4
+ const target = span * Math.max(MIN_TICK_SPACING, textHeight * 3) / height;
5
+ const magnitude = 10 ** Math.floor(Math.log10(target));
6
+ const normalized = target / magnitude;
7
+ // Tolerate floating-point noise at a density boundary across repeated pans.
8
+ const factor = [1, 2, 2.5, 5, 10].find((value) => value >= normalized * (1 - 1e-10));
9
+ return Number((factor * magnitude).toPrecision(12));
10
+ }
11
+ function priceText(value, step) {
12
+ // Retain the usual two decimals; tiny prices/close ticks need enough digits
13
+ // to avoid adjacent labels becoming identical after rounding.
14
+ const difference = value * Math.expm1(step * Math.LN10);
15
+ const precision = Math.max(2, 1 - Math.floor(Math.log10(difference)));
16
+ return precision > 12 || value >= 1e12
17
+ ? value.toExponential(6)
18
+ : value.toFixed(precision);
19
+ }
20
+ /** Positive candle prices: fixed log lattice, shared by ticks and grid lines. */
21
+ export function createLogPriceTicks({ range, bounding, defaultTicks }, reverse, presentation = {}) {
22
+ const { realFrom, realTo, realRange } = range;
23
+ const { height } = bounding;
24
+ if (!(range.from > 0 && range.to > range.from && realRange > 0 && height > 0)
25
+ || ![realFrom, realTo, realRange, height].every(Number.isFinite)) {
26
+ return defaultTicks;
27
+ }
28
+ const textHeight = presentation.textHeight ?? 12;
29
+ const step = logStep(realRange, height, textHeight);
30
+ if (!(step > 0 && Number.isFinite(step)))
31
+ return defaultTicks;
32
+ const first = Math.ceil(realFrom / step);
33
+ const last = Math.floor(realTo / step);
34
+ if (!Number.isSafeInteger(first) || !Number.isSafeInteger(last))
35
+ return defaultTicks;
36
+ const ticks = [];
37
+ // Anchor to log10(price)=0, not the viewport edge. Compute each tick from
38
+ // its integer index so newly exposed ticks extend the same price sequence.
39
+ for (let index = first; index <= last && ticks.length < 1000; index++) {
40
+ const logValue = Number((index * step).toPrecision(14));
41
+ const value = 10 ** logValue;
42
+ const fraction = (logValue - realFrom) / realRange;
43
+ const coord = Math.round(height * (reverse ? fraction : 1 - fraction));
44
+ if (coord <= textHeight || coord >= height - textHeight)
45
+ continue;
46
+ if (!(value > 0 && Number.isFinite(value)))
47
+ continue;
48
+ const text = priceText(value, step);
49
+ ticks.push({ value, coord, text: presentation.formatText?.(text) ?? text });
50
+ }
51
+ return ticks;
52
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"panes.d.ts","sourceRoot":"","sources":["../../src/conversion/panes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAErF,OAAO,KAAK,EAAE,KAAK,EAAS,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAS/C,iDAAiD;AACjD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjE;AA2BD,qDAAqD;AACrD,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,aAAa,UAAQ,GACnB,IAAI,CAIN;AAED,wCAAwC;AACxC,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CA4EpF"}
1
+ {"version":3,"file":"panes.d.ts","sourceRoot":"","sources":["../../src/conversion/panes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAErF,OAAO,KAAK,EAAyB,KAAK,EAAS,MAAM,aAAa,CAAC;AAEvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAU/C,iDAAiD;AACjD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjE;AAmCD,qDAAqD;AACrD,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,aAAa,UAAQ,GACnB,IAAI,CAIN;AAED,wCAAwC;AACxC,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CA6EpF"}
@@ -1,16 +1,24 @@
1
1
  import { SceneError } from '@baron1996/kline-scene-schema';
2
2
  import { requireMappedId } from './id-map.js';
3
3
  import { createPaneIndicators } from './indicators.js';
4
+ import { createLogPriceTicks } from './log-price-ticks.js';
4
5
  /** 蜡烛主价格轴默认只格式化展示文本,不改变 Scene 与 Drawing 数值精度。 */
5
6
  export function formatDefaultPriceAxisValue(value) {
6
7
  const rounded = Number(value.toFixed(2));
7
8
  return (Object.is(rounded, -0) ? 0 : rounded).toFixed(2);
8
9
  }
9
- function axisOverride(axis, enginePaneId, engineAxisId, formatAsPrice) {
10
+ function axisOverride(chart, axis, enginePaneId, engineAxisId, formatAsPrice) {
10
11
  return {
11
12
  id: engineAxisId,
12
13
  paneId: enginePaneId,
13
14
  name: axis.scale === 'logarithmic' ? 'logarithm' : 'normal',
15
+ // Explicit passthrough also clears our callback when switching to linear.
16
+ createTicks: (params) => formatAsPrice && axis.scale === 'logarithmic'
17
+ ? createLogPriceTicks(params, axis.reverse, {
18
+ textHeight: chart.getStyles().yAxis.tickText.size,
19
+ formatText: (text) => chart.getDecimalFold().format(chart.getThousandsSeparator().format(text)),
20
+ })
21
+ : params.defaultTicks,
14
22
  reverse: axis.reverse,
15
23
  inside: axis.inside,
16
24
  position: axis.position,
@@ -29,7 +37,7 @@ function axisOverride(axis, enginePaneId, engineAxisId, formatAsPrice) {
29
37
  export function overrideSceneYAxis(chart, idMap, axis, paneId, path, formatAsPrice = false) {
30
38
  const enginePaneId = requireMappedId(idMap.paneToEngine, paneId, `${path}/paneId`, 'Pane');
31
39
  const engineAxisId = requireMappedId(idMap.yAxisToEngine, axis.id, `${path}/id`, 'Y-axis');
32
- chart.overrideYAxis(axisOverride(axis, enginePaneId, engineAxisId, formatAsPrice));
40
+ chart.overrideYAxis(axisOverride(chart, axis, enginePaneId, engineAxisId, formatAsPrice));
33
41
  }
34
42
  /** 按 Scene 顺序创建 Pane、Y 轴和指标,并核对每个映射。 */
35
43
  export function applyPanes(scene, chart, idMap) {
@@ -56,7 +64,7 @@ export function applyPanes(scene, chart, idMap) {
56
64
  continue;
57
65
  }
58
66
  const engineAxisId = requireMappedId(idMap.yAxisToEngine, axis.id, `/panes/${paneIndex}/yAxes/${axisIndex}/id`, 'Y-axis');
59
- const override = axisOverride(axis, enginePaneId, engineAxisId, pane.kind === 'candle' && axis.role === 'primary');
67
+ const override = axisOverride(chart, axis, enginePaneId, engineAxisId, pane.kind === 'candle' && axis.role === 'primary');
60
68
  const axes = chart.getYAxes({ paneId: enginePaneId });
61
69
  if (axes.some((candidate) => candidate.id === engineAxisId)) {
62
70
  chart.overrideYAxis(override);
package/dist/version.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Adapter 包版本。 */
2
- export declare const ADAPTER_PACKAGE_VERSION: "0.9.22";
2
+ export declare const ADAPTER_PACKAGE_VERSION: "0.9.23";
3
3
  /** 唯一允许加载的 KLineCharts 引擎版本。 */
4
4
  export declare const KLINECHARTS_ENGINE_VERSION: "10.0.0";
5
5
  /** 与 ChartScene 绑定的 Runtime 协议版本。 */
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Adapter 包版本。 */
2
- export const ADAPTER_PACKAGE_VERSION = '0.9.22';
2
+ export const ADAPTER_PACKAGE_VERSION = '0.9.23';
3
3
  /** 唯一允许加载的 KLineCharts 引擎版本。 */
4
4
  export const KLINECHARTS_ENGINE_VERSION = '10.0.0';
5
5
  /** 与 ChartScene 绑定的 Runtime 协议版本。 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baron1996/klinecharts-adapter",
3
- "version": "0.9.22",
3
+ "version": "0.9.23",
4
4
  "description": "Controlled ChartScene adapter for KLineCharts.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -38,7 +38,7 @@
38
38
  "typecheck": "tsc -p tsconfig.json --noEmit"
39
39
  },
40
40
  "dependencies": {
41
- "@baron1996/kline-scene-schema": "0.9.22",
41
+ "@baron1996/kline-scene-schema": "0.9.23",
42
42
  "klinecharts": "10.0.0"
43
43
  }
44
44
  }