Skip to content

Commit 4def087

Browse files
author
chmerdon
committed
first draft of 2d vectorplot with UnicodePlots
1 parent 838d19e commit 4def087

1 file changed

Lines changed: 81 additions & 2 deletions

File tree

ext/GridVisualizeUnicodePlotsExt.jl

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ Extension module for UnicodePlots.jl
55
"""
66
module GridVisualizeUnicodePlotsExt
77

8-
import GridVisualize: initialize!, gridplot!, scalarplot!, bregion_cmap, region_cmap, reveal
9-
using GridVisualize: UnicodePlotsType, GridVisualizer, SubVisualizer
8+
import GridVisualize: initialize!, gridplot!, scalarplot!, vectorplot!, bregion_cmap, region_cmap, reveal
9+
using GridVisualize: UnicodePlotsType, GridVisualizer, SubVisualizer, vectorsample, quiverdata
1010
using UnicodePlots: UnicodePlots
1111
using ExtendableGrids: Coordinates, simplexgrid, ON_CELLS, ON_FACES, ON_EDGES, CellNodes, FaceNodes, BFaceNodes, CellGeometries, CellRegions, BFaceRegions, num_cells, num_nodes, local_celledgenodes, num_bfaceregions, num_cellregions, num_targets, interpolate!
1212
using Colors: Colors, RGB, RGBA
@@ -414,4 +414,83 @@ function scalarplot!(
414414
return reveal(ctx, TP)
415415
end
416416

417+
function vectorplot!(ctx, TP::Type{UnicodePlotsType}, ::Type{Val{2}}, grid, func)
418+
419+
rc, rv = vectorsample(grid, func; gridscale = ctx[:gridscale], rasterpoints = ctx[:rasterpoints], offset = ctx[:offset])
420+
qc, qv = quiverdata(rc, rv; vscale = ctx[:vscale], vnormalize = ctx[:vnormalize], vconstant = ctx[:vconstant])
421+
422+
layout = ctx[:layout]
423+
resolution = ctx[:size] ./ 6 ./ (layout[2], layout[1]) # reduce pixel count in the terminal
424+
425+
coords = grid[Coordinates]
426+
ex = extrema(view(coords, 1, :))
427+
ey = extrema(view(coords, 2, :))
428+
429+
if (true) # auto scale feature, do we want this?
430+
wx = ex[2] - ex[1]
431+
wy = ey[2] - ey[1]
432+
rescale = wx / wy * (resolution[1] / (resolution[2]))
433+
if rescale > 1
434+
resolution = (resolution[1], resolution[2] / rescale)
435+
else
436+
resolution = (resolution[1] / rescale, resolution[2])
437+
end
438+
end
439+
440+
# we need an integer resolution
441+
resolution = @. Int(round(resolution))
442+
443+
# create UnicodePlots.Canvas
444+
legend_space = 5
445+
padding = 0.05 * (ex[2] - ex[1])
446+
ex = (ex[1] - padding, ex[2] + padding)
447+
CanvasType = UnicodePlots.BrailleCanvas # should this be a changeable parameter ?
448+
canvas = CanvasType(
449+
resolution[2], resolution[1] + legend_space, # number of rows and columns (characters)
450+
origin_y = 0, origin_x = ex[1], # position in virtual space
451+
height = 1, width = ex[2] - ex[1]; blend = false
452+
)
453+
454+
@info size(rv)
455+
456+
# plot arrows
457+
color_arrow = (150, 150, 150)
458+
color_head = (255, 255, 255)
459+
scale = minimum(resolution) / maximum(ctx[:rasterpoints]) / 300
460+
narrows = size(qv, 2)
461+
for a in 1:narrows
462+
# draw tail
463+
UnicodePlots.annotate!(canvas, qc[1, a], qc[2, a], "+", UInt32(0), false)
464+
# draw arrow
465+
tx, ty = qc[1, a] + 0.8 * qv[1, a], qc[2, a] + 0.8 * qv[2, a]
466+
UnicodePlots.lines!(
467+
canvas,
468+
qc[1, a], qc[2, a],
469+
tx, ty;
470+
color = color_arrow
471+
)
472+
# draw arrow head
473+
n1 = scale * ([qv[2, a], -qv[1, a]] .- (qv[:, a])) ./ norm(qv[:, a])
474+
n1[2] /= 2
475+
UnicodePlots.lines!(
476+
canvas,
477+
tx, ty,
478+
tx + n1[1], ty + n1[2];
479+
color = color_head
480+
)
481+
n2 = scale * ([-qv[2, a], qv[1, a]] .- (qv[:, a])) ./ norm(qv[:, a])
482+
n2[2] /= 2
483+
UnicodePlots.lines!(
484+
canvas,
485+
tx, ty,
486+
tx + n2[1], ty + n2[2];
487+
color = color_head
488+
)
489+
end
490+
491+
ctx[:figure] = UnicodePlots.Plot(canvas; title = ctx[:title])
492+
493+
return reveal(ctx, TP)
494+
end
495+
417496
end # module

0 commit comments

Comments
 (0)