summaryrefslogtreecommitdiff
path: root/metapost/context/base/mpiv/mp-lmtx.mpxl
diff options
context:
space:
mode:
Diffstat (limited to 'metapost/context/base/mpiv/mp-lmtx.mpxl')
-rw-r--r--metapost/context/base/mpiv/mp-lmtx.mpxl521
1 files changed, 521 insertions, 0 deletions
diff --git a/metapost/context/base/mpiv/mp-lmtx.mpxl b/metapost/context/base/mpiv/mp-lmtx.mpxl
index 45e216eef..9026255b3 100644
--- a/metapost/context/base/mpiv/mp-lmtx.mpxl
+++ b/metapost/context/base/mpiv/mp-lmtx.mpxl
@@ -18,6 +18,51 @@ if known context_lmtx : endinput ; fi ;
boolean context_lmtx ; context_lmtx := true ;
+presetparameters "text" [
+ offset = 0,
+ strut = "auto",
+ style = "",
+ color = "",
+ text = "",
+ anchor = "",
+ format = "",
+ position = origin,
+] ;
+
+def lmt_text = applyparameters "text" "lmt_do_text" enddef ;
+
+vardef lmt_do_text =
+ image (
+ pushparameters "text" ;
+ save style, anchor, txt, fmt, strt ;
+ string style, anchor, txt, fmt, strt ;
+ interim textextoffset := getparameter "offset" ;
+ style := getparameter "style" ;
+ anchor := getparameter "anchor" ;
+ strt := getparameter "strut" ;
+ fmt := getparameter "format" ;
+ txt := getparameter "text" ;
+ if fmt <> "" :
+ txt := "\formatone{" & fmt & "}{" & txt & "}"
+ fi ;
+ if strt == "yes" :
+ txt := "\strut " & txt ;
+ elseif strt == "auto" :
+ txt := "\setstrut\strut " & txt ;
+ fi ;
+ if style <> "" :
+ txt := "\style[" & style & "]{" & txt & "}" ;
+ fi ;
+ draw
+ if anchor == "" : thetextext else : scantokens("thetextext." & anchor) fi (
+ txt,
+ getparameter "position"
+ )
+ withcolor getparameter "color" ;
+ popparameters ;
+ )
+enddef ;
+
presetparameters "grid" [
nx = 1, dx = 1,
ny = 1, dy = 1,
@@ -841,3 +886,479 @@ enddef ;
vardef OverlayMesh(expr p, s) =
lmt_mesh [ paths = { meshed(p,OverlayBox,s) } ]
enddef ;
+
+% charts
+
+presetparameters "chart" [
+ originsize = 1mm,
+ trace = false,
+ showlabels = true,
+ center = false,
+
+ samples = { },
+
+ cumulative = false,
+ percentage = false,
+ maximum = 0,
+ distance = 1mm,
+
+ % labels = { },
+ labelstyle = "",
+ labelformat = "",
+ % labelstrut = "auto",
+ % labelanchor = "",
+ % labeloffset = 0,
+ labelfraction = 0.8,
+ labelcolor = "",
+
+ backgroundcolor = "",
+ drawcolor = "white",
+ fillcolors = { % use color palet
+ "darkred", "darkgreen", "darkblue",
+ "darkyellow", "darkmagenta", "darkcyan",
+ "darkgray"
+ },
+ colormode = "global",
+
+ linewidth = .25mm,
+
+ legendcolor = "",
+ legendstyle = "",
+ legend = { },
+] ;
+
+presetparameters "chart:circle" "chart" [
+ height = 5cm,
+ width = 5mm,
+ labelanchor = "",
+ labeloffset = 0,
+ labelstrut = "no",
+] ;
+
+presetparameters "chart:histogram" "chart" [
+ height = 5cm,
+ width = 5mm,
+ labelanchor = "bot",
+ labeloffset = 1mm,
+ labelstrut = "auto",
+] ;
+
+presetparameters "chart:bar" "chart" [
+ height = 5mm,
+ width = 5cm,
+ labelanchor = "lft",
+ labeloffset = 1mm,
+ labelstrut = "no",
+] ;
+
+def lmt_chart_circle = applyparameters "chart:circle" "lmt_do_chart_circle" enddef ;
+def lmt_chart_histogram = applyparameters "chart:histogram" "lmt_do_chart_histogram" enddef ;
+def lmt_chart_bar = applyparameters "chart:bar" "lmt_do_chart_bar" enddef ;
+
+def lmt_do_chart_start (expr what) =
+ pushparameters what ;
+ save width, height, distance, linewidth, labelgap, labelfraction, value, nofsamples, nofsamplesets ;
+ save fillcolor, drawcolor, labelcolor, labelstyle, labelformat, labelstrut, labelanchor, colormode ;
+ string fillcolor, drawcolor, labelcolor, labelstyle, labelformat, labelstrut, labelanchor, colormode ;
+ height := getparameter "height" ;
+ width := getparameter "width" ;
+ distance := getparameter "distance" ;
+ linewidth := getparameter "linewidth" ;
+ drawcolor := getparameter "drawcolor" ;
+ colormode := getparameter "colormode" ;
+ labelcolor := getparameter "labelcolor" ;
+ labelgap := getparameter "labeloffset" ;
+ labelstyle := getparameter "labelstyle" ;
+ labelformat := getparameter "labelformat" ;
+ labelstrut := getparameter "labelstrut" ;
+ labelanchor := getparameter "labelanchor" ;
+ labelfraction := getparameter "labelfraction" ;
+ nofsamplesets := getparametercount "samples" ;
+ nofsamples := getmaxparametercount "samples" ;
+enddef ;
+
+def lmt_do_chart_stop =
+ if getparameter "center" :
+ currentpicture := currentpicture shifted - center currentpicture ;
+ fi
+ if (getparameter "backgroundcolor") <> "" :
+ addbackground withcolor getparameter "backgroundcolor" ;
+ fi
+ if getparameter "trace" :
+ save b ; path b ; b := boundingbox currentpicture ;
+ draw image (
+ draw fullcircle scaled 1mm ;
+ draw b
+ )
+ dashed evenly scaled 1/4
+ withpen pencircle scaled .125mm
+ withcolor "darkgray" ;
+ fi
+ popparameters ;
+enddef ;
+
+vardef lmt_do_chart_text(expr s, i, value) =
+ lmt_text [
+ style = labelstyle,
+ format = labelformat,
+ strut = labelstrut,
+ anchor = labelanchor,
+ offset = labelgap,
+ color = labelcolor,
+ text = (getparameterdefault "labels" s i (decimal value))
+ ]
+enddef ;
+
+def lmt_do_chart_legend =
+ n := getparametercount "legend" ;
+ if n > 0 :
+ save dx, dy, p, l, w, o, d, ddy ; picture l ;
+ dx := xpart urcorner currentpicture + EmWidth ;
+ dy := ypart urcorner currentpicture ;
+ labelcolor := getparameter "legendcolor" ;
+ labelstyle := getparameter "legendstyle" ;
+ w := 2EmWidth ;
+ o := .25EmWidth ;
+ d := ExHeight ;
+ ddy := .8LineHeight ;
+ for i=1 upto n :
+ dy := dy - ddy ;
+ l := lmt_text [
+ text = getparameter "legend" i,
+ anchor = "rt"
+ style = labelstyle,
+ color = labelcolor,
+ ] ;
+ fill leftboundary l rightenlarged w
+ shifted (dx,dy+d)
+ withcolor getparameter "fillcolors" i ;
+ draw l
+ shifted (dx+w+o,dy+d) ;
+ endfor ;
+ fi ;
+enddef ;
+
+vardef lmt_do_chart_circle =
+ image (
+ lmt_do_chart_start("chart:circle") ;
+ if (nofsamplesets > 0) and (nofsamples > 0) :
+ nofsamplesets := 1 ;
+ save p, r, s, first, last, total, factor, n, percentage ;
+ path p, r, s[] ; boolean percentage ;
+ percentage := getparameter "percentage" ;
+ total := 0 ;
+ for i = 1 upto nofsamples :
+ total := total + getparameter "samples" (1) i ; % () is needed else 1i
+ endfor ;
+ factor := 100/total ;
+ first := 0 ;
+ p := fullcircle ysized (height) ;
+ r := origin -- (2*height,0) ;
+ for i = 1 upto nofsamples :
+ fillcolor := getparameter "fillcolors" i ;
+ value := (getparameter "samples" (1) i) * factor ;
+ last := first + (360 / 100) * value ;
+ s[i] := ((p cutbefore (r rotated first)) cutafter (r rotated last)) ;
+ fill origin -- s[i] -- cycle withcolor fillcolor ;
+ first := last ;
+ endfor ;
+ if linewidth > 0 :
+ if drawcolor == "" :
+ drawcolor := backgroundcolor ;
+ fi ;
+ for i = 1 upto nofsamples :
+ interim linecap := butt ;
+ draw origin -- (point 0 of s[i]) withpen pencircle scaled linewidth withcolor drawcolor ;
+ draw origin -- (point length(s[i]) of s[i]) withpen pencircle scaled linewidth withcolor drawcolor ;
+ endfor ;
+ fi ;
+ if getparameter "showlabels" :
+ first := 0 ;
+ for i = 1 upto nofsamples :
+ value := getparameter "samples" (1) i ;
+ last := first + (360/100) * value * factor ;
+ draw lmt_do_chart_text (s,i,value)
+ shifted ((labelfraction*(height/2),0) rotated ((first+last)/2)) ;
+ first := last ;
+ endfor ;
+ fi ;
+ lmt_do_chart_legend ;
+ n := getparameter "originsize" ;
+ if n > 0 :
+ fill fullcircle scaled n withcolor "white" ;
+ fi ;
+ fi ;
+ lmt_do_chart_stop ;
+ )
+enddef ;
+
+vardef lmt_do_chart_histogram =
+ image (
+ lmt_do_chart_start("chart:histogram") ;
+ if (nofsamplesets > 0) and (nofsamples > 0) :
+ save value, maximum, cumulative, maxwidth ; boolean cumulative ;
+ maximum := getparameter "maximum" ;
+ cumulative := getparameter "cumulative" ;
+ if labelanchor = "center" :
+ labelanchor := "vcenter" ;
+ fi ;
+ if maximum = 0 :
+ for s = 1 upto nofsamplesets :
+ for i = 1 upto nofsamples :
+ value := getparameter "samples" s i ;
+ maximum := if cumulative :
+ maximum + value ;
+ else :
+ max(maximum,value) ;
+ fi ;
+ endfor ;
+ endfor ;
+ fi ;
+ if nofsamplesets = 1 :
+ distance := 0 ;
+ fi ;
+ maxwidth := nofsamplesets * nofsamples * width + (nofsamples - 1)* distance ;
+ value := 0 ;
+ for s = 1 upto nofsamplesets :
+ for i = 1 upto nofsamples :
+ value := if cumulative : value + fi (getparameter "samples" s i) * height / maximum ;
+ fill unitsquare xyscaled (width,value)
+ if linewidth > 0 :
+ if i > 1 : leftenlarged (-linewidth/2) fi
+ if i < nofsamples : rightenlarged (-linewidth/2) fi
+ fi
+ shifted (nofsamplesets*(i-1)*width+(s-1)*width+(i-1)*distance,0)
+ withcolor getparameter "fillcolors" if colormode = "local" : s else : i fi ;
+ endfor ;
+ endfor ;
+ setbounds currentpicture to unitsquare xyscaled (maxwidth,height) ;
+ for s = 1 upto nofsamplesets :
+ if getparameter "showlabels" :
+ for i = 1 upto nofsamples :
+ draw lmt_do_chart_text (s,i,getparameter "samples" s i)
+ shifted (nofsamplesets*((i-1)*width)+width/2+(s-1)*width+(i-1)*distance,0) ;
+ endfor ;
+ fi ;
+ endfor ;
+ lmt_do_chart_legend ;
+ fi ;
+ lmt_do_chart_stop ;
+ )
+enddef ;
+
+vardef lmt_do_chart_bar =
+
+ image (
+ lmt_do_chart_start("chart:bar") ;
+ if (nofsamplesets > 0) and (nofsamples > 0) :
+ save value, maximum, cumulative, maxheight ; boolean cumulative ;
+ maximum := getparameter "maximum" ;
+ cumulative := getparameter "cumulative" ;
+ if labelanchor = "center" :
+ labelanchor := "hcenter" ;
+ fi ;
+ if maximum = 0 :
+ for s = 1 upto nofsamplesets :
+ for i = 1 upto nofsamples :
+ value := getparameter "samples" s i ;
+ maximum := if cumulative : maximum + value else : max(maximum,value) fi ;
+ endfor ;
+ endfor ;
+ fi ;
+ if nofsamplesets = 1 :
+ distance := 0 ;
+ fi ;
+ maxheight := nofsamplesets * nofsamples * height + (nofsamples - 1)* distance ;
+ for s = 1 upto nofsamplesets :
+ value := 0 ;
+ for i = 1 upto nofsamples :
+ value := if cumulative : value + fi (getparameter "samples" s i) * width / maximum ;
+ fill unitsquare xyscaled (value,height)
+ if linewidth > 0 :
+ if i > 1 : topenlarged (-linewidth/2) fi
+ if i < nofsamples : bottomenlarged (-linewidth/2) fi
+ fi
+ shifted (0,maxheight-nofsamplesets*i*height+(s-1)*height-(i-1)*distance)
+ withcolor getparameter "fillcolors" if colormode = "local" : s else : i fi ;
+ endfor ;
+ endfor ;
+ setbounds currentpicture to unitsquare xyscaled (width,maxheight) ;
+ if getparameter "showlabels" :
+ for s = 1 upto nofsamplesets :
+ for i = 1 upto nofsamples :
+ draw lmt_do_chart_text (s,i,getparameter "samples" s i)
+ shifted (0,maxheight-nofsamplesets*(i*height)+height/2+(s-1)*height-(i-1)*distance) ;
+ endfor ;
+ endfor ;
+ fi ;
+ lmt_do_chart_legend ;
+ fi ;
+ lmt_do_chart_stop ;
+ )
+enddef ;
+
+% more complex than needed but i want to trace so i need the vars
+
+presetparameters "shade" [
+ alternative = "circular",
+ path = origin -- cycle,
+ trace = false
+
+ % alternative = "circular" | "linear"
+ % domain = { a, b }
+ % radius = a | { a, b }
+ % factor = a
+ % origin = (a,b) | { (a,b), {c, d) }
+ % vector = { a, b }
+ % colors = { a, b }
+ % center = a | { a, b }
+ % direction = "up" | "down" | "left" | "right" | { a, b }
+
+] ;
+
+def lmt_shade = applyparameters "shade" "lmt_do_shade" enddef ;
+
+vardef lmt_do_shade =
+ image (
+ pushparameters "shade" ;
+
+ save domain_min, domain_max, radius_a, radius_b, factor ;
+ save color_a, color_b, center_a, center_b, alternative, s ;
+ string color_a, color_b, alternative, s ; pair center_a, center_b ;
+
+ alternative := getparameter "alternative" ;
+
+ mfun_with_shade_method_analyze(getparameter "path") ;
+
+ domain_min := 0 ;
+ domain_max := 1 ;
+
+ color_a := "white" ;
+ color_b := "black" ;
+
+ if alternative = "circular" :
+ center_a := center mfun_shade_path ;
+ center_b := center_a ;
+ radius_a := 0 ;
+ radius_b := mfun_max_radius(mfun_shade_path) ;
+ factor := 1.2 ;
+ else :
+ center_a := llcorner mfun_shade_path ;
+ center_b := urcorner mfun_shade_path ;
+ radius_a := 0 ;
+ radius_b := 0 ;
+ factor := 0;
+ fi ;
+
+ if hasparameter "domain" :
+ domain_min := getparameter "domain" 1 ;
+ domain_max := getparameter "domain" 2 ;
+ fi
+ if hasparameter "radius" :
+ if numeric getparameter "radius" :
+ radius_a := 0 ;
+ radius_b := getparameter "radius" ;
+ else :
+ radius_a := getparameter "radius" 1 ;
+ radius_b := getparameter "radius" 2 ;
+ fi ;
+ factor := 1 ;
+ fi
+ if hasparameter "factor" :
+ factor := getparameter "factor" ;
+ fi
+ if hasparameter "origin" :
+ if pair getparameter "origin" :
+ center_a := getparameter "origin" ;
+ center_b := center_b ;
+ else :
+ center_a := getparameter "origin" 1 ;
+ center_b := getparameter "origin" 2 ;
+ fi ;
+ fi
+ if hasparameter "vector" :
+ center_a := point (getparameter "vector" 1) of mfun_shade_path ;
+ center_b := point (getparameter "vector" 2) of mfun_shade_path ;
+ fi
+ if hasparameter "colors" :
+ color_a := getparameter "colors" 1 ;
+ color_b := getparameter "colors" 2 ;
+ fi
+ if hasparameter "center" :
+ if numeric getparameter "center" :
+ center_a := center mfun_shade_path shifted (
+ (getparameter "center") * bbwidth (mfun_shade_path)/2,
+ (getparameter "center") * bbheight(mfun_shade_path)/2
+ ) ;
+ else :
+ center_a := center mfun_shade_path shifted (
+ (getparameter "center" 1) * bbwidth (mfun_shade_path)/2,
+ (getparameter "center" 2) * bbheight(mfun_shade_path)/2
+ ) ;
+ fi
+ fi
+ if hasparameter "direction" :
+ save a, b, bb ; path bb ;
+ bb := boundingbox(mfun_shade_path) ;
+ a := b := -1 ;
+ if string getparameter "direction" :
+ s := getparameter "direction" ;
+ if s = "up" :
+ p_a := xpart shadedup ;
+ p_b := ypart shadedup ;
+ elseif s = "down" :
+ p_a := xpart shadeddown ;
+ p_b := ypart shadeddown ;
+ elseif s = "left" :
+ p_a := xpart shadedleft ;
+ p_b := ypart shadedleft ;
+ elseif s = "right" :
+ p_a := xpart shadedright ;
+ p_b := ypart shadedright ;
+ fi
+ else :
+ p_a := getparameter "direction" 1 ;
+ p_a := getparameter "direction" 2 ;
+ fi
+ if p_a >= 0 :
+ center_a := point p_a of bb ;
+ fi
+ if p_b >= 0 :
+ center_b := point p_b of bb ;
+ fi
+ fi ;
+ fill mfun_shade_path
+ withprescript "sh_domain=" & decimal domain_min & " " & decimal domain_max
+ withprescript "sh_transform=yes"
+ withprescript "sh_color=into"
+ withprescript "sh_color_a=" & colordecimals color_a
+ withprescript "sh_color_b=" & colordecimals color_b
+ withprescript "sh_first=" & ddecimal point 0 of mfun_shade_path % used for support scaling
+ withprescript "sh_set_x=" & ddecimal (mfun_shade_nx,mfun_shade_lx) %
+ withprescript "sh_set_y=" & ddecimal (mfun_shade_ny,mfun_shade_ly) %
+ if alternative = "linear" :
+ withprescript "sh_type=linear"
+ withprescript "sh_factor=1"
+ withprescript "sh_center_a=" & ddecimal center_a
+ withprescript "sh_center_b=" & ddecimal center_b
+ else :
+ withprescript "sh_type=circular"
+ withprescript "sh_factor=1.2"
+ withprescript "sh_center_a=" & ddecimal center_a
+ withprescript "sh_center_b=" & ddecimal center_b
+ withprescript "sh_radius_a=" & decimal radius_a
+ withprescript "sh_radius_b=" & decimal radius_b
+ fi ;
+ if getparameter "trace" :
+ draw fullcircle scaled 1mm shifted center_a ;
+ draw fullsquare scaled 2mm shifted center_b ;
+ draw textext.top("\strut\ttx center a") scaled .2 shifted center_a shifted (0, 2mm) ;
+ draw textext.bot("\strut\ttx center b") scaled .2 shifted center_b shifted (0,-2mm) ;
+ if alternative = "circular" :
+ draw fullcircle scaled ( radius_a * 2) shifted center_a dashed evenly ;
+ draw fullcircle scaled (factor * radius_b * 2) shifted -center_b dashed evenly ;
+ fi
+ fi
+ popparameters ;
+ )
+enddef ;