@363045841yyt/klinechart 0.4.4 → 0.4.7
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/LICENSE +21 -0
- package/README.md +10 -5
- package/dist/index.cjs +9 -9
- package/dist/index.js +1844 -1600
- package/dist/klinechart.css +1 -1
- package/dist/src/components/KLineChart.vue.d.ts +16 -5
- package/dist/src/components/KLineTooltip.vue.d.ts +2 -0
- package/dist/src/components/MarkerTooltip.vue.d.ts +3 -0
- package/dist/src/core/chart.d.ts +66 -12
- package/dist/src/core/controller/interaction.d.ts +34 -3
- package/dist/src/core/renderers/Indicator/scale/indicator_scale.d.ts +3 -0
- package/dist/src/core/renderers/Indicator/scale/volume_scale.d.ts +14 -0
- package/dist/src/core/renderers/subVolume.d.ts +6 -2
- package/dist/src/core/theme/colors.d.ts +12 -1
- package/dist/src/plugin/types.d.ts +4 -0
- package/dist/src/utils/kLineDraw/axis.d.ts +2 -0
- package/package.json +1 -1
package/dist/klinechart.css
CHANGED
|
@@ -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-acace457]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-acace457]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-acace457]::-webkit-scrollbar{display:none}.indicator-list[data-v-acace457]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-acace457]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-acace457]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-acace457],.indicator-item.draggable .indicator-btn[data-v-acace457],.indicator-item.draggable[data-v-acace457]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-acace457]{cursor:move}.indicator-item.is-dragging[data-v-acace457]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-acace457]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-acace457]{position:relative}.indicator-btn[data-v-acace457]{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-acace457]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-acace457]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-acace457]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-acace457]{z-index:1;position:relative}.param-hint[data-v-acace457]{opacity:.85;font-size:11px}.hover-overlay[data-v-acace457]{-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-acace457]{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-acace457]:hover{color:#333;background:#0000000f}.settings-btn[data-v-acace457]:hover{color:#1a1a1a}.remove-btn[data-v-acace457]:hover{color:#ff4d4f}.divider[data-v-acace457]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-acace457]{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-acace457]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-acace457]{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-acace457]{padding:4px 0}.menu-section[data-v-acace457]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-acace457]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-acace457]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-acace457]{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-acace457]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-acace457]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-acace457]{color:#999;font-size:11px}.active-tag[data-v-acace457]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-acace457],.fade-leave-active[data-v-acace457]{transition:opacity .2s}.fade-enter-from[data-v-acace457],.fade-leave-to[data-v-acace457]{opacity:0}.slide-enter-active[data-v-acace457],.slide-leave-active[data-v-acace457]{transition:all .2s}.slide-enter-from[data-v-acace457],.slide-leave-to[data-v-acace457]{opacity:0;transform:translate(-50%)translateY(8px)}.chart-wrapper[data-v-e5297864]{--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-e5297864]{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-e5297864]::-webkit-scrollbar{display:none}.chart-container[data-v-e5297864]:hover{cursor:grab}.chart-container.is-resizing-pane[data-v-e5297864],.chart-container.is-hovering-pane-separator[data-v-e5297864]{cursor:row-resize}.scroll-content[data-v-e5297864]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-e5297864]{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}.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;border-right:1px solid #e0e0e0}
|
|
1
|
+
.kline-tooltip[data-v-d0fe85e6]{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-d0fe85e6]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.kline-tooltip__grid[data-v-d0fe85e6]{grid-template-columns:1fr;gap:2px;display:grid}.kline-tooltip__grid .row[data-v-d0fe85e6]{justify-content:space-between;gap:10px;display:flex}.kline-tooltip__grid .row span[data-v-d0fe85e6]:first-child{color:#0000008f}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.kline-tooltip.use-anchor[data-v-d0fe85e6]{position-anchor:--kline-tooltip-anchor;left:anchor(left);top:anchor(top);position:absolute}.kline-tooltip.use-anchor.anchor-right-bottom[data-v-d0fe85e6]{transform:translate(14px,14px)}.kline-tooltip.use-anchor.anchor-left-bottom[data-v-d0fe85e6]{transform:translate(calc(-100% - 14px),14px)}}.marker-tooltip[data-v-5574cc25]{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-5574cc25]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.marker-tooltip__content[data-v-5574cc25]{grid-template-columns:1fr;gap:2px;display:grid}.marker-tooltip__content .row[data-v-5574cc25]{justify-content:space-between;gap:10px;display:flex}.marker-tooltip__content .row span[data-v-5574cc25]:first-child{color:#0000008f}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.marker-tooltip.use-anchor[data-v-5574cc25]{position-anchor:--marker-tooltip-anchor;left:anchor(left);top:anchor(top);position:absolute}.marker-tooltip.use-anchor.anchor-right-bottom[data-v-5574cc25]{transform:translate(12px,12px)}.marker-tooltip.use-anchor.anchor-left-bottom[data-v-5574cc25]{transform:translate(calc(-100% - 12px),12px)}}.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-4b90c954]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-4b90c954]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-4b90c954]::-webkit-scrollbar{display:none}.indicator-list[data-v-4b90c954]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-4b90c954]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-4b90c954]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-4b90c954],.indicator-item.draggable .indicator-btn[data-v-4b90c954],.indicator-item.draggable[data-v-4b90c954]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-4b90c954]{cursor:move}.indicator-item.is-dragging[data-v-4b90c954]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-4b90c954]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-4b90c954]{position:relative}.indicator-btn[data-v-4b90c954]{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-4b90c954]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-4b90c954]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-4b90c954]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-4b90c954]{z-index:1;position:relative}.param-hint[data-v-4b90c954]{opacity:.85;font-size:11px}.hover-overlay[data-v-4b90c954]{-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-4b90c954]{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-4b90c954]:hover{color:#333;background:#0000000f}.settings-btn[data-v-4b90c954]:hover{color:#1a1a1a}.remove-btn[data-v-4b90c954]:hover{color:#ff4d4f}.divider[data-v-4b90c954]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-4b90c954]{anchor-name:--indicator-add-btn;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-4b90c954]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-4b90c954]{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}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.add-menu.use-anchor[data-v-4b90c954]{position-anchor:--indicator-add-btn;left:anchor(center);top:anchor(top);max-width:calc(100vw - 16px);position:fixed;transform:translate(-50%,calc(-100% - 8px))}}.menu-section[data-v-4b90c954]{padding:4px 0}.menu-section[data-v-4b90c954]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-4b90c954]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-4b90c954]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-4b90c954]{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-4b90c954]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-4b90c954]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-4b90c954]{color:#999;font-size:11px}.active-tag[data-v-4b90c954]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-4b90c954],.fade-leave-active[data-v-4b90c954]{transition:opacity .2s}.fade-enter-from[data-v-4b90c954],.fade-leave-to[data-v-4b90c954]{opacity:0}.slide-enter-active[data-v-4b90c954],.slide-leave-active[data-v-4b90c954]{transition:all .2s}.slide-enter-from[data-v-4b90c954],.slide-leave-to[data-v-4b90c954]{opacity:0;transform:translate(-50%)translateY(8px)}.chart-wrapper[data-v-289d47a8]{--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-289d47a8]{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-289d47a8]::-webkit-scrollbar{display:none}.chart-container[data-v-289d47a8]:hover{cursor:crosshair}.chart-container.is-resizing-pane[data-v-289d47a8],.chart-container.is-hovering-pane-separator[data-v-289d47a8]{cursor:row-resize}.chart-container.is-hovering-kline[data-v-289d47a8]{cursor:pointer}.chart-container:hover.is-hovering-right-axis[data-v-289d47a8]{cursor:ns-resize}.chart-container.is-dragging[data-v-289d47a8]{cursor:grabbing}.scroll-content[data-v-289d47a8]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-289d47a8]{pointer-events:none;position:sticky;top:0;left:0}.tooltip-anchor[data-v-289d47a8]{pointer-events:none;width:1px;height:1px;position:absolute}.tooltip-anchor.kline-tooltip-anchor.use-anchor[data-v-289d47a8]{anchor-name:--kline-tooltip-anchor}.tooltip-anchor.marker-tooltip-anchor.use-anchor[data-v-289d47a8]{anchor-name:--marker-tooltip-anchor}.plot-canvas{display:block;position:absolute;top:0;left:0}.right-axis{display:block;position:absolute}.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;border-right:1px solid #e0e0e0}
|
|
2
2
|
/*$vite$:1*/
|
|
@@ -3,8 +3,6 @@ import { SubIndicatorType } from '../core/renderers/Indicator';
|
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
/** 语义化配置(必需,唯一控制源) */
|
|
5
5
|
semanticConfig: SemanticChartConfig;
|
|
6
|
-
kWidth?: number;
|
|
7
|
-
kGap?: number;
|
|
8
6
|
yPaddingPx?: number;
|
|
9
7
|
minKWidth?: number;
|
|
10
8
|
maxKWidth?: number;
|
|
@@ -14,6 +12,10 @@ type __VLS_Props = {
|
|
|
14
12
|
bottomAxisHeight?: number;
|
|
15
13
|
/** 价格标签额外宽度(用于显示涨跌幅,默认 60px) */
|
|
16
14
|
priceLabelWidth?: number;
|
|
15
|
+
/** 缩放级别数量(默认 10) */
|
|
16
|
+
zoomLevels?: number;
|
|
17
|
+
/** 初始缩放级别(1 ~ zoomLevels,默认居中) */
|
|
18
|
+
initialZoomLevel?: number;
|
|
17
19
|
};
|
|
18
20
|
declare function scheduleRender(): void;
|
|
19
21
|
declare function addSubPane(indicatorId?: SubIndicatorType, params?: Record<string, number>): boolean;
|
|
@@ -29,15 +31,24 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {
|
|
|
29
31
|
switchSubIndicator: typeof switchSubIndicator;
|
|
30
32
|
clearAllSubPanes: typeof clearAllSubPanes;
|
|
31
33
|
plugin: import('..').PluginHostImpl | undefined;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
zoomToLevel: (level: number, anchorX?: number) => void | undefined;
|
|
35
|
+
zoomIn: (anchorX?: number) => void | undefined;
|
|
36
|
+
zoomOut: (anchorX?: number) => void | undefined;
|
|
37
|
+
getZoomLevel: () => number;
|
|
38
|
+
getZoomLevelCount: () => number;
|
|
39
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
40
|
+
zoomLevelChange: (level: number, kWidth: number) => any;
|
|
41
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
42
|
+
onZoomLevelChange?: ((level: number, kWidth: number) => any) | undefined;
|
|
43
|
+
}>, {
|
|
35
44
|
yPaddingPx: number;
|
|
36
45
|
rightAxisWidth: number;
|
|
37
46
|
bottomAxisHeight: number;
|
|
38
47
|
minKWidth: number;
|
|
39
48
|
maxKWidth: number;
|
|
40
49
|
priceLabelWidth: number;
|
|
50
|
+
zoomLevels: number;
|
|
51
|
+
initialZoomLevel: number;
|
|
41
52
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
42
53
|
containerRef: HTMLDivElement;
|
|
43
54
|
canvasLayerRef: HTMLDivElement;
|
|
@@ -5,6 +5,9 @@ type __VLS_Props = {
|
|
|
5
5
|
x: number;
|
|
6
6
|
y: number;
|
|
7
7
|
};
|
|
8
|
+
useAnchor?: boolean;
|
|
9
|
+
anchorPlacement?: 'right-bottom' | 'left-bottom';
|
|
10
|
+
setEl?: (el: HTMLDivElement | null) => void;
|
|
8
11
|
};
|
|
9
12
|
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
10
13
|
export default _default;
|
package/dist/src/core/chart.d.ts
CHANGED
|
@@ -37,8 +37,10 @@ export type PaneRendererDom = {
|
|
|
37
37
|
yAxisCanvas: HTMLCanvasElement;
|
|
38
38
|
};
|
|
39
39
|
export type ChartOptions = {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
/** K 线宽度(可选,由 zoomLevel 派生) */
|
|
41
|
+
kWidth?: number;
|
|
42
|
+
/** K 线间隙(可选,由 DPR 计算) */
|
|
43
|
+
kGap?: number;
|
|
42
44
|
yPaddingPx: number;
|
|
43
45
|
rightAxisWidth: number;
|
|
44
46
|
bottomAxisHeight: number;
|
|
@@ -51,6 +53,17 @@ export type ChartOptions = {
|
|
|
51
53
|
priceLabelWidth?: number;
|
|
52
54
|
/** pane 最小高度(逻辑像素,默认 60) */
|
|
53
55
|
defaultPaneMinHeightPx?: number;
|
|
56
|
+
/**
|
|
57
|
+
* 缩放级别数量(默认 10)
|
|
58
|
+
* - 将 minKWidth ~ maxKWidth 划分为多少个离散级别
|
|
59
|
+
* - 例如 10 表示有 10 个缩放级别(1-10)
|
|
60
|
+
*/
|
|
61
|
+
zoomLevels?: number;
|
|
62
|
+
/**
|
|
63
|
+
* 初始缩放级别(1 ~ zoomLevels,默认 1)
|
|
64
|
+
* 未指定时默认为最小级别
|
|
65
|
+
*/
|
|
66
|
+
initialZoomLevel?: number;
|
|
54
67
|
};
|
|
55
68
|
/** K 线起始 x 坐标数组,positions[i] 表示第 i 根 K 线的起始 x 坐标(逻辑像素) */
|
|
56
69
|
export type KLinePositions = number[];
|
|
@@ -62,6 +75,10 @@ export type Viewport = {
|
|
|
62
75
|
scrollLeft: number;
|
|
63
76
|
dpr: number;
|
|
64
77
|
};
|
|
78
|
+
type ResolvedChartOptions = Omit<ChartOptions, 'kWidth' | 'kGap'> & {
|
|
79
|
+
kWidth: number;
|
|
80
|
+
kGap: number;
|
|
81
|
+
};
|
|
65
82
|
export declare class Chart {
|
|
66
83
|
private dom;
|
|
67
84
|
private opt;
|
|
@@ -87,6 +104,12 @@ export declare class Chart {
|
|
|
87
104
|
private onViewportChange?;
|
|
88
105
|
/** pane 布局回流回调(Chart -> UI 单向) */
|
|
89
106
|
private onPaneLayoutChange?;
|
|
107
|
+
/** 缩放级别变化回调 */
|
|
108
|
+
private onZoomLevelChange?;
|
|
109
|
+
/** 当前缩放级别(1 ~ zoomLevelCount) */
|
|
110
|
+
private currentZoomLevel;
|
|
111
|
+
/** 缩放级别总数 */
|
|
112
|
+
private readonly zoomLevelCount;
|
|
90
113
|
/**
|
|
91
114
|
* 创建图表实例
|
|
92
115
|
* @param dom 由 Vue 组件传入的 DOM 句柄
|
|
@@ -122,19 +145,50 @@ export declare class Chart {
|
|
|
122
145
|
*/
|
|
123
146
|
zoomAt(mouseX: number, scrollLeft: number, deltaY: number): void;
|
|
124
147
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* @param kWidth 新的 K 线宽度
|
|
128
|
-
* @param kGap 新的 K 线间隙
|
|
148
|
+
* 应用缩放级别(在 scrollLeft 落地后调用)
|
|
149
|
+
* @param level 缩放级别
|
|
129
150
|
*/
|
|
130
|
-
applyZoom(
|
|
131
|
-
/**
|
|
151
|
+
applyZoom(level: number): void;
|
|
152
|
+
/** 缩放回调 */
|
|
132
153
|
private onZoomChange?;
|
|
154
|
+
setOnZoomChange(cb: (level: number, kWidth: number, kGap: number, targetScrollLeft: number) => void): void;
|
|
155
|
+
/**
|
|
156
|
+
* 将缩放级别转换为 K 线宽度
|
|
157
|
+
* @param level 缩放级别(1 ~ zoomLevels)
|
|
158
|
+
* @returns K 线宽度(逻辑像素)
|
|
159
|
+
*/
|
|
160
|
+
private zoomLevelToKWidth;
|
|
161
|
+
/**
|
|
162
|
+
* 缩放到指定级别
|
|
163
|
+
* @param level 目标级别(1 ~ zoomLevels)
|
|
164
|
+
* @param anchorX 缩放中心点(相对 container 左侧的 x 坐标,默认为中心)
|
|
165
|
+
*/
|
|
166
|
+
zoomToLevel(level: number, anchorX?: number): void;
|
|
167
|
+
/**
|
|
168
|
+
* 获取当前缩放级别
|
|
169
|
+
* @returns 当前级别(1 ~ zoomLevels)
|
|
170
|
+
*/
|
|
171
|
+
getZoomLevel(): number;
|
|
172
|
+
/**
|
|
173
|
+
* 获取总缩放级别数
|
|
174
|
+
* @returns 级别总数
|
|
175
|
+
*/
|
|
176
|
+
getZoomLevelCount(): number;
|
|
177
|
+
/**
|
|
178
|
+
* 放大一级
|
|
179
|
+
* @param anchorX 缩放中心点(默认为中心)
|
|
180
|
+
*/
|
|
181
|
+
zoomIn(anchorX?: number): void;
|
|
182
|
+
/**
|
|
183
|
+
* 缩小一级
|
|
184
|
+
* @param anchorX 缩放中心点(默认为中心)
|
|
185
|
+
*/
|
|
186
|
+
zoomOut(anchorX?: number): void;
|
|
133
187
|
/**
|
|
134
|
-
*
|
|
135
|
-
* @param cb
|
|
188
|
+
* 注册缩放级别变化回调
|
|
189
|
+
* @param cb 回调函数,参数为 (level, kWidth)
|
|
136
190
|
*/
|
|
137
|
-
|
|
191
|
+
setOnZoomLevelChange(cb: (level: number, kWidth: number) => void): void;
|
|
138
192
|
/** 注册视口变化回调 */
|
|
139
193
|
setOnViewportChange(cb: (viewport: Viewport) => void): void;
|
|
140
194
|
/** 注册 pane 布局回流回调 */
|
|
@@ -150,7 +204,7 @@ export declare class Chart {
|
|
|
150
204
|
/** 获取 ChartDom(供 InteractionController 使用) */
|
|
151
205
|
getDom(): ChartDom;
|
|
152
206
|
/** 获取当前 ChartOptions(返回内部当前快照) */
|
|
153
|
-
getOption():
|
|
207
|
+
getOption(): ResolvedChartOptions;
|
|
154
208
|
/**
|
|
155
209
|
* 计算 K 线起始 x 坐标数组,与 candle.ts 的像素对齐方式保持一致
|
|
156
210
|
* @param range 可见 K 线索引范围
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import { Chart } from '../chart';
|
|
2
2
|
import { MarkerEntity, CustomMarkerEntity } from '../marker/registry';
|
|
3
3
|
/** 标记 hover 事件数据 */
|
|
4
|
-
export interface
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
export interface InteractionSnapshot {
|
|
5
|
+
crosshairPos: {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
} | null;
|
|
9
|
+
crosshairIndex: number | null;
|
|
10
|
+
crosshairPrice: number | null;
|
|
11
|
+
hoveredIndex: number | null;
|
|
12
|
+
activePaneId: string | null;
|
|
13
|
+
tooltipPos: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
tooltipAnchorPlacement: 'right-bottom' | 'left-bottom';
|
|
18
|
+
hoveredMarkerData: MarkerEntity | null;
|
|
19
|
+
hoveredCustomMarker: CustomMarkerEntity | null;
|
|
20
|
+
isDragging: boolean;
|
|
21
|
+
isResizingPaneBoundary: boolean;
|
|
22
|
+
isHoveringPaneBoundary: boolean;
|
|
23
|
+
isHoveringRightAxis: boolean;
|
|
7
24
|
}
|
|
8
25
|
/**
|
|
9
26
|
* 交互控制器,处理拖拽滚动、缩放、十字线 hover 等交互逻辑
|
|
@@ -20,6 +37,8 @@ export declare class InteractionController {
|
|
|
20
37
|
/** 分隔线拖拽相关 */
|
|
21
38
|
private activeSeparatorUpperPaneId;
|
|
22
39
|
private hoveredSeparatorUpperPaneId;
|
|
40
|
+
/** 右轴悬浮相关 */
|
|
41
|
+
private hoveredRightAxisPaneId;
|
|
23
42
|
/** [触屏]:触摸会话标记,避免触摸触发的模拟 mouse 事件干扰 */
|
|
24
43
|
private isTouchSession;
|
|
25
44
|
/** 十字线位置 */
|
|
@@ -45,6 +64,12 @@ export declare class InteractionController {
|
|
|
45
64
|
width: number;
|
|
46
65
|
height: number;
|
|
47
66
|
};
|
|
67
|
+
/** tooltip 锚定位放置方向 */
|
|
68
|
+
tooltipAnchorPlacement: 'right-bottom' | 'left-bottom';
|
|
69
|
+
/** 是否使用 CSS 锚定位 */
|
|
70
|
+
private useTooltipAnchorPositioning;
|
|
71
|
+
/** 统一交互状态变更回调 */
|
|
72
|
+
private onInteractionChangeCallback?;
|
|
48
73
|
/** 当前 hover 的 marker ID */
|
|
49
74
|
hoveredMarkerId: string | null;
|
|
50
75
|
/** 当前点击的 marker ID */
|
|
@@ -70,6 +95,9 @@ export declare class InteractionController {
|
|
|
70
95
|
/** K 线宽度(物理像素),用于计算 K 线中心偏移 */
|
|
71
96
|
private kWidthPx;
|
|
72
97
|
constructor(chart: Chart);
|
|
98
|
+
getInteractionSnapshot(): InteractionSnapshot;
|
|
99
|
+
setOnInteractionChange(callback: (snapshot: InteractionSnapshot) => void): void;
|
|
100
|
+
private notifyInteractionChange;
|
|
73
101
|
/**
|
|
74
102
|
* 处理滚轮缩放事件
|
|
75
103
|
* @param e WheelEvent
|
|
@@ -88,6 +116,7 @@ export declare class InteractionController {
|
|
|
88
116
|
width: number;
|
|
89
117
|
height: number;
|
|
90
118
|
}): void;
|
|
119
|
+
setTooltipAnchorPositioning(enabled: boolean): void;
|
|
91
120
|
/**
|
|
92
121
|
* 处理 Pointer 抬起事件
|
|
93
122
|
* @param e PointerEvent
|
|
@@ -135,6 +164,8 @@ export declare class InteractionController {
|
|
|
135
164
|
isResizingPaneBoundaryState(): boolean;
|
|
136
165
|
/** 是否悬停在可拖拽分隔线上 */
|
|
137
166
|
isHoveringPaneBoundaryState(): boolean;
|
|
167
|
+
/** 是否悬停在右轴区域 */
|
|
168
|
+
isHoveringRightAxisState(): boolean;
|
|
138
169
|
/** 设置 marker hover 回调 */
|
|
139
170
|
setOnMarkerHover(callback: (marker: MarkerEntity | null) => void): void;
|
|
140
171
|
/** 设置 marker click 回调 */
|
|
@@ -11,6 +11,8 @@ export interface IndicatorScaleRendererOptions {
|
|
|
11
11
|
price: number;
|
|
12
12
|
activePaneId: string | null;
|
|
13
13
|
} | null;
|
|
14
|
+
formatTickLabel?: (value: number) => string;
|
|
15
|
+
formatCrosshairLabel?: (value: number) => string;
|
|
14
16
|
}
|
|
15
17
|
export interface DrawScaleTicksOptions {
|
|
16
18
|
ctx: CanvasRenderingContext2D;
|
|
@@ -24,6 +26,7 @@ export interface DrawScaleTicksOptions {
|
|
|
24
26
|
isMain: boolean;
|
|
25
27
|
decimals?: number;
|
|
26
28
|
hideEdgeTicks?: boolean;
|
|
29
|
+
formatLabel?: (value: number) => string;
|
|
27
30
|
}
|
|
28
31
|
export declare function drawScaleTicks(options: DrawScaleTicksOptions): void;
|
|
29
32
|
export declare function createIndicatorScaleRendererPlugin(options: IndicatorScaleRendererOptions): RendererPluginWithHost;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RendererPluginWithHost } from '../../../../plugin';
|
|
2
|
+
/**
|
|
3
|
+
* 创建成交量刻度渲染器插件
|
|
4
|
+
*/
|
|
5
|
+
export declare function createVolumeScaleRendererPlugin(options: {
|
|
6
|
+
axisWidth: number;
|
|
7
|
+
paneId: string;
|
|
8
|
+
yPaddingPx?: number;
|
|
9
|
+
getCrosshair?: () => {
|
|
10
|
+
y: number;
|
|
11
|
+
price: number;
|
|
12
|
+
activePaneId: string | null;
|
|
13
|
+
} | null;
|
|
14
|
+
}): RendererPluginWithHost;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RendererPluginWithHost, BaseIndicatorState } from '../../plugin';
|
|
2
2
|
export interface VolumeRendererOptions {
|
|
3
3
|
/** 目标 pane ID(默认 'sub') */
|
|
4
4
|
paneId?: string;
|
|
5
5
|
}
|
|
6
|
+
export interface VolumeRenderState extends BaseIndicatorState {
|
|
7
|
+
valueMin: number;
|
|
8
|
+
valueMax: number;
|
|
9
|
+
}
|
|
6
10
|
/**
|
|
7
11
|
* 创建副图成交量渲染器插件
|
|
8
12
|
*/
|
|
9
|
-
export declare function createVolumeRendererPlugin(options?: VolumeRendererOptions):
|
|
13
|
+
export declare function createVolumeRendererPlugin(options?: VolumeRendererOptions): RendererPluginWithHost;
|
|
@@ -45,7 +45,7 @@ export declare const PRICE_COLORS: {
|
|
|
45
45
|
/** 中性颜色 */
|
|
46
46
|
readonly NEUTRAL: "rgba(0, 0, 0, 0.78)";
|
|
47
47
|
/** 最新价颜色 */
|
|
48
|
-
readonly LAST_PRICE: "
|
|
48
|
+
readonly LAST_PRICE: "rgba(196, 74, 86, 0.95)";
|
|
49
49
|
};
|
|
50
50
|
/**
|
|
51
51
|
* 十字线标签背景颜色
|
|
@@ -129,6 +129,17 @@ export declare const MACD_COLORS: {
|
|
|
129
129
|
/** MACD 柱淡绿色(负值上升) */
|
|
130
130
|
readonly BAR_DOWN_LIGHT: "#ace5dc";
|
|
131
131
|
};
|
|
132
|
+
/**
|
|
133
|
+
* 成交量颜色(与 MACD 柱子配色一致)
|
|
134
|
+
*/
|
|
135
|
+
export declare const VOLUME_COLORS: {
|
|
136
|
+
/** 上涨柱子(与 MACD BAR_UP 一致) */
|
|
137
|
+
readonly UP: "#ff5252";
|
|
138
|
+
/** 下跌柱子(与 MACD BAR_DOWN 一致) */
|
|
139
|
+
readonly DOWN: "#22ab94";
|
|
140
|
+
/** 中性/平盘柱子 */
|
|
141
|
+
readonly NEUTRAL: "rgba(0, 0, 0, 0.78)";
|
|
142
|
+
};
|
|
132
143
|
/**
|
|
133
144
|
* RSI 颜色
|
|
134
145
|
*/
|
|
@@ -167,6 +167,10 @@ export interface RenderContext {
|
|
|
167
167
|
yAxisCtx?: CanvasRenderingContext2D;
|
|
168
168
|
xAxisCtx?: CanvasRenderingContext2D;
|
|
169
169
|
borderCtx?: CanvasRenderingContext2D;
|
|
170
|
+
/** 当前缩放级别(1 ~ zoomLevels) */
|
|
171
|
+
zoomLevel?: number;
|
|
172
|
+
/** 总缩放级别数 */
|
|
173
|
+
zoomLevelCount?: number;
|
|
170
174
|
}
|
|
171
175
|
/** 全局 Pane ID(渲染到所有 pane) */
|
|
172
176
|
export declare const GLOBAL_PANE_ID: unique symbol;
|
|
@@ -87,6 +87,7 @@ export interface CrosshairPriceLabelOptions {
|
|
|
87
87
|
yPaddingPx?: number;
|
|
88
88
|
dpr: number;
|
|
89
89
|
bgColor?: string;
|
|
90
|
+
borderColor?: string;
|
|
90
91
|
textColor?: string;
|
|
91
92
|
fontSize?: number;
|
|
92
93
|
paddingX?: number;
|
|
@@ -94,6 +95,7 @@ export interface CrosshairPriceLabelOptions {
|
|
|
94
95
|
priceOffset?: number;
|
|
95
96
|
/** 优先显示的价格(如十字线已按 active pane 算好) */
|
|
96
97
|
price?: number;
|
|
98
|
+
formatPrice?: (price: number) => string;
|
|
97
99
|
}
|
|
98
100
|
export interface CrosshairTimeLabelOptions {
|
|
99
101
|
x: number;
|