Skip to content

Commit 0739ea7

Browse files
committed
Make a few consistency/documentation improvements
1 parent 97e0f2b commit 0739ea7

File tree

7 files changed

+62
-15
lines changed

7 files changed

+62
-15
lines changed

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22

33
This plugin adds enables for arbitrary shapes to be drawn on the chart. It requires LWC version `5.0.0` or greater.
44

5+
Shape features:
6+
- Border styling: colour, width, style, visibility
7+
- Fill styling: colour, opacity
8+
- Ability to drag corners of shapes, or the whole shape
9+
- Mutability: *true* (default) for interactivity (hovering/dragging), *false* for simply displaying the shape
10+
- Hovering: change border width, change fill opacity, show a custom shape on the corners (square or circle) and set its size, detect when hovering over the fill and/or the borders of a shape
11+
- Show/hide the time/price axis labels of the unique corners of a shape, including changing label/text colours and price/time formatters
12+
13+
See the `ShapeDrawingOptions` interface in `./src/options.ts` for setting these properties.
14+
15+
## Visual Demo
16+
17+
![shape-drawing-demo](https://github.com/user-attachments/assets/e5b28fdf-548a-4e3e-80f6-fb957e99bf71)
18+
519
## Running Locally
620

721
```shell
@@ -11,7 +25,7 @@ npm run dev
1125

1226
Visit `localhost:5173` in the browser.
1327

14-
## Example:
28+
## Code Example
1529

1630
```js
1731
// Draw a triangle

src/example/classes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const defaultShapeOptions: Partial<ShapeDrawingOptions> = {
88
borderColor: '#f0f',
99
borderWidth: 2,
1010
borderStyle: LineStyle.Dashed,
11-
hoveredEdgeWidth: 4,
11+
hoveredBorderWidth: 4,
1212
hoveredFillOpacity: 0.6,
1313
};
1414

src/example/example.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const shape1 = new ShapeDrawing(
2424
showPriceAxisLabels: true,
2525
labelColor: '#aaa',
2626
labelTextColor: '#000',
27-
hoveredEdgeWidth: 8,
27+
hoveredBorderWidth: 8,
2828
hoveredFillOpacity: 0.6,
2929
},
3030
);

src/example/helpers.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,39 @@
11
import { Logical, MouseEventParams, Time } from "lightweight-charts";
22
import { defaultShapeOptions, Point } from "./classes";
3-
import { chart, fillOpacityElement, lineSeries, seriesPricePrecision, state } from "./data";
3+
import { chart, fillOpacityElement, lineSeries, seriesPricePrecision, shapeDrawingSelectionElement, state } from "./data";
44
import { HoveredObject, ShapeDrawing } from "../shape-drawing";
55

6+
const selectedButtonColor = '#aaa';
7+
const deselectedButtonColor = '#ccc';
8+
69
export function shapeDrawingSelection(event: MouseEvent) {
710
if (!(event.target instanceof HTMLButtonElement)) {
811
return;
912
}
1013

14+
if (state.currentlySelectedShape) {
15+
selectShape(null);
16+
}
17+
1118
if (state.shapeToDraw === event.target.textContent) { // Deselect it
12-
event.target.style.backgroundColor = '#ccc';
19+
event.target.style.backgroundColor = deselectedButtonColor;
1320
state.shapeToDraw = '';
1421
state.edgeCount = 0;
1522
state.shapeOptions = defaultShapeOptions;
1623
return;
1724
}
1825

19-
event.target.style.backgroundColor = '#aaa';
26+
if (state.shapeToDraw !== '') {
27+
// Fetch the shapeToDraw button by iterating through all buttons and finding the one with the same textContent
28+
const shapeToDrawButton = Array.from(shapeDrawingSelectionElement.children).find(
29+
button => (button as HTMLButtonElement).textContent === state.shapeToDraw
30+
);
31+
if (shapeToDrawButton) {
32+
(shapeToDrawButton as HTMLButtonElement).style.backgroundColor = deselectedButtonColor;
33+
}
34+
}
35+
36+
event.target.style.backgroundColor = selectedButtonColor;
2037

2138
state.shapeToDraw = event.target.textContent!;
2239

@@ -195,6 +212,17 @@ export function chartCrosshairMoveEvent(event: MouseEventParams<Time>) {
195212
export function keyUpEvent(event: KeyboardEvent) {
196213
switch (event.key) {
197214
case 'Escape':
215+
if (state.shapeToDraw !== '') {
216+
// Fetch the shapeToDraw button by iterating through all buttons and finding the one with the same textContent
217+
const shapeToDrawButton = Array.from(shapeDrawingSelectionElement.children).find(
218+
button => (button as HTMLButtonElement).textContent === state.shapeToDraw
219+
);
220+
if (shapeToDrawButton) {
221+
(shapeToDrawButton as HTMLButtonElement).style.backgroundColor = deselectedButtonColor;
222+
}
223+
state.shapeToDraw = '';
224+
}
225+
198226
if (state.currentlySelectedShape) {
199227
selectShape(null);
200228
}

src/example/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#shapeDrawingSelection > button {
3434
font-size: 2em;
3535
display: block;
36+
background-color: #ccc;
3637
}
3738

3839
#shapeDrawingSelection > button:hover {
@@ -54,6 +55,10 @@
5455
#shapeDrawingOptions > label {
5556
display: block;
5657
}
58+
59+
#shapeDrawingOptions > label > input {
60+
display: block;
61+
}
5762
</style>
5863
</head>
5964
<body style="background-color: #555">

src/options.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export interface ShapeDrawingOptions {
1919
hoveredFillDetection: boolean; // Allows for hovering over the middle of a shape. Always off if joinFirstToLastCorner = false
2020
hoveredCornerShape: HoveredCornerShape | null; // The fill is the same as the border color
2121
hoveredCornerSize: number; // The size of the corner in pixels
22-
hoveredEdgeWidth: number;
23-
hoveredEdgeDetection: boolean;
22+
hoveredBorderWidth: number;
23+
hoveredBorderDetection: boolean;
2424

2525
// Axis options
2626
showTimeAxisLabels: boolean;
@@ -42,12 +42,12 @@ export const defaultOptions: ShapeDrawingOptions = {
4242
joinFirstToLastCorner: true,
4343

4444
mutable: true,
45-
hoveredEdgeWidth: 2,
45+
hoveredBorderWidth: 2,
4646
hoveredFillOpacity: 0.7,
4747
hoveredCornerShape: HoveredCornerShape.Square,
4848
hoveredCornerSize: 20,
4949
hoveredFillDetection: true,
50-
hoveredEdgeDetection: true,
50+
hoveredBorderDetection: true,
5151

5252
showTimeAxisLabels: false,
5353
showPriceAxisLabels: false,

src/shape-drawing.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ export class ShapeDrawing
156156

157157
private _setHovered(yes: boolean) {
158158
if (yes) {
159-
if (this._options.borderWidth !== this._options.hoveredEdgeWidth) {
160-
this._options.borderWidth = this._options.hoveredEdgeWidth;
159+
if (this._options.borderWidth !== this._options.hoveredBorderWidth) {
160+
this._options.borderWidth = this._options.hoveredBorderWidth;
161161
this._options.fillOpacity = this._options.hoveredFillOpacity;
162162
this._highlightCorners = true;
163163
this.requestUpdate();
@@ -197,12 +197,12 @@ export class ShapeDrawing
197197
// For lines (2 points), check if cursor is near the line segment
198198
// For polygons (3+ points), check if cursor is inside the shape
199199
if (points.length === 2) {
200-
if (this._options.hoveredEdgeDetection && this._isPointNearLine(x, y, points[0], points[1])) {
200+
if (this._options.hoveredBorderDetection && this._isPointNearLine(x, y, points[0], points[1])) {
201201
hovered = true;
202202
}
203203
} else if (points.length >= 3) {
204204
if (!this._options.hoveredFillDetection || !this._options.joinFirstToLastCorner) { // Border hovering only
205-
if (this._options.hoveredEdgeDetection) {
205+
if (this._options.hoveredBorderDetection) {
206206
for (let i = 1; i < points.length; i++) {
207207
if (this._isPointNearLine(x, y, points[i - 1], points[i])) {
208208
hovered = true;
@@ -306,7 +306,7 @@ export class ShapeDrawing
306306
return false;
307307
}
308308

309-
const hitRadius = this._options.hoveredEdgeWidth / devicePixelRatio;
309+
const hitRadius = this._options.hoveredBorderWidth / devicePixelRatio;
310310

311311
// Calculate the distance from point (x, y) to line segment (p1, p2)
312312
const A = x - p1.x;

0 commit comments

Comments
 (0)