@363045841yyt/klinechart 0.4.5 → 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.
@@ -1,2 +1,2 @@
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-0ddb3f15]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-0ddb3f15]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-0ddb3f15]::-webkit-scrollbar{display:none}.indicator-list[data-v-0ddb3f15]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-0ddb3f15]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-0ddb3f15]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-0ddb3f15],.indicator-item.draggable .indicator-btn[data-v-0ddb3f15],.indicator-item.draggable[data-v-0ddb3f15]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-0ddb3f15]{cursor:move}.indicator-item.is-dragging[data-v-0ddb3f15]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-0ddb3f15]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-0ddb3f15]{position:relative}.indicator-btn[data-v-0ddb3f15]{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-0ddb3f15]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-0ddb3f15]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-0ddb3f15]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-0ddb3f15]{z-index:1;position:relative}.param-hint[data-v-0ddb3f15]{opacity:.85;font-size:11px}.hover-overlay[data-v-0ddb3f15]{-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-0ddb3f15]{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-0ddb3f15]:hover{color:#333;background:#0000000f}.settings-btn[data-v-0ddb3f15]:hover{color:#1a1a1a}.remove-btn[data-v-0ddb3f15]:hover{color:#ff4d4f}.divider[data-v-0ddb3f15]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-0ddb3f15]{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-0ddb3f15]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-0ddb3f15]{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-0ddb3f15]{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-0ddb3f15]{padding:4px 0}.menu-section[data-v-0ddb3f15]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-0ddb3f15]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-0ddb3f15]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-0ddb3f15]{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-0ddb3f15]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-0ddb3f15]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-0ddb3f15]{color:#999;font-size:11px}.active-tag[data-v-0ddb3f15]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-0ddb3f15],.fade-leave-active[data-v-0ddb3f15]{transition:opacity .2s}.fade-enter-from[data-v-0ddb3f15],.fade-leave-to[data-v-0ddb3f15]{opacity:0}.slide-enter-active[data-v-0ddb3f15],.slide-leave-active[data-v-0ddb3f15]{transition:all .2s}.slide-enter-from[data-v-0ddb3f15],.slide-leave-to[data-v-0ddb3f15]{opacity:0;transform:translate(-50%)translateY(8px)}.chart-wrapper[data-v-288af50a]{--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-288af50a]{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-288af50a]::-webkit-scrollbar{display:none}.chart-container[data-v-288af50a]:hover{cursor:grab}.chart-container.is-resizing-pane[data-v-288af50a],.chart-container.is-hovering-pane-separator[data-v-288af50a]{cursor:row-resize}.scroll-content[data-v-288af50a]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-288af50a]{pointer-events:none;position:sticky;top:0;left:0}.tooltip-anchor[data-v-288af50a]{pointer-events:none;width:1px;height:1px;position:absolute}.tooltip-anchor.kline-tooltip-anchor.use-anchor[data-v-288af50a]{anchor-name:--kline-tooltip-anchor}.tooltip-anchor.marker-tooltip-anchor.use-anchor[data-v-288af50a]{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}
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;
@@ -43,8 +41,6 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {
43
41
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
44
42
  onZoomLevelChange?: ((level: number, kWidth: number) => any) | undefined;
45
43
  }>, {
46
- kWidth: number;
47
- kGap: number;
48
44
  yPaddingPx: number;
49
45
  rightAxisWidth: number;
50
46
  bottomAxisHeight: number;
@@ -37,8 +37,10 @@ export type PaneRendererDom = {
37
37
  yAxisCanvas: HTMLCanvasElement;
38
38
  };
39
39
  export type ChartOptions = {
40
- kWidth: number;
41
- kGap: number;
40
+ /** K 线宽度(可选,由 zoomLevel 派生) */
41
+ kWidth?: number;
42
+ /** K 线间隙(可选,由 DPR 计算) */
43
+ kGap?: number;
42
44
  yPaddingPx: number;
43
45
  rightAxisWidth: number;
44
46
  bottomAxisHeight: number;
@@ -58,8 +60,8 @@ export type ChartOptions = {
58
60
  */
59
61
  zoomLevels?: number;
60
62
  /**
61
- * 初始缩放级别(1 ~ zoomLevels,默认居中)
62
- * 未指定时自动计算为中间级别
63
+ * 初始缩放级别(1 ~ zoomLevels,默认 1)
64
+ * 未指定时默认为最小级别
63
65
  */
64
66
  initialZoomLevel?: number;
65
67
  };
@@ -73,6 +75,10 @@ export type Viewport = {
73
75
  scrollLeft: number;
74
76
  dpr: number;
75
77
  };
78
+ type ResolvedChartOptions = Omit<ChartOptions, 'kWidth' | 'kGap'> & {
79
+ kWidth: number;
80
+ kGap: number;
81
+ };
76
82
  export declare class Chart {
77
83
  private dom;
78
84
  private opt;
@@ -139,31 +145,19 @@ export declare class Chart {
139
145
  */
140
146
  zoomAt(mouseX: number, scrollLeft: number, deltaY: number): void;
141
147
  /**
142
- * 由外部(Vue 组件)在 scrollLeft 落地后调用,原子性地应用缩放参数
143
- * 确保 draw() 看到的 (kWidth, kGap, scrollLeft) 是一致的
144
- * @param kWidth 新的 K 线宽度
145
- * @param kGap 新的 K 线间隙
148
+ * 应用缩放级别(在 scrollLeft 落地后调用)
149
+ * @param level 缩放级别
146
150
  */
147
- applyZoom(kWidth: number, kGap: number): void;
148
- /** 缩放回调函数,用于通知外部同步 kWidth、kGap 与 scrollLeft */
151
+ applyZoom(level: number): void;
152
+ /** 缩放回调 */
149
153
  private onZoomChange?;
150
- /**
151
- * 注册缩放回调函数
152
- * @param cb 缩放回调函数
153
- */
154
- setOnZoomChange(cb: (kWidth: number, kGap: number, targetScrollLeft: number) => void): void;
154
+ setOnZoomChange(cb: (level: number, kWidth: number, kGap: number, targetScrollLeft: number) => void): void;
155
155
  /**
156
156
  * 将缩放级别转换为 K 线宽度
157
157
  * @param level 缩放级别(1 ~ zoomLevels)
158
158
  * @returns K 线宽度(逻辑像素)
159
159
  */
160
160
  private zoomLevelToKWidth;
161
- /**
162
- * 将 K 线宽度转换为缩放级别
163
- * @param kWidth K 线宽度
164
- * @returns 缩放级别(1 ~ zoomLevels)
165
- */
166
- private kWidthToZoomLevel;
167
161
  /**
168
162
  * 缩放到指定级别
169
163
  * @param level 目标级别(1 ~ zoomLevels)
@@ -210,7 +204,7 @@ export declare class Chart {
210
204
  /** 获取 ChartDom(供 InteractionController 使用) */
211
205
  getDom(): ChartDom;
212
206
  /** 获取当前 ChartOptions(返回内部当前快照) */
213
- getOption(): ChartOptions;
207
+ getOption(): ResolvedChartOptions;
214
208
  /**
215
209
  * 计算 K 线起始 x 坐标数组,与 candle.ts 的像素对齐方式保持一致
216
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 MarkerHoverEvent {
5
- type: 'volume-price' | 'custom';
6
- marker: MarkerEntity | CustomMarkerEntity;
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
  /** 十字线位置 */
@@ -49,6 +68,8 @@ export declare class InteractionController {
49
68
  tooltipAnchorPlacement: 'right-bottom' | 'left-bottom';
50
69
  /** 是否使用 CSS 锚定位 */
51
70
  private useTooltipAnchorPositioning;
71
+ /** 统一交互状态变更回调 */
72
+ private onInteractionChangeCallback?;
52
73
  /** 当前 hover 的 marker ID */
53
74
  hoveredMarkerId: string | null;
54
75
  /** 当前点击的 marker ID */
@@ -74,6 +95,9 @@ export declare class InteractionController {
74
95
  /** K 线宽度(物理像素),用于计算 K 线中心偏移 */
75
96
  private kWidthPx;
76
97
  constructor(chart: Chart);
98
+ getInteractionSnapshot(): InteractionSnapshot;
99
+ setOnInteractionChange(callback: (snapshot: InteractionSnapshot) => void): void;
100
+ private notifyInteractionChange;
77
101
  /**
78
102
  * 处理滚轮缩放事件
79
103
  * @param e WheelEvent
@@ -140,6 +164,8 @@ export declare class InteractionController {
140
164
  isResizingPaneBoundaryState(): boolean;
141
165
  /** 是否悬停在可拖拽分隔线上 */
142
166
  isHoveringPaneBoundaryState(): boolean;
167
+ /** 是否悬停在右轴区域 */
168
+ isHoveringRightAxisState(): boolean;
143
169
  /** 设置 marker hover 回调 */
144
170
  setOnMarkerHover(callback: (marker: MarkerEntity | null) => void): void;
145
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 { RendererPlugin } from '../../plugin';
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): RendererPlugin;
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: "rgb(183, 22, 22)";
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
  */
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@363045841yyt/klinechart",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": "^20.19.0 || >=22.12.0"