@363045841yyt/klinechart 0.4.7 → 0.5.0-alpha.0

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-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}
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)}.left-toolbar[data-v-39e1168e]{box-sizing:border-box;-webkit-user-select:none;user-select:none;background:#fafbfc;border:1px solid #e5e7eb;border-radius:6px;flex-direction:column;flex:0 0 40px;align-items:center;gap:6px;padding:8px 5px;display:flex;box-shadow:0 1px 3px #0000000f}.left-toolbar__group[data-v-39e1168e]{flex-direction:column;gap:4px;display:flex}.left-toolbar__divider[data-v-39e1168e]{background:#e5e7eb;width:18px;height:1px}.left-toolbar__button[data-v-39e1168e]{color:#6b7280;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:4px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:border-color .15s,background .15s,color .15s;display:inline-flex;position:relative}.left-toolbar__button[data-v-39e1168e]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.left-toolbar__button.active[data-v-39e1168e]{color:#1f2937;background:#e5e7eb;border-color:#9ca3af}.left-toolbar__button[data-v-39e1168e]:focus-visible{border-color:#6b7280;outline:none}.tool-icon[data-v-39e1168e]{width:16px;height:16px}.corner-indicator[data-v-39e1168e]{cursor:pointer;width:8px;height:8px;position:absolute;bottom:0;right:0;overflow:hidden}.corner-indicator[data-v-39e1168e]:after{content:"";opacity:.45;border-bottom:5px solid;border-left:5px solid #0000;width:0;height:0;transition:opacity .15s;position:absolute;bottom:0;right:0}.left-toolbar__button:hover .corner-indicator[data-v-39e1168e]:after,.left-toolbar__button.active .corner-indicator[data-v-39e1168e]:after{opacity:.7}.corner-indicator.open[data-v-39e1168e]:after{opacity:.8}.tool-dropdown[data-v-39e1168e]{-webkit-backdrop-filter:blur(8px);box-sizing:border-box;z-index:100;background:#fafbfcd1;border:1px solid #e5e7eb;border-radius:6px;flex-direction:row;align-items:center;gap:4px;height:40px;padding:0 5px;display:flex;position:absolute;top:50%;left:calc(100% + 13px);transform:translateY(-50%);box-shadow:0 1px 3px #0000000f}.tool-item[data-v-39e1168e]{position:relative}.dropdown-enter-active[data-v-39e1168e],.dropdown-leave-active[data-v-39e1168e]{transition:opacity .15s,transform .15s}.dropdown-enter-from[data-v-39e1168e],.dropdown-leave-to[data-v-39e1168e]{opacity:0;transform:translateY(-50%)translate(-6px)}@media (width<=768px),(height<=640px){.left-toolbar[data-v-39e1168e]{border-radius:5px;flex-basis:36px;gap:5px;padding:6px 4px}.left-toolbar__group[data-v-39e1168e]{gap:3px}.left-toolbar__button[data-v-39e1168e]{border-radius:3px;width:26px;height:26px}.left-toolbar__divider[data-v-39e1168e]{width:16px}.corner-indicator[data-v-39e1168e]{width:7px;height:7px}.corner-indicator[data-v-39e1168e]:after{border-bottom-width:4px;border-left-width:4px}.tool-dropdown[data-v-39e1168e]{height:36px}}.chart-wrapper[data-v-a3b8c041]{--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-stage[data-v-a3b8c041]{align-items:stretch;gap:8px;width:95%;height:85%;min-height:255px;display:flex}.chart-container[data-v-a3b8c041]{height:100%;min-height:inherit;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;background:#fff;border:1px solid #e5e7eb;border-radius:6px;flex:auto;position:relative;overflow:auto hidden}.chart-container[data-v-a3b8c041]::-webkit-scrollbar{display:none}.chart-container[data-v-a3b8c041]:hover{cursor:crosshair}.chart-container.is-resizing-pane[data-v-a3b8c041],.chart-container.is-hovering-pane-separator[data-v-a3b8c041]{cursor:row-resize}.chart-container.is-hovering-kline[data-v-a3b8c041]{cursor:pointer}.chart-container:hover.is-hovering-right-axis[data-v-a3b8c041]{cursor:ns-resize}.chart-container.is-dragging[data-v-a3b8c041]{cursor:grabbing}.scroll-content[data-v-a3b8c041]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-a3b8c041]{pointer-events:none;position:sticky;top:0;left:0}.tooltip-anchor[data-v-a3b8c041]{pointer-events:none;width:1px;height:1px;position:absolute}.tooltip-anchor.kline-tooltip-anchor.use-anchor[data-v-a3b8c041]{anchor-name:--kline-tooltip-anchor}.tooltip-anchor.marker-tooltip-anchor.use-anchor[data-v-a3b8c041]{anchor-name:--marker-tooltip-anchor}@media (width<=768px),(height<=640px){.chart-stage[data-v-a3b8c041]{gap:6px}}.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*/
@@ -1,2 +1,4 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
1
+ declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
2
+ embedContainerRef: HTMLDivElement;
3
+ }, HTMLDivElement>;
2
4
  export default _default;
@@ -8,9 +8,10 @@ declare class DataSourceFactory {
8
8
  static create(type: DataSourceType): IKLineDataSource;
9
9
  }
10
10
  /**
11
- * 获取 K 线数据(统一入口)
11
+ * 获取 K 线数据(统一入口,带缓存)
12
12
  * @param type 数据源类型
13
13
  * @param config 统一配置
14
+ * @param useCache 是否使用缓存,默认 true
14
15
  * @returns Promise<KLineData[]>
15
16
  *
16
17
  * 使用示例:
@@ -26,8 +27,11 @@ declare class DataSourceFactory {
26
27
  *
27
28
  * // 切换东财只需改第一个参数
28
29
  * const data = await fetchKLineData('dongcai', { ... })
30
+ *
31
+ * // 跳过缓存强制刷新
32
+ * const data = await fetchKLineData('baostock', config, false)
29
33
  * ```
30
34
  */
31
- export declare function fetchKLineData(type: DataSourceType, config: KLineDataSourceConfig): Promise<KLineData[]>;
35
+ export declare function fetchKLineData(type: DataSourceType, config: KLineDataSourceConfig, useCache?: boolean): Promise<KLineData[]>;
32
36
  export { DataSourceFactory };
33
37
  export type { KLineDataSourceConfig, DataSourceType, IKLineDataSource };
@@ -16,6 +16,8 @@ type __VLS_Props = {
16
16
  zoomLevels?: number;
17
17
  /** 初始缩放级别(1 ~ zoomLevels,默认居中) */
18
18
  initialZoomLevel?: number;
19
+ /** 是否全屏 */
20
+ isFullscreen?: boolean;
19
21
  };
20
22
  declare function scheduleRender(): void;
21
23
  declare function addSubPane(indicatorId?: SubIndicatorType, params?: Record<string, number>): boolean;
@@ -30,15 +32,17 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {
30
32
  removeSubPane: typeof removeSubPane;
31
33
  switchSubIndicator: typeof switchSubIndicator;
32
34
  clearAllSubPanes: typeof clearAllSubPanes;
33
- plugin: import('..').PluginHostImpl | undefined;
35
+ plugin: import('../plugin').PluginHostImpl | undefined;
34
36
  zoomToLevel: (level: number, anchorX?: number) => void | undefined;
35
37
  zoomIn: (anchorX?: number) => void | undefined;
36
38
  zoomOut: (anchorX?: number) => void | undefined;
37
39
  getZoomLevel: () => number;
38
40
  getZoomLevelCount: () => number;
39
41
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
42
+ toggleFullscreen: () => any;
40
43
  zoomLevelChange: (level: number, kWidth: number) => any;
41
44
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
45
+ onToggleFullscreen?: (() => any) | undefined;
42
46
  onZoomLevelChange?: ((level: number, kWidth: number) => any) | undefined;
43
47
  }>, {
44
48
  yPaddingPx: number;
@@ -49,6 +53,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {
49
53
  priceLabelWidth: number;
50
54
  zoomLevels: number;
51
55
  initialZoomLevel: number;
56
+ isFullscreen: boolean;
52
57
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
53
58
  containerRef: HTMLDivElement;
54
59
  canvasLayerRef: HTMLDivElement;
@@ -0,0 +1,17 @@
1
+ export interface ToolDef {
2
+ id: string;
3
+ title: string;
4
+ icon: unknown;
5
+ children?: ToolDef[];
6
+ }
7
+ type __VLS_Props = {
8
+ isFullscreen?: boolean;
9
+ };
10
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
11
+ selectTool: (toolId: string) => any;
12
+ toggleFullscreen: () => any;
13
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
14
+ onSelectTool?: ((toolId: string) => any) | undefined;
15
+ onToggleFullscreen?: (() => any) | undefined;
16
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLElement>;
17
+ export default _default;
@@ -87,6 +87,7 @@ export declare class Chart {
87
87
  private viewport;
88
88
  private paneRenderers;
89
89
  private markerManager;
90
+ private drawingStore;
90
91
  readonly interaction: InteractionController;
91
92
  /** 插件宿主 */
92
93
  private pluginHost;
@@ -224,6 +225,8 @@ export declare class Chart {
224
225
  upsertPane(def: PaneSpec): void;
225
226
  removePaneDefinition(paneId: string): void;
226
227
  bindIndicatorToPane(paneId: string, indicatorId: SubIndicatorType, params?: Record<string, number>): void;
228
+ /** 更新绘图对象 */
229
+ setDrawings(drawings: import('../plugin').DrawingObject[]): void;
227
230
  /** 获取当前 pane 布局快照(含 ratio) */
228
231
  getPaneLayoutSpecs(): PaneSpec[];
229
232
  private emitPaneLayoutChange;
@@ -287,6 +290,8 @@ export declare class Chart {
287
290
  updateData(data: KLineData[]): void;
288
291
  /** 获取当前数据源(供 renderers 和 interaction 使用) */
289
292
  getData(): KLineData[];
293
+ /** 根据视口内 X 坐标反查数据索引(用于绘图落点) */
294
+ getDataIndexAtX(mouseX: number): number | null;
290
295
  /** 获取内容总宽度(用于外部 scroll-content 撑开 scrollWidth) */
291
296
  getContentWidth(): number;
292
297
  /** 容器尺寸变化时调用 */
@@ -0,0 +1,37 @@
1
+ import { DrawingObject, DrawingKind, DrawingDefinition, DrawingComputeContext, DrawingGeometry, DrawingStyle, PointPrimitive, LinePrimitive, AreaPrimitive, TextPrimitive } from '../../plugin';
2
+ export type { DrawingObject, DrawingKind, DrawingDefinition, DrawingComputeContext, DrawingGeometry, DrawingStyle, PointPrimitive, LinePrimitive, AreaPrimitive, TextPrimitive, };
3
+ export declare class DrawingStore {
4
+ private drawings;
5
+ getAll(): DrawingObject[];
6
+ getVisibleByPane(paneId: string): DrawingObject[];
7
+ setAll(drawings: DrawingObject[]): void;
8
+ upsert(drawing: DrawingObject): void;
9
+ remove(id: string): void;
10
+ clear(): void;
11
+ }
12
+ export declare class DrawingDefinitionRegistry {
13
+ private definitions;
14
+ register<TParams = Record<string, unknown>>(definition: DrawingDefinition<TParams>): void;
15
+ get(kind: DrawingKind): DrawingDefinition | undefined;
16
+ compute(drawing: DrawingObject, context: DrawingComputeContext): DrawingGeometry | null;
17
+ }
18
+ export type PrimitiveRendererSet = {
19
+ point: (ctx: CanvasRenderingContext2D, primitive: PointPrimitive, dpr: number) => void;
20
+ line: (ctx: CanvasRenderingContext2D, primitive: LinePrimitive, viewportClip: {
21
+ left: number;
22
+ top: number;
23
+ right: number;
24
+ bottom: number;
25
+ }, dpr: number) => void;
26
+ area: (ctx: CanvasRenderingContext2D, primitive: AreaPrimitive, dpr: number) => void;
27
+ text: (ctx: CanvasRenderingContext2D, primitive: TextPrimitive, dpr: number) => void;
28
+ };
29
+ export declare function createDefaultPrimitiveRendererSet(): PrimitiveRendererSet;
30
+ export declare function createTwoPointLineDefinition(kind: DrawingKind, extend: LinePrimitive['extend']): DrawingDefinition;
31
+ export declare function createSingleAnchorLineDefinition(kind: DrawingKind): DrawingDefinition;
32
+ export declare function createInfoLineDefinition(): DrawingDefinition;
33
+ export declare function createParallelChannelDefinition(): DrawingDefinition;
34
+ export declare function createRegressionChannelDefinition(): DrawingDefinition;
35
+ export declare function registerDefaultDrawingDefinitions(registry: DrawingDefinitionRegistry): void;
36
+ export { DrawingInteractionController } from './interaction';
37
+ export type { DrawingToolId, DrawingAnchorInput, DrawingInteractionCallbacks } from './interaction';
@@ -0,0 +1,40 @@
1
+ import { DrawingObject } from '../../plugin';
2
+ import { Chart } from '../chart';
3
+ export type DrawingToolId = 'cursor' | 'trend-line' | 'ray' | 'h-line' | 'h-ray' | 'v-line' | 'crosshair-line' | 'info-line' | 'text' | 'measure';
4
+ export interface DrawingAnchorInput {
5
+ time: number;
6
+ price: number;
7
+ }
8
+ export interface DrawingInteractionCallbacks {
9
+ onDrawingCreated?: (drawing: DrawingObject) => void;
10
+ onToolChange?: (toolId: DrawingToolId) => void;
11
+ }
12
+ /**
13
+ * 绘图交互控制器
14
+ * 封装绘图工具的交互逻辑,与 Vue 组件解耦
15
+ */
16
+ export declare class DrawingInteractionController {
17
+ private chart;
18
+ private activeTool;
19
+ private pendingAnchor;
20
+ private drawings;
21
+ private callbacks;
22
+ private static readonly SINGLE_ANCHOR_TOOLS;
23
+ private static readonly DOUBLE_ANCHOR_TOOLS;
24
+ constructor(chart: Chart);
25
+ setCallbacks(callbacks: DrawingInteractionCallbacks): void;
26
+ getActiveTool(): DrawingToolId;
27
+ setTool(toolId: DrawingToolId): void;
28
+ getDrawings(): DrawingObject[];
29
+ setDrawings(drawings: DrawingObject[]): void;
30
+ clear(): void;
31
+ /**
32
+ * 处理指针按下事件
33
+ * @returns 是否处理了事件(阻止冒泡)
34
+ */
35
+ onPointerDown(e: PointerEvent, container: HTMLElement): boolean;
36
+ private resolveAnchorFromPointer;
37
+ private createSingleAnchorDrawing;
38
+ private createDoubleAnchorDrawing;
39
+ private getDrawingKind;
40
+ }
@@ -0,0 +1,8 @@
1
+ import { RendererPlugin } from '../../plugin';
2
+ import { DrawingStore, DrawingDefinitionRegistry, PrimitiveRendererSet } from './index';
3
+ export declare function createDrawingRendererPlugin(options: {
4
+ store: DrawingStore;
5
+ paneId?: string;
6
+ definitions?: DrawingDefinitionRegistry;
7
+ renderers?: PrimitiveRendererSet;
8
+ }): RendererPlugin;
@@ -1,6 +1,4 @@
1
- /**
2
- * 插件系统核心类型定义
3
- */
1
+ import { KLineData } from '../types/price';
4
2
  /** 插件生命周期状态 */
5
3
  export declare enum PluginState {
6
4
  Registered = "registered",
@@ -171,6 +169,107 @@ export interface RenderContext {
171
169
  zoomLevel?: number;
172
170
  /** 总缩放级别数 */
173
171
  zoomLevelCount?: number;
172
+ viewport?: {
173
+ scrollLeft: number;
174
+ plotWidth: number;
175
+ plotHeight: number;
176
+ };
177
+ }
178
+ export type DrawingAnchor = {
179
+ id: string;
180
+ time: number | string;
181
+ price: number;
182
+ };
183
+ export type DrawingKind = 'trend-line' | 'ray' | 'extended-line' | 'horizontal-line' | 'horizontal-ray' | 'vertical-line' | 'cross-line' | 'info-line' | 'parallel-channel' | 'regression-channel';
184
+ export type DrawingStyle = {
185
+ stroke?: string;
186
+ strokeWidth?: number;
187
+ strokeStyle?: 'solid' | 'dashed' | 'dotted';
188
+ fill?: string;
189
+ fillOpacity?: number;
190
+ pointRadius?: number;
191
+ textColor?: string;
192
+ fontSize?: number;
193
+ };
194
+ export type DrawingObject<TParams = Record<string, unknown>> = {
195
+ id: string;
196
+ kind: DrawingKind;
197
+ paneId: string;
198
+ visible: boolean;
199
+ locked?: boolean;
200
+ zIndex?: number;
201
+ anchors: DrawingAnchor[];
202
+ params: TParams;
203
+ style: DrawingStyle;
204
+ };
205
+ export type ScreenPoint = {
206
+ x: number;
207
+ y: number;
208
+ };
209
+ export type PointPrimitive = {
210
+ kind: 'point';
211
+ point: ScreenPoint;
212
+ role?: 'anchor' | 'handle' | 'marker' | 'center';
213
+ style?: DrawingStyle;
214
+ };
215
+ export type LinePrimitive = {
216
+ kind: 'line';
217
+ a: ScreenPoint;
218
+ b: ScreenPoint;
219
+ extend?: 'none' | 'left' | 'right' | 'both';
220
+ showEndpoints?: boolean;
221
+ style?: DrawingStyle;
222
+ };
223
+ export type AreaPrimitive = {
224
+ kind: 'area';
225
+ points: ScreenPoint[];
226
+ closed: boolean;
227
+ style?: DrawingStyle;
228
+ };
229
+ export type TextPrimitive = {
230
+ kind: 'text';
231
+ point: ScreenPoint;
232
+ text: string;
233
+ align?: 'left' | 'center' | 'right';
234
+ baseline?: 'top' | 'middle' | 'bottom';
235
+ style?: DrawingStyle;
236
+ };
237
+ export type DrawingPrimitive = PointPrimitive | LinePrimitive | AreaPrimitive | TextPrimitive;
238
+ export type DrawingGeometry = {
239
+ primitives: DrawingPrimitive[];
240
+ bounds?: {
241
+ left: number;
242
+ top: number;
243
+ right: number;
244
+ bottom: number;
245
+ };
246
+ meta?: Record<string, unknown>;
247
+ };
248
+ export type DrawingComputeContext = {
249
+ pane: PaneInfo;
250
+ visibleData: KLineData[];
251
+ seriesData: KLineData[];
252
+ range: {
253
+ start: number;
254
+ end: number;
255
+ };
256
+ kLinePositions: number[];
257
+ kWidth: number;
258
+ kGap: number;
259
+ dpr: number;
260
+ paneWidth: number;
261
+ viewport: {
262
+ scrollLeft: number;
263
+ plotWidth: number;
264
+ plotHeight: number;
265
+ };
266
+ toScreen(anchor: DrawingAnchor): ScreenPoint;
267
+ };
268
+ export interface DrawingDefinition<TParams = Record<string, unknown>> {
269
+ kind: DrawingKind;
270
+ minAnchors: number;
271
+ maxAnchors: number;
272
+ compute(drawing: DrawingObject<TParams>, context: DrawingComputeContext): DrawingGeometry;
174
273
  }
175
274
  /** 全局 Pane ID(渲染到所有 pane) */
176
275
  export declare const GLOBAL_PANE_ID: unique symbol;
@@ -185,13 +284,12 @@ export declare const RENDERER_PRIORITY: {
185
284
  * 所有指标渲染器必须使用此优先级或 ≤30 的值
186
285
  */
187
286
  readonly INDICATOR: 30;
287
+ readonly MAIN: 50;
188
288
  /**
189
- * 指标刻度渲染器(依赖于前方 INDICATOR 的状态)
190
- * 所有刻度渲染器必须使用此优先级或 ≥35 的值,
191
- * 确保每次绘制时指标更新先于刻度。
289
+ * 指标刻度渲染器(依赖于前方指标写入的共享状态)
290
+ * 必须晚于 INDICATOR 和 MAIN,确保每次绘制时先更新指标状态再绘制刻度。
192
291
  */
193
- readonly INDICATOR_SCALE: 35;
194
- readonly MAIN: 50;
292
+ readonly INDICATOR_SCALE: 55;
195
293
  readonly OVERLAY: 80;
196
294
  readonly FOREGROUND: 100;
197
295
  readonly SYSTEM_BORDER: 120;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@363045841yyt/klinechart",
3
- "version": "0.4.7",
3
+ "version": "0.5.0-alpha.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": "^20.19.0 || >=22.12.0"
@@ -41,6 +41,7 @@
41
41
  "axios": "^1.16.0"
42
42
  },
43
43
  "devDependencies": {
44
+ "@iconify-json/tabler": "^1.2.34",
44
45
  "@tsconfig/node24": "^24.0.4",
45
46
  "@types/jsdom": "^28.0.1",
46
47
  "@types/node": "^25.6.0",
@@ -53,6 +54,8 @@
53
54
  "prettier": "3.8.3",
54
55
  "typedoc": "^0.28.19",
55
56
  "typescript": "~6.0.3",
57
+ "unplugin-icons": "^23.0.1",
58
+ "unplugin-vue-components": "^32.0.0",
56
59
  "vite": "^8.0.10",
57
60
  "vite-plugin-dts": "^4.5.4",
58
61
  "vite-plugin-vue-devtools": "^8.1.1",