Skip to content

Commit

Permalink
feat: Link (segment) graphic #101
Browse files Browse the repository at this point in the history
  • Loading branch information
lo5 committed Oct 31, 2022
1 parent 5f6751f commit 360f6af
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 2 deletions.
48 changes: 48 additions & 0 deletions help/docs/guide/graphics.md
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,54 @@ view(
![Screenshot](assets/screenshots/graphics_polygon.png)


## Link X

Set `mode='g-link-x'` to draw connecting lines between pairs of points.

Set `data=` to a sequence of normalized `[x1, y1, x2, y2, t1, t2]` values, where:

- `(x1, y1)` is the start point.
- `(x2, y2)` is the end point.
- `t1` (optional) is the start thickness. If omitted, the stroke thickness can be controlled using `style=`.
- `t2` (optional) is the end thickness. Defaults to `t1` if omitted.


```py
view(row(
box(
mode='g-link-x',
style='h-32 w-32 fill-none stroke-indigo-700',
data=[
[0.1, 0.75, 0.9, 0.95],
[0.1, 0.5, 0.9, 0.5],
[0.1, 0.25, 0.9, 0.05],
],
),
box(
mode='g-link-x',
style='h-32 w-32 fill-indigo-700 stroke-none',
data=[
[0.1, 0.75, 0.9, 0.75, 0.05], # add thickness
[0.1, 0.5, 0.9, 0.5, 0.1], # more thickness
[0.1, 0.25, 0.9, 0.25, 0.25], # even more thickness
],
),
box(
mode='g-link-x',
style='h-32 w-32 fill-indigo-700 stroke-none',
data=[
[0.1, 0.75, 0.9, 0.75, 0.1, 0.2], # start thin, end thick
[0.1, 0.5, 0.9, 0.5, 0.2, 0.1], # start thick, end thin
[0.1, 0.25, 0.9, 0.25, 0.1, 0.1], # uniform thickness
],
),
))
```


![Screenshot](assets/screenshots/graphics_link_x.png)


## Win Loss

Stack two bar graphics vertically to create a win-loss graphic.
Expand Down
1 change: 1 addition & 0 deletions help/docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ Draw visualizations, microcharts, sparklines, and other data graphics.
- [Circle](graphics.md#circle)
- [Polyline](graphics.md#polyline)
- [Polygon](graphics.md#polygon)
- [Link X](graphics.md#link-x)
- [Win Loss](graphics.md#win-loss)
- [Stacked bar](graphics.md#stacked-bar)
- [Bullet graph](graphics.md#bullet-graph)
Expand Down
41 changes: 41 additions & 0 deletions py/pkg/docs/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,47 @@ def graphics_polygon(view: View): # height 3
)


# ## Link X
# Set `mode='g-link-x'` to draw connecting lines between pairs of points.
#
# Set `data=` to a sequence of normalized `[x1, y1, x2, y2, t1, t2]` values, where:
#
# - `(x1, y1)` is the start point.
# - `(x2, y2)` is the end point.
# - `t1` (optional) is the start thickness. If omitted, the stroke thickness can be controlled using `style=`.
# - `t2` (optional) is the end thickness. Defaults to `t1` if omitted.
def graphics_link_x(view: View): # height 3
view(row(
box(
mode='g-link-x',
style='h-32 w-32 fill-none stroke-indigo-700',
data=[
[0.1, 0.75, 0.9, 0.95],
[0.1, 0.5, 0.9, 0.5],
[0.1, 0.25, 0.9, 0.05],
],
),
box(
mode='g-link-x',
style='h-32 w-32 fill-indigo-700 stroke-none',
data=[
[0.1, 0.75, 0.9, 0.75, 0.05], # add thickness
[0.1, 0.5, 0.9, 0.5, 0.1], # more thickness
[0.1, 0.25, 0.9, 0.25, 0.25], # even more thickness
],
),
box(
mode='g-link-x',
style='h-32 w-32 fill-indigo-700 stroke-none',
data=[
[0.1, 0.75, 0.9, 0.75, 0.1, 0.2], # start thin, end thick
[0.1, 0.5, 0.9, 0.5, 0.2, 0.1], # start thick, end thin
[0.1, 0.25, 0.9, 0.25, 0.1, 0.1], # uniform thickness
],
),
))


# ## Win Loss
# Stack two bar graphics vertically to create a win-loss graphic.
def graphics_win_loss(view: View): # height 3
Expand Down
4 changes: 4 additions & 0 deletions web/src/box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ export const XBox = ({ context: root, box }: BoxProps) => { // recursive
if (modes.has('g-circle')) return <Graphic2 context={context} box={box} />
if (modes.has('g-polyline')) return <Graphic2 context={context} box={box} />
if (modes.has('g-polygon')) return <Graphic2 context={context} box={box} />
if (modes.has('g-link-x')) return <Graphic2 context={context} box={box} />
if (modes.has('g-link-y')) return <Graphic2 context={context} box={box} />
if (modes.has('g-spline-x')) return <Graphic2 context={context} box={box} />
if (modes.has('g-spline-y')) return <Graphic2 context={context} box={box} />
if (modes.has('g')) return <Graphic context={context} box={box} />

if (modes.has('menu')) return (
Expand Down
24 changes: 23 additions & 1 deletion web/src/graphics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type Pairs = Pair[]
const
lerp = (f: F, a: F, b: F) => a * (1.0 - f) + (b * f),
clamp1 = (f: any) => isN(f) ? f < 0 ? 0 : f > 1 ? 1 : f : 0,
clamp1s = (fs: F[]) => fs.map(clamp1),
clamp1s = (fs: any[]) => fs.map(clamp1),
isPair = (x: any) => Array.isArray(x) && x.length === 2,
arePairs = (xs: any[]): xs is Pairs => xs.every(isPair),
newEl = (t: S) => document.createElementNS('http://www.w3.org/2000/svg', t),
Expand Down Expand Up @@ -547,6 +547,28 @@ export const Graphic2 = ({ box }: BoxProps) => {
svg.appendChild(el)
}
}
} else if (modes.has('g-link-x')) {
for (const d of data) {
if (Array.isArray(d)) {
let [x1, y1, x2, y2, t1, t2] = clamp1s(d)
x1 *= width
y1 = (1 - y1) * height
x2 *= width
y2 = (1 - y2) * height
if (isN(t1)) {
if (!isN(t2)) t2 = t1
t1 *= height / 2
t2 *= height / 2
const el = newEl('polygon')
el.setAttribute('points', `${x1},${y1 - t1} ${x2},${y2 - t2} ${x2},${y2 + t2} ${x1},${y1 + t1}`)
svg.appendChild(el)
} else {
const el = newEl('polyline')
el.setAttribute('points', `${x1},${y1} ${x2},${y2}`)
svg.appendChild(el)
}
}
}
}

while (div.firstChild) div.removeChild(div.firstChild)
Expand Down
2 changes: 1 addition & 1 deletion web/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export type BoxModifier = 'live'
| 'top' | 'middle' | 'bottom' | 'left' | 'center' | 'right'
| 'open' | 'closed'
// Graphics ("g") modes:
| 'g-label' | 'g-rect' | 'g-circle' | 'g-polygon' | 'g-polyline'
| 'g-label' | 'g-rect' | 'g-circle' | 'g-polygon' | 'g-polyline' | 'g-link-x' | 'g-link-y' | 'g-spline-x' | 'g-spline-y'
| 'gauge-c' | 'gauge-sc'
| 'guide-x' | 'gauge-x'
| 'line-y' | 'curve-y' | 'step-y' | 'bar-y' | 'stroke-y' | 'tick-y' | 'guide-y' | 'gauge-y'
Expand Down

0 comments on commit 360f6af

Please sign in to comment.