@363045841yyt/klinechart 0.3.1 → 0.4.1

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.
Files changed (70) hide show
  1. package/README.md +21 -0
  2. package/dist/index.cjs +9 -9
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +2297 -1733
  5. package/dist/klinechart.css +1 -1
  6. package/dist/src/api/data/baostock.d.ts +1 -1
  7. package/dist/src/api/data/kLine.d.ts +1 -1
  8. package/dist/src/api/data/types.d.ts +1 -1
  9. package/dist/src/api/data/unified.d.ts +1 -1
  10. package/dist/src/components/IndicatorSelector.vue.d.ts +2 -0
  11. package/dist/src/components/KLineChart.vue.d.ts +2 -2
  12. package/dist/src/components/KLineTooltip.vue.d.ts +1 -1
  13. package/dist/src/components/MarkerTooltip.vue.d.ts +1 -1
  14. package/dist/src/core/chart.d.ts +40 -13
  15. package/dist/src/core/controller/interaction.d.ts +12 -6
  16. package/dist/src/core/layout/pane.d.ts +4 -4
  17. package/dist/src/core/renderers/Indicator/boll.d.ts +2 -2
  18. package/dist/src/core/renderers/Indicator/cci.d.ts +7 -3
  19. package/dist/src/core/renderers/Indicator/ene.d.ts +2 -2
  20. package/dist/src/core/renderers/Indicator/expma.d.ts +2 -2
  21. package/dist/src/core/renderers/Indicator/fastk.d.ts +7 -3
  22. package/dist/src/core/renderers/Indicator/index.d.ts +1 -1
  23. package/dist/src/core/renderers/Indicator/kst.d.ts +7 -3
  24. package/dist/src/core/renderers/Indicator/ma.d.ts +1 -1
  25. package/dist/src/core/renderers/Indicator/macd.d.ts +13 -3
  26. package/dist/src/core/renderers/Indicator/macdLegend.d.ts +1 -1
  27. package/dist/src/core/renderers/Indicator/mainIndicatorLegend.d.ts +1 -1
  28. package/dist/src/core/renderers/Indicator/mom.d.ts +7 -3
  29. package/dist/src/core/renderers/Indicator/rsi.d.ts +7 -3
  30. package/dist/src/core/renderers/Indicator/scale/cci_scale.d.ts +5 -0
  31. package/dist/src/core/renderers/Indicator/scale/fastk_scale.d.ts +5 -0
  32. package/dist/src/core/renderers/Indicator/scale/indicator_scale.d.ts +23 -0
  33. package/dist/src/core/renderers/Indicator/scale/kst_scale.d.ts +5 -0
  34. package/dist/src/core/renderers/Indicator/scale/macd_scale.d.ts +8 -0
  35. package/dist/src/core/renderers/Indicator/scale/mom_scale.d.ts +5 -0
  36. package/dist/src/core/renderers/Indicator/scale/rsi_scale.d.ts +5 -0
  37. package/dist/src/core/renderers/Indicator/scale/stoch_scale.d.ts +5 -0
  38. package/dist/src/core/renderers/Indicator/scale/wmsr_scale.d.ts +5 -0
  39. package/dist/src/core/renderers/Indicator/stoch.d.ts +7 -3
  40. package/dist/src/core/renderers/Indicator/wmsr.d.ts +7 -3
  41. package/dist/src/core/renderers/candle.d.ts +3 -3
  42. package/dist/src/core/renderers/crosshair.d.ts +1 -1
  43. package/dist/src/core/renderers/customMarkers.d.ts +1 -1
  44. package/dist/src/core/renderers/extremaMarkers.d.ts +1 -1
  45. package/dist/src/core/renderers/gridLines.d.ts +1 -1
  46. package/dist/src/core/renderers/lastPrice.d.ts +1 -1
  47. package/dist/src/core/renderers/paneTitle.d.ts +1 -1
  48. package/dist/src/core/renderers/subVolume.d.ts +1 -1
  49. package/dist/src/core/renderers/timeAxis.d.ts +1 -1
  50. package/dist/src/core/renderers/yAxis.d.ts +2 -2
  51. package/dist/src/core/utils/tickCount.d.ts +3 -2
  52. package/dist/src/core/viewport/viewport.d.ts +2 -2
  53. package/dist/src/plugin/HookSystem.d.ts +3 -3
  54. package/dist/src/plugin/PluginHost.d.ts +12 -5
  55. package/dist/src/plugin/StateStore.d.ts +37 -0
  56. package/dist/src/plugin/rendererPluginManager.d.ts +4 -0
  57. package/dist/src/plugin/stateKeys.d.ts +6 -0
  58. package/dist/src/plugin/types.d.ts +38 -2
  59. package/dist/src/semantic/controller.d.ts +1 -1
  60. package/dist/src/utils/kLineDraw/MA.d.ts +1 -1
  61. package/dist/src/utils/kLineDraw/axis.d.ts +1 -1
  62. package/dist/src/utils/kLineDraw/grid.d.ts +1 -1
  63. package/dist/src/utils/kLineDraw/kLine.d.ts +1 -1
  64. package/dist/src/utils/kline/format.d.ts +2 -2
  65. package/dist/src/utils/kline/ma.d.ts +1 -1
  66. package/dist/src/utils/kline/viewport.d.ts +1 -1
  67. package/dist/src/utils/mock/genRandomPriceData.d.ts +1 -1
  68. package/dist/src/utils/volumePrice.d.ts +2 -2
  69. package/package.json +1 -1
  70. /package/dist/{semantic → src/semantic}/schema.json.d.ts +0 -0
@@ -1,2 +1,2 @@
1
- .kline-tooltip[data-v-95daa55c]{z-index:10;color:#000000c7;pointer-events:none;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#ffffffeb;border:1px solid #0000001f;border-radius:8px;min-width:200px;max-width:260px;padding:10px 12px;font-size:12px;line-height:1.4;position:absolute;box-shadow:0 6px 18px #0000001f}.kline-tooltip__title[data-v-95daa55c]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.kline-tooltip__grid[data-v-95daa55c]{grid-template-columns:1fr;gap:2px;display:grid}.kline-tooltip__grid .row[data-v-95daa55c]{justify-content:space-between;gap:10px;display:flex}.kline-tooltip__grid .row span[data-v-95daa55c]:first-child{color:#0000008f}.marker-tooltip[data-v-dd43da4f]{z-index:10;color:#000000c7;pointer-events:none;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#ffffffeb;border:1px solid #0000001f;border-radius:8px;min-width:180px;max-width:260px;padding:10px 12px;font-size:12px;line-height:1.4;position:absolute;box-shadow:0 6px 18px #0000001f}.marker-tooltip__title[data-v-dd43da4f]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.marker-tooltip__content[data-v-dd43da4f]{grid-template-columns:1fr;gap:2px;display:grid}.marker-tooltip__content .row[data-v-dd43da4f]{justify-content:space-between;gap:10px;display:flex}.marker-tooltip__content .row span[data-v-dd43da4f]:first-child{color:#0000008f}.params-overlay[data-v-c14eedcc]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.indicator-params[data-v-c14eedcc]{background:#fff;border:1px solid #e0e0e0;border-radius:12px;width:90vw;min-width:340px;max-width:420px;overflow:hidden;box-shadow:0 8px 40px #00000026}.params-header[data-v-c14eedcc]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-c14eedcc]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-c14eedcc]{align-items:center;gap:8px;display:flex}.params-title[data-v-c14eedcc]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.params-subtitle[data-v-c14eedcc]{color:#999;font-size:11px}.toggle-desc-btn[data-v-c14eedcc]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:all .2s;display:flex}.toggle-desc-btn[data-v-c14eedcc]:hover{color:#555;background:#f0f0f0;border-color:#ccc}.toggle-desc-btn.active[data-v-c14eedcc]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.toggle-desc-btn svg[data-v-c14eedcc]{width:14px;height:14px}.params-close[data-v-c14eedcc]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:background .15s,color .15s,border-color .15s;display:flex}.params-close[data-v-c14eedcc]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.params-close svg[data-v-c14eedcc]{width:14px;height:14px}.indicator-description[data-v-c14eedcc]{background:#f0f7ff;border-bottom:1px solid #d6e8f5;padding:12px 20px}.indicator-description p[data-v-c14eedcc]{color:#2c5282;margin:0;font-size:12px;line-height:1.6}.params-body[data-v-c14eedcc]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.param-item[data-v-c14eedcc]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:10px 14px;transition:border-color .2s}.param-item[data-v-c14eedcc]:has(.param-input:focus){border-color:#bbb}.param-item.has-desc[data-v-c14eedcc]{padding:10px 14px 8px}.param-header[data-v-c14eedcc]{justify-content:space-between;align-items:center;gap:16px;display:flex}.param-label[data-v-c14eedcc]{flex-direction:column;gap:3px;display:flex}.param-label-text[data-v-c14eedcc]{color:#333;font-size:13px;font-weight:500}.param-range[data-v-c14eedcc]{color:#999;font-size:11px}.param-description[data-v-c14eedcc]{color:#666;border-top:1px dashed #e0e0e0;margin-top:8px;padding-top:8px;font-size:11px;line-height:1.5}.input-wrapper[data-v-c14eedcc]{background:#fff;border:1px solid #d0d0d0;border-radius:7px;align-items:stretch;height:32px;transition:border-color .2s;display:flex;overflow:hidden}.input-wrapper[data-v-c14eedcc]:focus-within{border-color:#999}.stepper-btn[data-v-c14eedcc]{cursor:pointer;color:#666;background:#f0f0f0;border:none;flex-shrink:0;justify-content:center;align-items:center;width:28px;font-size:15px;font-weight:400;line-height:1;transition:background .15s,color .15s;display:flex}.stepper-btn[data-v-c14eedcc]:hover:not(:disabled){color:#333;background:#e0e0e0}.stepper-btn[data-v-c14eedcc]:disabled{color:#ccc;cursor:not-allowed}.param-input[data-v-c14eedcc]{text-align:center;color:#1a1a1a;appearance:textfield;background:0 0;border:none;border-left:1px solid #e8e8e8;border-right:1px solid #e8e8e8;width:60px;font-size:13px;font-weight:600}.param-input[data-v-c14eedcc]::-webkit-inner-spin-button{-webkit-appearance:none}.param-input[data-v-c14eedcc]::-webkit-outer-spin-button{-webkit-appearance:none}.param-input[data-v-c14eedcc]:focus{outline:none}.params-footer[data-v-c14eedcc]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-c14eedcc]{gap:8px;display:flex}.params-btn[data-v-c14eedcc]{cursor:pointer;border:1px solid #0000;border-radius:7px;align-items:center;gap:5px;padding:6px 14px;font-size:13px;font-weight:500;line-height:1.4;transition:all .15s;display:flex}.params-btn svg[data-v-c14eedcc]{flex-shrink:0;width:12px;height:12px}.params-btn.reset[data-v-c14eedcc]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.reset[data-v-c14eedcc]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.params-btn.cancel[data-v-c14eedcc]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.cancel[data-v-c14eedcc]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.params-btn.confirm[data-v-c14eedcc]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.params-btn.confirm[data-v-c14eedcc]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.params-btn.confirm[data-v-c14eedcc]:active{box-shadow:none;transform:translateY(0)}.overlay-enter-active[data-v-c14eedcc],.overlay-leave-active[data-v-c14eedcc]{transition:opacity .2s}.overlay-enter-from[data-v-c14eedcc],.overlay-leave-to[data-v-c14eedcc]{opacity:0}.modal-enter-active[data-v-c14eedcc]{transition:all .22s cubic-bezier(.34,1.56,.64,1)}.modal-leave-active[data-v-c14eedcc]{transition:all .16s ease-in}.modal-enter-from[data-v-c14eedcc]{opacity:0;transform:scale(.88)translateY(-16px)}.modal-leave-to[data-v-c14eedcc]{opacity:0;transform:scale(.94)translateY(8px)}.slide-enter-active[data-v-c14eedcc],.slide-leave-active[data-v-c14eedcc]{transition:all .2s;overflow:hidden}.slide-enter-from[data-v-c14eedcc],.slide-leave-to[data-v-c14eedcc]{opacity:0;max-height:0;margin-top:0;padding-top:0;padding-bottom:0}.indicator-selector[data-v-aad3b750]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-aad3b750]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-aad3b750]::-webkit-scrollbar{display:none}.indicator-list[data-v-aad3b750]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-item[data-v-aad3b750]{align-items:center;gap:4px;display:flex}.indicator-btn-wrapper[data-v-aad3b750]{position:relative}.indicator-btn[data-v-aad3b750]{color:#666;cursor:pointer;white-space:nowrap;background:#fff;border:1px solid #e0e0e0;border-radius:16px;flex-shrink:0;justify-content:center;align-items:center;gap:4px;padding:6px 16px;font-size:13px;font-weight:500;transition:all .3s;display:flex;position:relative;overflow:hidden}.indicator-btn[data-v-aad3b750]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-aad3b750]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-aad3b750]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-aad3b750]{z-index:1;position:relative}.param-hint[data-v-aad3b750]{opacity:.85;font-size:11px}.hover-overlay[data-v-aad3b750]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2;background:#ffffffd9;border-radius:16px;justify-content:center;align-items:center;gap:4px;display:flex;position:absolute;inset:0}.action-btn[data-v-aad3b750]{color:#666;cursor:pointer;background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;padding:0;transition:all .2s;display:flex}.action-btn[data-v-aad3b750]:hover{color:#333;background:#0000000f}.settings-btn[data-v-aad3b750]:hover{color:#1a1a1a}.remove-btn[data-v-aad3b750]:hover{color:#ff4d4f}.divider[data-v-aad3b750]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-aad3b750]{color:#999;cursor:pointer;background:0 0;border:1px dashed #d9d9d9;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;padding:0;transition:all .3s;display:flex}.add-btn[data-v-aad3b750]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-aad3b750]{white-space:nowrap;z-index:9999;background:#fff;border-radius:8px;padding:8px 0;position:fixed;transform:translate(-50%);box-shadow:0 6px 16px #00000014,0 3px 6px -4px #0000001f,0 9px 28px 8px #0000000d}.menu-section[data-v-aad3b750]{padding:4px 0}.menu-section[data-v-aad3b750]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-aad3b750]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-aad3b750]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-aad3b750]{text-align:left;color:#333;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;width:100%;padding:8px 16px;font-size:13px;transition:background .2s;display:flex}.menu-item[data-v-aad3b750]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-aad3b750]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-aad3b750]{color:#999;font-size:11px}.active-tag[data-v-aad3b750]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-aad3b750],.fade-leave-active[data-v-aad3b750]{transition:opacity .2s}.fade-enter-from[data-v-aad3b750],.fade-leave-to[data-v-aad3b750]{opacity:0}.slide-enter-active[data-v-aad3b750],.slide-leave-active[data-v-aad3b750]{transition:all .2s}.slide-enter-from[data-v-aad3b750],.slide-leave-to[data-v-aad3b750]{opacity:0;transform:translate(-50%)translateY(8px)}.chart-wrapper[data-v-d60162bc]{--kmap-height:var(--kmap-chart-height,100%);--kmap-width:var(--kmap-chart-width,100%);width:var(--kmap-width);height:var(--kmap-height);flex-direction:column;justify-content:center;align-items:center;min-height:300px;display:flex}.chart-container[data-v-d60162bc]{scrollbar-width:none;-ms-overflow-style:none;box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:none;border:1px solid #e0e0e0;width:95%;height:85%;min-height:255px;position:relative;overflow:auto hidden}.chart-container[data-v-d60162bc]::-webkit-scrollbar{display:none}.chart-container[data-v-d60162bc]:hover{cursor:grab}.chart-container[data-v-d60162bc]:active{cursor:grabbing}.scroll-content[data-v-d60162bc]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-d60162bc]{pointer-events:none;position:sticky;top:0;left:0}.plot-canvas{display:block;position:absolute;top:0;left:0}.right-axis{display:block;position:absolute;right:0}.x-axis-canvas{z-index:10;display:block;position:absolute;bottom:0;left:0}
1
+ .kline-tooltip[data-v-95daa55c]{z-index:10;color:#000000c7;pointer-events:none;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#ffffffeb;border:1px solid #0000001f;border-radius:8px;min-width:200px;max-width:260px;padding:10px 12px;font-size:12px;line-height:1.4;position:absolute;box-shadow:0 6px 18px #0000001f}.kline-tooltip__title[data-v-95daa55c]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.kline-tooltip__grid[data-v-95daa55c]{grid-template-columns:1fr;gap:2px;display:grid}.kline-tooltip__grid .row[data-v-95daa55c]{justify-content:space-between;gap:10px;display:flex}.kline-tooltip__grid .row span[data-v-95daa55c]:first-child{color:#0000008f}.marker-tooltip[data-v-dd43da4f]{z-index:10;color:#000000c7;pointer-events:none;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#ffffffeb;border:1px solid #0000001f;border-radius:8px;min-width:180px;max-width:260px;padding:10px 12px;font-size:12px;line-height:1.4;position:absolute;box-shadow:0 6px 18px #0000001f}.marker-tooltip__title[data-v-dd43da4f]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.marker-tooltip__content[data-v-dd43da4f]{grid-template-columns:1fr;gap:2px;display:grid}.marker-tooltip__content .row[data-v-dd43da4f]{justify-content:space-between;gap:10px;display:flex}.marker-tooltip__content .row span[data-v-dd43da4f]:first-child{color:#0000008f}.params-overlay[data-v-c14eedcc]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.indicator-params[data-v-c14eedcc]{background:#fff;border:1px solid #e0e0e0;border-radius:12px;width:90vw;min-width:340px;max-width:420px;overflow:hidden;box-shadow:0 8px 40px #00000026}.params-header[data-v-c14eedcc]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-c14eedcc]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-c14eedcc]{align-items:center;gap:8px;display:flex}.params-title[data-v-c14eedcc]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.params-subtitle[data-v-c14eedcc]{color:#999;font-size:11px}.toggle-desc-btn[data-v-c14eedcc]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:all .2s;display:flex}.toggle-desc-btn[data-v-c14eedcc]:hover{color:#555;background:#f0f0f0;border-color:#ccc}.toggle-desc-btn.active[data-v-c14eedcc]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.toggle-desc-btn svg[data-v-c14eedcc]{width:14px;height:14px}.params-close[data-v-c14eedcc]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:background .15s,color .15s,border-color .15s;display:flex}.params-close[data-v-c14eedcc]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.params-close svg[data-v-c14eedcc]{width:14px;height:14px}.indicator-description[data-v-c14eedcc]{background:#f0f7ff;border-bottom:1px solid #d6e8f5;padding:12px 20px}.indicator-description p[data-v-c14eedcc]{color:#2c5282;margin:0;font-size:12px;line-height:1.6}.params-body[data-v-c14eedcc]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.param-item[data-v-c14eedcc]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:10px 14px;transition:border-color .2s}.param-item[data-v-c14eedcc]:has(.param-input:focus){border-color:#bbb}.param-item.has-desc[data-v-c14eedcc]{padding:10px 14px 8px}.param-header[data-v-c14eedcc]{justify-content:space-between;align-items:center;gap:16px;display:flex}.param-label[data-v-c14eedcc]{flex-direction:column;gap:3px;display:flex}.param-label-text[data-v-c14eedcc]{color:#333;font-size:13px;font-weight:500}.param-range[data-v-c14eedcc]{color:#999;font-size:11px}.param-description[data-v-c14eedcc]{color:#666;border-top:1px dashed #e0e0e0;margin-top:8px;padding-top:8px;font-size:11px;line-height:1.5}.input-wrapper[data-v-c14eedcc]{background:#fff;border:1px solid #d0d0d0;border-radius:7px;align-items:stretch;height:32px;transition:border-color .2s;display:flex;overflow:hidden}.input-wrapper[data-v-c14eedcc]:focus-within{border-color:#999}.stepper-btn[data-v-c14eedcc]{cursor:pointer;color:#666;background:#f0f0f0;border:none;flex-shrink:0;justify-content:center;align-items:center;width:28px;font-size:15px;font-weight:400;line-height:1;transition:background .15s,color .15s;display:flex}.stepper-btn[data-v-c14eedcc]:hover:not(:disabled){color:#333;background:#e0e0e0}.stepper-btn[data-v-c14eedcc]:disabled{color:#ccc;cursor:not-allowed}.param-input[data-v-c14eedcc]{text-align:center;color:#1a1a1a;appearance:textfield;background:0 0;border:none;border-left:1px solid #e8e8e8;border-right:1px solid #e8e8e8;width:60px;font-size:13px;font-weight:600}.param-input[data-v-c14eedcc]::-webkit-inner-spin-button{-webkit-appearance:none}.param-input[data-v-c14eedcc]::-webkit-outer-spin-button{-webkit-appearance:none}.param-input[data-v-c14eedcc]:focus{outline:none}.params-footer[data-v-c14eedcc]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-c14eedcc]{gap:8px;display:flex}.params-btn[data-v-c14eedcc]{cursor:pointer;border:1px solid #0000;border-radius:7px;align-items:center;gap:5px;padding:6px 14px;font-size:13px;font-weight:500;line-height:1.4;transition:all .15s;display:flex}.params-btn svg[data-v-c14eedcc]{flex-shrink:0;width:12px;height:12px}.params-btn.reset[data-v-c14eedcc]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.reset[data-v-c14eedcc]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.params-btn.cancel[data-v-c14eedcc]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.cancel[data-v-c14eedcc]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.params-btn.confirm[data-v-c14eedcc]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.params-btn.confirm[data-v-c14eedcc]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.params-btn.confirm[data-v-c14eedcc]:active{box-shadow:none;transform:translateY(0)}.overlay-enter-active[data-v-c14eedcc],.overlay-leave-active[data-v-c14eedcc]{transition:opacity .2s}.overlay-enter-from[data-v-c14eedcc],.overlay-leave-to[data-v-c14eedcc]{opacity:0}.modal-enter-active[data-v-c14eedcc]{transition:all .22s cubic-bezier(.34,1.56,.64,1)}.modal-leave-active[data-v-c14eedcc]{transition:all .16s ease-in}.modal-enter-from[data-v-c14eedcc]{opacity:0;transform:scale(.88)translateY(-16px)}.modal-leave-to[data-v-c14eedcc]{opacity:0;transform:scale(.94)translateY(8px)}.slide-enter-active[data-v-c14eedcc],.slide-leave-active[data-v-c14eedcc]{transition:all .2s;overflow:hidden}.slide-enter-from[data-v-c14eedcc],.slide-leave-to[data-v-c14eedcc]{opacity:0;max-height:0;margin-top:0;padding-top:0;padding-bottom:0}.indicator-selector[data-v-5d35de74]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-5d35de74]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-5d35de74]::-webkit-scrollbar{display:none}.indicator-list[data-v-5d35de74]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-5d35de74]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-5d35de74]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-5d35de74],.indicator-item.draggable .indicator-btn[data-v-5d35de74],.indicator-item.draggable[data-v-5d35de74]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-5d35de74]{cursor:move}.indicator-item.is-dragging[data-v-5d35de74]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-5d35de74]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-5d35de74]{position:relative}.indicator-btn[data-v-5d35de74]{color:#666;cursor:pointer;white-space:nowrap;background:#fff;border:1px solid #e0e0e0;border-radius:16px;flex-shrink:0;justify-content:center;align-items:center;gap:4px;padding:6px 16px;font-size:13px;font-weight:500;transition:all .3s;display:flex;position:relative;overflow:hidden}.indicator-btn[data-v-5d35de74]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-5d35de74]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-5d35de74]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-5d35de74]{z-index:1;position:relative}.param-hint[data-v-5d35de74]{opacity:.85;font-size:11px}.hover-overlay[data-v-5d35de74]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2;background:#ffffffd9;border-radius:16px;justify-content:center;align-items:center;gap:4px;display:flex;position:absolute;inset:0}.action-btn[data-v-5d35de74]{color:#666;cursor:pointer;background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;padding:0;transition:all .2s;display:flex}.action-btn[data-v-5d35de74]:hover{color:#333;background:#0000000f}.settings-btn[data-v-5d35de74]:hover{color:#1a1a1a}.remove-btn[data-v-5d35de74]:hover{color:#ff4d4f}.divider[data-v-5d35de74]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-5d35de74]{color:#999;cursor:pointer;background:0 0;border:1px dashed #d9d9d9;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;padding:0;transition:all .3s;display:flex}.add-btn[data-v-5d35de74]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-5d35de74]{white-space:nowrap;z-index:9999;background:#fff;border-radius:8px;padding:8px 0;position:fixed;transform:translate(-50%);box-shadow:0 6px 16px #00000014,0 3px 6px -4px #0000001f,0 9px 28px 8px #0000000d}.menu-section[data-v-5d35de74]{padding:4px 0}.menu-section[data-v-5d35de74]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-5d35de74]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-5d35de74]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-5d35de74]{text-align:left;color:#333;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;width:100%;padding:8px 16px;font-size:13px;transition:background .2s;display:flex}.menu-item[data-v-5d35de74]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-5d35de74]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-5d35de74]{color:#999;font-size:11px}.active-tag[data-v-5d35de74]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-5d35de74],.fade-leave-active[data-v-5d35de74]{transition:opacity .2s}.fade-enter-from[data-v-5d35de74],.fade-leave-to[data-v-5d35de74]{opacity:0}.slide-enter-active[data-v-5d35de74],.slide-leave-active[data-v-5d35de74]{transition:all .2s}.slide-enter-from[data-v-5d35de74],.slide-leave-to[data-v-5d35de74]{opacity:0;transform:translate(-50%)translateY(8px)}.chart-wrapper[data-v-953428dd]{--kmap-height:var(--kmap-chart-height,100%);--kmap-width:var(--kmap-chart-width,100%);width:var(--kmap-width);height:var(--kmap-height);flex-direction:column;justify-content:center;align-items:center;min-height:300px;display:flex}.chart-container[data-v-953428dd]{scrollbar-width:none;-ms-overflow-style:none;box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:none;border:1px solid #e0e0e0;width:95%;height:85%;min-height:255px;position:relative;overflow:auto hidden}.chart-container[data-v-953428dd]::-webkit-scrollbar{display:none}.chart-container[data-v-953428dd]:hover{cursor:grab}.chart-container.is-resizing-pane[data-v-953428dd],.chart-container.is-hovering-pane-separator[data-v-953428dd]{cursor:row-resize}.scroll-content[data-v-953428dd]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-953428dd]{pointer-events:none;position:sticky;top:0;left:0}.plot-canvas{display:block;position:absolute;top:0;left:0}.right-axis{display:block;position:absolute;right:0}.x-axis-canvas{z-index:10;display:block;position:absolute;bottom:0;left:0}.main,.sub{border-bottom:1px solid #e0e0e0;border-right:1px solid #e0e0e0}.x-axis-canvas{border-right:1px solid #e0e0e0}.right-axis{border-bottom:1px solid #e0e0e0}
2
2
  /*$vite$:1*/
@@ -1,4 +1,4 @@
1
- import { KLineData } from '../../../types/price';
1
+ import { KLineData } from '../../types/price';
2
2
  interface BaoStockKDataRequest {
3
3
  /** 股票代码,如 `sh.600000`(沪市)、`sz.000001`(深市) */
4
4
  stock_code: string;
@@ -1,4 +1,4 @@
1
- import { KLineDailyDongCaiResponse } from '../../../types/price';
1
+ import { KLineDailyDongCaiResponse } from '../../types/price';
2
2
  interface KLineDailyDongCaiRequest {
3
3
  symbol: string;
4
4
  period: 'daily' | 'weekly' | 'monthly';
@@ -1,4 +1,4 @@
1
- import { KLineData } from '../../../types/price';
1
+ import { KLineData } from '../../types/price';
2
2
  /**
3
3
  * 统一的数据源配置
4
4
  */
@@ -1,4 +1,4 @@
1
- import { KLineData } from '../../../types/price';
1
+ import { KLineData } from '../../types/price';
2
2
  import { KLineDataSourceConfig, IKLineDataSource, DataSourceType } from './types';
3
3
  /**
4
4
  * 数据源工厂
@@ -14,9 +14,11 @@ type __VLS_Props = {
14
14
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
15
15
  toggle: (indicatorId: string, active: boolean) => any;
16
16
  updateParams: (indicatorId: string, params: Record<string, number>) => any;
17
+ reorderSubIndicators: (orderedIndicatorIds: string[]) => any;
17
18
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
18
19
  onToggle?: ((indicatorId: string, active: boolean) => any) | undefined;
19
20
  onUpdateParams?: ((indicatorId: string, params: Record<string, number>) => any) | undefined;
21
+ onReorderSubIndicators?: ((orderedIndicatorIds: string[]) => any) | undefined;
20
22
  }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
21
23
  addBtnRef: HTMLButtonElement;
22
24
  addMenuRef: HTMLDivElement;
@@ -1,5 +1,5 @@
1
- import { SemanticChartConfig } from '../../semantic';
2
- import { SubIndicatorType } from '../../core/renderers/Indicator';
1
+ import { SemanticChartConfig } from '../semantic';
2
+ import { SubIndicatorType } from '../core/renderers/Indicator';
3
3
  type __VLS_Props = {
4
4
  /** 语义化配置(必需,唯一控制源) */
5
5
  semanticConfig: SemanticChartConfig;
@@ -1,4 +1,4 @@
1
- import { KLineData } from '../../types/price';
1
+ import { KLineData } from '../types/price';
2
2
  type __VLS_Props = {
3
3
  k: KLineData | null;
4
4
  /** 当前k在 data 中的索引 */
@@ -1,4 +1,4 @@
1
- import { MarkerEntity, CustomMarkerEntity } from '../../core/marker/registry';
1
+ import { MarkerEntity, CustomMarkerEntity } from '../core/marker/registry';
2
2
  type __VLS_Props = {
3
3
  marker: MarkerEntity | CustomMarkerEntity | null;
4
4
  pos: {
@@ -1,11 +1,11 @@
1
- import { KLineData } from '../../types/price';
2
- import { VisibleRange } from '../../core/layout/pane';
3
- import { InteractionController } from '../../core/controller/interaction';
4
- import { PaneRenderer } from '../../core/paneRenderer';
1
+ import { KLineData } from '../types/price';
2
+ import { VisibleRange } from './layout/pane';
3
+ import { InteractionController } from './controller/interaction';
4
+ import { PaneRenderer } from './paneRenderer';
5
5
  import { MarkerManager, CustomMarkerEntity } from './marker/registry';
6
- import { getPhysicalKLineConfig, calcKWidthPx } from '../../core/utils/klineConfig';
7
- import { PluginHostImpl, RendererPlugin, RendererPluginWithHost } from '../../plugin';
8
- import { SubIndicatorType } from '../../core/renderers/Indicator';
6
+ import { getPhysicalKLineConfig, calcKWidthPx } from './utils/klineConfig';
7
+ import { PluginHostImpl, RendererPlugin, RendererPluginWithHost } from '../plugin';
8
+ import { SubIndicatorType } from './renderers/Indicator';
9
9
  export { getPhysicalKLineConfig, calcKWidthPx };
10
10
  /**
11
11
  * 图表 DOM 元素引用
@@ -28,6 +28,7 @@ export type PaneSpec = {
28
28
  id: string;
29
29
  ratio: number;
30
30
  visible?: boolean;
31
+ minHeightPx?: number;
31
32
  };
32
33
  export type PaneRendererDom = {
33
34
  plotCanvas: HTMLCanvasElement;
@@ -46,6 +47,8 @@ export type ChartOptions = {
46
47
  paneGap?: number;
47
48
  /** 价格标签额外宽度(用于显示涨跌幅,默认 60px) */
48
49
  priceLabelWidth?: number;
50
+ /** pane 最小高度(逻辑像素,默认 60) */
51
+ defaultPaneMinHeightPx?: number;
49
52
  };
50
53
  /** K 线起始 x 坐标数组,positions[i] 表示第 i 根 K 线的起始 x 坐标(逻辑像素) */
51
54
  export type KLinePositions = number[];
@@ -70,16 +73,27 @@ export declare class Chart {
70
73
  private pluginHost;
71
74
  /** 渲染器插件管理器 */
72
75
  private rendererPluginManager;
73
- /** 精确 DPR(来自 devicePixelContentBoxSize) */
76
+ /** 精确 DPR(来自 ResizeObserver 的 devicePixelContentBoxSize) */
74
77
  private preciseDpr;
75
- /** 用于监听物理像素尺寸变化 */
76
- private dprObserver?;
78
+ /** 统一监听容器尺寸与 DPR 变化 */
79
+ private resizeObserver?;
80
+ /** 最近一次观测到的容器尺寸 */
81
+ private observedSize;
82
+ /** pane ratio 状态(按 paneId 维护,sum=1 仅对可见 pane) */
83
+ private paneRatios;
84
+ /** 视口变化回调(供外部同步 DPR/尺寸) */
85
+ private onViewportChange?;
77
86
  /**
78
87
  * 创建图表实例
79
88
  * @param dom 由 Vue 组件传入的 DOM 句柄
80
89
  * @param opt 初始配置
81
90
  */
82
91
  constructor(dom: ChartDom, opt: ChartOptions);
92
+ private initResizeObserver;
93
+ private updateObservedMetrics;
94
+ private getEffectiveDpr;
95
+ getViewport(): Viewport | null;
96
+ getCurrentDpr(): number;
83
97
  /** 获取插件宿主 */
84
98
  get plugin(): PluginHostImpl;
85
99
  /** 安装渲染器插件 */
@@ -117,6 +131,8 @@ export declare class Chart {
117
131
  * @param cb 缩放回调函数
118
132
  */
119
133
  setOnZoomChange(cb: (kWidth: number, kGap: number, targetScrollLeft: number) => void): void;
134
+ /** 注册视口变化回调 */
135
+ setOnViewportChange(cb: (viewport: Viewport) => void): void;
120
136
  /** 获取所有 PaneRenderer */
121
137
  getPaneRenderers(): PaneRenderer[];
122
138
  /** 获取 MarkerManager(供 InteractionController 使用) */
@@ -140,11 +156,18 @@ export declare class Chart {
140
156
  * @param partial 部分配置项
141
157
  */
142
158
  updateOptions(partial: Partial<ChartOptions>): void;
143
- /**
144
- * 更新 pane 布局配置
159
+ /** 更新 pane 布局配置
145
160
  * @param panes 新的 pane 配置数组
146
161
  */
147
162
  updatePaneLayout(panes: PaneSpec[]): void;
163
+ /** 获取当前 pane 布局快照(含 ratio) */
164
+ getPaneLayoutSpecs(): PaneSpec[];
165
+ /**
166
+ * 调整相邻 pane 边界(upper 与其下方一个 pane)
167
+ * @param upperPaneId 上方 pane ID
168
+ * @param deltaY Y 方向位移(逻辑像素,正数表示边界向下)
169
+ */
170
+ resizePaneBoundary(upperPaneId: string, deltaY: number): boolean;
148
171
  /**
149
172
  * 动态添加 pane
150
173
  * @param paneId pane 标识符
@@ -205,8 +228,12 @@ export declare class Chart {
205
228
  destroy(): Promise<void>;
206
229
  /** 初始化所有 pane */
207
230
  private initPanes;
231
+ private syncPaneRatiosFromSpecs;
232
+ private syncPaneRatiosToSpecs;
233
+ private normalizeVisiblePaneRatios;
234
+ private getPaneMinHeight;
235
+ private computePaneHeightsByRatio;
208
236
  /** 计算每个 pane 的布局(top 和 height) */
209
237
  private layoutPanes;
210
- /** 计算并应用 viewport */
211
238
  private computeViewport;
212
239
  }
@@ -1,5 +1,5 @@
1
1
  import { Chart } from '../chart';
2
- import { MarkerEntity, CustomMarkerEntity } from '../../../core/marker/registry';
2
+ import { MarkerEntity, CustomMarkerEntity } from '../marker/registry';
3
3
  /** 标记 hover 事件数据 */
4
4
  export interface MarkerHoverEvent {
5
5
  type: 'volume-price' | 'custom';
@@ -11,11 +11,15 @@ export interface MarkerHoverEvent {
11
11
  export declare class InteractionController {
12
12
  private chart;
13
13
  private isDragging;
14
+ private dragMode;
14
15
  private dragStartX;
15
16
  private scrollStartX;
16
17
  /** 垂直拖动相关 */
17
18
  private dragStartY;
18
19
  private activePaneIdOnDrag;
20
+ /** 分隔线拖拽相关 */
21
+ private activeSeparatorUpperPaneId;
22
+ private hoveredSeparatorUpperPaneId;
19
23
  /** [触屏]:触摸会话标记,避免触摸触发的模拟 mouse 事件干扰 */
20
24
  private isTouchSession;
21
25
  /** 十字线位置 */
@@ -127,6 +131,10 @@ export declare class InteractionController {
127
131
  } | null, kWidthPx?: number): void;
128
132
  /** 检查是否正在拖拽 */
129
133
  isDraggingState(): boolean;
134
+ /** 是否处于分隔线拖拽状态 */
135
+ isResizingPaneBoundaryState(): boolean;
136
+ /** 是否悬停在可拖拽分隔线上 */
137
+ isHoveringPaneBoundaryState(): boolean;
130
138
  /** 设置 marker hover 回调 */
131
139
  setOnMarkerHover(callback: (marker: MarkerEntity | null) => void): void;
132
140
  /** 设置 marker click 回调 */
@@ -135,13 +143,11 @@ export declare class InteractionController {
135
143
  setOnCustomMarkerHover(callback: (marker: CustomMarkerEntity | null) => void): void;
136
144
  /** 设置自定义标记 click 回调 */
137
145
  setOnCustomMarkerClick(callback: (marker: CustomMarkerEntity) => void): void;
146
+ /** 命中可拖拽分隔线(返回上方 paneId) */
147
+ private hitTestPaneSeparator;
138
148
  /** 清除 hover 状态 */
139
149
  private clearHover;
140
- /**
141
- * 从鼠标事件更新 hover 状态
142
- * @param e MouseEvent
143
- */
144
- private updateHover;
150
+ private clearSeparatorState;
145
151
  /**
146
152
  * 从屏幕坐标更新 hover 状态
147
153
  * @param clientX 屏幕 x 坐标
@@ -1,7 +1,7 @@
1
- import { KLineData } from '../../../types/price';
2
- import { PriceRange } from '../../../core/scale/price';
3
- import { PriceScale } from '../../../core/scale/priceScale';
4
- import { MarkerManager } from '../../../core/marker/registry';
1
+ import { KLineData } from '../../types/price';
2
+ import { PriceRange } from '../scale/price';
3
+ import { PriceScale } from '../scale/priceScale';
4
+ import { MarkerManager } from '../marker/registry';
5
5
  export type VisibleRange = {
6
6
  start: number;
7
7
  end: number;
@@ -1,5 +1,5 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPlugin } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface BOLLConfig {
4
4
  /** 周期(默认20) */
5
5
  period?: number;
@@ -1,11 +1,15 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPluginWithHost, BaseIndicatorState } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface CCIConfig {
4
4
  /** 周期(默认 14) */
5
5
  period?: number;
6
6
  /** 是否显示 CCI 线 */
7
7
  showCCI?: boolean;
8
8
  }
9
+ export interface CCIRenderState extends BaseIndicatorState {
10
+ valueMin: number;
11
+ valueMax: number;
12
+ }
9
13
  export interface CCIRendererOptions {
10
14
  /** 目标 pane ID(默认 'sub') */
11
15
  paneId?: string;
@@ -15,7 +19,7 @@ export interface CCIRendererOptions {
15
19
  /**
16
20
  * 创建 CCI 渲染器插件
17
21
  */
18
- export declare function createCCIRendererPlugin(options?: CCIRendererOptions): RendererPlugin;
22
+ export declare function createCCIRendererPlugin(options?: CCIRendererOptions): RendererPluginWithHost;
19
23
  /**
20
24
  * 计算指定索引处的 CCI 值
21
25
  */
@@ -1,5 +1,5 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPlugin } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface ENEConfig {
4
4
  /** 周期(默认10) */
5
5
  period?: number;
@@ -1,5 +1,5 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPlugin } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface EXPMAConfig {
4
4
  /** 快线周期(默认12) */
5
5
  fastPeriod?: number;
@@ -1,11 +1,15 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPluginWithHost, BaseIndicatorState } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface FASTKConfig {
4
4
  /** 周期(默认 9) */
5
5
  period?: number;
6
6
  /** 是否显示 FASTK 线 */
7
7
  showFASTK?: boolean;
8
8
  }
9
+ export interface FASTKRenderState extends BaseIndicatorState {
10
+ valueMin: number;
11
+ valueMax: number;
12
+ }
9
13
  export interface FASTKRendererOptions {
10
14
  /** 目标 pane ID(默认 'sub') */
11
15
  paneId?: string;
@@ -15,7 +19,7 @@ export interface FASTKRendererOptions {
15
19
  /**
16
20
  * 创建 FASTK 渲染器插件
17
21
  */
18
- export declare function createFASTKRendererPlugin(options?: FASTKRendererOptions): RendererPlugin;
22
+ export declare function createFASTKRendererPlugin(options?: FASTKRendererOptions): RendererPluginWithHost;
19
23
  /**
20
24
  * 计算指定索引处的 FASTK 值
21
25
  */
@@ -1,4 +1,4 @@
1
- import { RendererPlugin } from '../../../../plugin';
1
+ import { RendererPlugin } from '../../../plugin';
2
2
  export { createMARendererPlugin, type MAFlags } from './ma';
3
3
  export { createBOLLRendererPlugin, calcBOLLAtIndex, type BOLLConfig } from './boll';
4
4
  export { createEXPMARendererPlugin, calcEXPMAAtIndex, type EXPMAConfig } from './expma';
@@ -1,5 +1,5 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPluginWithHost, BaseIndicatorState } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface KSTConfig {
4
4
  /** ROC1 周期(默认 10) */
5
5
  roc1?: number;
@@ -20,6 +20,10 @@ interface KSTPoint {
20
20
  kst: number;
21
21
  signal: number;
22
22
  }
23
+ export interface KSTRenderState extends BaseIndicatorState {
24
+ valueMin: number;
25
+ valueMax: number;
26
+ }
23
27
  export interface KSTRendererOptions {
24
28
  /** 目标 pane ID(默认 'sub') */
25
29
  paneId?: string;
@@ -29,7 +33,7 @@ export interface KSTRendererOptions {
29
33
  /**
30
34
  * 创建 KST 渲染器插件
31
35
  */
32
- export declare function createKSTRendererPlugin(options?: KSTRendererOptions): RendererPlugin;
36
+ export declare function createKSTRendererPlugin(options?: KSTRendererOptions): RendererPluginWithHost;
33
37
  /**
34
38
  * 计算指定索引处的 KST 值
35
39
  */
@@ -1,4 +1,4 @@
1
- import { RendererPlugin } from '../../../../plugin';
1
+ import { RendererPlugin } from '../../../plugin';
2
2
  export type MAFlags = {
3
3
  ma5?: boolean;
4
4
  ma10?: boolean;
@@ -1,5 +1,5 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPluginWithHost, BaseIndicatorState } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface MACDConfig {
4
4
  /** 快线周期(默认 12) */
5
5
  fastPeriod?: number;
@@ -14,6 +14,16 @@ export interface MACDConfig {
14
14
  /** 是否显示 MACD 柱 */
15
15
  showBAR?: boolean;
16
16
  }
17
+ /** MACD 渲染器状态(共享给刻度渲染器) */
18
+ export interface MACDRenderState extends BaseIndicatorState {
19
+ valueMin: number;
20
+ valueMax: number;
21
+ latestValues?: {
22
+ dif: number;
23
+ dea: number;
24
+ macd: number;
25
+ };
26
+ }
17
27
  export interface MACDRendererOptions {
18
28
  /** 目标 pane ID(默认 'sub') */
19
29
  paneId?: string;
@@ -23,7 +33,7 @@ export interface MACDRendererOptions {
23
33
  /**
24
34
  * 创建 MACD 渲染器插件
25
35
  */
26
- export declare function createMACDRendererPlugin(options?: MACDRendererOptions): RendererPlugin;
36
+ export declare function createMACDRendererPlugin(options?: MACDRendererOptions): RendererPluginWithHost;
27
37
  /**
28
38
  * 计算指定索引处的 MACD 值(供图例使用)
29
39
  */
@@ -1,4 +1,4 @@
1
- import { RendererPlugin } from '../../../../plugin';
1
+ import { RendererPlugin } from '../../../plugin';
2
2
  export interface MACDLegendOptions {
3
3
  /** Y 轴内边距(与主图保持一致) */
4
4
  yPaddingPx?: number;
@@ -1,4 +1,4 @@
1
- import { RendererPlugin } from '../../../../plugin';
1
+ import { RendererPlugin } from '../../../plugin';
2
2
  /**
3
3
  * 创建主图指标图例渲染器插件
4
4
  *
@@ -1,11 +1,15 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPluginWithHost, BaseIndicatorState } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface MOMConfig {
4
4
  /** 周期(默认 10) */
5
5
  period?: number;
6
6
  /** 是否显示 MOM 线 */
7
7
  showMOM?: boolean;
8
8
  }
9
+ export interface MOMRenderState extends BaseIndicatorState {
10
+ valueMin: number;
11
+ valueMax: number;
12
+ }
9
13
  export interface MOMRendererOptions {
10
14
  /** 目标 pane ID(默认 'sub') */
11
15
  paneId?: string;
@@ -15,7 +19,7 @@ export interface MOMRendererOptions {
15
19
  /**
16
20
  * 创建 MOM 渲染器插件
17
21
  */
18
- export declare function createMOMRendererPlugin(options?: MOMRendererOptions): RendererPlugin;
22
+ export declare function createMOMRendererPlugin(options?: MOMRendererOptions): RendererPluginWithHost;
19
23
  /**
20
24
  * 计算指定索引处的 MOM 值
21
25
  */
@@ -1,5 +1,5 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPluginWithHost, BaseIndicatorState } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface RSIConfig {
4
4
  /** 第一条 RSI 周期(默认 6) */
5
5
  period1?: number;
@@ -14,6 +14,10 @@ export interface RSIConfig {
14
14
  /** 是否显示 RSI3 */
15
15
  showRSI3?: boolean;
16
16
  }
17
+ export interface RSIRenderState extends BaseIndicatorState {
18
+ valueMin: number;
19
+ valueMax: number;
20
+ }
17
21
  export interface RSIRendererOptions {
18
22
  /** 目标 pane ID(默认 'sub') */
19
23
  paneId?: string;
@@ -23,7 +27,7 @@ export interface RSIRendererOptions {
23
27
  /**
24
28
  * 创建 RSI 渲染器插件
25
29
  */
26
- export declare function createRSIRendererPlugin(options?: RSIRendererOptions): RendererPlugin;
30
+ export declare function createRSIRendererPlugin(options?: RSIRendererOptions): RendererPluginWithHost;
27
31
  /**
28
32
  * 计算指定索引处的 RSI 值
29
33
  */
@@ -0,0 +1,5 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ export declare function createCciScaleRendererPlugin(options: {
3
+ axisWidth: number;
4
+ paneId: string;
5
+ }): RendererPluginWithHost;
@@ -0,0 +1,5 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ export declare function createFastkScaleRendererPlugin(options: {
3
+ axisWidth: number;
4
+ paneId: string;
5
+ }): RendererPluginWithHost;
@@ -0,0 +1,23 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ export interface IndicatorScaleRendererOptions {
3
+ axisWidth: number;
4
+ paneId: string;
5
+ indicatorKey: string;
6
+ label: string;
7
+ decimals?: number;
8
+ }
9
+ export interface DrawScaleTicksOptions {
10
+ ctx: CanvasRenderingContext2D;
11
+ dpr: number;
12
+ axisWidth: number;
13
+ height: number;
14
+ paddingTop: number;
15
+ paddingBottom: number;
16
+ valueMin: number;
17
+ valueMax: number;
18
+ isMain: boolean;
19
+ decimals?: number;
20
+ hideEdgeTicks?: boolean;
21
+ }
22
+ export declare function drawScaleTicks(options: DrawScaleTicksOptions): void;
23
+ export declare function createIndicatorScaleRendererPlugin(options: IndicatorScaleRendererOptions): RendererPluginWithHost;
@@ -0,0 +1,5 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ export declare function createKstScaleRendererPlugin(options: {
3
+ axisWidth: number;
4
+ paneId: string;
5
+ }): RendererPluginWithHost;
@@ -0,0 +1,8 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ /**
3
+ * 创建 MACD 刻度渲染器插件
4
+ */
5
+ export declare function createMacdScaleRendererPlugin(options: {
6
+ axisWidth: number;
7
+ paneId: string;
8
+ }): RendererPluginWithHost;
@@ -0,0 +1,5 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ export declare function createMomScaleRendererPlugin(options: {
3
+ axisWidth: number;
4
+ paneId: string;
5
+ }): RendererPluginWithHost;
@@ -0,0 +1,5 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ export declare function createRsiScaleRendererPlugin(options: {
3
+ axisWidth: number;
4
+ paneId: string;
5
+ }): RendererPluginWithHost;
@@ -0,0 +1,5 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ export declare function createStochScaleRendererPlugin(options: {
3
+ axisWidth: number;
4
+ paneId: string;
5
+ }): RendererPluginWithHost;
@@ -0,0 +1,5 @@
1
+ import { RendererPluginWithHost } from '../../../../plugin';
2
+ export declare function createWmsrScaleRendererPlugin(options: {
3
+ axisWidth: number;
4
+ paneId: string;
5
+ }): RendererPluginWithHost;
@@ -1,5 +1,5 @@
1
- import { RendererPlugin } from '../../../../plugin';
2
- import { KLineData } from '../../../../types/price';
1
+ import { RendererPluginWithHost, BaseIndicatorState } from '../../../plugin';
2
+ import { KLineData } from '../../../types/price';
3
3
  export interface STOCHConfig {
4
4
  /** K 周期(默认 9) */
5
5
  n?: number;
@@ -14,6 +14,10 @@ interface STOCHPoint {
14
14
  k: number;
15
15
  d: number;
16
16
  }
17
+ export interface STOCHRenderState extends BaseIndicatorState {
18
+ valueMin: number;
19
+ valueMax: number;
20
+ }
17
21
  export interface STOCHRendererOptions {
18
22
  /** 目标 pane ID(默认 'sub') */
19
23
  paneId?: string;
@@ -23,7 +27,7 @@ export interface STOCHRendererOptions {
23
27
  /**
24
28
  * 创建 STOCH 渲染器插件
25
29
  */
26
- export declare function createSTOCHRendererPlugin(options?: STOCHRendererOptions): RendererPlugin;
30
+ export declare function createSTOCHRendererPlugin(options?: STOCHRendererOptions): RendererPluginWithHost;
27
31
  /**
28
32
  * 计算指定索引处的 STOCH 值
29
33
  */