@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.69 → 2.0.0-next.71
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/bundle/openbridge-webcomponents.bundle.js +5082 -4913
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +98 -4
- package/dist/components/textbox/textbox.css.js +114 -0
- package/dist/components/textbox/textbox.css.js.map +1 -0
- package/dist/components/textbox/textbox.d.ts +70 -0
- package/dist/components/textbox/textbox.d.ts.map +1 -0
- package/dist/components/textbox/textbox.js +84 -0
- package/dist/components/textbox/textbox.js.map +1 -0
- package/dist/navigation-instruments/indicator-graph/indicator-graph.d.ts +1 -0
- package/dist/navigation-instruments/indicator-graph/indicator-graph.d.ts.map +1 -1
- package/dist/navigation-instruments/indicator-graph/indicator-graph.js +17 -9
- package/dist/navigation-instruments/indicator-graph/indicator-graph.js.map +1 -1
- package/eslint.config.mjs +2 -7
- package/package.json +1 -1
- package/src/components/textbox/textbox.css +100 -0
- package/src/components/textbox/textbox.stories.ts +165 -0
- package/src/components/textbox/textbox.ts +103 -0
- package/src/navigation-instruments/indicator-graph/indicator-graph.stories.ts +20 -0
- package/src/navigation-instruments/indicator-graph/indicator-graph.ts +19 -10
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-block;
|
|
3
|
+
line-height: 0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.wrapper {
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
width: fit-content;
|
|
10
|
+
--height: 24px;
|
|
11
|
+
--padding: 4px;
|
|
12
|
+
font-family: var(--font-family-main);
|
|
13
|
+
letter-spacing: var(--global-typography-generic-l-letter-spacing);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* The inner-wrapper is the box: its height (--height) is the full textbox
|
|
17
|
+
height, padding included. The content is sized to the cap height and
|
|
18
|
+
vertically centered, which leaves the padding as equal space above and
|
|
19
|
+
below. In engines that support text-box-trim the content box collapses to
|
|
20
|
+
the cap height exactly; in Firefox (no text-box-trim) the content keeps its
|
|
21
|
+
natural line box, so align-items:center + overflow:hidden crops it to the
|
|
22
|
+
same height instead. No padding here – the centering provides it.
|
|
23
|
+
(A small top padding could be added later to nudge the text up in Firefox.) */
|
|
24
|
+
.inner-wrapper {
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: var(--alignment-justify, flex-end);
|
|
29
|
+
height: var(--height);
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* The spacer must share the content's exact font metrics so the width it
|
|
34
|
+
reserves equals the rendered content width. font-size-adjust scales the
|
|
35
|
+
font, so it has to match too. */
|
|
36
|
+
.content,
|
|
37
|
+
.length-spacer {
|
|
38
|
+
font-size: calc(var(--height) - 2 * var(--padding));
|
|
39
|
+
font-size-adjust: cap-height 1;
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.content {
|
|
44
|
+
text-box-trim: trim-both;
|
|
45
|
+
text-box-edge: cap alphabetic;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.wrapper.size-xs .inner-wrapper {
|
|
49
|
+
--height: 16px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.wrapper.size-s .inner-wrapper {
|
|
53
|
+
--height: 20px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.wrapper.size-m .inner-wrapper {
|
|
57
|
+
--height: 24px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.wrapper.size-l .inner-wrapper {
|
|
61
|
+
--height: 32px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.wrapper.size-xl .inner-wrapper {
|
|
65
|
+
--height: 40px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.wrapper.font-weight-regular {
|
|
69
|
+
font-weight: var(--global-typography-generic-l-font-weight-regular);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.wrapper.font-weight-semibold {
|
|
73
|
+
font-weight: var(--global-typography-generic-l-font-weight-medium);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.wrapper.font-weight-bold {
|
|
77
|
+
font-weight: var(--global-typography-generic-l-font-weight-bold);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.wrapper.alignment-left {
|
|
81
|
+
--alignment-justify: flex-start;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.wrapper.alignment-center {
|
|
85
|
+
--alignment-justify: center;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.wrapper.alignment-right {
|
|
89
|
+
--alignment-justify: flex-end;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Reserves the box width from the `length` slot without occupying vertical
|
|
93
|
+
space. Acts as a minimum width so the box does not resize as visible
|
|
94
|
+
text changes. */
|
|
95
|
+
.length-spacer {
|
|
96
|
+
height: 0;
|
|
97
|
+
opacity: 0;
|
|
98
|
+
visibility: hidden;
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import type {Meta, StoryObj} from '@storybook/web-components-vite';
|
|
2
|
+
import {
|
|
3
|
+
ObcTextbox,
|
|
4
|
+
ObcTextboxAlignment,
|
|
5
|
+
ObcTextboxFontWeight,
|
|
6
|
+
ObcTextboxSize,
|
|
7
|
+
} from './textbox.js';
|
|
8
|
+
import './textbox.js';
|
|
9
|
+
import {html} from 'lit';
|
|
10
|
+
|
|
11
|
+
interface TextboxStoryArgs extends Partial<ObcTextbox> {
|
|
12
|
+
content: string;
|
|
13
|
+
length: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const meta: Meta<TextboxStoryArgs> = {
|
|
17
|
+
title: 'Building Blocks/Textbox',
|
|
18
|
+
tags: ['autodocs', '6.0'],
|
|
19
|
+
component: 'obc-textbox',
|
|
20
|
+
args: {
|
|
21
|
+
size: ObcTextboxSize.m,
|
|
22
|
+
fontWeight: ObcTextboxFontWeight.regular,
|
|
23
|
+
alignment: ObcTextboxAlignment.Right,
|
|
24
|
+
content: '123 ABC',
|
|
25
|
+
length: '1234567 ABC',
|
|
26
|
+
},
|
|
27
|
+
argTypes: {
|
|
28
|
+
size: {
|
|
29
|
+
control: {type: 'radio'},
|
|
30
|
+
options: Object.values(ObcTextboxSize),
|
|
31
|
+
},
|
|
32
|
+
fontWeight: {
|
|
33
|
+
control: {type: 'radio'},
|
|
34
|
+
options: Object.values(ObcTextboxFontWeight),
|
|
35
|
+
},
|
|
36
|
+
alignment: {
|
|
37
|
+
control: {type: 'radio'},
|
|
38
|
+
options: Object.values(ObcTextboxAlignment),
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
render: (args) => html`
|
|
42
|
+
<obc-textbox
|
|
43
|
+
.size=${args.size}
|
|
44
|
+
.fontWeight=${args.fontWeight}
|
|
45
|
+
.alignment=${args.alignment}
|
|
46
|
+
>
|
|
47
|
+
<div>${args.content}</div>
|
|
48
|
+
<div slot="length">${args.length}</div>
|
|
49
|
+
</obc-textbox>
|
|
50
|
+
`,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default meta;
|
|
54
|
+
type Story = StoryObj<TextboxStoryArgs>;
|
|
55
|
+
|
|
56
|
+
const labelStyle =
|
|
57
|
+
'font-size: 12px; color: var(--element-neutral-color, #777);';
|
|
58
|
+
const captionStyle =
|
|
59
|
+
'font-size: 11px; font-style: italic; max-width: 520px; color: var(--element-neutral-color, #777);';
|
|
60
|
+
const boxOutline = 'outline: 1px solid var(--border-outline-color);';
|
|
61
|
+
|
|
62
|
+
export const Default: Story = {};
|
|
63
|
+
|
|
64
|
+
export const Sizes: Story = {
|
|
65
|
+
render: () => html`
|
|
66
|
+
<div
|
|
67
|
+
style="display: flex; flex-direction: column; align-items: flex-start; gap: 16px;"
|
|
68
|
+
>
|
|
69
|
+
${Object.values(ObcTextboxSize).map(
|
|
70
|
+
(size) => html`
|
|
71
|
+
<obc-textbox .size=${size}>
|
|
72
|
+
<div>${size.toUpperCase()} – 123 ABC</div>
|
|
73
|
+
</obc-textbox>
|
|
74
|
+
`
|
|
75
|
+
)}
|
|
76
|
+
</div>
|
|
77
|
+
`,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const FontWeights: Story = {
|
|
81
|
+
render: () => html`
|
|
82
|
+
<div
|
|
83
|
+
style="display: flex; flex-direction: column; align-items: flex-start; gap: 16px;"
|
|
84
|
+
>
|
|
85
|
+
${Object.values(ObcTextboxFontWeight).map(
|
|
86
|
+
(fontWeight) => html`
|
|
87
|
+
<obc-textbox .fontWeight=${fontWeight}>
|
|
88
|
+
<div>${fontWeight} – 123 ABC</div>
|
|
89
|
+
</obc-textbox>
|
|
90
|
+
`
|
|
91
|
+
)}
|
|
92
|
+
</div>
|
|
93
|
+
`,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const Alignments: Story = {
|
|
97
|
+
render: (args) => html`
|
|
98
|
+
<div
|
|
99
|
+
style="display: flex; flex-direction: column; align-items: flex-start; gap: 16px;"
|
|
100
|
+
>
|
|
101
|
+
<div style=${captionStyle}>
|
|
102
|
+
Alignment positions the content within the box when the box is wider
|
|
103
|
+
than the content. The width is determined by whichever is wider: the
|
|
104
|
+
visible content or the reserved length slot.
|
|
105
|
+
</div>
|
|
106
|
+
${Object.values(ObcTextboxAlignment).map(
|
|
107
|
+
(alignment) => html`
|
|
108
|
+
<div style="display: flex; align-items: center; gap: 12px;">
|
|
109
|
+
<div style="${labelStyle} width: 56px;">${alignment}</div>
|
|
110
|
+
<obc-textbox
|
|
111
|
+
.size=${args.size}
|
|
112
|
+
.fontWeight=${args.fontWeight}
|
|
113
|
+
.alignment=${alignment}
|
|
114
|
+
style=${boxOutline}
|
|
115
|
+
>
|
|
116
|
+
<div>${args.content}</div>
|
|
117
|
+
<div slot="length">${args.length}</div>
|
|
118
|
+
</obc-textbox>
|
|
119
|
+
</div>
|
|
120
|
+
`
|
|
121
|
+
)}
|
|
122
|
+
</div>
|
|
123
|
+
`,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const ReserveSpace: Story = {
|
|
127
|
+
args: {
|
|
128
|
+
content: '5',
|
|
129
|
+
length: '00000',
|
|
130
|
+
},
|
|
131
|
+
render: (args) => html`
|
|
132
|
+
<div
|
|
133
|
+
style="display: flex; flex-direction: column; align-items: flex-start; gap: 16px;"
|
|
134
|
+
>
|
|
135
|
+
<div style=${captionStyle}>
|
|
136
|
+
Content placed in the length slot reserves width invisibly, so the box
|
|
137
|
+
keeps the size of the longest expected value (here "${args.length}")
|
|
138
|
+
even when the visible content is shorter.
|
|
139
|
+
</div>
|
|
140
|
+
<div style="display: flex; align-items: center; gap: 12px;">
|
|
141
|
+
<div style="${labelStyle} width: 104px;">no length slot</div>
|
|
142
|
+
<obc-textbox
|
|
143
|
+
.size=${args.size}
|
|
144
|
+
.fontWeight=${args.fontWeight}
|
|
145
|
+
.alignment=${args.alignment}
|
|
146
|
+
style=${boxOutline}
|
|
147
|
+
>
|
|
148
|
+
<div>${args.content}</div>
|
|
149
|
+
</obc-textbox>
|
|
150
|
+
</div>
|
|
151
|
+
<div style="display: flex; align-items: center; gap: 12px;">
|
|
152
|
+
<div style="${labelStyle} width: 104px;">length: ${args.length}</div>
|
|
153
|
+
<obc-textbox
|
|
154
|
+
.size=${args.size}
|
|
155
|
+
.fontWeight=${args.fontWeight}
|
|
156
|
+
.alignment=${args.alignment}
|
|
157
|
+
style=${boxOutline}
|
|
158
|
+
>
|
|
159
|
+
<div>${args.content}</div>
|
|
160
|
+
<div slot="length">${args.length}</div>
|
|
161
|
+
</obc-textbox>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
`,
|
|
165
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import {LitElement, html, unsafeCSS} from 'lit';
|
|
2
|
+
import {customElement} from '../../decorator.js';
|
|
3
|
+
import componentStyle from './textbox.css?inline';
|
|
4
|
+
import {property} from 'lit/decorators.js';
|
|
5
|
+
import {classMap} from 'lit/directives/class-map.js';
|
|
6
|
+
|
|
7
|
+
export enum ObcTextboxAlignment {
|
|
8
|
+
Left = 'left',
|
|
9
|
+
Center = 'center',
|
|
10
|
+
Right = 'right',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export enum ObcTextboxSize {
|
|
14
|
+
xs = 'xs',
|
|
15
|
+
s = 's',
|
|
16
|
+
m = 'm',
|
|
17
|
+
l = 'l',
|
|
18
|
+
xl = 'xl',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export enum ObcTextboxFontWeight {
|
|
22
|
+
regular = 'regular',
|
|
23
|
+
semibold = 'semibold',
|
|
24
|
+
bold = 'bold',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* `<obc-textbox>` – A text container that renders inline text at a
|
|
29
|
+
* precise, cap-height-trimmed size with configurable alignment and reservable
|
|
30
|
+
* width.
|
|
31
|
+
*
|
|
32
|
+
* Use it to present short, read-only strings – such as values, labels, or
|
|
33
|
+
* units – where vertical metrics must line up exactly across rows and the
|
|
34
|
+
* horizontal footprint should stay stable while the text changes (for example
|
|
35
|
+
* a numeric value that updates frequently). Synonyms: text container, value
|
|
36
|
+
* box, label box.
|
|
37
|
+
*
|
|
38
|
+
* ## Features / Variants
|
|
39
|
+
* - **Size:** `xs`, `s`, `m` (default), `l`, `xl` – each maps to a fixed box
|
|
40
|
+
* height (16 / 20 / 24 / 32 / 40 px) with 4px padding above and below, giving
|
|
41
|
+
* cap heights of 8 / 12 / 16 / 24 / 32 px so text aligns to a predictable
|
|
42
|
+
* grid.
|
|
43
|
+
* - **Font weight:** `regular` (default), `semibold`, `bold`.
|
|
44
|
+
* - **Alignment:** `left`, `center`, `right` (default) – positions the text
|
|
45
|
+
* within the box's width when the box is wider than the content.
|
|
46
|
+
* - **Reserved width:** content placed in the `length` slot reserves a minimum
|
|
47
|
+
* width invisibly, so the box does not resize as the visible text changes.
|
|
48
|
+
* The box always shows all content – it never crops.
|
|
49
|
+
*
|
|
50
|
+
* ## Usage Guidelines
|
|
51
|
+
* - Pass the longest expected string to the `length` slot (e.g. `"888.8"` or
|
|
52
|
+
* `"Wind speed"`) so the box reserves space and does not jump in width as the
|
|
53
|
+
* visible value updates.
|
|
54
|
+
* - This is a display primitive for static text – use an input component for
|
|
55
|
+
* editable values.
|
|
56
|
+
*
|
|
57
|
+
* ## Slots
|
|
58
|
+
* | Slot | Renders when… | Purpose |
|
|
59
|
+
* |-----------|--------------------|------------------------------------------------------|
|
|
60
|
+
* | (default) | Always | The visible text content. |
|
|
61
|
+
* | `length` | Always (invisible) | Reserves a minimum width based on its content width. |
|
|
62
|
+
*
|
|
63
|
+
* @slot - The visible text content.
|
|
64
|
+
* @slot length - Reserves a minimum width based on its content width.
|
|
65
|
+
*/
|
|
66
|
+
@customElement('obc-textbox')
|
|
67
|
+
export class ObcTextbox extends LitElement {
|
|
68
|
+
@property({type: String}) alignment: ObcTextboxAlignment =
|
|
69
|
+
ObcTextboxAlignment.Right;
|
|
70
|
+
@property({type: String}) size: ObcTextboxSize = ObcTextboxSize.m;
|
|
71
|
+
@property({type: String}) fontWeight: ObcTextboxFontWeight =
|
|
72
|
+
ObcTextboxFontWeight.regular;
|
|
73
|
+
|
|
74
|
+
override render() {
|
|
75
|
+
return html`
|
|
76
|
+
<div
|
|
77
|
+
class=${classMap({
|
|
78
|
+
wrapper: true,
|
|
79
|
+
[`alignment-${this.alignment}`]: true,
|
|
80
|
+
[`size-${this.size}`]: true,
|
|
81
|
+
[`font-weight-${this.fontWeight}`]: true,
|
|
82
|
+
})}
|
|
83
|
+
>
|
|
84
|
+
<div class="inner-wrapper">
|
|
85
|
+
<div class="content">
|
|
86
|
+
<slot></slot>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="length-spacer" aria-hidden="true">
|
|
90
|
+
<slot name="length"></slot>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static override styles = unsafeCSS(componentStyle);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
declare global {
|
|
100
|
+
interface HTMLElementTagNameMap {
|
|
101
|
+
'obc-textbox': ObcTextbox;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -30,6 +30,14 @@ type Story = StoryObj<ObcIndicatorGraph>;
|
|
|
30
30
|
|
|
31
31
|
export const Primary: Story = {};
|
|
32
32
|
|
|
33
|
+
export const NoZeroLine: Story = {
|
|
34
|
+
args: {
|
|
35
|
+
layout: {
|
|
36
|
+
y: {showZeroLine: false},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
33
41
|
export const WithRange: Story = {
|
|
34
42
|
args: {
|
|
35
43
|
layout: {
|
|
@@ -114,3 +122,15 @@ export const Realtime: Story = {
|
|
|
114
122
|
}, 1000 / 60);
|
|
115
123
|
},
|
|
116
124
|
};
|
|
125
|
+
|
|
126
|
+
export const BelowZero: Story = {
|
|
127
|
+
args: {
|
|
128
|
+
data: [
|
|
129
|
+
Array.from({length: 30}, (_, i) => i),
|
|
130
|
+
Array.from({length: 30}, (_, i) => -2 - Math.sin((i / 30) * 2 * Math.PI)),
|
|
131
|
+
],
|
|
132
|
+
layout: {
|
|
133
|
+
y: {min: -10, max: 0},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
};
|
|
@@ -15,10 +15,11 @@ export enum ObcIndicatorGraphPriority {
|
|
|
15
15
|
enhanced = 'enhanced',
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
// showZeroLine is defaulted to true
|
|
18
19
|
export interface ObcIndicatorGraphLayout {
|
|
19
20
|
size?: ObcIndicatorGraphSize;
|
|
20
21
|
priority?: ObcIndicatorGraphPriority;
|
|
21
|
-
y?: {min?: number; max?: number};
|
|
22
|
+
y?: {min?: number; max?: number; showZeroLine?: boolean};
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
/**
|
|
@@ -39,10 +40,10 @@ export class ObcIndicatorGraph extends LitElement {
|
|
|
39
40
|
private chart!: HTMLDivElement;
|
|
40
41
|
|
|
41
42
|
@state()
|
|
42
|
-
private y: number =
|
|
43
|
+
private y: number | undefined = undefined;
|
|
43
44
|
|
|
44
45
|
@state()
|
|
45
|
-
private zeroLineY: number =
|
|
46
|
+
private zeroLineY: number | undefined = undefined;
|
|
46
47
|
|
|
47
48
|
private uplot: uPlot | null = null;
|
|
48
49
|
private resizeObserver: ResizeObserver | null = null;
|
|
@@ -115,7 +116,7 @@ export class ObcIndicatorGraph extends LitElement {
|
|
|
115
116
|
const {min: minY, max: maxY} = this.layout.y ?? {};
|
|
116
117
|
const range = maxY ?? initMax - (minY ?? initMin);
|
|
117
118
|
let min = minY ?? initMin - range * 0.1;
|
|
118
|
-
if (minY === undefined) {
|
|
119
|
+
if (minY === undefined && this.layout.y?.showZeroLine !== false) {
|
|
119
120
|
min = Math.min(0, min);
|
|
120
121
|
}
|
|
121
122
|
return [min, maxY ?? initMax + range * 0.1] as [number, number];
|
|
@@ -169,7 +170,11 @@ export class ObcIndicatorGraph extends LitElement {
|
|
|
169
170
|
const lastY = this.data[1][this.data[1].length - 1];
|
|
170
171
|
// @ts-expect-error - valToPct is not a property of the Scale interface
|
|
171
172
|
const yRatio = this.uplot.scales.y.valToPct(lastY);
|
|
172
|
-
|
|
173
|
+
if (yRatio < 0 || yRatio > 1) {
|
|
174
|
+
this.y = undefined;
|
|
175
|
+
} else {
|
|
176
|
+
this.y = yRatio * this.chart.clientHeight;
|
|
177
|
+
}
|
|
173
178
|
this.updateZeroLine();
|
|
174
179
|
}
|
|
175
180
|
|
|
@@ -179,6 +184,10 @@ export class ObcIndicatorGraph extends LitElement {
|
|
|
179
184
|
}
|
|
180
185
|
// @ts-expect-error - valToPct is not a property of the Scale interface
|
|
181
186
|
const yRatio = this.uplot.scales.y.valToPct(0);
|
|
187
|
+
if (yRatio < 0 || yRatio > 1) {
|
|
188
|
+
this.zeroLineY = undefined;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
182
191
|
this.zeroLineY = yRatio * this.chart.clientHeight;
|
|
183
192
|
}
|
|
184
193
|
|
|
@@ -198,15 +207,15 @@ export class ObcIndicatorGraph extends LitElement {
|
|
|
198
207
|
>
|
|
199
208
|
<div
|
|
200
209
|
id="zero-line"
|
|
201
|
-
style="transform: translateY(${-this.zeroLineY}px);
|
|
202
|
-
display: ${this.zeroLineY
|
|
210
|
+
style="transform: translateY(${-(this.zeroLineY ?? 0)}px);
|
|
211
|
+
display: ${this.zeroLineY !== undefined ? 'block' : 'none'};
|
|
203
212
|
"
|
|
204
213
|
></div>
|
|
205
214
|
<div
|
|
206
215
|
id="dot"
|
|
207
|
-
style="transform: translateY(${-this.y}px);
|
|
208
|
-
|
|
209
|
-
|
|
216
|
+
style="transform: translateY(${-(this.y ?? 0)}px);
|
|
217
|
+
display: ${this.y !== undefined ? 'block' : 'none'};
|
|
218
|
+
"
|
|
210
219
|
></div>
|
|
211
220
|
</div>
|
|
212
221
|
`;
|