From 3bdc9b9072bba774cd5c604fe185d39ddbdc911e Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 9 Dec 2022 18:16:10 +0100 Subject: 2022-12-09 16:33:00 --- metapost/context/base/mpxl/mp-lmtx.mpxl | 134 +++++++++++++++++--------------- 1 file changed, 71 insertions(+), 63 deletions(-) (limited to 'metapost') diff --git a/metapost/context/base/mpxl/mp-lmtx.mpxl b/metapost/context/base/mpxl/mp-lmtx.mpxl index f26af8a60..e6daff660 100644 --- a/metapost/context/base/mpxl/mp-lmtx.mpxl +++ b/metapost/context/base/mpxl/mp-lmtx.mpxl @@ -1024,6 +1024,7 @@ presetparameters "chart" [ percentage = false, maximum = 0, distance = 1mm, + threshold = eps, % labels = { }, labelstyle = "", @@ -1084,17 +1085,18 @@ def lmt_chart_bar = applyparameters "chart:bar" "lmt_do_chart_bar" def lmt_do_chart_start (expr what) = pushparameters what ; - save width, height, depth, distance, linewidth, linegap, labelgap, labelfraction, value, nofsamples, nofsamplesets ; + save width, height, depth, distance, threshold, linewidth, linegap, labelgap, labelfraction, value, nofsamples, nofsamplesets ; save fillcolor, linecolor, drawcolor, labelcolor, labelstyle, labelformat, labelstrut, labelanchor, colormode ; string fillcolor, linecolor, drawcolor, labelcolor, labelstyle, labelformat, labelstrut, labelanchor, colormode ; if hasparameter "sampleset" : setluaparameter what "samples" (getparameter "sampleset") ; fi ; + threshold := getparameter "threshold" ; + linewidth := getparameter "linewidth" ; height := getparameter "height" ; - depth := max((getparameter "originsize"), (getparameter "innerradius")) ; + depth := max(getparameter "originsize", (getparameter "innerradius"), 8*linewidth) ; width := getparameter "width" ; distance := getparameter "distance" ; - linewidth := getparameter "linewidth" ; linegap := getparameterdefault "linegap" linewidth ; drawcolor := getparameter "drawcolor" ; colormode := getparameter "colormode" ; @@ -1194,78 +1196,84 @@ vardef lmt_do_chart_circle = nofsamplesets := 1 ; save p, q, r, s, t, pl, ql, first, last, total, factor, n, percentage, initial, clockwise ; path p, q, r, s[], t[] ; boolean percentage, clockwise ; + save value, v; clockwise := true ; percentage := getparameter "percentage" ; initial := if not clockwise : - fi getparameter "initialangle" ; % watch sign total := 0 ; for i = 1 upto nofsamples : - total := total + getparameter "samples" (1) i ; % () is needed else 1i - endfor ; - factor := 100/total ; - first := initial ; - if clockwise : - p := (reverse fullcircle rotated first) ysized (height) ; - q := (reverse fullcircle rotated first) ysized (depth) ; - else : - p := fullcircle ysized (height) ; - q := fullcircle ysized (depth) ; - fi ; - r := origin -- (2*height,0) ; - pl := ((linewidth + linegap) / (arclength p)) * 360; - ql := ((linewidth + linegap) / (arclength q)) * 360; - for i = 1 upto nofsamples : - fillcolor := getparameter "fillcolors" i ; - linecolor := getparameterdefault "linecolors" i "" ; - if linecolor = "" : - linecolor := fillcolor ; + value := getparameter "samples" (1) i ; + if value > threshold : + total := total + value ; fi ; - value := (getparameter "samples" (1) i) * factor ; -if (value > -eps) and (value < eps) : - s[i] := origin ; - t[i] := origin ; -else : -% if (value > -eps) and (value < eps) : -% value := eps ; % otherwise weird effects with zero -% fi ; - last := first if clockwise : - else : + fi (360/100) * value ; - s[i] := ((p cutbefore (r rotated first)) cutafter (r rotated (last + pl))) ; - t[i] := reverse ((q cutbefore (r rotated first)) cutafter (r rotated (last + ql))) ; - path piece ; piece := s[i] -- t[i] -- cycle ; - if fillcolor <> "" : - fill piece - withpen pencircle scaled linewidth - withcolor fillcolor - ; - fi ; - if linecolor <> "" : - if linewidth > 0 : - interim linecap := butt ; - draw piece - withpen pencircle scaled linewidth - withcolor if linecolor <> "" : linecolor else drawcolor : fi - ; - fi ; - fi ; - first := last ; -fi ; endfor ; - if linewidth > 0 : - clip currentpicture to p enlarged linewidth ; - fi ; - if getparameter "showlabels" : + if total = 0 : + message("zero total in circular chart"); + else : + factor := 100/total ; first := initial ; + if clockwise : + p := (reverse fullcircle rotated first) ysized (height) ; + q := (reverse fullcircle rotated first) ysized (depth) ; + else : + p := fullcircle ysized (height) ; + q := fullcircle ysized (depth) ; + fi ; + r := origin -- (2*height,0) ; + pl := ((linewidth + linegap) / (arclength p)) * 360; + ql := ((linewidth + linegap) / (arclength q)) * 360; + v := 0 ; for i = 1 upto nofsamples : value := getparameter "samples" (1) i ; - last := first if clockwise : - else : + fi (360/100) * value * factor ; -if (value > -eps) and (value < eps) : -else : - draw lmt_do_chart_text (s,i,value) - shifted ((labelfraction*(height/2),0) rotated ((first+last)/2)) ; - first := last ; -fi ; + if value > threshold : + v := v + 1 ; + fillcolor := getparameter "fillcolors" i ; + linecolor := getparameterdefault "linecolors" i "" ; + if linecolor = "" : + linecolor := fillcolor ; + fi ; + value := value * factor ; + last := first if clockwise : - else : + fi (360/100) * value ; + s[v] := ((p cutbefore (r rotated first)) cutafter (r rotated (last + pl))) ; + t[v] := reverse ((q cutbefore (r rotated first)) cutafter (r rotated (last + ql))) ; + path piece ; piece := s[v] -- t[v] -- cycle ; + if fillcolor <> "" : + fill piece + withpen pencircle scaled linewidth + withcolor fillcolor + ; + fi ; + if linecolor <> "" : + if linewidth > 0 : + interim linecap := butt ; + draw piece + withpen pencircle scaled linewidth + withcolor if linecolor <> "" : linecolor else drawcolor : fi + ; + fi ; + fi ; + first := last ; + fi ; endfor ; + if linewidth > 0 : + clip currentpicture to p enlarged linewidth ; + fi ; + if getparameter "showlabels" : + first := initial ; + v := 0 ; + for i = 1 upto nofsamples : + value := getparameter "samples" (1) i ; + if value > threshold : + v := v + 1 ; + last := first if clockwise : - else : + fi (360/100) * value * factor ; + draw lmt_do_chart_text (s,i,value) + shifted ((labelfraction*(height/2),0) rotated ((first+last)/2)) ; + first := last ; + fi + endfor ; + fi ; + lmt_do_chart_legend ; fi ; - lmt_do_chart_legend ; fi ; lmt_do_chart_stop ; ) -- cgit v1.2.3