Skip to content

Commit 0cc98b4

Browse files
authored
Merge pull request #152 from martinRenou/stroke_lines
Add stroke_lines method
2 parents fdb0b32 + 3739bdc commit 0cc98b4

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

examples/plotting.ipynb

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -241,19 +241,12 @@
241241
" # Draw lines\n",
242242
" n_points = min(self.x.shape[0], self.y.shape[0])\n",
243243
"\n",
244-
" plot_layer.begin_path()\n",
245244
" plot_layer.stroke_style = self.line_color\n",
246245
" plot_layer.line_width = self.line_width\n",
247246
" plot_layer.line_join = 'bevel'\n",
248247
" plot_layer.line_cap = 'round'\n",
249-
" plot_layer.move_to(self.scale_x(self.x[0]), self.scale_y(self.y[0]))\n",
250-
" for idx in range(1, n_points):\n",
251-
" plot_layer.line_to(\n",
252-
" self.scale_x(self.x[idx]), self.scale_y(self.y[idx])\n",
253-
" )\n",
254-
"\n",
255-
" plot_layer.stroke()\n",
256-
" plot_layer.close_path()\n",
248+
" \n",
249+
" plot_layer.stroke_lines(np.stack((self.scale_x(self.x), self.scale_y(self.y)), axis=1))\n",
257250
"\n",
258251
" plot_layer.restore()"
259252
]
@@ -451,7 +444,7 @@
451444
"metadata": {},
452445
"outputs": [],
453446
"source": [
454-
"n = 1_000\n",
447+
"n = 2_000\n",
455448
"x = np.linspace(0, 100, n)\n",
456449
"y = np.cumsum(np.random.randn(n))\n",
457450
"\n",

ipycanvas/canvas.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
'putImageData': 31, 'clip': 32, 'save': 33, 'restore': 34, 'translate': 35,
3131
'rotate': 36, 'scale': 37, 'transform': 38, 'setTransform': 39, 'resetTransform': 40,
3232
'set': 41, 'clear': 42, 'sleep': 43, 'fillPolygon': 44, 'strokePolygon': 45,
33+
'strokeLines': 46,
3334
}
3435

3536

@@ -575,6 +576,15 @@ def stroke_line(self, x1, y1, x2, y2):
575576
"""Draw a line from ``(x1, y1)`` to ``(x2, y2)``."""
576577
self._send_canvas_command(COMMANDS['strokeLine'], [x1, y1, x2, y2])
577578

579+
def stroke_lines(self, points):
580+
"""Draw a path of consecutive lines from a list of points ``[(x1, y1), (x2, y2), ..., (xn, yn)]``."""
581+
args = []
582+
buffers = []
583+
584+
populate_args(points, args, buffers)
585+
586+
self._send_canvas_command(COMMANDS['strokeLines'], args, buffers)
587+
578588
# Paths methods
579589
def begin_path(self):
580590
"""Call this method when you want to create a new path."""

src/widget.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ const COMMANDS = [
7070
'putImageData', 'clip', 'save', 'restore', 'translate',
7171
'rotate', 'scale', 'transform', 'setTransform', 'resetTransform',
7272
'set', 'clear', 'sleep', 'fillPolygon', 'strokePolygon',
73+
'strokeLines',
7374
];
7475

7576

@@ -361,6 +362,9 @@ class CanvasModel extends DOMWidgetModel {
361362
case 'strokeLine':
362363
this.strokeLine(args, buffers);
363364
break;
365+
case 'strokeLines':
366+
this.strokeLines(args, buffers);
367+
break;
364368
case 'fillPolygon':
365369
this.fillPolygon(args, buffers);
366370
break;
@@ -500,6 +504,20 @@ class CanvasModel extends DOMWidgetModel {
500504
this.ctx.closePath();
501505
}
502506

507+
protected strokeLines(args: any[], buffers: any) {
508+
this.ctx.beginPath();
509+
const points = getArg(args[0], buffers);
510+
511+
// Move to the first point, then create lines between points
512+
this.ctx.moveTo(points.getItem(0), points.getItem(1));
513+
for (let idx = 2; idx < points.length; idx += 2) {
514+
this.ctx.lineTo(points.getItem(idx), points.getItem(idx + 1));
515+
}
516+
517+
this.ctx.stroke();
518+
this.ctx.closePath();
519+
}
520+
503521
protected fillPolygon(args: any[], buffers: any) {
504522
this.ctx.beginPath();
505523
const points = getArg(args[0], buffers);
@@ -674,6 +692,17 @@ class RoughCanvasModel extends CanvasModel {
674692
this.roughCanvas.line(args[0], args[1], args[2], args[3], this.getRoughStrokeStyle());
675693
}
676694

695+
protected strokeLines(args: any[], buffers: any) {
696+
const points = getArg(args[0], buffers);
697+
698+
const polygon: [number, number][] = [];
699+
for (let idx = 0; idx < points.length; idx += 2) {
700+
polygon.push([points.getItem(idx), points.getItem(idx + 1)]);
701+
}
702+
703+
this.roughCanvas.linearPath(polygon, this.getRoughStrokeStyle());
704+
}
705+
677706
protected async fillPath(args: any[], buffers: any) {
678707
const [serializedPath] = args;
679708

0 commit comments

Comments
 (0)