waveform-analysis 0.1.32 → 0.1.36
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 +28 -3
- package/dist/index.cjs +1 -1
- package/dist/index.js +426 -411
- package/dist/style.css +1 -1
- package/dist/types/components/WaveformChart.vue.d.ts +1 -0
- package/dist/types/components/core/trackLayoutBuilder.d.ts +2 -1
- package/dist/types/components/core/types.d.ts +2 -0
- package/dist/types/components/core/useWaveformChartController.d.ts +1 -0
- package/dist/types/components/core/waveformChartTypes.d.ts +3 -2
- package/dist/types/components/core/xDomain.d.ts +3 -0
- package/dist/types/components/data/types.d.ts +1 -1
- package/dist/types/components/interaction/WaveformTooltip.vue.d.ts +1 -0
- package/dist/types/components/waveform.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/types/chart.d.ts +10 -0
- package/dist/types/types/data.d.ts +3 -0
- package/dist/types/types/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/WaveformChart.vue +1 -0
- package/src/components/core/trackLayoutBuilder.ts +19 -7
- package/src/components/core/types.ts +2 -0
- package/src/components/core/useWaveformChartLifecycle.ts +1 -0
- package/src/components/core/useWaveformLayout.ts +19 -6
- package/src/components/core/waveformChartTypes.ts +3 -0
- package/src/components/core/xDomain.test.ts +28 -0
- package/src/components/core/xDomain.ts +25 -0
- package/src/components/data/types.ts +1 -0
- package/src/components/interaction/WaveformTooltip.test.ts +17 -9
- package/src/components/interaction/WaveformTooltip.vue +41 -45
- package/src/components/interaction/useWaveformHover.ts +1 -0
- package/src/components/waveform.ts +1 -0
- package/src/components/waveformChartCases/compactAndSharedHover.test.ts +4 -4
- package/src/components/waveformChartCases/dataAndHoverPerformance.test.ts +2 -2
- package/src/components/waveformChartCases/viewportReset.test.ts +35 -0
- package/src/components/waveformChartCases/xDomainStrategy.test.ts +96 -0
- package/src/core/data.test.ts +22 -0
- package/src/core/data.ts +1 -0
- package/src/data/simulatedWaveforms.test.ts +1 -0
- package/src/data/simulatedWaveforms.ts +7 -1
- package/src/index.ts +1 -0
- package/src/types/chart.ts +11 -0
- package/src/types/data.ts +3 -0
- package/src/types/index.ts +1 -0
- package/src/views/FixedYDomainDemo.vue +2 -0
package/dist/style.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
.waveform-annotation-layer[data-v-7254383e]{pointer-events:none}.waveform-annotation-layer--interactive .waveform-annotation[data-v-7254383e]{pointer-events:auto;cursor:grab;touch-action:none}.waveform-annotation-layer--interactive .waveform-annotation[data-v-7254383e]:active{cursor:grabbing}.waveform-annotation__arrow[data-v-7254383e]{stroke-width:2px;stroke-linecap:round;pointer-events:none}.waveform-annotation__box[data-v-7254383e]{stroke-width:1px;rx:3}.waveform-annotation-layer--interactive .waveform-annotation__box[data-v-7254383e]{pointer-events:auto}.waveform-annotation__text[data-v-7254383e]{pointer-events:none;-webkit-user-select:none;user-select:none}.waveform-annotation-context-menu[data-v-c70c98a1]{z-index:30;background:#fff;border:1px solid #dfe5ef;border-radius:4px;min-width:112px;padding:4px;display:grid;position:absolute;box-shadow:0 4px 14px #10182829}.waveform-annotation-context-menu button[data-v-c70c98a1]{color:#344054;text-align:left;white-space:nowrap;cursor:pointer;background:0 0;border:0;border-radius:3px;padding:7px 10px;font-size:12px}.waveform-annotation-context-menu button[data-v-c70c98a1]:hover{background:#f2f4f7}.waveform-annotation-editor[data-v-52818b45]{z-index:40;background:#10182852;place-items:center;padding:20px;animation:.16s ease-out waveform-annotation-editor-fade-in-52818b45;display:grid;position:absolute;inset:0}.waveform-annotation-editor__panel[data-v-52818b45]{color:#344054;background:#fff;border:1px solid #e4e7ec;border-radius:12px;gap:20px;width:min(440px,100%);max-height:100%;padding:22px;font-size:13px;animation:.18s ease-out waveform-annotation-editor-rise-in-52818b45;display:grid;overflow-y:auto;box-shadow:0 20px 50px #10182838}.waveform-annotation-editor__header[data-v-52818b45]{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.waveform-annotation-editor__header h2[data-v-52818b45]{color:#101828;margin:0;font-size:18px;line-height:1.3}.waveform-annotation-editor__header p[data-v-52818b45]{color:#667085;margin:5px 0 0;font-size:12px}.waveform-annotation-editor__close[data-v-52818b45]{color:#667085;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:0 0 30px;place-items:center;width:30px;height:30px;padding:0;font-size:22px;line-height:1;display:inline-grid}.waveform-annotation-editor__close[data-v-52818b45]:hover{color:#101828;background:#f2f4f7}.waveform-annotation-editor__coordinates[data-v-52818b45]{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.waveform-annotation-editor__coordinates span[data-v-52818b45],.waveform-annotation-editor__series[data-v-52818b45]{background:#f8fafc;border:1px solid #eaecf0;border-radius:7px;align-items:center;gap:8px;min-width:0;padding:9px 10px;display:flex}.waveform-annotation-editor__coordinates span[data-v-52818b45]{color:#667085}.waveform-annotation-editor__coordinates b[data-v-52818b45]{color:#1677ff;font-size:11px}.waveform-annotation-editor__coordinates code[data-v-52818b45]{color:#344054;text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:SFMono-Regular,Consolas,monospace;font-size:11px;overflow:hidden}.waveform-annotation-editor__series[data-v-52818b45]{gap:10px}.waveform-annotation-editor__series i[data-v-52818b45]{border:1px solid #0000001f;border-radius:2px;flex:0 0 12px;width:12px;height:12px}.waveform-annotation-editor__series-label[data-v-52818b45]{gap:1px;min-width:0;display:grid}.waveform-annotation-editor__series select[data-v-52818b45]{color:#344054;min-width:0;max-width:190px;font:inherit;background:#fff;border:1px solid #d0d5dd;border-radius:5px;margin-left:auto;padding:5px 7px}.waveform-annotation-editor__series small[data-v-52818b45]{color:#667085;font-size:10px}.waveform-annotation-editor__series b[data-v-52818b45]{color:#344054;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.waveform-annotation-editor__series code[data-v-52818b45]{color:#667085;margin-left:auto;font-size:11px}.waveform-annotation-editor__field[data-v-52818b45],.waveform-annotation-editor__color-field[data-v-52818b45]{gap:4px;display:grid}.waveform-annotation-editor__label-row[data-v-52818b45]{justify-content:space-between;align-items:center;gap:8px;display:flex}.waveform-annotation-editor__label-row b[data-v-52818b45],.waveform-annotation-editor__colors legend[data-v-52818b45]{color:#344054;font-size:12px;font-weight:600}.waveform-annotation-editor__label-row small[data-v-52818b45]{color:#98a2b3;font-size:11px}.waveform-annotation-editor textarea[data-v-52818b45]{box-sizing:border-box;color:#1d2939;width:100%;min-height:92px;font:inherit;resize:vertical;background:#fff;border:1px solid #d0d5dd;border-radius:7px;padding:10px 11px;line-height:1.5}.waveform-annotation-editor textarea[data-v-52818b45]:focus{border-color:#1677ff;outline:3px solid #1677ff24}.waveform-annotation-editor__colors[data-v-52818b45]{border:0;border-top:1px solid #eaecf0;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;min-width:0;margin:0;padding:14px 0 0;display:grid}.waveform-annotation-editor__colors legend[data-v-52818b45]{grid-column:1/-1;padding:0}.waveform-annotation-editor__color-field[data-v-52818b45]{color:#667085;text-align:left;place-items:stretch stretch;min-width:0;font-size:11px}.waveform-annotation-editor__color-field[data-v-52818b45] .vc-color-wrap{border:1px solid #cfd5df;border-radius:6px;width:100%;height:34px;margin-right:0;box-shadow:inset 0 0 0 1px #ffffff61}.waveform-annotation-editor__color-field[data-v-52818b45] .vc-color-wrap:hover{border-color:#98a2b3;box-shadow:0 0 0 3px #1677ff1f}.waveform-annotation-editor__actions[data-v-52818b45]{border-top:1px solid #eaecf0;justify-content:flex-end;gap:8px;padding-top:8px;display:flex}.waveform-annotation-editor__actions button[data-v-52818b45]{color:#475467;cursor:pointer;background:#fff;border:1px solid #d0d5dd;border-radius:6px;height:34px;padding:0 12px}.waveform-annotation-editor__actions button.is-primary[data-v-52818b45]{color:#fff;background:#1677ff;border-color:#1677ff}.waveform-annotation-editor__actions button[data-v-52818b45]:disabled{opacity:.45;cursor:not-allowed}@keyframes waveform-annotation-editor-fade-in-52818b45{0%{opacity:0}to{opacity:1}}@keyframes waveform-annotation-editor-rise-in-52818b45{0%{opacity:0;transform:translateY(8px)scale(.98)}to{opacity:1;transform:translateY(0)scale(1)}}@media (width<=420px){.waveform-annotation-editor[data-v-52818b45]{padding:12px}.waveform-annotation-editor__panel[data-v-52818b45]{gap:16px;padding:18px}.waveform-annotation-editor__coordinates[data-v-52818b45]{grid-template-columns:1fr}}.waveform-tooltip[data-v-93daa641]{box-sizing:border-box;z-index:2;color:#333;pointer-events:none;background:#fff;border:1px solid #d9d9d9;border-radius:2px;gap:3px;width:max-content;max-width:min(320px,100% - 16px);padding:8px 10px;font:12px/1.45 ui-monospace,SFMono-Regular,Consolas,monospace;display:grid;position:absolute;box-shadow:0 4px 12px #1018281f}.waveform-tooltip__time[data-v-93daa641]{border-bottom:1px solid #f0f0f0;padding-bottom:4px}.waveform-tooltip__series[data-v-93daa641]{grid-template-columns:8px minmax(0,1fr);align-items:start;gap:6px;display:grid}.waveform-tooltip__series i[data-v-93daa641]{border-radius:50%;flex:none;width:8px;height:8px;margin-top:4px}.waveform-tooltip__series-content[data-v-93daa641]{overflow-wrap:anywhere;white-space:normal;min-width:0}.waveform-tooltip__series strong[data-v-93daa641]{font-weight:600}.waveform-tooltip__value[data-v-93daa641]{overflow-wrap:anywhere}.waveform-tooltip__series small[data-v-93daa641]{color:#667085}.waveform-track__line[data-v-42a3fd47]{fill:none;stroke-width:1.5px;stroke-linejoin:round;stroke-linecap:round}.waveform-track__error-bar[data-v-42a3fd47]{fill:none}.waveform-track__point[data-v-42a3fd47],.waveform-track__error-bar[data-v-42a3fd47]{pointer-events:none}.waveform-track{isolation:isolate;pointer-events:none}.waveform-track__y-axis-label-bg{fill:#fff;opacity:.9;pointer-events:none}.waveform-track__y-axis-label{pointer-events:none;font-size:12px;font-weight:500}.waveform-track__grid{pointer-events:none}.waveform-track__grid--major line{stroke:#dfe5ef;stroke-width:1px}.waveform-track__grid--minor line{stroke:#f2f5fa;stroke-width:1px}.waveform-track__plot-frame,.waveform-track__plot-background{pointer-events:none}.waveform-track__watermark{fill:#1677ff1a;pointer-events:none;-webkit-user-select:none;user-select:none;font-family:Consolas,Monaco,Courier New,monospace}.waveform-track__overlay{fill:#0000;cursor:crosshair;pointer-events:all;touch-action:none}.waveform-track__no-visible-series{fill:#8c8c8c;pointer-events:none;font:13px sans-serif}.waveform-track__overlay.is-zoomable{cursor:grab}.waveform-track__overlay.is-zoomable:active{cursor:grabbing}.waveform-track__overlay.is-annotating{cursor:crosshair}.waveform-track__overlay.is-presentation{cursor:default;pointer-events:none}.waveform-track__zero-line{fill:none;pointer-events:none}.waveform-track__axis-endpoint{fill:#667085;pointer-events:none;font-size:11px}.waveform-track__axis-exponent{fill:#666;font-family:sans-serif;font-size:10px}.waveform-track__axis path,.waveform-track__axis line{stroke:#1f2937}.waveform-track__axis text{fill:#667085;font-size:11px}.waveform-legend[data-v-2ae12e71]{pointer-events:none;overflow:hidden}.waveform-legend__viewport[data-v-2ae12e71]{box-sizing:border-box;width:100%;height:100%;padding:8px;display:flex;overflow:hidden}.waveform-legend__viewport--top-left[data-v-2ae12e71]{justify-content:flex-start;align-items:flex-start}.waveform-legend__viewport--top[data-v-2ae12e71]{justify-content:center;align-items:flex-start}.waveform-legend__viewport--top-right[data-v-2ae12e71]{justify-content:flex-end;align-items:flex-start}.waveform-legend__viewport--right[data-v-2ae12e71]{justify-content:flex-end;align-items:center}.waveform-legend__viewport--bottom-right[data-v-2ae12e71]{justify-content:flex-end;align-items:flex-end}.waveform-legend__viewport--bottom[data-v-2ae12e71]{justify-content:center;align-items:flex-end}.waveform-legend__viewport--bottom-left[data-v-2ae12e71]{justify-content:flex-start;align-items:flex-end}.waveform-legend__viewport--left[data-v-2ae12e71]{justify-content:flex-start;align-items:center}.waveform-legend__panel[data-v-2ae12e71]{color:#344054;border:1px solid #d0d5dde6;border-radius:4px;flex:0 auto;gap:5px 12px;max-width:100%;max-height:100%;padding:5px 7px;font:12px/1.35 sans-serif;display:flex;overflow:hidden}.waveform-legend__panel--interactive[data-v-2ae12e71]{pointer-events:auto}.waveform-legend__panel--horizontal[data-v-2ae12e71]{flex-flow:wrap;align-items:center}.waveform-legend__panel--vertical[data-v-2ae12e71]{flex-flow:column;align-items:stretch}.waveform-legend__item[data-v-2ae12e71]{min-width:0;max-width:160px;color:inherit;font:inherit;text-align:left;white-space:nowrap;appearance:none;background:0 0;border:0;align-items:center;gap:6px;padding:0;display:flex}.waveform-legend__item[data-v-2ae12e71]:disabled{opacity:1}.waveform-legend__panel--interactive .waveform-legend__item[data-v-2ae12e71]{cursor:pointer}.waveform-legend__panel--interactive .waveform-legend__item[data-v-2ae12e71]:focus-visible{outline-offset:2px;outline:2px solid #1677ff}.waveform-legend__item.is-hidden[data-v-2ae12e71]{opacity:.45}.waveform-legend__item.is-hidden .waveform-legend__label[data-v-2ae12e71]{text-decoration:line-through}.waveform-legend__swatch[data-v-2ae12e71]{stroke-linecap:round;stroke-linejoin:round;flex:0 0 26px;width:26px;height:16px;overflow:visible}.waveform-legend__label[data-v-2ae12e71]{text-overflow:ellipsis;min-width:0;overflow:hidden}.waveform-track__crosshair[data-v-a6f82099]{pointer-events:none}.waveform-track__crosshair line[data-v-a6f82099]{stroke:#57617b;stroke-width:1px;stroke-dasharray:4 3}.waveform-chart{box-sizing:border-box;color:#475467;background:#fff;border:1px solid #00000014;border-radius:6px;min-width:0;min-height:180px;position:relative;overflow:hidden}.waveform-chart--clean{border-color:#0000}.waveform-chart__pagination{z-index:2;position:absolute;bottom:6px;right:10px}.waveform-chart__title-area{background:#fff;align-items:center;width:100%;min-width:0;padding:0 24px;display:flex;position:relative;overflow:hidden}.waveform-chart__title-measure{visibility:hidden;pointer-events:none;display:block;position:absolute}.waveform-chart__title-visual{flex:none;min-width:0;position:relative;overflow:visible}.waveform-chart__title-text{transform-origin:50%;line-height:1.2;display:block;position:absolute;top:50%;left:50%;overflow:visible}.waveform-chart__pagination .ant-pagination-item,.waveform-chart__pagination .ant-pagination-prev .ant-pagination-item-link,.waveform-chart__pagination .ant-pagination-next .ant-pagination-item-link{background:#fff;border-color:#d9d9d9}.waveform-chart__pagination .ant-pagination-item-active{border-color:#1677ff}.waveform-chart__grid-slot-placeholder{fill:#fafbfc;stroke:#e4e7ec;stroke-dasharray:4 4;pointer-events:none}.waveform-chart__svg{max-width:100%;display:block}.waveform-chart__overlay{fill:#0000;cursor:crosshair;touch-action:none}.waveform-chart__overlay.is-zoomable{cursor:crosshair}.waveform-chart--panning .waveform-chart__overlay.is-zoomable{cursor:grabbing}.waveform-chart__zoom-selection{fill:#1677ff24;stroke:#1677ff;stroke-width:1px;pointer-events:none}.waveform-chart__overlay.is-annotating{cursor:crosshair}.waveform-chart--presentation .waveform-chart__overlay{cursor:default;pointer-events:none}.waveform-chart__label,.waveform-chart__empty{fill:#595959;font-size:12px}
|
|
1
|
+
.waveform-annotation-layer[data-v-7254383e]{pointer-events:none}.waveform-annotation-layer--interactive .waveform-annotation[data-v-7254383e]{pointer-events:auto;cursor:grab;touch-action:none}.waveform-annotation-layer--interactive .waveform-annotation[data-v-7254383e]:active{cursor:grabbing}.waveform-annotation__arrow[data-v-7254383e]{stroke-width:2px;stroke-linecap:round;pointer-events:none}.waveform-annotation__box[data-v-7254383e]{stroke-width:1px;rx:3}.waveform-annotation-layer--interactive .waveform-annotation__box[data-v-7254383e]{pointer-events:auto}.waveform-annotation__text[data-v-7254383e]{pointer-events:none;-webkit-user-select:none;user-select:none}.waveform-annotation-context-menu[data-v-c70c98a1]{z-index:30;background:#fff;border:1px solid #dfe5ef;border-radius:4px;min-width:112px;padding:4px;display:grid;position:absolute;box-shadow:0 4px 14px #10182829}.waveform-annotation-context-menu button[data-v-c70c98a1]{color:#344054;text-align:left;white-space:nowrap;cursor:pointer;background:0 0;border:0;border-radius:3px;padding:7px 10px;font-size:12px}.waveform-annotation-context-menu button[data-v-c70c98a1]:hover{background:#f2f4f7}.waveform-annotation-editor[data-v-52818b45]{z-index:40;background:#10182852;place-items:center;padding:20px;animation:.16s ease-out waveform-annotation-editor-fade-in-52818b45;display:grid;position:absolute;inset:0}.waveform-annotation-editor__panel[data-v-52818b45]{color:#344054;background:#fff;border:1px solid #e4e7ec;border-radius:12px;gap:20px;width:min(440px,100%);max-height:100%;padding:22px;font-size:13px;animation:.18s ease-out waveform-annotation-editor-rise-in-52818b45;display:grid;overflow-y:auto;box-shadow:0 20px 50px #10182838}.waveform-annotation-editor__header[data-v-52818b45]{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.waveform-annotation-editor__header h2[data-v-52818b45]{color:#101828;margin:0;font-size:18px;line-height:1.3}.waveform-annotation-editor__header p[data-v-52818b45]{color:#667085;margin:5px 0 0;font-size:12px}.waveform-annotation-editor__close[data-v-52818b45]{color:#667085;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:0 0 30px;place-items:center;width:30px;height:30px;padding:0;font-size:22px;line-height:1;display:inline-grid}.waveform-annotation-editor__close[data-v-52818b45]:hover{color:#101828;background:#f2f4f7}.waveform-annotation-editor__coordinates[data-v-52818b45]{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.waveform-annotation-editor__coordinates span[data-v-52818b45],.waveform-annotation-editor__series[data-v-52818b45]{background:#f8fafc;border:1px solid #eaecf0;border-radius:7px;align-items:center;gap:8px;min-width:0;padding:9px 10px;display:flex}.waveform-annotation-editor__coordinates span[data-v-52818b45]{color:#667085}.waveform-annotation-editor__coordinates b[data-v-52818b45]{color:#1677ff;font-size:11px}.waveform-annotation-editor__coordinates code[data-v-52818b45]{color:#344054;text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:SFMono-Regular,Consolas,monospace;font-size:11px;overflow:hidden}.waveform-annotation-editor__series[data-v-52818b45]{gap:10px}.waveform-annotation-editor__series i[data-v-52818b45]{border:1px solid #0000001f;border-radius:2px;flex:0 0 12px;width:12px;height:12px}.waveform-annotation-editor__series-label[data-v-52818b45]{gap:1px;min-width:0;display:grid}.waveform-annotation-editor__series select[data-v-52818b45]{color:#344054;min-width:0;max-width:190px;font:inherit;background:#fff;border:1px solid #d0d5dd;border-radius:5px;margin-left:auto;padding:5px 7px}.waveform-annotation-editor__series small[data-v-52818b45]{color:#667085;font-size:10px}.waveform-annotation-editor__series b[data-v-52818b45]{color:#344054;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.waveform-annotation-editor__series code[data-v-52818b45]{color:#667085;margin-left:auto;font-size:11px}.waveform-annotation-editor__field[data-v-52818b45],.waveform-annotation-editor__color-field[data-v-52818b45]{gap:4px;display:grid}.waveform-annotation-editor__label-row[data-v-52818b45]{justify-content:space-between;align-items:center;gap:8px;display:flex}.waveform-annotation-editor__label-row b[data-v-52818b45],.waveform-annotation-editor__colors legend[data-v-52818b45]{color:#344054;font-size:12px;font-weight:600}.waveform-annotation-editor__label-row small[data-v-52818b45]{color:#98a2b3;font-size:11px}.waveform-annotation-editor textarea[data-v-52818b45]{box-sizing:border-box;color:#1d2939;width:100%;min-height:92px;font:inherit;resize:vertical;background:#fff;border:1px solid #d0d5dd;border-radius:7px;padding:10px 11px;line-height:1.5}.waveform-annotation-editor textarea[data-v-52818b45]:focus{border-color:#1677ff;outline:3px solid #1677ff24}.waveform-annotation-editor__colors[data-v-52818b45]{border:0;border-top:1px solid #eaecf0;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;min-width:0;margin:0;padding:14px 0 0;display:grid}.waveform-annotation-editor__colors legend[data-v-52818b45]{grid-column:1/-1;padding:0}.waveform-annotation-editor__color-field[data-v-52818b45]{color:#667085;text-align:left;place-items:stretch stretch;min-width:0;font-size:11px}.waveform-annotation-editor__color-field[data-v-52818b45] .vc-color-wrap{border:1px solid #cfd5df;border-radius:6px;width:100%;height:34px;margin-right:0;box-shadow:inset 0 0 0 1px #ffffff61}.waveform-annotation-editor__color-field[data-v-52818b45] .vc-color-wrap:hover{border-color:#98a2b3;box-shadow:0 0 0 3px #1677ff1f}.waveform-annotation-editor__actions[data-v-52818b45]{border-top:1px solid #eaecf0;justify-content:flex-end;gap:8px;padding-top:8px;display:flex}.waveform-annotation-editor__actions button[data-v-52818b45]{color:#475467;cursor:pointer;background:#fff;border:1px solid #d0d5dd;border-radius:6px;height:34px;padding:0 12px}.waveform-annotation-editor__actions button.is-primary[data-v-52818b45]{color:#fff;background:#1677ff;border-color:#1677ff}.waveform-annotation-editor__actions button[data-v-52818b45]:disabled{opacity:.45;cursor:not-allowed}@keyframes waveform-annotation-editor-fade-in-52818b45{0%{opacity:0}to{opacity:1}}@keyframes waveform-annotation-editor-rise-in-52818b45{0%{opacity:0;transform:translateY(8px)scale(.98)}to{opacity:1;transform:translateY(0)scale(1)}}@media (width<=420px){.waveform-annotation-editor[data-v-52818b45]{padding:12px}.waveform-annotation-editor__panel[data-v-52818b45]{gap:16px;padding:18px}.waveform-annotation-editor__coordinates[data-v-52818b45]{grid-template-columns:1fr}}.waveform-tooltip[data-v-1f55d6c8]{box-sizing:border-box;z-index:2;color:#505050;pointer-events:none;background:#fff;border:1px solid #e3e7eb;border-radius:4px;gap:2px;width:max-content;max-width:min(560px,100% - 16px);padding:9px 12px;font:14px/1.35 Arial,sans-serif;display:grid;position:absolute;box-shadow:0 3px 10px #10182826}.waveform-tooltip__series[data-v-1f55d6c8]{grid-template-columns:8px minmax(0,1fr);align-items:start;gap:6px;display:grid}.waveform-tooltip__series i[data-v-1f55d6c8]{border-radius:50%;flex:none;width:8px;height:8px;margin-top:4px}.waveform-tooltip__series-content[data-v-1f55d6c8]{flex-wrap:nowrap;align-items:baseline;gap:12px;min-width:0;display:flex}.waveform-tooltip__series-label[data-v-1f55d6c8]{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}.waveform-tooltip__value[data-v-1f55d6c8]{white-space:nowrap;flex:none}.waveform-tooltip__series strong[data-v-1f55d6c8]{font-weight:600}.waveform-tooltip__value[data-v-1f55d6c8]{color:#555}.waveform-tooltip__series small[data-v-1f55d6c8]{color:#667085}.waveform-track__line[data-v-42a3fd47]{fill:none;stroke-width:1.5px;stroke-linejoin:round;stroke-linecap:round}.waveform-track__error-bar[data-v-42a3fd47]{fill:none}.waveform-track__point[data-v-42a3fd47],.waveform-track__error-bar[data-v-42a3fd47]{pointer-events:none}.waveform-track{isolation:isolate;pointer-events:none}.waveform-track__y-axis-label-bg{fill:#fff;opacity:.9;pointer-events:none}.waveform-track__y-axis-label{pointer-events:none;font-size:12px;font-weight:500}.waveform-track__grid{pointer-events:none}.waveform-track__grid--major line{stroke:#dfe5ef;stroke-width:1px}.waveform-track__grid--minor line{stroke:#f2f5fa;stroke-width:1px}.waveform-track__plot-frame,.waveform-track__plot-background{pointer-events:none}.waveform-track__watermark{fill:#1677ff1a;pointer-events:none;-webkit-user-select:none;user-select:none;font-family:Consolas,Monaco,Courier New,monospace}.waveform-track__overlay{fill:#0000;cursor:crosshair;pointer-events:all;touch-action:none}.waveform-track__no-visible-series{fill:#8c8c8c;pointer-events:none;font:13px sans-serif}.waveform-track__overlay.is-zoomable{cursor:grab}.waveform-track__overlay.is-zoomable:active{cursor:grabbing}.waveform-track__overlay.is-annotating{cursor:crosshair}.waveform-track__overlay.is-presentation{cursor:default;pointer-events:none}.waveform-track__zero-line{fill:none;pointer-events:none}.waveform-track__axis-endpoint{fill:#667085;pointer-events:none;font-size:11px}.waveform-track__axis-exponent{fill:#666;font-family:sans-serif;font-size:10px}.waveform-track__axis path,.waveform-track__axis line{stroke:#1f2937}.waveform-track__axis text{fill:#667085;font-size:11px}.waveform-legend[data-v-2ae12e71]{pointer-events:none;overflow:hidden}.waveform-legend__viewport[data-v-2ae12e71]{box-sizing:border-box;width:100%;height:100%;padding:8px;display:flex;overflow:hidden}.waveform-legend__viewport--top-left[data-v-2ae12e71]{justify-content:flex-start;align-items:flex-start}.waveform-legend__viewport--top[data-v-2ae12e71]{justify-content:center;align-items:flex-start}.waveform-legend__viewport--top-right[data-v-2ae12e71]{justify-content:flex-end;align-items:flex-start}.waveform-legend__viewport--right[data-v-2ae12e71]{justify-content:flex-end;align-items:center}.waveform-legend__viewport--bottom-right[data-v-2ae12e71]{justify-content:flex-end;align-items:flex-end}.waveform-legend__viewport--bottom[data-v-2ae12e71]{justify-content:center;align-items:flex-end}.waveform-legend__viewport--bottom-left[data-v-2ae12e71]{justify-content:flex-start;align-items:flex-end}.waveform-legend__viewport--left[data-v-2ae12e71]{justify-content:flex-start;align-items:center}.waveform-legend__panel[data-v-2ae12e71]{color:#344054;border:1px solid #d0d5dde6;border-radius:4px;flex:0 auto;gap:5px 12px;max-width:100%;max-height:100%;padding:5px 7px;font:12px/1.35 sans-serif;display:flex;overflow:hidden}.waveform-legend__panel--interactive[data-v-2ae12e71]{pointer-events:auto}.waveform-legend__panel--horizontal[data-v-2ae12e71]{flex-flow:wrap;align-items:center}.waveform-legend__panel--vertical[data-v-2ae12e71]{flex-flow:column;align-items:stretch}.waveform-legend__item[data-v-2ae12e71]{min-width:0;max-width:160px;color:inherit;font:inherit;text-align:left;white-space:nowrap;appearance:none;background:0 0;border:0;align-items:center;gap:6px;padding:0;display:flex}.waveform-legend__item[data-v-2ae12e71]:disabled{opacity:1}.waveform-legend__panel--interactive .waveform-legend__item[data-v-2ae12e71]{cursor:pointer}.waveform-legend__panel--interactive .waveform-legend__item[data-v-2ae12e71]:focus-visible{outline-offset:2px;outline:2px solid #1677ff}.waveform-legend__item.is-hidden[data-v-2ae12e71]{opacity:.45}.waveform-legend__item.is-hidden .waveform-legend__label[data-v-2ae12e71]{text-decoration:line-through}.waveform-legend__swatch[data-v-2ae12e71]{stroke-linecap:round;stroke-linejoin:round;flex:0 0 26px;width:26px;height:16px;overflow:visible}.waveform-legend__label[data-v-2ae12e71]{text-overflow:ellipsis;min-width:0;overflow:hidden}.waveform-track__crosshair[data-v-a6f82099]{pointer-events:none}.waveform-track__crosshair line[data-v-a6f82099]{stroke:#57617b;stroke-width:1px;stroke-dasharray:4 3}.waveform-chart{box-sizing:border-box;color:#475467;background:#fff;border:1px solid #00000014;border-radius:6px;min-width:0;min-height:180px;position:relative;overflow:hidden}.waveform-chart--clean{border-color:#0000}.waveform-chart__pagination{z-index:2;position:absolute;bottom:6px;right:10px}.waveform-chart__title-area{background:#fff;align-items:center;width:100%;min-width:0;padding:0 24px;display:flex;position:relative;overflow:hidden}.waveform-chart__title-measure{visibility:hidden;pointer-events:none;display:block;position:absolute}.waveform-chart__title-visual{flex:none;min-width:0;position:relative;overflow:visible}.waveform-chart__title-text{transform-origin:50%;line-height:1.2;display:block;position:absolute;top:50%;left:50%;overflow:visible}.waveform-chart__pagination .ant-pagination-item,.waveform-chart__pagination .ant-pagination-prev .ant-pagination-item-link,.waveform-chart__pagination .ant-pagination-next .ant-pagination-item-link{background:#fff;border-color:#d9d9d9}.waveform-chart__pagination .ant-pagination-item-active{border-color:#1677ff}.waveform-chart__grid-slot-placeholder{fill:#fafbfc;stroke:#e4e7ec;stroke-dasharray:4 4;pointer-events:none}.waveform-chart__svg{max-width:100%;display:block}.waveform-chart__overlay{fill:#0000;cursor:crosshair;touch-action:none}.waveform-chart__overlay.is-zoomable{cursor:crosshair}.waveform-chart--panning .waveform-chart__overlay.is-zoomable{cursor:grabbing}.waveform-chart__zoom-selection{fill:#1677ff24;stroke:#1677ff;stroke-width:1px;pointer-events:none}.waveform-chart__overlay.is-annotating{cursor:crosshair}.waveform-chart--presentation .waveform-chart__overlay{cursor:default;pointer-events:none}.waveform-chart__label,.waveform-chart__empty{fill:#595959;font-size:12px}
|
|
2
2
|
/*$vite$:1*/
|
|
@@ -44,6 +44,7 @@ declare const __VLS_export: import("vue").DefineComponent<WaveformChartProps, {
|
|
|
44
44
|
zoomable: boolean;
|
|
45
45
|
pannable: boolean;
|
|
46
46
|
minVisiblePoints: number;
|
|
47
|
+
xDomainStrategy: import("..").WaveformXDomainStrategy;
|
|
47
48
|
timeUnit: "s" | "ms";
|
|
48
49
|
annotationsVisible: boolean;
|
|
49
50
|
grid: import("..").WaveformGridOptions;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ZoomTransform } from 'd3';
|
|
2
2
|
import { type ResolvedWaveformRenderingOptions } from '../../core/rendering';
|
|
3
|
-
import type { WaveformDisplayMode, WaveformOverlayMode, WaveformXAxisLabelFormatter } from '../../types';
|
|
3
|
+
import type { WaveformDisplayMode, WaveformOverlayMode, WaveformXDomainStrategy, WaveformXAxisLabelFormatter } from '../../types';
|
|
4
4
|
import { type GridCellGeometry, type NormalizedWaveformGridOptions } from './grid';
|
|
5
5
|
import type { DisplayTrack, TrackLayout } from './types';
|
|
6
6
|
interface SeriesGridCell extends GridCellGeometry {
|
|
@@ -15,6 +15,7 @@ export interface BuildTrackLayoutsOptions {
|
|
|
15
15
|
sharedZoomDomain: [number, number];
|
|
16
16
|
initialXDomain?: [number, number];
|
|
17
17
|
initialXDomains?: Record<string, [number, number]>;
|
|
18
|
+
xDomainStrategy?: WaveformXDomainStrategy;
|
|
18
19
|
fixedYDomain?: [number, number];
|
|
19
20
|
fixedYDomains?: Record<string, [number, number]>;
|
|
20
21
|
yDomains?: Record<string, [number, number]>;
|
|
@@ -6,6 +6,7 @@ import type { NormalizedWaveformGridLineOptions } from './grid';
|
|
|
6
6
|
*/
|
|
7
7
|
export interface DisplaySeries {
|
|
8
8
|
id: string;
|
|
9
|
+
shotNo?: string;
|
|
9
10
|
trackId?: string;
|
|
10
11
|
name: string;
|
|
11
12
|
unit?: string;
|
|
@@ -52,6 +53,7 @@ export interface WaveformYAxisLayout {
|
|
|
52
53
|
*/
|
|
53
54
|
export interface HoveredSeriesPoint {
|
|
54
55
|
id: string;
|
|
56
|
+
shotNo?: string;
|
|
55
57
|
name: string;
|
|
56
58
|
unit?: string;
|
|
57
59
|
color: string;
|
|
@@ -330,6 +330,7 @@ export declare function useWaveformChartController(props: ResolvedWaveformChartP
|
|
|
330
330
|
minZoomSpan?: number | undefined;
|
|
331
331
|
minVisiblePoints: number;
|
|
332
332
|
initialXDomains?: Record<string, [number, number]> | undefined;
|
|
333
|
+
xDomainStrategy: import("../..").WaveformXDomainStrategy;
|
|
333
334
|
yDomain?: [number, number] | undefined;
|
|
334
335
|
yDomains?: Record<string, [number, number]> | undefined;
|
|
335
336
|
timeUnit: "s" | "ms";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WaveformAnnotation, WaveformAxesOptions, WaveformData, WaveformDisplayMode, WaveformFrameStyle, WaveformInteractionMode, WaveformLegendOptions, WaveformOverlayMode, WaveformPlotMargin, WaveformPoint, WaveformRenderingOptions, WaveformTitleOptions, WaveformZeroLineOptions, WaveformZoomEndPayload, WaveformZoomResetPayload } from '../data/types';
|
|
1
|
+
import type { WaveformAnnotation, WaveformAxesOptions, WaveformData, WaveformDisplayMode, WaveformFrameStyle, WaveformInteractionMode, WaveformLegendOptions, WaveformOverlayMode, WaveformPlotMargin, WaveformPoint, WaveformRenderingOptions, WaveformTitleOptions, WaveformXDomainStrategy, WaveformZeroLineOptions, WaveformZoomEndPayload, WaveformZoomResetPayload } from '../data/types';
|
|
2
2
|
import type { WaveformGridOptions } from './grid';
|
|
3
3
|
export interface WaveformChartProps {
|
|
4
4
|
data: WaveformData;
|
|
@@ -16,6 +16,7 @@ export interface WaveformChartProps {
|
|
|
16
16
|
minVisiblePoints?: number;
|
|
17
17
|
initialXDomain?: [number, number];
|
|
18
18
|
initialXDomains?: Record<string, [number, number]>;
|
|
19
|
+
xDomainStrategy?: WaveformXDomainStrategy;
|
|
19
20
|
yDomain?: [number, number];
|
|
20
21
|
yDomains?: Record<string, [number, number]>;
|
|
21
22
|
timeUnit?: 's' | 'ms';
|
|
@@ -36,7 +37,7 @@ export interface WaveformChartProps {
|
|
|
36
37
|
presentationMode?: boolean;
|
|
37
38
|
zeroLine?: WaveformZeroLineOptions;
|
|
38
39
|
}
|
|
39
|
-
type DefaultedProp = 'displayMode' | 'overlayMode' | 'yLabel' | 'lineColor' | 'showTooltip' | 'zoomable' | 'pannable' | 'minVisiblePoints' | 'timeUnit' | 'annotations' | 'annotationsVisible' | 'grid' | 'rendering' | 'plotMargin' | 'legend' | 'defaultHiddenSeriesIds' | 'cleanView' | 'presentationMode' | 'zeroLine';
|
|
40
|
+
type DefaultedProp = 'displayMode' | 'overlayMode' | 'yLabel' | 'lineColor' | 'showTooltip' | 'zoomable' | 'pannable' | 'minVisiblePoints' | 'xDomainStrategy' | 'timeUnit' | 'annotations' | 'annotationsVisible' | 'grid' | 'rendering' | 'plotMargin' | 'legend' | 'defaultHiddenSeriesIds' | 'cleanView' | 'presentationMode' | 'zeroLine';
|
|
40
41
|
export type ResolvedWaveformChartProps = Readonly<WaveformChartProps & Required<Pick<WaveformChartProps, DefaultedProp>>>;
|
|
41
42
|
export interface WaveformChartEmit {
|
|
42
43
|
(event: 'point-hover', point: WaveformPoint | null): void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { WaveformXDomainStrategy } from '../../types';
|
|
2
|
+
/** Derives a viewport domain without changing any source coordinates. */
|
|
3
|
+
export declare function applyXDomainStrategy(domain: [number, number], strategy: WaveformXDomainStrategy, explicit?: boolean): [number, number];
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* 数据系统类型定义
|
|
3
3
|
* 重新导出 src/types 中的类型,方便组件内部使用
|
|
4
4
|
*/
|
|
5
|
-
export type { WaveformPoint, WaveformDisplayMode, WaveformOverlayMode, WaveformInteractionMode, WaveformZoomEndPayload, WaveformZoomResetPayload, WaveformAnnotationStyle, WaveformAnnotation, WaveformRenderingOptions, WaveformPlotMargin, WaveformTitleTextStyle, WaveformTitleOptions, WaveformLegendPosition, WaveformLegendOrientation, WaveformLegendOptions, WaveformFrameStyle, WaveformAxesOptions, WaveformZeroLineOptions, SingleWaveformData, WaveformLineType, WaveformLineStyle, WaveformPointType, WaveformErrorBarOptions, ResolvedWaveformErrorBarOptions, WaveformSeries, WaveformData, NormalizedWaveformSeries, } from '../../types';
|
|
5
|
+
export type { WaveformPoint, WaveformDisplayMode, WaveformOverlayMode, WaveformInteractionMode, WaveformXDomainStrategy, WaveformZoomEndPayload, WaveformZoomResetPayload, WaveformAnnotationStyle, WaveformAnnotation, WaveformRenderingOptions, WaveformPlotMargin, WaveformTitleTextStyle, WaveformTitleOptions, WaveformLegendPosition, WaveformLegendOrientation, WaveformLegendOptions, WaveformFrameStyle, WaveformAxesOptions, WaveformZeroLineOptions, SingleWaveformData, WaveformLineType, WaveformLineStyle, WaveformPointType, WaveformErrorBarOptions, ResolvedWaveformErrorBarOptions, WaveformSeries, WaveformData, NormalizedWaveformSeries, } from '../../types';
|
|
6
6
|
export type { WaveformGridOptions, WaveformGridLineOptions, WaveformGridTrackLines, } from '../core/grid';
|
|
7
7
|
export { normalizeWaveformData, normalizeWaveformSeries } from '../../core';
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* 向后兼容的导出文件
|
|
3
3
|
* 保留原有导入路径,内部从新的模块结构导出
|
|
4
4
|
*/
|
|
5
|
-
export type { WaveformPoint, WaveformDisplayMode, WaveformOverlayMode, WaveformInteractionMode, WaveformAnnotationStyle, WaveformAnnotation, WaveformRenderingOptions, WaveformPlotMargin, WaveformTitleTextStyle, WaveformTitleOptions, WaveformFrameStyle, SingleWaveformData, WaveformSeries, WaveformLineStyle, WaveformData, NormalizedWaveformSeries, } from '../types';
|
|
5
|
+
export type { WaveformPoint, WaveformDisplayMode, WaveformOverlayMode, WaveformInteractionMode, WaveformXDomainStrategy, WaveformAnnotationStyle, WaveformAnnotation, WaveformRenderingOptions, WaveformPlotMargin, WaveformTitleTextStyle, WaveformTitleOptions, WaveformFrameStyle, SingleWaveformData, WaveformSeries, WaveformLineStyle, WaveformData, NormalizedWaveformSeries, } from '../types';
|
|
6
6
|
export { normalizeWaveformData, normalizeWaveformSeries } from '../core';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
export { default as WaveformChart } from './components/WaveformChart.vue';
|
|
6
|
-
export type { WaveformPoint, WaveformDisplayMode, WaveformOverlayMode, WaveformInteractionMode, WaveformZoomEndPayload, WaveformZoomResetPayload, WaveformAnnotationStyle, WaveformAnnotation, WaveformRenderingOptions, WaveformPlotMargin, WaveformTitleTextStyle, WaveformTitleOptions, WaveformLegendPosition, WaveformLegendOrientation, WaveformLegendOptions, WaveformFrameStyle, WaveformXAxisLabelKind, WaveformXAxisLabelFormatterContext, WaveformXAxisLabelFormatter, WaveformAxesOptions, WaveformZeroLineOptions, SingleWaveformData, WaveformLineType, WaveformLineStyle, WaveformPointType, WaveformErrorBarOptions, ResolvedWaveformErrorBarOptions, WaveformSeries, WaveformData, NormalizedWaveformSeries, } from './types';
|
|
6
|
+
export type { WaveformPoint, WaveformDisplayMode, WaveformOverlayMode, WaveformInteractionMode, WaveformXDomainStrategy, WaveformZoomEndPayload, WaveformZoomResetPayload, WaveformAnnotationStyle, WaveformAnnotation, WaveformRenderingOptions, WaveformPlotMargin, WaveformTitleTextStyle, WaveformTitleOptions, WaveformLegendPosition, WaveformLegendOrientation, WaveformLegendOptions, WaveformFrameStyle, WaveformXAxisLabelKind, WaveformXAxisLabelFormatterContext, WaveformXAxisLabelFormatter, WaveformAxesOptions, WaveformZeroLineOptions, SingleWaveformData, WaveformLineType, WaveformLineStyle, WaveformPointType, WaveformErrorBarOptions, ResolvedWaveformErrorBarOptions, WaveformSeries, WaveformData, NormalizedWaveformSeries, } from './types';
|
|
7
7
|
export type { WaveformGridOptions, WaveformGridLineOptions, WaveformGridTrackLines, } from './components/core/grid';
|
|
8
8
|
export { normalizeWaveformData, normalizeWaveformSeries } from './core';
|
|
9
9
|
export { paddedDomain, buildMinorTicks, displayTime, formatEndpointTime, formatAxisTime, formatTooltipTime, resolveTrackGeometry, clamp, type TimeUnit, type TrackGeometry, } from './utils';
|
|
@@ -22,6 +22,16 @@ export type WaveformDisplayMode = 'independent' | 'separated' | 'compact';
|
|
|
22
22
|
export type WaveformOverlayMode = 'single-axis' | 'multi-axis';
|
|
23
23
|
/** 标注工具模式 */
|
|
24
24
|
export type WaveformInteractionMode = 'zoom' | 'annotation';
|
|
25
|
+
/** Controls how the initial X viewport is derived when no explicit domain is configured. */
|
|
26
|
+
export interface WaveformXDomainStrategy {
|
|
27
|
+
type: 'data' | 'nice';
|
|
28
|
+
/** Selects which bounds are expanded when type is `nice`. Defaults to `both`. */
|
|
29
|
+
bounds?: 'both' | 'end';
|
|
30
|
+
/** Stable tick count used to calculate nice bounds. Defaults to 10. */
|
|
31
|
+
tickCount?: number;
|
|
32
|
+
/** Applies the strategy to explicit initial domains. Defaults to false. */
|
|
33
|
+
includeExplicit?: boolean;
|
|
34
|
+
}
|
|
25
35
|
/** Describes the X-axis viewport after a zoom gesture completes. */
|
|
26
36
|
export interface WaveformZoomEndPayload {
|
|
27
37
|
start: number;
|
|
@@ -33,6 +33,8 @@ export type SingleWaveformData = {
|
|
|
33
33
|
*/
|
|
34
34
|
export interface WaveformSeries {
|
|
35
35
|
id?: string;
|
|
36
|
+
/** 炮号,未提供时 Tooltip 显示“未配置炮号”。 */
|
|
37
|
+
shotNo?: string;
|
|
36
38
|
/** 相同 trackId 的系列叠加在同一图框中;默认每个系列独占一个图框。 */
|
|
37
39
|
trackId?: string;
|
|
38
40
|
name: string;
|
|
@@ -56,6 +58,7 @@ export type WaveformData = SingleWaveformData | {
|
|
|
56
58
|
*/
|
|
57
59
|
export interface NormalizedWaveformSeries {
|
|
58
60
|
id: string;
|
|
61
|
+
shotNo?: string;
|
|
59
62
|
trackId?: string;
|
|
60
63
|
name: string;
|
|
61
64
|
unit?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 类型定义统一导出
|
|
3
3
|
*/
|
|
4
|
-
export type { WaveformPoint, WaveformDisplayMode, WaveformOverlayMode, WaveformInteractionMode, WaveformZoomEndPayload, WaveformZoomResetPayload, WaveformAnnotationStyle, WaveformAnnotation, WaveformRenderingOptions, WaveformPlotMargin, WaveformTitleTextStyle, WaveformTitleOptions, WaveformLegendPosition, WaveformLegendOrientation, WaveformLegendOptions, WaveformFrameStyle, WaveformXAxisLabelKind, WaveformXAxisLabelFormatterContext, WaveformXAxisLabelFormatter, WaveformAxesOptions, WaveformZeroLineOptions, } from './chart';
|
|
4
|
+
export type { WaveformPoint, WaveformDisplayMode, WaveformOverlayMode, WaveformInteractionMode, WaveformXDomainStrategy, WaveformZoomEndPayload, WaveformZoomResetPayload, WaveformAnnotationStyle, WaveformAnnotation, WaveformRenderingOptions, WaveformPlotMargin, WaveformTitleTextStyle, WaveformTitleOptions, WaveformLegendPosition, WaveformLegendOrientation, WaveformLegendOptions, WaveformFrameStyle, WaveformXAxisLabelKind, WaveformXAxisLabelFormatterContext, WaveformXAxisLabelFormatter, WaveformAxesOptions, WaveformZeroLineOptions, } from './chart';
|
|
5
5
|
export type { SingleWaveformData, WaveformLineType, WaveformLineStyle, WaveformPointType, WaveformErrorBarOptions, ResolvedWaveformErrorBarOptions, WaveformSeries, WaveformData, NormalizedWaveformSeries, } from './data';
|
package/package.json
CHANGED
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
WaveformDisplayMode,
|
|
17
17
|
WaveformOverlayMode,
|
|
18
18
|
WaveformPoint,
|
|
19
|
+
WaveformXDomainStrategy,
|
|
19
20
|
WaveformXAxisLabelFormatter,
|
|
20
21
|
} from '../../types'
|
|
21
22
|
import { buildMinorTicks, formatXAxisLabel } from '../../utils'
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
} from './grid'
|
|
27
28
|
import { axisTextMetrics, resolveYAxisSeriesGroups } from './layout'
|
|
28
29
|
import type { DisplaySeries, DisplayTrack, TrackLayout, WaveformYAxisLayout } from './types'
|
|
30
|
+
import { applyXDomainStrategy } from './xDomain'
|
|
29
31
|
import {
|
|
30
32
|
Y_AXIS_LABEL_BAND_WIDTH,
|
|
31
33
|
Y_AXIS_LABEL_GAP,
|
|
@@ -46,6 +48,7 @@ export interface BuildTrackLayoutsOptions {
|
|
|
46
48
|
sharedZoomDomain: [number, number]
|
|
47
49
|
initialXDomain?: [number, number]
|
|
48
50
|
initialXDomains?: Record<string, [number, number]>
|
|
51
|
+
xDomainStrategy?: WaveformXDomainStrategy
|
|
49
52
|
fixedYDomain?: [number, number]
|
|
50
53
|
fixedYDomains?: Record<string, [number, number]>
|
|
51
54
|
yDomains?: Record<string, [number, number]>
|
|
@@ -57,6 +60,21 @@ export interface BuildTrackLayoutsOptions {
|
|
|
57
60
|
showCompactEmptyTracks: boolean
|
|
58
61
|
}
|
|
59
62
|
|
|
63
|
+
function resolveIndependentXDomain(
|
|
64
|
+
track: DisplayTrack,
|
|
65
|
+
seriesId: string,
|
|
66
|
+
options: BuildTrackLayoutsOptions,
|
|
67
|
+
): [number, number] {
|
|
68
|
+
const strategy = options.xDomainStrategy ?? { type: 'data' }
|
|
69
|
+
const explicitDomain =
|
|
70
|
+
options.initialXDomains?.[track.id] ??
|
|
71
|
+
options.initialXDomains?.[seriesId] ??
|
|
72
|
+
options.initialXDomain
|
|
73
|
+
return explicitDomain
|
|
74
|
+
? applyXDomainStrategy(explicitDomain, strategy, true)
|
|
75
|
+
: applyXDomainStrategy(track.xDomain, strategy)
|
|
76
|
+
}
|
|
77
|
+
|
|
60
78
|
export function buildTrackLayouts(options: BuildTrackLayoutsOptions): TrackLayout[] {
|
|
61
79
|
const visibleCells = options.cells.map((cell) => ({ ...cell, hasSeries: Boolean(cell.series) }))
|
|
62
80
|
const bottomCells = getBottomRowCellIndexes(visibleCells, options.grid.columnCount)
|
|
@@ -88,13 +106,7 @@ export function buildTrackLayouts(options: BuildTrackLayoutsOptions): TrackLayou
|
|
|
88
106
|
const series = displayTrack.visibleSeries[0] ?? displayTrack.series[0] ?? emptySeries
|
|
89
107
|
const baseXScale =
|
|
90
108
|
options.displayMode === 'independent'
|
|
91
|
-
? scaleLinear(
|
|
92
|
-
options.initialXDomains?.[displayTrack.id] ??
|
|
93
|
-
options.initialXDomains?.[series.id] ??
|
|
94
|
-
options.initialXDomain ??
|
|
95
|
-
displayTrack.xDomain,
|
|
96
|
-
[0, cell.width],
|
|
97
|
-
)
|
|
109
|
+
? scaleLinear(resolveIndependentXDomain(displayTrack, series.id, options), [0, cell.width])
|
|
98
110
|
: scaleLinear(options.sharedZoomDomain, [0, cell.width])
|
|
99
111
|
const transform =
|
|
100
112
|
options.displayMode === 'independent'
|
|
@@ -13,6 +13,7 @@ import type { NormalizedWaveformGridLineOptions } from './grid'
|
|
|
13
13
|
*/
|
|
14
14
|
export interface DisplaySeries {
|
|
15
15
|
id: string
|
|
16
|
+
shotNo?: string
|
|
16
17
|
trackId?: string
|
|
17
18
|
name: string
|
|
18
19
|
unit?: string
|
|
@@ -63,6 +64,7 @@ export interface WaveformYAxisLayout {
|
|
|
63
64
|
*/
|
|
64
65
|
export interface HoveredSeriesPoint {
|
|
65
66
|
id: string
|
|
67
|
+
shotNo?: string
|
|
66
68
|
name: string
|
|
67
69
|
unit?: string
|
|
68
70
|
color: string
|
|
@@ -204,6 +204,7 @@ export function useWaveformChartLifecycle(context: LifecycleContext) {
|
|
|
204
204
|
() => props.minVisiblePoints,
|
|
205
205
|
() => props.initialXDomain,
|
|
206
206
|
() => props.initialXDomains,
|
|
207
|
+
() => props.xDomainStrategy,
|
|
207
208
|
() => props.displayMode,
|
|
208
209
|
() => chartTracks.value.length,
|
|
209
210
|
currentPage,
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
import type { DisplaySeries, DisplayTrack, TrackLayout } from './types'
|
|
35
35
|
import type { PreparedWaveformSeries } from './useWaveformData'
|
|
36
36
|
import type { ResolvedWaveformChartProps } from './waveformChartTypes'
|
|
37
|
+
import { applyXDomainStrategy } from './xDomain'
|
|
37
38
|
import type { useWaveformAnnotationInteraction } from '../annotation'
|
|
38
39
|
|
|
39
40
|
interface LayoutContext {
|
|
@@ -224,9 +225,13 @@ export function useWaveformLayout(context: LayoutContext) {
|
|
|
224
225
|
Number.isFinite(domain[1]) &&
|
|
225
226
|
domain[0] !== domain[1]
|
|
226
227
|
) {
|
|
227
|
-
return
|
|
228
|
+
return applyXDomainStrategy(
|
|
229
|
+
domain[0] < domain[1] ? domain : [domain[1], domain[0]],
|
|
230
|
+
props.xDomainStrategy,
|
|
231
|
+
true,
|
|
232
|
+
)
|
|
228
233
|
}
|
|
229
|
-
return sharedXDomain.value
|
|
234
|
+
return applyXDomainStrategy(sharedXDomain.value, props.xDomainStrategy)
|
|
230
235
|
})
|
|
231
236
|
const resolveInitialTrackDomain = (track: TrackLayout): [number, number] => {
|
|
232
237
|
const configuredDomain =
|
|
@@ -239,11 +244,18 @@ export function useWaveformLayout(context: LayoutContext) {
|
|
|
239
244
|
Number.isFinite(configuredDomain[1]) &&
|
|
240
245
|
configuredDomain[0] !== configuredDomain[1]
|
|
241
246
|
) {
|
|
242
|
-
return
|
|
243
|
-
|
|
244
|
-
|
|
247
|
+
return applyXDomainStrategy(
|
|
248
|
+
configuredDomain[0] < configuredDomain[1]
|
|
249
|
+
? configuredDomain
|
|
250
|
+
: [configuredDomain[1], configuredDomain[0]],
|
|
251
|
+
props.xDomainStrategy,
|
|
252
|
+
true,
|
|
253
|
+
)
|
|
245
254
|
}
|
|
246
|
-
return
|
|
255
|
+
return applyXDomainStrategy(
|
|
256
|
+
paddedDomain(track.seriesList.flatMap((series) => series.xDomain)),
|
|
257
|
+
props.xDomainStrategy,
|
|
258
|
+
)
|
|
247
259
|
}
|
|
248
260
|
const sharedZoomDomain = computed(
|
|
249
261
|
() =>
|
|
@@ -272,6 +284,7 @@ export function useWaveformLayout(context: LayoutContext) {
|
|
|
272
284
|
sharedZoomDomain: sharedZoomDomain.value,
|
|
273
285
|
initialXDomain: props.initialXDomain ? initialXDomain.value : undefined,
|
|
274
286
|
initialXDomains: props.initialXDomains,
|
|
287
|
+
xDomainStrategy: props.xDomainStrategy,
|
|
275
288
|
fixedYDomain: props.yDomain,
|
|
276
289
|
fixedYDomains: props.yDomains,
|
|
277
290
|
yDomains:
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
WaveformPoint,
|
|
12
12
|
WaveformRenderingOptions,
|
|
13
13
|
WaveformTitleOptions,
|
|
14
|
+
WaveformXDomainStrategy,
|
|
14
15
|
WaveformZeroLineOptions,
|
|
15
16
|
WaveformZoomEndPayload,
|
|
16
17
|
WaveformZoomResetPayload,
|
|
@@ -33,6 +34,7 @@ export interface WaveformChartProps {
|
|
|
33
34
|
minVisiblePoints?: number
|
|
34
35
|
initialXDomain?: [number, number]
|
|
35
36
|
initialXDomains?: Record<string, [number, number]>
|
|
37
|
+
xDomainStrategy?: WaveformXDomainStrategy
|
|
36
38
|
yDomain?: [number, number]
|
|
37
39
|
yDomains?: Record<string, [number, number]>
|
|
38
40
|
timeUnit?: 's' | 'ms'
|
|
@@ -63,6 +65,7 @@ type DefaultedProp =
|
|
|
63
65
|
| 'zoomable'
|
|
64
66
|
| 'pannable'
|
|
65
67
|
| 'minVisiblePoints'
|
|
68
|
+
| 'xDomainStrategy'
|
|
66
69
|
| 'timeUnit'
|
|
67
70
|
| 'annotations'
|
|
68
71
|
| 'annotationsVisible'
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { applyXDomainStrategy } from './xDomain'
|
|
4
|
+
|
|
5
|
+
describe('applyXDomainStrategy', () => {
|
|
6
|
+
it('keeps the exact data domain by default', () => {
|
|
7
|
+
expect(applyXDomainStrategy([0, 4999.999], { type: 'data' })).toEqual([0, 4999.999])
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('expands both bounds to stable nice values', () => {
|
|
11
|
+
expect(applyXDomainStrategy([123, 456], { type: 'nice' })).toEqual([100, 500])
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('can expand only the end bound', () => {
|
|
15
|
+
expect(applyXDomainStrategy([123, 456], { type: 'nice', bounds: 'end' })).toEqual([123, 500])
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('keeps explicit domains exact unless they are included', () => {
|
|
19
|
+
expect(applyXDomainStrategy([123, 456], { type: 'nice' }, true)).toEqual([123, 456])
|
|
20
|
+
expect(applyXDomainStrategy([123, 456], { type: 'nice', includeExplicit: true }, true)).toEqual(
|
|
21
|
+
[100, 500],
|
|
22
|
+
)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('falls back to the default tick count for invalid values', () => {
|
|
26
|
+
expect(applyXDomainStrategy([0, 4999.999], { type: 'nice', tickCount: 0 })).toEqual([0, 5000])
|
|
27
|
+
})
|
|
28
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { scaleLinear } from 'd3'
|
|
2
|
+
|
|
3
|
+
import type { WaveformXDomainStrategy } from '../../types'
|
|
4
|
+
|
|
5
|
+
const DEFAULT_NICE_TICK_COUNT = 10
|
|
6
|
+
|
|
7
|
+
function resolveTickCount(value: number | undefined): number {
|
|
8
|
+
if (!Number.isFinite(value) || (value ?? 0) < 1) return DEFAULT_NICE_TICK_COUNT
|
|
9
|
+
return Math.max(1, Math.trunc(value as number))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Derives a viewport domain without changing any source coordinates. */
|
|
13
|
+
export function applyXDomainStrategy(
|
|
14
|
+
domain: [number, number],
|
|
15
|
+
strategy: WaveformXDomainStrategy,
|
|
16
|
+
explicit = false,
|
|
17
|
+
): [number, number] {
|
|
18
|
+
if (strategy.type !== 'nice' || (explicit && !strategy.includeExplicit)) return [...domain]
|
|
19
|
+
|
|
20
|
+
const niceDomain = scaleLinear()
|
|
21
|
+
.domain(domain)
|
|
22
|
+
.nice(resolveTickCount(strategy.tickCount))
|
|
23
|
+
.domain() as [number, number]
|
|
24
|
+
return strategy.bounds === 'end' ? [domain[0], niceDomain[1]] : niceDomain
|
|
25
|
+
}
|
|
@@ -80,7 +80,7 @@ describe('WaveformTooltip', () => {
|
|
|
80
80
|
expect(tooltip.attributes('style')).toContain('max-width: 280px')
|
|
81
81
|
})
|
|
82
82
|
|
|
83
|
-
it('
|
|
83
|
+
it('omits units and errors from the strict x/y value format', () => {
|
|
84
84
|
const pointWithErrors = { x: 1, y: 12, error: 1, upperError: 2 }
|
|
85
85
|
const wrapper = mount(WaveformTooltip, {
|
|
86
86
|
props: {
|
|
@@ -102,10 +102,12 @@ describe('WaveformTooltip', () => {
|
|
|
102
102
|
},
|
|
103
103
|
})
|
|
104
104
|
|
|
105
|
-
expect(wrapper.get('.waveform-
|
|
105
|
+
expect(wrapper.get('.waveform-tooltip__value').text()).toBe('(x:1 y:12)')
|
|
106
|
+
expect(wrapper.get('.waveform-tooltip__value').text()).not.toContain('C')
|
|
107
|
+
expect(wrapper.get('.waveform-tooltip__value').text()).not.toContain('+2')
|
|
106
108
|
})
|
|
107
109
|
|
|
108
|
-
it('
|
|
110
|
+
it('renders the configured shot number, channel, and formatted coordinates', () => {
|
|
109
111
|
const hoveredPoint = { x: 1, y: -1405.4932 }
|
|
110
112
|
const wrapper = mount(WaveformTooltip, {
|
|
111
113
|
props: {
|
|
@@ -117,6 +119,7 @@ describe('WaveformTooltip', () => {
|
|
|
117
119
|
{
|
|
118
120
|
trackIndex: 0,
|
|
119
121
|
name: 'ENG8KJXAc(10001)',
|
|
122
|
+
shotNo: '炮 7',
|
|
120
123
|
color: '#ffb43b',
|
|
121
124
|
unit: 'A',
|
|
122
125
|
point: hoveredPoint,
|
|
@@ -127,26 +130,31 @@ describe('WaveformTooltip', () => {
|
|
|
127
130
|
},
|
|
128
131
|
})
|
|
129
132
|
|
|
130
|
-
expect(wrapper.get('.waveform-
|
|
133
|
+
expect(wrapper.get('.waveform-tooltip__series-label').text()).toBe('炮 7: ENG8KJXAc(10001)(A)')
|
|
134
|
+
expect(wrapper.get('.waveform-tooltip__value').text()).toBe('(x:1,000 y:-1,405.4932)')
|
|
131
135
|
})
|
|
132
136
|
|
|
133
|
-
it('
|
|
137
|
+
it('renders each series row with the formatted x coordinate and series label', () => {
|
|
134
138
|
const wrapper = mount(WaveformTooltip, {
|
|
135
139
|
props: {
|
|
136
140
|
visible: true,
|
|
137
141
|
position: { x: 10, y: 10 },
|
|
138
142
|
timeUnit: 's',
|
|
139
143
|
hoveredPoint: { x: 1.234567, y: 12 },
|
|
140
|
-
seriesPoints: [
|
|
144
|
+
seriesPoints: [
|
|
145
|
+
{ trackIndex: 0, name: '温度', color: '#f00', point: { x: 1.234567, y: 12 } },
|
|
146
|
+
],
|
|
141
147
|
containerWidth: 400,
|
|
142
148
|
containerHeight: 300,
|
|
143
149
|
},
|
|
144
150
|
})
|
|
145
151
|
|
|
146
|
-
expect(wrapper.
|
|
152
|
+
expect(wrapper.find('.waveform-tooltip__time').exists()).toBe(false)
|
|
153
|
+
expect(wrapper.get('.waveform-tooltip__series-label').text()).toBe('未配置炮号: 温度')
|
|
154
|
+
expect(wrapper.get('.waveform-tooltip__value').text()).toBe('(x:1.2346 y:12)')
|
|
147
155
|
})
|
|
148
156
|
|
|
149
|
-
it('
|
|
157
|
+
it('uses the fallback shot number when shotNo is blank', () => {
|
|
150
158
|
const point = { x: 1, y: 12 }
|
|
151
159
|
const wrapper = mount(WaveformTooltip, {
|
|
152
160
|
props: {
|
|
@@ -160,6 +168,6 @@ describe('WaveformTooltip', () => {
|
|
|
160
168
|
},
|
|
161
169
|
})
|
|
162
170
|
|
|
163
|
-
expect(wrapper.
|
|
171
|
+
expect(wrapper.get('.waveform-tooltip__series-label').text()).toBe('未配置炮号: 温度')
|
|
164
172
|
})
|
|
165
173
|
})
|