新建监控功能
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
<div class="summary-value">{{ item.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="向量信息" name="vector">
|
||||
@@ -23,27 +24,16 @@
|
||||
:last-vector-parse-error-message="lastVectorParseErrorMessage"
|
||||
:active-vector-channel-name="activeVectorChannelName"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="feature-header">特征值</div>
|
||||
<div v-if="featureCards.length" class="feature-grid">
|
||||
<div v-for="item in featureCards" :key="item.title" class="feature-card">
|
||||
<div class="feature-card-title">{{ item.title }}</div>
|
||||
<div v-for="row in item.rows" :key="row.label" class="feature-row">
|
||||
<span>{{ row.label }}</span>
|
||||
<span>{{ row.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty-inline">当前文件未返回特征值结果。</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="panel-body">
|
||||
<div class="empty-block">
|
||||
<div class="empty-title">暂无解析信息</div>
|
||||
<div class="empty-text">接口联调完成后,右侧会展示波形信息、向量信息和特征值。</div>
|
||||
<div class="empty-text">接口联调完成后,右侧会展示波形信息和向量信息。</div>
|
||||
<div v-if="lastParseErrorMessage" class="empty-text error-text">最近一次解析失败:{{ lastParseErrorMessage }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -53,13 +43,12 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import type { Waveform } from '@/api/tools/waveform/interface'
|
||||
import type { FeatureCardItem, SummaryItem } from './types'
|
||||
import type { SummaryItem } from './types'
|
||||
import WaveformVectorInfo from './WaveformVectorInfo.vue'
|
||||
|
||||
defineProps<{
|
||||
hasParsedWaveform: boolean
|
||||
summaryItems: SummaryItem[]
|
||||
featureCards: FeatureCardItem[]
|
||||
vectorParseResult: Waveform.WaveComtradeVectorResultVO | null
|
||||
lastParseErrorMessage: string
|
||||
lastVectorParseErrorMessage: string
|
||||
@@ -143,18 +132,40 @@ const activeInfoTab = ref('waveform')
|
||||
}
|
||||
|
||||
.info-body {
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.info-tabs {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-tabs :deep(.el-tabs__header) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.info-tabs :deep(.el-tabs__content) {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.info-tabs :deep(.el-tab-pane) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.info-tab-panel {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.info-tabs :deep(.el-tabs__item) {
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -165,23 +176,15 @@ const activeInfoTab = ref('waveform')
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.feature-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.summary-item,
|
||||
.feature-card {
|
||||
.summary-item {
|
||||
padding: 10px;
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
border-radius: 4px;
|
||||
background: var(--cn-color-canvas-bg);
|
||||
}
|
||||
|
||||
.summary-label,
|
||||
.feature-card-title,
|
||||
.feature-header {
|
||||
.summary-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
@@ -195,24 +198,7 @@ const activeInfoTab = ref('waveform')
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.feature-header {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.feature-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
font-size: 13px;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.summary-grid {
|
||||
@@ -221,8 +207,7 @@ const activeInfoTab = ref('waveform')
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.summary-grid,
|
||||
.feature-grid {
|
||||
.summary-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
placeholder="请选择同一组.cfg和.dat文件"
|
||||
class="file-input"
|
||||
/>
|
||||
<el-button type="primary" :loading="isParsing" @click="openWaveformFilePicker">选择波形</el-button>
|
||||
<el-button type="primary" :icon="FolderOpened" :loading="isParsing" @click="openWaveformFilePicker">
|
||||
选择波形
|
||||
</el-button>
|
||||
<input
|
||||
ref="waveformFileInputRef"
|
||||
type="file"
|
||||
@@ -59,13 +61,16 @@
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
<el-button type="primary" :disabled="!hasWaveformData" @click="emit('download')">下载数据</el-button>
|
||||
<el-button type="primary" :icon="Download" :disabled="!hasWaveformData" @click="emit('download')">
|
||||
下载数据
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Download, FolderOpened } from '@element-plus/icons-vue'
|
||||
import { ref } from 'vue'
|
||||
import type { DisplayMode, LabelValueOption, ValueMode, WaveformDetailOption } from './types'
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
</el-tabs>
|
||||
|
||||
<div v-if="activeCycle" class="vector-tab-content">
|
||||
<div class="feature-header feature-header--nested">基础指标</div>
|
||||
<div v-if="phaseMetricColumns.length" class="phase-metric-table">
|
||||
<div class="phase-metric-row phase-metric-row--header" :style="phaseMetricGridStyle">
|
||||
<span class="phase-metric-cell phase-metric-cell--label">指标</span>
|
||||
@@ -83,23 +84,8 @@
|
||||
/>
|
||||
</el-tabs>
|
||||
|
||||
<div v-if="activeHarmonicRows.length" class="harmonic-list">
|
||||
<div class="harmonic-row harmonic-row--header">
|
||||
<span>次数</span>
|
||||
<span>幅值</span>
|
||||
<span>有效值</span>
|
||||
<span>占比</span>
|
||||
</div>
|
||||
<div
|
||||
v-for="item in activeHarmonicRows"
|
||||
:key="`${activePhaseKey}-${item.harmonicOrder}`"
|
||||
class="harmonic-row"
|
||||
>
|
||||
<span>{{ item.harmonicOrder ?? '--' }}</span>
|
||||
<span>{{ formatWaveValue(item.amplitude, activeVectorGroup?.unit) }}</span>
|
||||
<span>{{ formatWaveValue(item.rms, activeVectorGroup?.unit) }}</span>
|
||||
<span>{{ formatPercentValue(item.rate) }}</span>
|
||||
</div>
|
||||
<div v-if="activeHarmonicRows.length" class="harmonic-chart-card">
|
||||
<div ref="harmonicChartRef" class="harmonic-chart" />
|
||||
</div>
|
||||
<div v-else class="empty-inline">当前相未返回谐波结果。</div>
|
||||
</div>
|
||||
@@ -112,8 +98,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch, type CSSProperties } from 'vue'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch, type CSSProperties } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import * as echarts from 'echarts'
|
||||
import type { Waveform } from '@/api/tools/waveform/interface'
|
||||
import type { SummaryItem } from './types'
|
||||
|
||||
@@ -163,26 +150,12 @@ const formatWaveformTime = (value?: string) => {
|
||||
return parsedValue.isValid() ? parsedValue.format('YYYY-MM-DD HH:mm:ss.SSS') : value
|
||||
}
|
||||
|
||||
const formatWaveValue = (value: unknown, unit?: string) => {
|
||||
const formatWaveValue = (value: unknown) => {
|
||||
const formattedValue = formatNumber(value)
|
||||
if (formattedValue === '--') return '--'
|
||||
return unit ? `${formattedValue} ${unit}` : formattedValue
|
||||
return formattedValue
|
||||
}
|
||||
|
||||
const formatPhaseAngle = (value: unknown) => {
|
||||
const formattedValue = formatNumber(value)
|
||||
return formattedValue === '--' ? '--' : `${formattedValue} °`
|
||||
}
|
||||
|
||||
const formatPercentValue = (value: unknown) => {
|
||||
const formattedValue = formatNumber(value)
|
||||
return formattedValue === '--' ? '--' : `${formattedValue}%`
|
||||
}
|
||||
|
||||
const formatCycleTime = (value: unknown) => {
|
||||
const formattedValue = formatNumber(value)
|
||||
return formattedValue === '--' ? '--' : `${formattedValue} ms`
|
||||
}
|
||||
|
||||
const buildMetricLabel = (label: string, unit?: string) => {
|
||||
return unit ? `${label} (${unit})` : label
|
||||
@@ -190,13 +163,15 @@ const buildMetricLabel = (label: string, unit?: string) => {
|
||||
|
||||
const phaseMetricConfigs: Array<{
|
||||
label: string
|
||||
getValue: (phase: Waveform.WavePhaseVectorDTO, unit?: string) => string
|
||||
unit?: string
|
||||
useGroupUnit?: boolean
|
||||
getValue: (phase: Waveform.WavePhaseVectorDTO) => string
|
||||
}> = [
|
||||
{ label: '总有效值', getValue: (phase, unit) => formatWaveValue(phase.totalRms, unit) },
|
||||
{ label: '基波幅值', getValue: (phase, unit) => formatWaveValue(phase.fundamentalAmplitude, unit) },
|
||||
{ label: '基波有效值', getValue: (phase, unit) => formatWaveValue(phase.fundamentalRms, unit) },
|
||||
{ label: '基波相角', getValue: phase => formatPhaseAngle(phase.fundamentalPhaseAngle) },
|
||||
{ label: '谐波畸变率', getValue: phase => formatPercentValue(phase.harmonicDistortionRate) }
|
||||
{ label: '总有效值', useGroupUnit: true, getValue: phase => formatWaveValue(phase.totalRms) },
|
||||
{ label: '基波幅值', useGroupUnit: true, getValue: phase => formatWaveValue(phase.fundamentalAmplitude) },
|
||||
{ label: '基波有效值', useGroupUnit: true, getValue: phase => formatWaveValue(phase.fundamentalRms) },
|
||||
{ label: '基波相角', unit: '°', getValue: phase => formatWaveValue(phase.fundamentalPhaseAngle) },
|
||||
{ label: '谐波畸变率', unit: '%', getValue: phase => formatWaveValue(phase.harmonicDistortionRate) }
|
||||
]
|
||||
|
||||
const buildVectorGroupKey = (group: Waveform.WaveVectorGroupDTO, index: number) => {
|
||||
@@ -299,15 +274,15 @@ const phaseMetricColumns = computed<PhaseMetricColumn[]>(() => {
|
||||
})
|
||||
|
||||
const phaseMetricGridStyle = computed<CSSProperties>(() => ({
|
||||
gridTemplateColumns: `96px repeat(${Math.max(phaseMetricColumns.value.length, 1)}, minmax(96px, 1fr))`
|
||||
gridTemplateColumns: `128px repeat(${Math.max(phaseMetricColumns.value.length, 1)}, minmax(96px, 1fr))`
|
||||
}))
|
||||
|
||||
const sequenceMetricGridStyle = computed<CSSProperties>(() => ({
|
||||
gridTemplateColumns: `132px repeat(${Math.max(sequenceMetricColumns.value.length, 1)}, minmax(0, 1fr))`
|
||||
gridTemplateColumns: `88px repeat(${Math.max(sequenceMetricColumns.value.length, 1)}, minmax(64px, 1fr))`
|
||||
}))
|
||||
|
||||
const unbalanceMetricGridStyle = computed<CSSProperties>(() => ({
|
||||
gridTemplateColumns: '156px minmax(0, 1fr)'
|
||||
gridTemplateColumns: '128px minmax(72px, 1fr)'
|
||||
}))
|
||||
|
||||
const phaseMetricRows = computed<PhaseMetricRow[]>(() => {
|
||||
@@ -315,11 +290,11 @@ const phaseMetricRows = computed<PhaseMetricRow[]>(() => {
|
||||
|
||||
// 相量基础指标按“指标为行、相别为列”转置,减少 A/B/C 三相重复标签。
|
||||
return phaseMetricConfigs.map(config => ({
|
||||
label: config.label,
|
||||
label: buildMetricLabel(config.label, config.useGroupUnit ? activeGroup?.unit : config.unit),
|
||||
values: activePhaseVectors.value.reduce<Record<string, string>>((result, phase, index) => {
|
||||
const column = phaseMetricColumns.value[index]
|
||||
if (column) {
|
||||
result[column.key] = config.getValue(phase, activeGroup?.unit)
|
||||
result[column.key] = config.getValue(phase)
|
||||
}
|
||||
return result
|
||||
}, {})
|
||||
@@ -380,11 +355,158 @@ const unbalanceMetricRows = computed<MetricRow[]>(() => {
|
||||
]
|
||||
})
|
||||
|
||||
const activeHarmonicRows = computed(() => {
|
||||
const activeHarmonicRows = computed<Waveform.WaveHarmonicDTO[]>(() => {
|
||||
if (!activePhaseVector.value) return []
|
||||
|
||||
return activePhaseVector.value.harmonicVoltageContentRates || activePhaseVector.value.harmonicCurrentAmplitudes || []
|
||||
})
|
||||
|
||||
const harmonicChartRef = ref<HTMLDivElement>()
|
||||
let harmonicChart: echarts.ECharts | null = null
|
||||
let harmonicResizeObserver: ResizeObserver | null = null
|
||||
|
||||
const normalizeChartValue = (value: unknown) => {
|
||||
const numberValue = Number(value)
|
||||
return Number.isFinite(numberValue) ? Number(numberValue.toFixed(3)) : null
|
||||
}
|
||||
|
||||
const harmonicChartOption = computed<echarts.EChartsOption>(() => {
|
||||
const unit = activeVectorGroup.value?.unit || ''
|
||||
const categories = activeHarmonicRows.value.map(item => `${item.harmonicOrder ?? '--'}次`)
|
||||
const hasRate = activeHarmonicRows.value.some(item => Number.isFinite(Number(item.rate)))
|
||||
const valueAxisName = unit ? `幅值 / 有效值 (${unit})` : '幅值 / 有效值'
|
||||
const series: echarts.SeriesOption[] = [
|
||||
{
|
||||
name: unit ? `幅值 (${unit})` : '幅值',
|
||||
type: 'bar',
|
||||
barMaxWidth: 16,
|
||||
data: activeHarmonicRows.value.map(item => normalizeChartValue(item.amplitude))
|
||||
},
|
||||
{
|
||||
name: unit ? `有效值 (${unit})` : '有效值',
|
||||
type: 'bar',
|
||||
barMaxWidth: 16,
|
||||
data: activeHarmonicRows.value.map(item => normalizeChartValue(item.rms))
|
||||
}
|
||||
]
|
||||
|
||||
if (hasRate) {
|
||||
series.push({
|
||||
name: '占比 (%)',
|
||||
type: 'bar',
|
||||
yAxisIndex: 1,
|
||||
barMaxWidth: 16,
|
||||
data: activeHarmonicRows.value.map(item => normalizeChartValue(item.rate))
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
color: ['#2f80ed', '#07ccca', '#ffbf00'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { type: 'shadow' },
|
||||
confine: true
|
||||
},
|
||||
legend: {
|
||||
top: 0,
|
||||
right: 8,
|
||||
itemWidth: 12,
|
||||
itemHeight: 8,
|
||||
textStyle: { color: '#606266', fontSize: 12 }
|
||||
},
|
||||
grid: {
|
||||
top: 36,
|
||||
right: hasRate ? 52 : 16,
|
||||
bottom: 42,
|
||||
left: 12,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
name: '谐波次数',
|
||||
nameGap: 22,
|
||||
data: categories,
|
||||
axisTick: { show: false },
|
||||
axisLabel: { color: '#606266', fontSize: 11 },
|
||||
axisLine: { lineStyle: { color: '#dcdfe6' } }
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: valueAxisName,
|
||||
nameTextStyle: { color: '#606266', fontSize: 11 },
|
||||
axisLabel: { color: '#606266', fontSize: 11 },
|
||||
splitLine: { lineStyle: { color: '#ebeef5', type: 'dashed' } }
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '%',
|
||||
show: hasRate,
|
||||
nameTextStyle: { color: '#606266', fontSize: 11 },
|
||||
axisLabel: { color: '#606266', fontSize: 11 },
|
||||
splitLine: { show: false }
|
||||
}
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 0,
|
||||
end: Math.min(100, activeHarmonicRows.value.length > 18 ? 36 : 100)
|
||||
},
|
||||
{
|
||||
type: 'slider',
|
||||
height: 12,
|
||||
bottom: 12,
|
||||
start: 0,
|
||||
end: Math.min(100, activeHarmonicRows.value.length > 18 ? 36 : 100)
|
||||
}
|
||||
],
|
||||
series
|
||||
}
|
||||
})
|
||||
|
||||
const resizeHarmonicChart = () => {
|
||||
if (!harmonicChart || !harmonicChartRef.value || harmonicChartRef.value.offsetHeight === 0) return
|
||||
harmonicChart.resize()
|
||||
}
|
||||
|
||||
const renderHarmonicChart = async () => {
|
||||
await nextTick()
|
||||
|
||||
if (!harmonicChartRef.value || !activeHarmonicRows.value.length) {
|
||||
harmonicChart?.dispose()
|
||||
harmonicChart = null
|
||||
harmonicResizeObserver?.disconnect()
|
||||
harmonicResizeObserver = null
|
||||
return
|
||||
}
|
||||
|
||||
if (!harmonicChart) {
|
||||
harmonicChart = echarts.init(harmonicChartRef.value)
|
||||
}
|
||||
|
||||
harmonicChart.setOption(harmonicChartOption.value, true)
|
||||
|
||||
if (!harmonicResizeObserver) {
|
||||
harmonicResizeObserver = new ResizeObserver(() => resizeHarmonicChart())
|
||||
harmonicResizeObserver.observe(harmonicChartRef.value)
|
||||
}
|
||||
|
||||
resizeHarmonicChart()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
renderHarmonicChart()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
harmonicResizeObserver?.disconnect()
|
||||
harmonicChart?.dispose()
|
||||
})
|
||||
|
||||
watch(harmonicChartOption, () => {
|
||||
renderHarmonicChart()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -397,6 +519,12 @@ const activeHarmonicRows = computed(() => {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.waveform-vector-info {
|
||||
flex: none;
|
||||
min-height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.empty-text,
|
||||
.empty-inline,
|
||||
.vector-placeholder {
|
||||
@@ -425,7 +553,7 @@ const activeHarmonicRows = computed(() => {
|
||||
.summary-item,
|
||||
.feature-card,
|
||||
.vector-placeholder,
|
||||
.harmonic-list {
|
||||
.harmonic-chart-card {
|
||||
padding: 10px;
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
border-radius: 4px;
|
||||
@@ -488,6 +616,11 @@ const activeHarmonicRows = computed(() => {
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
|
||||
.phase-metric-table--fit .phase-metric-cell {
|
||||
padding-right: 8px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.phase-metric-table--fit .phase-metric-row {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
@@ -509,12 +642,20 @@ const activeHarmonicRows = computed(() => {
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
color: var(--el-text-color-regular);
|
||||
text-align: right;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
border-right: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
|
||||
.phase-metric-cell--label {
|
||||
overflow: visible;
|
||||
text-align: left;
|
||||
text-overflow: clip;
|
||||
white-space: normal;
|
||||
word-break: keep-all;
|
||||
}
|
||||
|
||||
.phase-metric-row--header .phase-metric-cell {
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
@@ -523,9 +664,6 @@ const activeHarmonicRows = computed(() => {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.phase-metric-cell--label {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.vector-tabs {
|
||||
width: 100%;
|
||||
@@ -544,36 +682,14 @@ const activeHarmonicRows = computed(() => {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.harmonic-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
max-height: 240px;
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
.harmonic-chart-card {
|
||||
height: 280px;
|
||||
padding: 10px 8px 4px;
|
||||
}
|
||||
|
||||
.harmonic-row {
|
||||
display: grid;
|
||||
grid-template-columns: 52px repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
padding: 8px 10px;
|
||||
font-size: 12px;
|
||||
color: var(--el-text-color-regular);
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
|
||||
.harmonic-row:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.harmonic-row--header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
background: var(--el-bg-color);
|
||||
.harmonic-chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@@ -585,7 +701,7 @@ const activeHarmonicRows = computed(() => {
|
||||
@media (min-width: 993px) {
|
||||
.vector-tab-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
grid-template-columns: minmax(0, 1.35fr) minmax(200px, 0.65fr);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
@@ -594,29 +710,30 @@ const activeHarmonicRows = computed(() => {
|
||||
}
|
||||
|
||||
.vector-tab-content > :first-child,
|
||||
.vector-tab-content > :nth-child(n + 6) {
|
||||
.vector-tab-content > :nth-child(2),
|
||||
.vector-tab-content > :nth-child(n + 7) {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.vector-tab-content > :nth-child(2) {
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
}
|
||||
|
||||
.vector-tab-content > :nth-child(3) {
|
||||
grid-column: 1;
|
||||
grid-row: 3;
|
||||
}
|
||||
|
||||
.vector-tab-content > :nth-child(4) {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
grid-column: 1;
|
||||
grid-row: 4;
|
||||
}
|
||||
|
||||
.vector-tab-content > :nth-child(5) {
|
||||
grid-column: 2;
|
||||
grid-row: 3;
|
||||
}
|
||||
|
||||
.vector-tab-content > :nth-child(6) {
|
||||
grid-column: 2;
|
||||
grid-row: 4;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
@@ -626,8 +743,6 @@ const activeHarmonicRows = computed(() => {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.harmonic-row {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user