@@ -369,6 +369,8 @@ function gr_polyline(
369369 arrowside = :none ,
370370 arrowstyle = :simple ,
371371 arrowsize = 1 ,
372+ linestyle = :solid ,
373+ linewidth = 1.0 ,
372374 )
373375 draw_head = arrowside in (:head , :both )
374376 draw_tail = arrowside in (:tail , :both )
@@ -395,7 +397,11 @@ function gr_polyline(
395397 end
396398 # if we found a start and end, draw the line segment, otherwise we're done
397399 if istart > 0 && iend > 0
398- func (x[istart: iend], y[istart: iend])
400+ if func === GR. polyline
401+ gr_styled_polyline (x[istart: iend], y[istart: iend], linestyle, linewidth)
402+ else
403+ func (x[istart: iend], y[istart: iend])
404+ end
399405 if draw_head
400406 gr_set_arrowstyle (arrowstyle)
401407 GR. drawarrow (x[iend - 1 ], y[iend - 1 ], x[iend], y[iend])
@@ -411,6 +417,59 @@ function gr_polyline(
411417 return
412418end
413419
420+ function gr_styled_polyline (x, y, style, linewidth)
421+ style in (:dash , :dot , :dashdot , :dashdotdot ) || return GR. polyline (x, y)
422+ GR. setlinetype (gr_linetypes. solid)
423+ lscale = max (1 , linewidth) / 2
424+ dash = 0.012 lscale
425+ gap = 0.008 lscale
426+ dot = 0.0025 lscale
427+ return if style === :dash
428+ gr_dashed_polyline (x, y, (dash, gap))
429+ elseif style === :dot
430+ gr_dashed_polyline (x, y, (dot, gap))
431+ elseif style === :dashdot
432+ gr_dashed_polyline (x, y, (dash, gap, dot, gap))
433+ else
434+ gr_dashed_polyline (x, y, (dash, gap, dot, gap, dot, gap))
435+ end
436+ end
437+
438+ function gr_dashed_polyline (x, y, pattern)
439+ ipattern = 1
440+ pattern_offset = 0.0
441+ xs = Vector {Float64} (undef, 2 )
442+ ys = Vector {Float64} (undef, 2 )
443+ for i in 1 : (length (x) - 1 )
444+ x1, y1 = GR. wctondc (x[i], y[i])
445+ x2, y2 = GR. wctondc (x[i + 1 ], y[i + 1 ])
446+ dx, dy = x2 - x1, y2 - y1
447+ segment_length = hypot (dx, dy)
448+ segment_length > 0 || continue
449+ segment_offset = 0.0
450+ while segment_offset < segment_length
451+ pattern_remaining = pattern[ipattern] - pattern_offset
452+ step = min (pattern_remaining, segment_length - segment_offset)
453+ if isodd (ipattern)
454+ t1 = segment_offset / segment_length
455+ t2 = (segment_offset + step) / segment_length
456+ xa, ya = GR. ndctowc (x1 + t1 * dx, y1 + t1 * dy)
457+ xb, yb = GR. ndctowc (x1 + t2 * dx, y1 + t2 * dy)
458+ xs[1 ], xs[2 ] = xa, xb
459+ ys[1 ], ys[2 ] = ya, yb
460+ GR. polyline (xs, ys)
461+ end
462+ segment_offset += step
463+ pattern_offset += step
464+ if pattern_offset >= pattern[ipattern]
465+ pattern_offset = 0.0
466+ ipattern = ipattern == length (pattern) ? 1 : ipattern + 1
467+ end
468+ end
469+ end
470+ return
471+ end
472+
414473function gr_polyline3d (x, y, z, func = GR. polyline3d)
415474 iend = 0
416475 n = length (x)
@@ -600,10 +659,11 @@ end
600659# ---------------------------------------------------------
601660
602661function gr_set_line (lw, style, c, s) # s can be Subplot or Series
662+ linewidth = get_thickness_scaling (s) * max (0 , lw / gr_nominal_size (s))
603663 GR. setlinetype (gr_linetypes[style])
604- GR. setlinewidth (get_thickness_scaling (s) * max ( 0 , lw / gr_nominal_size (s)) )
664+ GR. setlinewidth (linewidth )
605665 gr_set_linecolor (c)
606- return nothing
666+ return linewidth
607667end
608668
609669gr_set_fill (c) = (gr_set_fillcolor (c); GR. setfillintstyle (GR. INTSTYLE_SOLID); nothing )
@@ -1190,7 +1250,7 @@ gr_legend_bbox(xpos, ypos, leg) = GR.drawrect(
11901250 ypos + 0.5 leg. dy,
11911251)
11921252
1193- const gr_lw_clamp_factor = Ref (5 )
1253+ const gr_lw_clamp_factor = Ref (3 )
11941254
11951255function gr_add_legend (sp, leg, viewport_area)
11961256 sp[:legend_position ] ∈ (:none , :inline ) && return
@@ -1244,7 +1304,7 @@ function gr_add_legend(sp, leg, viewport_area)
12441304 ls = get_linestyle (series)
12451305 la = get_linealpha (series)
12461306 clamped_lw = (lfps / 8 ) * clamp (lw, min_lw, max_lw)
1247- gr_set_line (clamped_lw, ls, lc, sp) # see github.com/JuliaPlots/Plots.jl/issues/3003
1307+ linewidth = gr_set_line (clamped_lw, ls, lc, sp) # see github.com/JuliaPlots/Plots.jl/issues/3003
12481308 _debug[] && gr_legend_bbox (xpos, ypos, leg)
12491309
12501310 if ((st ≡ :shape || series[:fillrange ] ≢ nothing ) && series[:ribbon ] ≡ nothing )
@@ -1262,16 +1322,21 @@ function gr_add_legend(sp, leg, viewport_area)
12621322 gr_set_transparency (fc, get_fillalpha (series))
12631323 gr_polyline (x, y, GR. fillarea)
12641324 gr_set_transparency (lc, la)
1265- gr_set_line (clamped_lw, ls, lc, sp)
1266- st ≡ :shape && gr_polyline (x, y)
1325+ linewidth = gr_set_line (clamped_lw, ls, lc, sp)
1326+ st ≡ :shape && gr_styled_polyline (x, y, ls, linewidth )
12671327 end
12681328
12691329 max_markersize = Inf
12701330 if st in (:path , :straightline , :path3d )
12711331 max_markersize = leg. base_markersize
12721332 gr_set_transparency (lc, la)
12731333 filled = series[:fillrange ] ≢ nothing && series[:ribbon ] ≡ nothing
1274- GR. polyline (xpos .+ [lft, rgt], ypos .+ (filled ? [top, top] : [0 , 0 ]))
1334+ gr_styled_polyline (
1335+ xpos .+ [lft, rgt],
1336+ ypos .+ (filled ? [top, top] : [0 , 0 ]),
1337+ ls,
1338+ linewidth,
1339+ )
12751340 end
12761341
12771342 if (msh = series[:markershape ]) ≢ :none
@@ -2033,7 +2098,8 @@ function gr_draw_segments(series, x, y, z, fillrange, clims)
20332098 GR. fillarea (fx, fy)
20342099 end
20352100 (lc = get_linecolor (series, clims, i)) |> gr_set_fillcolor
2036- gr_set_line (get_linewidth (series, i), get_linestyle (series, i), lc, series)
2101+ ls = get_linestyle (series, i)
2102+ linewidth = gr_set_line (get_linewidth (series, i), ls, lc, series)
20372103 gr_set_transparency (lc, get_linealpha (series, i))
20382104 if is3d
20392105 GR. polyline3d (x[rng], y[rng], z[rng])
@@ -2044,7 +2110,15 @@ function gr_draw_segments(series, x, y, z, fillrange, clims)
20442110 arrowside, arrowstyle, arrowsize =
20452111 arrow. side, arrow. style, (arrow. headlength + arrow. headwidth) / 2
20462112
2047- gr_polyline (x[rng], y[rng]; arrowside, arrowstyle, arrowsize)
2113+ gr_polyline (
2114+ x[rng],
2115+ y[rng];
2116+ arrowside,
2117+ arrowstyle,
2118+ arrowsize,
2119+ linestyle = ls,
2120+ linewidth,
2121+ )
20482122 end
20492123 end
20502124 return
@@ -2110,9 +2184,10 @@ function gr_draw_shapes(series, clims)
21102184
21112185 # draw the shapes
21122186 lc = get_linecolor (series, clims, i)
2113- gr_set_line (get_linewidth (series, i), get_linestyle (series, i), lc, series)
2187+ ls = get_linestyle (series, i)
2188+ linewidth = gr_set_line (get_linewidth (series, i), ls, lc, series)
21142189 gr_set_transparency (lc, get_linealpha (series, i))
2115- GR . polyline (xseg, yseg)
2190+ gr_styled_polyline (xseg, yseg, ls, linewidth )
21162191 end
21172192 end
21182193 return
0 commit comments