This commit is contained in:
@@ -188,6 +188,38 @@ describe('WaveformChart', () => {
|
||||
})),
|
||||
})
|
||||
|
||||
it('keeps clip path ids unique across chart instances', async () => {
|
||||
const data: WaveformData = {
|
||||
kind: 'series',
|
||||
series: [
|
||||
{
|
||||
id: 'channel-1',
|
||||
name: '通道 1',
|
||||
data: {
|
||||
kind: 'points',
|
||||
points: [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: 1, y: 1 },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
const first = await mountSizedChart(data)
|
||||
const second = await mountSizedChart(data)
|
||||
const firstClipPathId = first.get('clipPath').attributes('id')
|
||||
const secondClipPathId = second.get('clipPath').attributes('id')
|
||||
|
||||
expect(firstClipPathId).toBeTruthy()
|
||||
expect(secondClipPathId).toBeTruthy()
|
||||
expect(firstClipPathId).not.toBe(secondClipPathId)
|
||||
expect(first.get('[clip-path]').attributes('clip-path')).toContain(firstClipPathId)
|
||||
expect(second.get('[clip-path]').attributes('clip-path')).toContain(secondClipPathId)
|
||||
|
||||
first.unmount()
|
||||
second.unmount()
|
||||
})
|
||||
|
||||
it('places start, middle, and end step transitions at the expected X positions', async () => {
|
||||
const lineTypes = ['step-start', 'step-middle', 'step-end', 'step-after'] as const
|
||||
const wrapper = await mountSizedChart({
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
onMounted,
|
||||
ref,
|
||||
shallowRef,
|
||||
useId,
|
||||
watch,
|
||||
type CSSProperties,
|
||||
} from 'vue'
|
||||
@@ -79,6 +78,7 @@ import { buildTrackLayouts, measureTrackYAxisClearance, Y_AXIS_EXPONENT_GAP } fr
|
||||
import { calculateRotatedTitleLayout, TITLE_AREA_HORIZONTAL_PADDING } from './core/title'
|
||||
import { usePreparedWaveformSeries } from './core/useWaveformData'
|
||||
import WaveformAnnotationEditor from './annotation/WaveformAnnotationEditor.vue'
|
||||
import { useWaveformInstanceId } from '../utils/waveformId'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -174,7 +174,7 @@ const suppressHoverUntilMove = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const resizeObserver = shallowRef<ResizeObserver>()
|
||||
const zoomBehaviors = new Map<number | 'shared', ZoomBehavior<SVGRectElement, unknown>>()
|
||||
const clipPathId = `${useId()}-waveform-clip`
|
||||
const clipPathId = useWaveformInstanceId('waveform-clip')
|
||||
const internalInteractionMode = ref<WaveformInteractionMode | undefined>(undefined)
|
||||
const internalHiddenSeriesIds = ref(new Set(props.defaultHiddenSeriesIds))
|
||||
const annotationInteraction = useWaveformAnnotationInteraction()
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineAsyncComponent, nextTick, ref, useId, watch } from 'vue'
|
||||
import { computed, defineAsyncComponent, nextTick, ref, watch } from 'vue'
|
||||
|
||||
import type { WaveformAnnotation } from '../../types'
|
||||
import { formatAnnotationTime, formatPlainNumber, type TimeUnit } from '../../utils'
|
||||
import { ANNOTATION_MAX_TEXT_LENGTH, resolveAnnotationStyle } from './markup'
|
||||
import type { AnnotationSeriesCandidate, AnnotationSeriesInfo } from './types'
|
||||
import { useWaveformInstanceId } from '../../utils/waveformId'
|
||||
|
||||
const ColorPicker = defineAsyncComponent(async () => {
|
||||
await import('vue3-colorpicker/style.css')
|
||||
@@ -29,7 +30,7 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const textarea = ref<HTMLTextAreaElement>()
|
||||
const dialogTitleId = `waveform-annotation-editor-title-${useId()}`
|
||||
const dialogTitleId = useWaveformInstanceId('waveform-annotation-editor-title')
|
||||
const text = ref('')
|
||||
const borderColor = ref('')
|
||||
const textColor = ref('')
|
||||
|
||||
@@ -8,6 +8,30 @@ import WaveformAnnotationLayer from './WaveformAnnotationLayer.vue'
|
||||
import WaveformAnnotationToolbar from './WaveformAnnotationToolbar.vue'
|
||||
|
||||
describe('waveform annotation controls', () => {
|
||||
it('keeps dialog title ids unique across editor instances', () => {
|
||||
const first = mount(WaveformAnnotationEditor, {
|
||||
props: {
|
||||
annotation: { id: 'first', seriesId: 'a', x: 1, y: 2, text: '说明' },
|
||||
mode: 'edit',
|
||||
},
|
||||
})
|
||||
const second = mount(WaveformAnnotationEditor, {
|
||||
props: {
|
||||
annotation: { id: 'second', seriesId: 'a', x: 1, y: 2, text: '说明' },
|
||||
mode: 'edit',
|
||||
},
|
||||
})
|
||||
|
||||
const firstTitleId = first.get('h2').attributes('id')
|
||||
const secondTitleId = second.get('h2').attributes('id')
|
||||
|
||||
expect(firstTitleId).toBeTruthy()
|
||||
expect(secondTitleId).toBeTruthy()
|
||||
expect(firstTitleId).not.toBe(secondTitleId)
|
||||
expect(first.get('[role="dialog"]').attributes('aria-labelledby')).toBe(firstTitleId)
|
||||
expect(second.get('[role="dialog"]').attributes('aria-labelledby')).toBe(secondTitleId)
|
||||
})
|
||||
|
||||
it('allows changing the annotation series inside the editor', async () => {
|
||||
const wrapper = mount(WaveformAnnotationEditor, {
|
||||
props: {
|
||||
|
||||
Reference in New Issue
Block a user