@363045841yyt/klinechart 0.6.1 → 0.6.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.
- package/README.md +3 -1
- package/dist/index.cjs +53 -6
- package/dist/index.js +2691 -1926
- package/dist/klinechart.css +1 -1
- package/dist/src/config/chartSettings.d.ts +29 -1
- package/dist/src/core/chart.d.ts +83 -1
- package/dist/src/core/controller/interaction.d.ts +5 -1
- package/dist/src/core/indicators/scheduler.d.ts +15 -0
- package/dist/src/core/layout/pane.d.ts +5 -1
- package/dist/src/core/paneRenderer.d.ts +14 -0
- package/dist/src/core/renderers/Indicator/boll.d.ts +0 -9
- package/dist/src/core/renderers/Indicator/expma.d.ts +0 -9
- package/dist/src/core/renderers/Indicator/ma.d.ts +0 -9
- package/dist/src/core/renderers/webgl/candleSurface.d.ts +45 -0
- package/dist/src/plugin/types.d.ts +6 -1
- package/package.json +1 -1
package/dist/klinechart.css
CHANGED
|
@@ -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-bb1d1eb3]{-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-bb1d1eb3]{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-bb1d1eb3]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-bb1d1eb3]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-bb1d1eb3]{align-items:center;gap:8px;display:flex}.params-title[data-v-bb1d1eb3]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.params-subtitle[data-v-bb1d1eb3]{color:#999;font-size:11px}.toggle-desc-btn[data-v-bb1d1eb3]{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-bb1d1eb3]:hover{color:#555;background:#f0f0f0;border-color:#ccc}.toggle-desc-btn.active[data-v-bb1d1eb3]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.toggle-desc-btn svg[data-v-bb1d1eb3]{width:14px;height:14px}.params-close[data-v-bb1d1eb3]{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-bb1d1eb3]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.params-close svg[data-v-bb1d1eb3]{width:14px;height:14px}.indicator-description[data-v-bb1d1eb3]{background:#f0f7ff;border-bottom:1px solid #d6e8f5;padding:12px 20px}.indicator-description p[data-v-bb1d1eb3]{color:#2c5282;margin:0;font-size:12px;line-height:1.6}.params-body[data-v-bb1d1eb3]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.param-item[data-v-bb1d1eb3]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:10px 14px;transition:border-color .2s}.param-item[data-v-bb1d1eb3]:has(.param-input:focus){border-color:#bbb}.param-item.has-desc[data-v-bb1d1eb3]{padding:10px 14px 8px}.param-header[data-v-bb1d1eb3]{justify-content:space-between;align-items:center;gap:16px;display:flex}.param-label[data-v-bb1d1eb3]{flex-direction:column;gap:3px;display:flex}.param-label-text[data-v-bb1d1eb3]{color:#333;font-size:13px;font-weight:500}.param-range[data-v-bb1d1eb3]{color:#999;font-size:11px}.param-description[data-v-bb1d1eb3]{color:#666;border-top:1px dashed #e0e0e0;margin-top:8px;padding-top:8px;font-size:11px;line-height:1.5}.input-wrapper[data-v-bb1d1eb3]{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-bb1d1eb3]:focus-within{border-color:#999}.stepper-btn[data-v-bb1d1eb3]{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-bb1d1eb3]:hover:not(:disabled){color:#333;background:#e0e0e0}.stepper-btn[data-v-bb1d1eb3]:disabled{color:#ccc;cursor:not-allowed}.param-input[data-v-bb1d1eb3]{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-bb1d1eb3]::-webkit-inner-spin-button{-webkit-appearance:none}.param-input[data-v-bb1d1eb3]::-webkit-outer-spin-button{-webkit-appearance:none}.param-input[data-v-bb1d1eb3]:focus{outline:none}.params-footer[data-v-bb1d1eb3]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-bb1d1eb3]{gap:8px;display:flex}.params-btn[data-v-bb1d1eb3]{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-bb1d1eb3]{flex-shrink:0;width:12px;height:12px}.params-btn.reset[data-v-bb1d1eb3]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.reset[data-v-bb1d1eb3]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.params-btn.cancel[data-v-bb1d1eb3]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.cancel[data-v-bb1d1eb3]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.params-btn.confirm[data-v-bb1d1eb3]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.params-btn.confirm[data-v-bb1d1eb3]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.params-btn.confirm[data-v-bb1d1eb3]:active{box-shadow:none;transform:translateY(0)}.overlay-enter-active[data-v-bb1d1eb3],.overlay-leave-active[data-v-bb1d1eb3]{transition:opacity .2s}.overlay-enter-from[data-v-bb1d1eb3],.overlay-leave-to[data-v-bb1d1eb3]{opacity:0}.modal-enter-active[data-v-bb1d1eb3]{transition:all .22s cubic-bezier(.34,1.56,.64,1)}.modal-leave-active[data-v-bb1d1eb3]{transition:all .16s ease-in}.modal-enter-from[data-v-bb1d1eb3]{opacity:0;transform:scale(.88)translateY(-16px)}.modal-leave-to[data-v-bb1d1eb3]{opacity:0;transform:scale(.94)translateY(8px)}.slide-enter-active[data-v-bb1d1eb3],.slide-leave-active[data-v-bb1d1eb3]{transition:all .2s;overflow:hidden}.slide-enter-from[data-v-bb1d1eb3],.slide-leave-to[data-v-bb1d1eb3]{opacity:0;max-height:0;margin-top:0;padding-top:0;padding-bottom:0}.indicator-selector[data-v-0f3a76b5]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-0f3a76b5]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-0f3a76b5]::-webkit-scrollbar{display:none}.indicator-list[data-v-0f3a76b5]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-0f3a76b5]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-0f3a76b5]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-0f3a76b5],.indicator-item.draggable .indicator-btn[data-v-0f3a76b5],.indicator-item.draggable[data-v-0f3a76b5]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-0f3a76b5]{cursor:move}.indicator-item.is-dragging[data-v-0f3a76b5]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-0f3a76b5]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-0f3a76b5]{position:relative}.indicator-btn[data-v-0f3a76b5]{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-0f3a76b5]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-0f3a76b5]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-0f3a76b5]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-0f3a76b5]{z-index:1;position:relative}.param-hint[data-v-0f3a76b5]{opacity:.85;font-size:11px}.hover-overlay[data-v-0f3a76b5]{-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-0f3a76b5]{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-0f3a76b5]:hover{color:#333;background:#0000000f}.settings-btn[data-v-0f3a76b5]:hover{color:#1a1a1a}.remove-btn[data-v-0f3a76b5]:hover{color:#ff4d4f}.divider[data-v-0f3a76b5]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-0f3a76b5]{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-0f3a76b5]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-0f3a76b5]{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-0f3a76b5]{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-0f3a76b5]{padding:4px 0}.menu-section[data-v-0f3a76b5]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-0f3a76b5]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-0f3a76b5]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-0f3a76b5]{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-0f3a76b5]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-0f3a76b5]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-0f3a76b5]{color:#999;font-size:11px}.active-tag[data-v-0f3a76b5]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-0f3a76b5],.fade-leave-active[data-v-0f3a76b5]{transition:opacity .2s}.fade-enter-from[data-v-0f3a76b5],.fade-leave-to[data-v-0f3a76b5]{opacity:0}.slide-enter-active[data-v-0f3a76b5],.slide-leave-active[data-v-0f3a76b5]{transition:all .2s}.slide-enter-from[data-v-0f3a76b5],.slide-leave-to[data-v-0f3a76b5]{opacity:0;transform:translate(-50%)translateY(8px)}.drawing-style-toolbar[data-v-92699cb2]{-webkit-backdrop-filter:blur(8px);z-index:100;-webkit-user-select:none;user-select:none;pointer-events:auto;background:#fafbfce0;border:1px solid #e5e7eb;border-radius:6px;align-items:center;gap:6px;height:32px;padding:4px 8px;display:flex;position:absolute;top:8px;left:50%;transform:translate(-50%);box-shadow:0 1px 3px #0000000f}.toolbar-item[data-v-92699cb2]{justify-content:center;align-items:center;display:inline-flex}.color-item[data-v-92699cb2]{width:24px;height:24px;position:relative}.color-swatch[data-v-92699cb2]{cursor:pointer;border:1px solid #d1d5db;border-radius:4px;width:100%;height:100%;display:block}.color-input[data-v-92699cb2]{opacity:0;cursor:pointer;width:100%;height:100%;position:absolute;inset:0}.toolbar-select[data-v-92699cb2]{color:#374151;cursor:pointer;background:#fff;border:1px solid #d1d5db;border-radius:4px;outline:none;height:24px;padding:0 4px;font-size:12px}.toolbar-select[data-v-92699cb2]:hover{border-color:#9ca3af}.toolbar-btn[data-v-92699cb2]{color:#6b7280;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:4px;justify-content:center;align-items:center;width:24px;height:24px;padding:0;transition:border-color .15s,background .15s,color .15s;display:inline-flex}.toolbar-btn[data-v-92699cb2]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.delete-btn[data-v-92699cb2]:hover{color:#dc2626;background:#fef2f2;border-color:#fca5a5}.delete-icon[data-v-92699cb2]{width:14px;height:14px}.left-toolbar[data-v-43b6f5f6]{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-43b6f5f6]{flex-direction:column;gap:4px;display:flex}.left-toolbar__divider[data-v-43b6f5f6]{background:#e5e7eb;width:18px;height:1px}.left-toolbar__button[data-v-43b6f5f6]{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-43b6f5f6]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.left-toolbar__button.active[data-v-43b6f5f6]{color:#1f2937;background:#e5e7eb;border-color:#9ca3af}.left-toolbar__button[data-v-43b6f5f6]:focus-visible{border-color:#6b7280;outline:none}.tool-icon[data-v-43b6f5f6]{width:16px;height:16px}.corner-indicator[data-v-43b6f5f6]{cursor:pointer;width:8px;height:8px;position:absolute;bottom:0;right:0;overflow:hidden}.corner-indicator[data-v-43b6f5f6]: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-43b6f5f6]:after,.left-toolbar__button.active .corner-indicator[data-v-43b6f5f6]:after{opacity:.7}.corner-indicator.open[data-v-43b6f5f6]:after{opacity:.8}.tool-dropdown[data-v-43b6f5f6]{-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-43b6f5f6]{position:relative}.dropdown-enter-active[data-v-43b6f5f6],.dropdown-leave-active[data-v-43b6f5f6]{transition:opacity .15s,transform .15s}.dropdown-enter-from[data-v-43b6f5f6],.dropdown-leave-to[data-v-43b6f5f6]{opacity:0;transform:translateY(-50%)translate(-6px)}@media (width<=768px),(height<=640px){.left-toolbar[data-v-43b6f5f6]{border-radius:5px;flex-basis:36px;gap:5px;padding:6px 4px}.left-toolbar__group[data-v-43b6f5f6]{gap:3px}.left-toolbar__button[data-v-43b6f5f6]{border-radius:3px;width:26px;height:26px}.left-toolbar__divider[data-v-43b6f5f6]{width:16px}.corner-indicator[data-v-43b6f5f6]{width:7px;height:7px}.corner-indicator[data-v-43b6f5f6]:after{border-bottom-width:4px;border-left-width:4px}.tool-dropdown[data-v-43b6f5f6]{height:36px}}.settings-overlay[data-v-43b6f5f6]{-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}.settings-modal[data-v-43b6f5f6]{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}.settings-header[data-v-43b6f5f6]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-43b6f5f6]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-43b6f5f6]{align-items:center;gap:8px;display:flex}.settings-title[data-v-43b6f5f6]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.settings-subtitle[data-v-43b6f5f6]{color:#999;font-size:11px}.settings-close[data-v-43b6f5f6]{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}.settings-close[data-v-43b6f5f6]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.settings-close svg[data-v-43b6f5f6]{width:14px;height:14px}.settings-body[data-v-43b6f5f6]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.settings-item[data-v-43b6f5f6]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:8px 12px}.settings-label[data-v-43b6f5f6]{color:#333;cursor:pointer;justify-content:space-between;align-items:center;font-size:13px;display:flex}.settings-checkbox[data-v-43b6f5f6]{cursor:pointer;accent-color:#1a1a1a;width:16px;height:16px}.settings-section-divider[data-v-43b6f5f6]{align-items:center;gap:8px;margin-top:4px;display:flex}.settings-section-divider[data-v-43b6f5f6]:before,.settings-section-divider[data-v-43b6f5f6]:after{content:"";border-top:1px solid #e0e0e0;flex:1}.settings-section-label[data-v-43b6f5f6]{color:#999;white-space:nowrap;font-size:11px}.settings-item.experimental[data-v-43b6f5f6]{background:#fdf8f3;border-color:#f0e0d0}.settings-footer[data-v-43b6f5f6]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-43b6f5f6]{gap:8px;display:flex}.settings-btn[data-v-43b6f5f6]{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}.settings-btn svg[data-v-43b6f5f6]{flex-shrink:0;width:12px;height:12px}.settings-btn.reset[data-v-43b6f5f6]{color:#666;background:0 0;border-color:#d0d0d0}.settings-btn.reset[data-v-43b6f5f6]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.settings-btn.cancel[data-v-43b6f5f6]{color:#666;background:0 0;border-color:#d0d0d0}.settings-btn.cancel[data-v-43b6f5f6]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.settings-btn.confirm[data-v-43b6f5f6]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.settings-btn.confirm[data-v-43b6f5f6]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.settings-btn.confirm[data-v-43b6f5f6]:active{box-shadow:none;transform:translateY(0)}.chart-wrapper[data-v-59c0bc54]{--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-59c0bc54]{align-items:stretch;gap:8px;width:95%;height:85%;min-height:255px;display:flex}.chart-main[data-v-59c0bc54]{flex:auto;align-items:stretch;gap:0;min-width:0;height:100%;display:flex;position:relative}.pane-separator-layer[data-v-59c0bc54]{pointer-events:none;z-index:20;position:absolute;inset:0}.pane-separator-line[data-v-59c0bc54]{opacity:1;box-sizing:border-box;border-top:1px solid #e5e7eb;height:0;transition:border-top-color .12s,border-top-width .12s,margin-top .12s,opacity .12s;position:absolute;left:0;right:0}.pane-separator-line.is-active[data-v-59c0bc54]{border-top-width:2px;border-top-color:#3b82f6;margin-top:-1px}.chart-stage.is-resizing-pane[data-v-59c0bc54],.chart-stage.is-hovering-pane-separator[data-v-59c0bc54]{cursor:ns-resize}.chart-stage.is-hovering-kline[data-v-59c0bc54]{cursor:pointer}.chart-stage.is-hovering-right-axis[data-v-59c0bc54]{cursor:ns-resize}.chart-stage.is-dragging[data-v-59c0bc54]{cursor:grabbing}.chart-container[data-v-59c0bc54]{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-right:0;border-radius:6px 0 0 6px;flex:auto;position:relative;overflow:auto hidden}.chart-container[data-v-59c0bc54]::-webkit-scrollbar{display:none}.chart-container[data-v-59c0bc54]:hover{cursor:crosshair}.chart-stage.is-resizing-pane .chart-container[data-v-59c0bc54],.chart-stage.is-hovering-pane-separator .chart-container[data-v-59c0bc54]{cursor:ns-resize}.chart-stage.is-hovering-kline .chart-container[data-v-59c0bc54]{cursor:pointer}.chart-stage.is-dragging .chart-container[data-v-59c0bc54]{cursor:grabbing}.right-axis-host[data-v-59c0bc54]{height:100%;min-height:inherit;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-top-right-radius:6px;border-bottom-right-radius:6px;flex:none;position:relative;overflow:visible}.scroll-content[data-v-59c0bc54]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-59c0bc54]{pointer-events:none;position:sticky;top:0;left:0}.tooltip-layer[data-v-59c0bc54]{pointer-events:none;z-index:30;position:absolute;inset:0}.tooltip-anchor[data-v-59c0bc54]{pointer-events:none;width:1px;height:1px;position:absolute}.tooltip-anchor.kline-tooltip-anchor.use-anchor[data-v-59c0bc54]{anchor-name:--kline-tooltip-anchor}.tooltip-anchor.marker-tooltip-anchor.use-anchor[data-v-59c0bc54]{anchor-name:--marker-tooltip-anchor}@media (width<=768px),(height<=640px){.chart-stage[data-v-59c0bc54]{gap:6px}}.plot-canvas{display:block;position:absolute;top:0;left:0}.right-axis{display:block;position:absolute;left:0}.x-axis-canvas{z-index:10;display:block;position:absolute;bottom:0;left:0}.right-axis{z-index:15}
|
|
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-bb1d1eb3]{-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-bb1d1eb3]{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-bb1d1eb3]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-bb1d1eb3]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-bb1d1eb3]{align-items:center;gap:8px;display:flex}.params-title[data-v-bb1d1eb3]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.params-subtitle[data-v-bb1d1eb3]{color:#999;font-size:11px}.toggle-desc-btn[data-v-bb1d1eb3]{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-bb1d1eb3]:hover{color:#555;background:#f0f0f0;border-color:#ccc}.toggle-desc-btn.active[data-v-bb1d1eb3]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.toggle-desc-btn svg[data-v-bb1d1eb3]{width:14px;height:14px}.params-close[data-v-bb1d1eb3]{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-bb1d1eb3]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.params-close svg[data-v-bb1d1eb3]{width:14px;height:14px}.indicator-description[data-v-bb1d1eb3]{background:#f0f7ff;border-bottom:1px solid #d6e8f5;padding:12px 20px}.indicator-description p[data-v-bb1d1eb3]{color:#2c5282;margin:0;font-size:12px;line-height:1.6}.params-body[data-v-bb1d1eb3]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.param-item[data-v-bb1d1eb3]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:10px 14px;transition:border-color .2s}.param-item[data-v-bb1d1eb3]:has(.param-input:focus){border-color:#bbb}.param-item.has-desc[data-v-bb1d1eb3]{padding:10px 14px 8px}.param-header[data-v-bb1d1eb3]{justify-content:space-between;align-items:center;gap:16px;display:flex}.param-label[data-v-bb1d1eb3]{flex-direction:column;gap:3px;display:flex}.param-label-text[data-v-bb1d1eb3]{color:#333;font-size:13px;font-weight:500}.param-range[data-v-bb1d1eb3]{color:#999;font-size:11px}.param-description[data-v-bb1d1eb3]{color:#666;border-top:1px dashed #e0e0e0;margin-top:8px;padding-top:8px;font-size:11px;line-height:1.5}.input-wrapper[data-v-bb1d1eb3]{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-bb1d1eb3]:focus-within{border-color:#999}.stepper-btn[data-v-bb1d1eb3]{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-bb1d1eb3]:hover:not(:disabled){color:#333;background:#e0e0e0}.stepper-btn[data-v-bb1d1eb3]:disabled{color:#ccc;cursor:not-allowed}.param-input[data-v-bb1d1eb3]{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-bb1d1eb3]::-webkit-inner-spin-button{-webkit-appearance:none}.param-input[data-v-bb1d1eb3]::-webkit-outer-spin-button{-webkit-appearance:none}.param-input[data-v-bb1d1eb3]:focus{outline:none}.params-footer[data-v-bb1d1eb3]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-bb1d1eb3]{gap:8px;display:flex}.params-btn[data-v-bb1d1eb3]{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-bb1d1eb3]{flex-shrink:0;width:12px;height:12px}.params-btn.reset[data-v-bb1d1eb3]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.reset[data-v-bb1d1eb3]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.params-btn.cancel[data-v-bb1d1eb3]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.cancel[data-v-bb1d1eb3]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.params-btn.confirm[data-v-bb1d1eb3]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.params-btn.confirm[data-v-bb1d1eb3]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.params-btn.confirm[data-v-bb1d1eb3]:active{box-shadow:none;transform:translateY(0)}.overlay-enter-active[data-v-bb1d1eb3],.overlay-leave-active[data-v-bb1d1eb3]{transition:opacity .2s}.overlay-enter-from[data-v-bb1d1eb3],.overlay-leave-to[data-v-bb1d1eb3]{opacity:0}.modal-enter-active[data-v-bb1d1eb3]{transition:all .22s cubic-bezier(.34,1.56,.64,1)}.modal-leave-active[data-v-bb1d1eb3]{transition:all .16s ease-in}.modal-enter-from[data-v-bb1d1eb3]{opacity:0;transform:scale(.88)translateY(-16px)}.modal-leave-to[data-v-bb1d1eb3]{opacity:0;transform:scale(.94)translateY(8px)}.slide-enter-active[data-v-bb1d1eb3],.slide-leave-active[data-v-bb1d1eb3]{transition:all .2s;overflow:hidden}.slide-enter-from[data-v-bb1d1eb3],.slide-leave-to[data-v-bb1d1eb3]{opacity:0;max-height:0;margin-top:0;padding-top:0;padding-bottom:0}.indicator-selector[data-v-f3fbebbd]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-f3fbebbd]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-f3fbebbd]::-webkit-scrollbar{display:none}.indicator-list[data-v-f3fbebbd]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-f3fbebbd]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-f3fbebbd]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-f3fbebbd],.indicator-item.draggable .indicator-btn[data-v-f3fbebbd],.indicator-item.draggable[data-v-f3fbebbd]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-f3fbebbd]{cursor:move}.indicator-item.is-dragging[data-v-f3fbebbd]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-f3fbebbd]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-f3fbebbd]{position:relative}.indicator-btn[data-v-f3fbebbd]{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-f3fbebbd]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-f3fbebbd]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-f3fbebbd]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-f3fbebbd]{z-index:1;position:relative}.param-hint[data-v-f3fbebbd]{opacity:.85;font-size:11px}.hover-overlay[data-v-f3fbebbd]{-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-f3fbebbd]{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-f3fbebbd]:hover{color:#333;background:#0000000f}.settings-btn[data-v-f3fbebbd]:hover{color:#1a1a1a}.remove-btn[data-v-f3fbebbd]:hover{color:#ff4d4f}.divider[data-v-f3fbebbd]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-f3fbebbd]{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-f3fbebbd]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-f3fbebbd]{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-f3fbebbd]{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-f3fbebbd]{padding:4px 0}.menu-section[data-v-f3fbebbd]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-f3fbebbd]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-f3fbebbd]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-f3fbebbd]{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-f3fbebbd]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-f3fbebbd]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-f3fbebbd]{color:#999;font-size:11px}.active-tag[data-v-f3fbebbd]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-f3fbebbd],.fade-leave-active[data-v-f3fbebbd]{transition:opacity .2s}.fade-enter-from[data-v-f3fbebbd],.fade-leave-to[data-v-f3fbebbd]{opacity:0}.slide-enter-active[data-v-f3fbebbd],.slide-leave-active[data-v-f3fbebbd]{transition:all .2s}.slide-enter-from[data-v-f3fbebbd],.slide-leave-to[data-v-f3fbebbd]{opacity:0;transform:translate(-50%)translateY(8px)}.drawing-style-toolbar[data-v-92699cb2]{-webkit-backdrop-filter:blur(8px);z-index:100;-webkit-user-select:none;user-select:none;pointer-events:auto;background:#fafbfce0;border:1px solid #e5e7eb;border-radius:6px;align-items:center;gap:6px;height:32px;padding:4px 8px;display:flex;position:absolute;top:8px;left:50%;transform:translate(-50%);box-shadow:0 1px 3px #0000000f}.toolbar-item[data-v-92699cb2]{justify-content:center;align-items:center;display:inline-flex}.color-item[data-v-92699cb2]{width:24px;height:24px;position:relative}.color-swatch[data-v-92699cb2]{cursor:pointer;border:1px solid #d1d5db;border-radius:4px;width:100%;height:100%;display:block}.color-input[data-v-92699cb2]{opacity:0;cursor:pointer;width:100%;height:100%;position:absolute;inset:0}.toolbar-select[data-v-92699cb2]{color:#374151;cursor:pointer;background:#fff;border:1px solid #d1d5db;border-radius:4px;outline:none;height:24px;padding:0 4px;font-size:12px}.toolbar-select[data-v-92699cb2]:hover{border-color:#9ca3af}.toolbar-btn[data-v-92699cb2]{color:#6b7280;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:4px;justify-content:center;align-items:center;width:24px;height:24px;padding:0;transition:border-color .15s,background .15s,color .15s;display:inline-flex}.toolbar-btn[data-v-92699cb2]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.delete-btn[data-v-92699cb2]:hover{color:#dc2626;background:#fef2f2;border-color:#fca5a5}.delete-icon[data-v-92699cb2]{width:14px;height:14px}.left-toolbar[data-v-f47a57b0]{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-f47a57b0]{flex-direction:column;gap:4px;display:flex}.left-toolbar__divider[data-v-f47a57b0]{background:#e5e7eb;width:18px;height:1px}.left-toolbar__button[data-v-f47a57b0]{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-f47a57b0]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.left-toolbar__button.active[data-v-f47a57b0]{color:#1f2937;background:#e5e7eb;border-color:#9ca3af}.left-toolbar__button[data-v-f47a57b0]:focus-visible{border-color:#6b7280;outline:none}.tool-icon[data-v-f47a57b0]{width:16px;height:16px}.corner-indicator[data-v-f47a57b0]{cursor:pointer;width:8px;height:8px;position:absolute;bottom:0;right:0;overflow:hidden}.corner-indicator[data-v-f47a57b0]: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-f47a57b0]:after,.left-toolbar__button.active .corner-indicator[data-v-f47a57b0]:after{opacity:.7}.corner-indicator.open[data-v-f47a57b0]:after{opacity:.8}.tool-dropdown[data-v-f47a57b0]{-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-f47a57b0]{position:relative}.dropdown-enter-active[data-v-f47a57b0],.dropdown-leave-active[data-v-f47a57b0]{transition:opacity .15s,transform .15s}.dropdown-enter-from[data-v-f47a57b0],.dropdown-leave-to[data-v-f47a57b0]{opacity:0;transform:translateY(-50%)translate(-6px)}@media (width<=768px),(height<=640px){.left-toolbar[data-v-f47a57b0]{border-radius:5px;flex-basis:36px;gap:5px;padding:6px 4px}.left-toolbar__group[data-v-f47a57b0]{gap:3px}.left-toolbar__button[data-v-f47a57b0]{border-radius:3px;width:26px;height:26px}.left-toolbar__divider[data-v-f47a57b0]{width:16px}.corner-indicator[data-v-f47a57b0]{width:7px;height:7px}.corner-indicator[data-v-f47a57b0]:after{border-bottom-width:4px;border-left-width:4px}.tool-dropdown[data-v-f47a57b0]{height:36px}}.settings-overlay[data-v-f47a57b0]{-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}.settings-modal[data-v-f47a57b0]{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}.settings-header[data-v-f47a57b0]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-f47a57b0]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-f47a57b0]{align-items:center;gap:8px;display:flex}.settings-title[data-v-f47a57b0]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.settings-subtitle[data-v-f47a57b0]{color:#999;font-size:11px}.settings-close[data-v-f47a57b0]{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}.settings-close[data-v-f47a57b0]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.settings-close svg[data-v-f47a57b0]{width:14px;height:14px}.settings-body[data-v-f47a57b0]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.settings-item[data-v-f47a57b0]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:8px 12px}.settings-label[data-v-f47a57b0]{color:#333;cursor:pointer;justify-content:space-between;align-items:center;font-size:13px;display:flex}.settings-checkbox[data-v-f47a57b0]{cursor:pointer;accent-color:#1a1a1a;width:16px;height:16px}.settings-section-divider[data-v-f47a57b0]{align-items:center;gap:8px;margin-top:4px;display:flex}.settings-section-divider[data-v-f47a57b0]:before,.settings-section-divider[data-v-f47a57b0]:after{content:"";border-top:1px solid #e0e0e0;flex:1}.settings-section-label[data-v-f47a57b0]{color:#999;white-space:nowrap;font-size:11px}.settings-item.experimental[data-v-f47a57b0]{background:#fdf8f3;border-color:#f0e0d0}.settings-footer[data-v-f47a57b0]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-f47a57b0]{gap:8px;display:flex}.settings-btn[data-v-f47a57b0]{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}.settings-btn svg[data-v-f47a57b0]{flex-shrink:0;width:12px;height:12px}.settings-btn.reset[data-v-f47a57b0]{color:#666;background:0 0;border-color:#d0d0d0}.settings-btn.reset[data-v-f47a57b0]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.settings-btn.cancel[data-v-f47a57b0]{color:#666;background:0 0;border-color:#d0d0d0}.settings-btn.cancel[data-v-f47a57b0]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.settings-btn.confirm[data-v-f47a57b0]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.settings-btn.confirm[data-v-f47a57b0]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.settings-btn.confirm[data-v-f47a57b0]:active{box-shadow:none;transform:translateY(0)}.chart-wrapper[data-v-533a72a5]{--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-533a72a5]{align-items:stretch;gap:8px;width:95%;height:85%;min-height:255px;display:flex}.chart-main[data-v-533a72a5]{flex:auto;align-items:stretch;gap:0;min-width:0;height:100%;display:flex;position:relative}.pane-separator-layer[data-v-533a72a5]{pointer-events:none;z-index:20;position:absolute;inset:0}.pane-separator-line[data-v-533a72a5]{opacity:1;box-sizing:border-box;border-top:1px solid #e5e7eb;height:0;transition:border-top-color .12s,border-top-width .12s,margin-top .12s,opacity .12s;position:absolute;left:0;right:0}.pane-separator-line.is-active[data-v-533a72a5]{border-top-width:2px;border-top-color:#3b82f6;margin-top:-1px}.chart-stage.is-resizing-pane[data-v-533a72a5],.chart-stage.is-hovering-pane-separator[data-v-533a72a5]{cursor:ns-resize}.chart-stage.is-hovering-kline[data-v-533a72a5]{cursor:pointer}.chart-stage.is-hovering-right-axis[data-v-533a72a5]{cursor:ns-resize}.chart-stage.is-dragging[data-v-533a72a5]{cursor:grabbing}.chart-container[data-v-533a72a5]{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-right:0;border-radius:6px 0 0 6px;flex:auto;position:relative;overflow:auto hidden}.chart-container[data-v-533a72a5]::-webkit-scrollbar{display:none}.chart-container[data-v-533a72a5]:hover{cursor:crosshair}.chart-stage.is-resizing-pane .chart-container[data-v-533a72a5],.chart-stage.is-hovering-pane-separator .chart-container[data-v-533a72a5]{cursor:ns-resize}.chart-stage.is-hovering-kline .chart-container[data-v-533a72a5]{cursor:pointer}.chart-stage.is-dragging .chart-container[data-v-533a72a5]{cursor:grabbing}.right-axis-host[data-v-533a72a5]{height:100%;min-height:inherit;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-top-right-radius:6px;border-bottom-right-radius:6px;flex:none;position:relative;overflow:visible}.scroll-content[data-v-533a72a5]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-533a72a5]{pointer-events:none;position:sticky;top:0;left:0}.tooltip-layer[data-v-533a72a5]{pointer-events:none;z-index:30;position:absolute;inset:0}.tooltip-anchor[data-v-533a72a5]{pointer-events:none;width:1px;height:1px;position:absolute}.tooltip-anchor.kline-tooltip-anchor.use-anchor[data-v-533a72a5]{anchor-name:--kline-tooltip-anchor}.tooltip-anchor.marker-tooltip-anchor.use-anchor[data-v-533a72a5]{anchor-name:--marker-tooltip-anchor}@media (width<=768px),(height<=640px){.chart-stage[data-v-533a72a5]{gap:6px}}.plot-canvas{display:block;position:absolute;top:0;left:0}.right-axis{display:block;position:absolute;left:0}.x-axis-canvas{z-index:10;display:block;position:absolute;bottom:0;left:0}.right-axis{z-index:15}
|
|
2
2
|
/*$vite$:1*/
|
|
@@ -9,6 +9,34 @@ export interface SettingItem {
|
|
|
9
9
|
group?: string;
|
|
10
10
|
}
|
|
11
11
|
/** 默认设置配置 */
|
|
12
|
-
export declare const DEFAULT_SETTINGS:
|
|
12
|
+
export declare const DEFAULT_SETTINGS: readonly [{
|
|
13
|
+
readonly key: "showVolumePriceMarkers";
|
|
14
|
+
readonly label: "显示量价关系标记";
|
|
15
|
+
readonly type: "boolean";
|
|
16
|
+
readonly default: true;
|
|
17
|
+
readonly group: "main";
|
|
18
|
+
}, {
|
|
19
|
+
readonly key: "logarithmicScale";
|
|
20
|
+
readonly label: "对数价格轴";
|
|
21
|
+
readonly type: "boolean";
|
|
22
|
+
readonly default: false;
|
|
23
|
+
readonly group: "main";
|
|
24
|
+
}, {
|
|
25
|
+
readonly key: "disableMainPaneVerticalScroll";
|
|
26
|
+
readonly label: "主图纵轴刻度自适应调整";
|
|
27
|
+
readonly type: "boolean";
|
|
28
|
+
readonly default: true;
|
|
29
|
+
readonly group: "experimental";
|
|
30
|
+
}, {
|
|
31
|
+
readonly key: "performanceTest10kKlines";
|
|
32
|
+
readonly label: "万条K线性能测试";
|
|
33
|
+
readonly type: "boolean";
|
|
34
|
+
readonly default: false;
|
|
35
|
+
readonly group: "experimental";
|
|
36
|
+
}];
|
|
37
|
+
/** 图表设置类型(从 DEFAULT_SETTINGS 自动推导,同时兼容扩展) */
|
|
38
|
+
export type ChartSettings = {
|
|
39
|
+
[K in (typeof DEFAULT_SETTINGS)[number]['key']]?: boolean;
|
|
40
|
+
} & Record<string, boolean>;
|
|
13
41
|
/** localStorage 存储键名 */
|
|
14
42
|
export declare const SETTINGS_STORAGE_KEY = "kline-chart-settings";
|
package/dist/src/core/chart.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { KLineData } from '../types/price';
|
|
2
|
+
import { ChartSettings } from '../config/chartSettings';
|
|
2
3
|
import { VisibleRange, UpdateLevel } from './layout/pane';
|
|
3
4
|
import { InteractionController } from './controller/interaction';
|
|
4
5
|
import { PaneRenderer } from './paneRenderer';
|
|
@@ -106,14 +107,22 @@ export declare class Chart {
|
|
|
106
107
|
private preciseDpr;
|
|
107
108
|
/** 统一监听容器尺寸与 DPR 变化 */
|
|
108
109
|
private resizeObserver?;
|
|
110
|
+
/** scroll 事件处理器引用(用于 cleanup) */
|
|
111
|
+
private onScroll?;
|
|
109
112
|
/** 最近一次观测到的容器尺寸 */
|
|
110
113
|
private observedSize;
|
|
114
|
+
/** 缓存的 scrollLeft(通过 scroll 事件同步,避免每帧读取 DOM 触发强制回流) */
|
|
115
|
+
private cachedScrollLeft;
|
|
116
|
+
/** overlay 上一帧是否有十字线(用于判断何时需要清除) */
|
|
117
|
+
private overlayHadCrosshair;
|
|
111
118
|
/** 用户设置配置(传递给渲染器) */
|
|
112
119
|
private settings;
|
|
113
120
|
/** pane ratio 状态(按 paneId 维护,sum=1 仅对可见 pane) */
|
|
114
121
|
private paneRatios;
|
|
115
122
|
/** 视口变化回调(供外部同步 DPR/尺寸) */
|
|
116
123
|
private onViewportChange?;
|
|
124
|
+
/** 共享 X 轴上下文缓存 */
|
|
125
|
+
private xAxisCtx;
|
|
117
126
|
/** pane 布局回流回调(Chart -> UI 单向) */
|
|
118
127
|
private onPaneLayoutChange?;
|
|
119
128
|
/** 数据变化回调(供外部同步 dataLength) */
|
|
@@ -128,6 +137,72 @@ export declare class Chart {
|
|
|
128
137
|
private indicatorScheduler;
|
|
129
138
|
/** 上次可见范围(用于检测视口变化) */
|
|
130
139
|
private lastVisibleRange;
|
|
140
|
+
/** Overlay 帧复用的最近主渲染结果 */
|
|
141
|
+
private cachedDrawFrame;
|
|
142
|
+
/** 当前激活的主图指标列表(如 ['boll', 'ma']) */
|
|
143
|
+
private activeMainIndicators;
|
|
144
|
+
/** 主图指标参数配置 */
|
|
145
|
+
private mainIndicatorParams;
|
|
146
|
+
/**
|
|
147
|
+
* 启用主图指标
|
|
148
|
+
* @param indicatorId 指标ID: 'MA' | 'BOLL' | 'EXPMA' | 'ENE'
|
|
149
|
+
* @param params 可选的指标参数
|
|
150
|
+
* @returns 是否成功启用
|
|
151
|
+
*/
|
|
152
|
+
enableMainIndicator(indicatorId: string, params?: Record<string, number | boolean>): boolean;
|
|
153
|
+
/**
|
|
154
|
+
* 禁用主图指标
|
|
155
|
+
* @param indicatorId 指标ID
|
|
156
|
+
* @returns 是否成功禁用
|
|
157
|
+
*/
|
|
158
|
+
disableMainIndicator(indicatorId: string): boolean;
|
|
159
|
+
/**
|
|
160
|
+
* 切换主图指标启用状态
|
|
161
|
+
* @param indicatorId 指标ID
|
|
162
|
+
* @param enabled 是否启用
|
|
163
|
+
*/
|
|
164
|
+
toggleMainIndicator(indicatorId: string, enabled: boolean): void;
|
|
165
|
+
/**
|
|
166
|
+
* 获取当前激活的主图指标列表
|
|
167
|
+
* @returns 激活的指标ID数组
|
|
168
|
+
*/
|
|
169
|
+
getActiveMainIndicators(): string[];
|
|
170
|
+
/**
|
|
171
|
+
* 检查主图指标是否激活
|
|
172
|
+
* @param indicatorId 指标ID
|
|
173
|
+
*/
|
|
174
|
+
isMainIndicatorActive(indicatorId: string): boolean;
|
|
175
|
+
/**
|
|
176
|
+
* 更新主图指标参数
|
|
177
|
+
* @param indicatorId 指标ID
|
|
178
|
+
* @param params 参数对象
|
|
179
|
+
*/
|
|
180
|
+
updateMainIndicatorParams(indicatorId: string, params: Record<string, number | boolean>): void;
|
|
181
|
+
/**
|
|
182
|
+
* 获取主图指标参数
|
|
183
|
+
* @param indicatorId 指标ID
|
|
184
|
+
*/
|
|
185
|
+
getMainIndicatorParams(indicatorId: string): Record<string, number | boolean> | null;
|
|
186
|
+
/**
|
|
187
|
+
* 清除所有主图指标
|
|
188
|
+
*/
|
|
189
|
+
clearMainIndicators(): void;
|
|
190
|
+
/**
|
|
191
|
+
* 启用主图指标渲染器(内部方法)
|
|
192
|
+
*/
|
|
193
|
+
private enableMainIndicatorRenderer;
|
|
194
|
+
/**
|
|
195
|
+
* 禁用主图指标渲染器(内部方法)
|
|
196
|
+
*/
|
|
197
|
+
private disableMainIndicatorRenderer;
|
|
198
|
+
/**
|
|
199
|
+
* 更新调度器配置(内部方法)
|
|
200
|
+
*/
|
|
201
|
+
private updateIndicatorSchedulerConfig;
|
|
202
|
+
/**
|
|
203
|
+
* @deprecated 使用 enableMainIndicator/disableMainIndicator 替代
|
|
204
|
+
*/
|
|
205
|
+
setActiveMainIndicators(indicators: string[]): void;
|
|
131
206
|
/**
|
|
132
207
|
* 创建图表实例
|
|
133
208
|
* @param dom 由 Vue 组件传入的 DOM 句柄
|
|
@@ -139,6 +214,8 @@ export declare class Chart {
|
|
|
139
214
|
private getEffectiveDpr;
|
|
140
215
|
getViewport(): Viewport | null;
|
|
141
216
|
getCurrentDpr(): number;
|
|
217
|
+
/** 获取缓存的 scrollLeft(避免读取 DOM 触发强制回流) */
|
|
218
|
+
getCachedScrollLeft(): number;
|
|
142
219
|
/** 获取插件宿主 */
|
|
143
220
|
get plugin(): PluginHostImpl;
|
|
144
221
|
/** 安装渲染器插件 */
|
|
@@ -154,7 +231,7 @@ export declare class Chart {
|
|
|
154
231
|
/** 获取所有渲染器 */
|
|
155
232
|
getAllRenderers(): RendererPlugin[];
|
|
156
233
|
/** 更新用户设置(触发重绘) */
|
|
157
|
-
updateSettings(settings:
|
|
234
|
+
updateSettings(settings: ChartSettings): void;
|
|
158
235
|
/**
|
|
159
236
|
* 绘制一帧
|
|
160
237
|
* @param level 更新级别,决定渲染哪些层
|
|
@@ -259,6 +336,11 @@ export declare class Chart {
|
|
|
259
336
|
* @param deltaY Y轴像素偏移(正数向下拖动)
|
|
260
337
|
*/
|
|
261
338
|
translatePrice(paneId: string, deltaY: number): void;
|
|
339
|
+
/**
|
|
340
|
+
* 重置价格轴垂直偏移
|
|
341
|
+
* @param paneId 目标 pane ID
|
|
342
|
+
*/
|
|
343
|
+
resetPriceOffset(paneId: string): void;
|
|
262
344
|
/**
|
|
263
345
|
* 缩放价格轴(用于右侧刻度栏上下拖动)
|
|
264
346
|
* @param paneId 目标 pane ID
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Chart } from '../chart';
|
|
2
2
|
import { MarkerEntity, CustomMarkerEntity } from '../marker/registry';
|
|
3
|
+
import { ChartSettings } from '../../config/chartSettings';
|
|
3
4
|
export interface InteractionSnapshot {
|
|
4
5
|
crosshairPos: {
|
|
5
6
|
x: number;
|
|
@@ -102,16 +103,19 @@ export declare class InteractionController {
|
|
|
102
103
|
private kLinePositions;
|
|
103
104
|
/** 当前帧的可见 K 线索引范围 */
|
|
104
105
|
private visibleRange;
|
|
106
|
+
/** hover 去重快照 */
|
|
107
|
+
private lastHoverRenderKey;
|
|
105
108
|
/** K 线宽度(物理像素),用于计算 K 线中心偏移 */
|
|
106
109
|
private kWidthPx;
|
|
107
110
|
constructor(chart: Chart);
|
|
108
111
|
/** 设置捏合缩放回调 */
|
|
109
112
|
setOnPinchZoom(callback: (delta: number, centerX: number) => void): void;
|
|
110
113
|
/** 更新用户设置 */
|
|
111
|
-
updateSettings(settings:
|
|
114
|
+
updateSettings(settings: ChartSettings): void;
|
|
112
115
|
getInteractionSnapshot(): InteractionSnapshot;
|
|
113
116
|
setOnInteractionChange(callback: (snapshot: InteractionSnapshot) => void): void;
|
|
114
117
|
private notifyInteractionChange;
|
|
118
|
+
private getHoverRenderKey;
|
|
115
119
|
/**
|
|
116
120
|
* [触屏]:处理 Pointer 按下事件
|
|
117
121
|
* @param e PointerEvent
|
|
@@ -157,10 +157,17 @@ export declare class IndicatorScheduler {
|
|
|
157
157
|
private dirtyWmsrState;
|
|
158
158
|
private dirtyKstState;
|
|
159
159
|
private dirtyFastkState;
|
|
160
|
+
/** 当前激活的主图指标列表 */
|
|
161
|
+
private activeMainIndicators;
|
|
160
162
|
/**
|
|
161
163
|
* 设置 PluginHost,用于读写 StateStore
|
|
162
164
|
*/
|
|
163
165
|
setPluginHost(host: PluginHost): void;
|
|
166
|
+
/**
|
|
167
|
+
* 设置当前激活的主图指标(用于极值计算过滤)
|
|
168
|
+
* @param indicators 激活的指标ID列表,如 ['ma', 'boll', 'expma', 'ene']
|
|
169
|
+
*/
|
|
170
|
+
setActiveMainIndicators(indicators: string[]): void;
|
|
164
171
|
/**
|
|
165
172
|
* 数据变更时调用
|
|
166
173
|
* @param data 新的 K 线数据
|
|
@@ -247,5 +254,13 @@ export declare class IndicatorScheduler {
|
|
|
247
254
|
* 3. 写入所有指标的 StateStore
|
|
248
255
|
*/
|
|
249
256
|
private computeIfDirty;
|
|
257
|
+
/**
|
|
258
|
+
* 获取主图指标极值(用于与K线极值合并计算价格轴范围)
|
|
259
|
+
* @returns 主图指标的价格范围,无指标时返回 null
|
|
260
|
+
*/
|
|
261
|
+
getMainIndicatorPriceRange(): {
|
|
262
|
+
min: number;
|
|
263
|
+
max: number;
|
|
264
|
+
} | null;
|
|
250
265
|
}
|
|
251
266
|
export {};
|
|
@@ -94,6 +94,10 @@ export declare class Pane {
|
|
|
94
94
|
* 根据当前可见索引区间更新 priceRange 并同步到 yAxis
|
|
95
95
|
* @param data 全量 K 线数据
|
|
96
96
|
* @param range 当前视口可见的索引范围(由 getVisibleRange 计算)
|
|
97
|
+
* @param indicatorRange 可选的指标极值范围,与K线极值合并
|
|
97
98
|
*/
|
|
98
|
-
updateRange(data: KLineData[], range: VisibleRange
|
|
99
|
+
updateRange(data: KLineData[], range: VisibleRange, indicatorRange?: {
|
|
100
|
+
min: number;
|
|
101
|
+
max: number;
|
|
102
|
+
} | null): void;
|
|
99
103
|
}
|
|
@@ -1,22 +1,36 @@
|
|
|
1
|
+
import { CandleWebGLSurface, LineWebGLSurface } from './renderers/webgl/candleSurface';
|
|
1
2
|
export type PaneRendererDom = {
|
|
2
3
|
mainCanvas: HTMLCanvasElement;
|
|
3
4
|
overlayCanvas: HTMLCanvasElement;
|
|
4
5
|
yAxisCanvas: HTMLCanvasElement;
|
|
5
6
|
};
|
|
7
|
+
export type PaneRendererContexts = {
|
|
8
|
+
mainCtx: CanvasRenderingContext2D | null;
|
|
9
|
+
overlayCtx: CanvasRenderingContext2D | null;
|
|
10
|
+
yAxisCtx: CanvasRenderingContext2D | null;
|
|
11
|
+
};
|
|
6
12
|
export type PaneRendererOptions = {
|
|
7
13
|
rightAxisWidth: number;
|
|
8
14
|
yPaddingPx: number;
|
|
9
15
|
priceLabelWidth?: number;
|
|
10
16
|
};
|
|
17
|
+
export type PaneRendererWebGLHandles = {
|
|
18
|
+
candleSurface: CandleWebGLSurface | null;
|
|
19
|
+
lineSurface: LineWebGLSurface | null;
|
|
20
|
+
};
|
|
11
21
|
export declare class PaneRenderer {
|
|
12
22
|
private dom;
|
|
13
23
|
private pane;
|
|
14
24
|
private opt;
|
|
25
|
+
private contexts;
|
|
26
|
+
private webgl;
|
|
15
27
|
constructor(dom: PaneRendererDom, pane: import('./layout/pane').Pane, opt: PaneRendererOptions);
|
|
16
28
|
/** 获取关联的 Pane 实例 */
|
|
17
29
|
getPane(): import('./layout/pane').Pane;
|
|
18
30
|
/** 获取 DOM 元素 */
|
|
19
31
|
getDom(): PaneRendererDom;
|
|
32
|
+
getContexts(): PaneRendererContexts;
|
|
33
|
+
getWebGL(): PaneRendererWebGLHandles;
|
|
20
34
|
/**
|
|
21
35
|
* 调整 Canvas 尺寸
|
|
22
36
|
* @param width pane 宽度(逻辑像素)
|
|
@@ -1,11 +1,2 @@
|
|
|
1
1
|
import { RendererPluginWithHost } from '../../../plugin';
|
|
2
|
-
/**
|
|
3
|
-
* 创建 BOLL(布林带)渲染器插件(无状态版本)
|
|
4
|
-
*
|
|
5
|
-
* 设计原则:
|
|
6
|
-
* 1. 不持有任何计算缓存或配置状态
|
|
7
|
-
* 2. 所有数据从 StateStore 读取(通过 BOLL_STATE_KEY)
|
|
8
|
-
* 3. 配置变更通过外部 IndicatorScheduler 处理
|
|
9
|
-
* 4. 纯绘制函数,无副作用
|
|
10
|
-
*/
|
|
11
2
|
export declare function createBOLLRendererPlugin(): RendererPluginWithHost;
|
|
@@ -1,11 +1,2 @@
|
|
|
1
1
|
import { RendererPluginWithHost } from '../../../plugin';
|
|
2
|
-
/**
|
|
3
|
-
* 创建 EXPMA(指数平滑移动平均线)渲染器插件(无状态版本)
|
|
4
|
-
*
|
|
5
|
-
* 设计原则:
|
|
6
|
-
* 1. 不持有任何计算缓存或配置状态
|
|
7
|
-
* 2. 所有数据从 StateStore 读取(通过 EXPMA_STATE_KEY)
|
|
8
|
-
* 3. 配置变更通过外部 IndicatorScheduler 处理
|
|
9
|
-
* 4. 纯绘制函数,无副作用
|
|
10
|
-
*/
|
|
11
2
|
export declare function createEXPMARendererPlugin(): RendererPluginWithHost;
|
|
@@ -1,12 +1,3 @@
|
|
|
1
1
|
import { RendererPluginWithHost } from '../../../plugin';
|
|
2
2
|
export type { MAFlags } from '../../indicators/calculators';
|
|
3
|
-
/**
|
|
4
|
-
* 创建 MA 均线渲染器插件(无状态版本)
|
|
5
|
-
*
|
|
6
|
-
* 设计原则:
|
|
7
|
-
* 1. 不持有任何计算缓存或配置状态
|
|
8
|
-
* 2. 所有数据从 StateStore 读取(通过 MA_STATE_KEY)
|
|
9
|
-
* 3. 配置变更通过外部 IndicatorScheduler 处理,不经过本渲染器
|
|
10
|
-
* 4. 纯绘制函数,无副作用
|
|
11
|
-
*/
|
|
12
3
|
export declare function createMARendererPlugin(): RendererPluginWithHost;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
type Rect = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
};
|
|
7
|
+
type LineStrip = {
|
|
8
|
+
points: Array<{
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
}>;
|
|
12
|
+
width: number;
|
|
13
|
+
};
|
|
14
|
+
export declare class CandleWebGLSurface {
|
|
15
|
+
private canvas;
|
|
16
|
+
private handles;
|
|
17
|
+
private logicalWidth;
|
|
18
|
+
private logicalHeight;
|
|
19
|
+
private available;
|
|
20
|
+
constructor(canvas?: HTMLCanvasElement);
|
|
21
|
+
isAvailable(): boolean;
|
|
22
|
+
getCanvas(): HTMLCanvasElement;
|
|
23
|
+
resize(width: number, height: number, dpr: number): void;
|
|
24
|
+
clear(): void;
|
|
25
|
+
drawRects(rects: Rect[], color: string, scrollLeft: number): boolean;
|
|
26
|
+
destroy(): void;
|
|
27
|
+
private initRectHandles;
|
|
28
|
+
}
|
|
29
|
+
export declare class LineWebGLSurface {
|
|
30
|
+
private canvas;
|
|
31
|
+
private handles;
|
|
32
|
+
private logicalWidth;
|
|
33
|
+
private logicalHeight;
|
|
34
|
+
private dpr;
|
|
35
|
+
private available;
|
|
36
|
+
constructor(canvas?: HTMLCanvasElement);
|
|
37
|
+
isAvailable(): boolean;
|
|
38
|
+
getCanvas(): HTMLCanvasElement;
|
|
39
|
+
resize(width: number, height: number, dpr: number): void;
|
|
40
|
+
clear(): void;
|
|
41
|
+
drawLineStrip(line: LineStrip, color: string, scrollLeft: number): boolean;
|
|
42
|
+
destroy(): void;
|
|
43
|
+
private initLineHandles;
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { KLineData } from '../types/price';
|
|
2
|
+
import { CandleWebGLSurface, LineWebGLSurface } from '../core/renderers/webgl/candleSurface';
|
|
2
3
|
/** 插件生命周期状态 */
|
|
3
4
|
export declare enum PluginState {
|
|
4
5
|
Registered = "registered",
|
|
@@ -228,6 +229,10 @@ export interface RenderContext {
|
|
|
228
229
|
borderCtx?: CanvasRenderingContext2D;
|
|
229
230
|
/** 覆盖层 Canvas 上下文(用于十字线、Tooltip 等动态内容) */
|
|
230
231
|
overlayCtx?: CanvasRenderingContext2D;
|
|
232
|
+
/** price pane 可选的 WebGL candle surface */
|
|
233
|
+
candleWebGLSurface?: CandleWebGLSurface;
|
|
234
|
+
/** line indicator 可选的 WebGL line surface */
|
|
235
|
+
lineWebGLSurface?: LineWebGLSurface;
|
|
231
236
|
/** 当前缩放级别(1 ~ zoomLevels) */
|
|
232
237
|
zoomLevel?: number;
|
|
233
238
|
/** 总缩放级别数 */
|
|
@@ -238,7 +243,7 @@ export interface RenderContext {
|
|
|
238
243
|
plotHeight: number;
|
|
239
244
|
};
|
|
240
245
|
/** 用户设置配置(渲染器只读) */
|
|
241
|
-
settings?:
|
|
246
|
+
settings?: import('../config/chartSettings').ChartSettings;
|
|
242
247
|
/** 需要在Y轴上绘制的标签列表(由各类标记渲染器填充) */
|
|
243
248
|
yAxisLabels?: YAxisLabel[];
|
|
244
249
|
/** 需要在X轴上绘制的标签列表(由各类标记渲染器填充) */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@363045841yyt/klinechart",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "A lightweight financial K-line charting library with first-class AI Agent support, crisp ResizeObserver-driven rendering, and plugin-based architecture. Focused on quantitative trading scenarios with TradingView-level interaction experience.",
|
|
5
5
|
"author": "363045841 <slslswbsy@qq.com>",
|
|
6
6
|
"license": "MIT",
|