@363045841yyt/klinechart 0.4.1 → 0.4.3

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.
@@ -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-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}
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-061fa6d4]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-061fa6d4]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-061fa6d4]::-webkit-scrollbar{display:none}.indicator-list[data-v-061fa6d4]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-061fa6d4]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-061fa6d4]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-061fa6d4],.indicator-item.draggable .indicator-btn[data-v-061fa6d4],.indicator-item.draggable[data-v-061fa6d4]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-061fa6d4]{cursor:move}.indicator-item.is-dragging[data-v-061fa6d4]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-061fa6d4]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-061fa6d4]{position:relative}.indicator-btn[data-v-061fa6d4]{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-061fa6d4]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-061fa6d4]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-061fa6d4]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-061fa6d4]{z-index:1;position:relative}.param-hint[data-v-061fa6d4]{opacity:.85;font-size:11px}.hover-overlay[data-v-061fa6d4]{-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-061fa6d4]{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-061fa6d4]:hover{color:#333;background:#0000000f}.settings-btn[data-v-061fa6d4]:hover{color:#1a1a1a}.remove-btn[data-v-061fa6d4]:hover{color:#ff4d4f}.divider[data-v-061fa6d4]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-061fa6d4]{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-061fa6d4]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-061fa6d4]{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-061fa6d4]{padding:4px 0}.menu-section[data-v-061fa6d4]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-061fa6d4]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-061fa6d4]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-061fa6d4]{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-061fa6d4]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-061fa6d4]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-061fa6d4]{color:#999;font-size:11px}.active-tag[data-v-061fa6d4]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-061fa6d4],.fade-leave-active[data-v-061fa6d4]{transition:opacity .2s}.fade-enter-from[data-v-061fa6d4],.fade-leave-to[data-v-061fa6d4]{opacity:0}.slide-enter-active[data-v-061fa6d4],.slide-leave-active[data-v-061fa6d4]{transition:all .2s}.slide-enter-from[data-v-061fa6d4],.slide-leave-to[data-v-061fa6d4]{opacity:0;transform:translate(-50%)translateY(8px)}.chart-wrapper[data-v-15fe4683]{--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-15fe4683]{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-15fe4683]::-webkit-scrollbar{display:none}.chart-container[data-v-15fe4683]:hover{cursor:grab}.chart-container.is-resizing-pane[data-v-15fe4683],.chart-container.is-hovering-pane-separator[data-v-15fe4683]{cursor:row-resize}.scroll-content[data-v-15fe4683]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-15fe4683]{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}
2
2
  /*$vite$:1*/
@@ -4,7 +4,7 @@ import { InteractionController } from './controller/interaction';
4
4
  import { PaneRenderer } from './paneRenderer';
5
5
  import { MarkerManager, CustomMarkerEntity } from './marker/registry';
6
6
  import { getPhysicalKLineConfig, calcKWidthPx } from './utils/klineConfig';
7
- import { PluginHostImpl, RendererPlugin, RendererPluginWithHost } from '../plugin';
7
+ import { PluginHostImpl, RendererPlugin, RendererPluginWithHost, PaneRole, PaneCapabilities } from '../plugin';
8
8
  import { SubIndicatorType } from './renderers/Indicator';
9
9
  export { getPhysicalKLineConfig, calcKWidthPx };
10
10
  /**
@@ -29,6 +29,8 @@ export type PaneSpec = {
29
29
  ratio: number;
30
30
  visible?: boolean;
31
31
  minHeightPx?: number;
32
+ role?: PaneRole;
33
+ capabilities?: Partial<PaneCapabilities>;
32
34
  };
33
35
  export type PaneRendererDom = {
34
36
  plotCanvas: HTMLCanvasElement;
@@ -83,6 +85,8 @@ export declare class Chart {
83
85
  private paneRatios;
84
86
  /** 视口变化回调(供外部同步 DPR/尺寸) */
85
87
  private onViewportChange?;
88
+ /** pane 布局回流回调(Chart -> UI 单向) */
89
+ private onPaneLayoutChange?;
86
90
  /**
87
91
  * 创建图表实例
88
92
  * @param dom 由 Vue 组件传入的 DOM 句柄
@@ -133,6 +137,8 @@ export declare class Chart {
133
137
  setOnZoomChange(cb: (kWidth: number, kGap: number, targetScrollLeft: number) => void): void;
134
138
  /** 注册视口变化回调 */
135
139
  setOnViewportChange(cb: (viewport: Viewport) => void): void;
140
+ /** 注册 pane 布局回流回调 */
141
+ setOnPaneLayoutChange(cb: (panes: PaneSpec[]) => void): void;
136
142
  /** 获取所有 PaneRenderer */
137
143
  getPaneRenderers(): PaneRenderer[];
138
144
  /** 获取 MarkerManager(供 InteractionController 使用) */
@@ -160,18 +166,21 @@ export declare class Chart {
160
166
  * @param panes 新的 pane 配置数组
161
167
  */
162
168
  updatePaneLayout(panes: PaneSpec[]): void;
169
+ setPaneDefinitions(defs: PaneSpec[]): void;
170
+ upsertPane(def: PaneSpec): void;
171
+ removePaneDefinition(paneId: string): void;
172
+ bindIndicatorToPane(paneId: string, indicatorId: SubIndicatorType, params?: Record<string, number>): void;
163
173
  /** 获取当前 pane 布局快照(含 ratio) */
164
174
  getPaneLayoutSpecs(): PaneSpec[];
175
+ private emitPaneLayoutChange;
176
+ private applyPaneLayoutSpecs;
165
177
  /**
166
- * 调整相邻 pane 边界(upper 与其下方一个 pane)
167
- * @param upperPaneId 上方 pane ID
168
- * @param deltaY Y 方向位移(逻辑像素,正数表示边界向下)
178
+ * 调整相邻 pane 边界(支持连锁挤压)
179
+ * @param upperPaneId 上方 pane ID(边界位于此 pane 与其下方邻居之间)
180
+ * @param deltaY Y 方向位移(逻辑像素,正数表示边界向下,upper 增大;负数表示向上,upper 减小)
169
181
  */
170
182
  resizePaneBoundary(upperPaneId: string, deltaY: number): boolean;
171
- /**
172
- * 动态添加 pane
173
- * @param paneId pane 标识符
174
- */
183
+ private resolvePaneRole;
175
184
  addPane(paneId: string): void;
176
185
  /**
177
186
  * 动态移除 pane
@@ -2,10 +2,15 @@ import { KLineData } from '../../types/price';
2
2
  import { PriceRange } from '../scale/price';
3
3
  import { PriceScale } from '../scale/priceScale';
4
4
  import { MarkerManager } from '../marker/registry';
5
+ import { PaneCapabilities, PaneRole } from '../../plugin';
5
6
  export type VisibleRange = {
6
7
  start: number;
7
8
  end: number;
8
9
  };
10
+ export interface PaneInitOptions {
11
+ role?: PaneRole;
12
+ capabilities?: Partial<PaneCapabilities>;
13
+ }
9
14
  /**
10
15
  * Pane 级渲染器接口:在单个 pane 的坐标系中绘制内容
11
16
  */
@@ -42,6 +47,8 @@ export interface PaneRenderer {
42
47
  */
43
48
  export declare class Pane {
44
49
  readonly id: string;
50
+ readonly role: PaneRole;
51
+ readonly capabilities: PaneCapabilities;
45
52
  top: number;
46
53
  height: number;
47
54
  /** 当前 pane 的可视价格范围(用于右侧轴、以及渲染器内部) */
@@ -54,7 +61,7 @@ export declare class Pane {
54
61
  * 创建 pane 实例
55
62
  * @param id pane 标识符(例如 'main'、'sub'),用于在 Chart/Interaction 中识别 pane
56
63
  */
57
- constructor(id: string);
64
+ constructor(id: string, options?: PaneInitOptions);
58
65
  /**
59
66
  * 设置 pane 的垂直布局
60
67
  * @param top 相对 plotCanvas 顶部的偏移(逻辑像素)
@@ -7,10 +7,6 @@ export type PaneRendererOptions = {
7
7
  yPaddingPx: number;
8
8
  priceLabelWidth?: number;
9
9
  };
10
- /**
11
- * PaneRenderer:负责单个 Pane 的 Canvas 管理
12
- * 渲染逻辑由 Chart 通过 RendererPluginManager 统一调度
13
- */
14
10
  export declare class PaneRenderer {
15
11
  private dom;
16
12
  private pane;
@@ -1,7 +1,7 @@
1
1
  import { RendererPlugin } from '../../plugin';
2
2
  /**
3
3
  * 创建 Y 轴渲染器插件
4
- * 仅渲染主图价格刻度;副图刻度由指标刻度插件负责
4
+ * 按 pane capability 决定是否绘制刻度与价格标签
5
5
  */
6
6
  export declare function createYAxisRendererPlugin(options: {
7
7
  axisWidth: number;
@@ -9,5 +9,6 @@ export declare function createYAxisRendererPlugin(options: {
9
9
  getCrosshair?: () => {
10
10
  y: number;
11
11
  price: number;
12
+ activePaneId: string | null;
12
13
  } | null;
13
14
  }): RendererPlugin;
@@ -34,8 +34,8 @@ export declare class RendererPluginManager {
34
34
  addKnownPaneId(paneId: string): void;
35
35
  /** 移除 paneId */
36
36
  removeKnownPaneId(paneId: string): void;
37
- /** 获取所有已知的 paneId */
38
- getKnownPaneIds(): string[];
37
+ /** 覆盖已知 paneId 集合 */
38
+ setKnownPaneIds(paneIds: string[]): void;
39
39
  /** 注册渲染器插件 */
40
40
  register(plugin: RendererPlugin | RendererPluginWithHost): void;
41
41
  /** 移除渲染器插件 */
@@ -89,9 +89,20 @@ export interface PluginHost {
89
89
  /** 按拥有者清除状态 */
90
90
  clearByOwner(ownerId: string): void;
91
91
  }
92
+ /** Pane 角色 */
93
+ export type PaneRole = 'price' | 'indicator' | 'auxiliary';
94
+ /** Pane 能力开关 */
95
+ export interface PaneCapabilities {
96
+ showPriceAxisTicks: boolean;
97
+ showCrosshairPriceLabel: boolean;
98
+ candleHitTest: boolean;
99
+ supportsPriceTranslate: boolean;
100
+ }
92
101
  /** Pane 信息接口 */
93
102
  export interface PaneInfo {
94
103
  id: string;
104
+ role: PaneRole;
105
+ capabilities: PaneCapabilities;
95
106
  top: number;
96
107
  height: number;
97
108
  yAxis: {
@@ -116,6 +127,8 @@ export interface PaneInfo {
116
127
  */
117
128
  export declare function wrapPaneInfo(pane: {
118
129
  id: string;
130
+ role: PaneRole;
131
+ capabilities: PaneCapabilities;
119
132
  top: number;
120
133
  height: number;
121
134
  yAxis: PaneInfo['yAxis'];
@@ -90,6 +90,10 @@ export interface CrosshairPriceLabelOptions {
90
90
  textColor?: string;
91
91
  fontSize?: number;
92
92
  paddingX?: number;
93
+ /** 价格偏移量(用于价格轴平移时同步显示) */
94
+ priceOffset?: number;
95
+ /** 优先显示的价格(如十字线已按 active pane 算好) */
96
+ price?: number;
93
97
  }
94
98
  export interface CrosshairTimeLabelOptions {
95
99
  x: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@363045841yyt/klinechart",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": "^20.19.0 || >=22.12.0"
@@ -59,4 +59,4 @@
59
59
  "vitest": "^4.1.5",
60
60
  "vue-tsc": "^3.2.7"
61
61
  }
62
- }
62
+ }