#ttygraph.awk == #\- awk script, to process file of data and plot commands #graph - processor for a graph-drawing language # input: data and specification of a graph # output: data plotted in specified area #from the awk programming language, by a-k-w, addison-wesley, 1988 #modified slightly by j.a. rupley - rupley!local@cs.arizona.edu BEGIN { # set frame dimensions # ht = 24; wid= 80 # height and width ht = 23; wid= 79 # height and width ox = 6; oy = 2 # offset for x and y axes number = "^[-+]?([0-9]+[.]?[0-9]*|[.][0-9]+)" \ "([eE][-+]?[0-9]+)?$" # M_LN10 = 2.30258509299404568402 M_LN10 = 2.302585093 } /^log.*scale/ { if ($0 ~ "x") log_scale_x = 1 if ($0 ~ "y") log_scale_y = 1 } $1 == "label" { # for bottom sub(/^[ \t]*label[ \t]*/, "") botlab = $0 next } $1 == "label1" { # for bottom of bottom sub(/^[ \t]*label1[ \t]*/, "") botlab1 = $0 next } $1 == "bottom" && $2 == "ticks" { # ticks for x-axis for (i = 3; i <= NF; i++) bticks[++nb] = $i next } $1 == "left" && $2 == "ticks" { # ticks for y-axis for (i = 3; i <= NF; i++) lticks[++nl] = $i next } $1 == "range" { #xmin ymin xmax ymax xmin = $2; ymin = $3; xmax = $4; ymax = $5 next } $1 == "endrange" { endrange = nd } $1 == "startrange" { startrange = nd + 1 } $1 == "height" { ht = $2; next } $1 == "width" { wid = $2; next } $1 ~ number && $2 ~ number { # pair of numbers nd++ # count number of data points x[nd] = $1; y[nd] = $2 ch[nd] = $3 # optional plotting character next } $1 ~ number && $2 !~ number { # single number nd++ # count number of data points x[nd] = nd; y[nd] = $1; ch[nd] = $2 next } END { #draw graph if (log_scale_x) for (i = 1; i <= nd; i++) if (x[i] > 0) x[i] = 1/M_LN10 * log(x[i]) if (log_scale_y) for (i = 1; i <= nd; i++) if (y[i] > 0) y[i] = 1/M_LN10 * log(y[i]) if (xmin == "") { # no range was given endrange = endrange > 0 ? endrange : nd startrange = startrange > 0 ? startrange : 1 xmin = xmax = x[startrange] # so compute it ymin = ymax = y[startrange] for (i = startrange + 1; i <= endrange; i++) { if (x[i] < xmin) xmin = x[i] if (x[i] > xmax) xmax = x[i] if (y[i] < ymin) ymin = y[i] if (y[i] > ymax) ymax = y[i] } } if (botlab1 && (ht == 23 || ht == 56 || ht == 66)) ht-- # if bottom of bottom, make space if # full screen or full page frame(); ticks(); label(); data(); draw(); label1() } function frame() { # create frame for graph for (i = ox; i < wid; i++) plot(i, oy, "-") # bottom for (i = ox; i < wid; i++) plot(i, ht - 1, "-") # top for (i = oy; i < ht; i++) plot(ox, i, "|") # left for (i = oy; i < ht; i++) plot(wid - 1, i, "|") # right } function ticks( i) { #create tick marks for both axes for (i = 1; i <= nb; i++) { plot(xscale(bticks[i]), oy, "|") obtick = length(bticks[i]) <= 1 ? 0 : int(length(bticks[i])/2) # center bottom tick labels splot(xscale(bticks[i]) - obtick, 1, bticks[i]) } for (i = 1; i <= nl; i++) { plot(ox, yscale(lticks[i]), "-") splot(0, yscale(lticks[i]), lticks[i]) } } function label() { # center label under x-axis if (length(botlab) < wid - ox) splot(int((wid + ox - length(botlab)) / 2), 0, botlab) else splot(int((wid - length(botlab)) / 2), 0, botlab) } function label1( i, blanks) { # print centered lower label if (length(botlab1) == 0) return botlab1 = substr(botlab1, 1, wid) blanks = int((wid - length(botlab1)) /2) for (i = 0; i < blanks; i++) printf " " print botlab1 } function data( i) { # create data points for (i = 1; i <= nd; i++) { plot(xscale(x[i]), yscale(y[i]), ch[i] == "" ? "*" : ch[i]) } } function draw( i, j) { # print graph from array for (i = ht - 1; i >= 0; i--) { for (j = 0; j < wid; j++) printf((j,i) in array ? array[j,i] : " ") printf("\n") } } function xscale(x, xtemp) { # scale x-value xtemp = (x - xmin) / (xmax - xmin) if (xtemp < -1e-10) xtemp = 100 # reject value in x-offset region return int(xtemp * (wid - 1 - ox) + ox + 0.5) } function yscale(y, ytemp) { # scale y-value ytemp = (y - ymin) / (ymax - ymin) if (ytemp < -1e-10) ytemp = 100 # reject value in y-offset region return int(ytemp * (ht - 1 - oy) + oy + 0.5) } function plot(x, y, c) { #put character c in array array[x, y] = c } function splot(x, y, s, i, n) { #put string s in array n = length(s) for (i = 0; i < n; i++) array[x + i, y] = substr(s, i+1, 1) }