home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / awk / awk320.zip / GRAPH.AWK < prev    next >
Text File  |  1990-02-08  |  3KB  |  102 lines

  1. # graph - processor for a graph-drawing language
  2. #   input:  data and specification of a graph
  3. #   output: data plotted in specified area
  4.  
  5. # AKW p137
  6.  
  7. BEGIN {                 # set frame dimensions
  8.     ht = 24; wid = 79   # height and width
  9.     ox = 6; oy = 2      # offset for x and y axes
  10.     number = "^[-+]?([0-9]+[.]?[0-9]*|[.][0-9]+)" \
  11.                             "([eE][-+]?[0-9]+)?$"
  12. }
  13. $1 == "label" {                         # for bottom
  14.     sub(/^ *label */, "")
  15.     botlab = $0
  16.     next
  17. }
  18. $1 == "bottom" && $2 == "ticks" {       # ticks for y-axis
  19.     for (i = 3; i <= NF; i++) bticks[++nb] = $i
  20.     next
  21. }
  22. $1 == "left" && $2 == "ticks" {         # ticks for x-axis
  23.     for (i = 3; i <= NF; i++) lticks[++nl] = $i
  24.     next
  25. }
  26. $1 == "range" {                         # xmin ymin xmax ymax
  27.     xmin = $2; ymin = $3; xmax = $4; ymax = $5
  28.     next
  29. }
  30. $1 == "height" { ht = $2; next }
  31. $1 == "width"  { wid = $2; next }
  32. $1 ~ number && $2 ~ number {            # pair of numbers
  33.     nd++;   # count number of data points
  34.     x[nd] = $1; y[nd] = $2
  35.     ch[nd] = $3     # optional plotting character
  36.     next
  37. }
  38. $1 ~ number && $2 !~ number {           # single number
  39.     nd++;   # count number of data points
  40.     x[nd] = nd; y[nd] = $1; ch[nd] = $2
  41.     next
  42. }
  43. END {       # draw graph
  44.     if (xmin == "") {           # no range was given
  45.         xmin = xmax = x[1]      # so compute it
  46.         ymin = ymax = y[1]
  47.         for (i = 2; i <= nd; i++) {
  48.             if (x[1] < xmin) xmin = x[i]
  49.             if (x[1] > xmax) xmax = x[i]
  50.             if (y[1] < ymin) ymin = y[i]
  51.             if (y[1] > ymax) ymax = y[i]
  52.         }
  53.     }
  54.     frame(); ticks(); label(); data(); draw()
  55.     getline <"con"
  56. }
  57. function frame() {          # create frame for graph
  58.     for (i = ox; i < wid; i++) plot(i, oy, "-")         # bottom
  59.     for (i = ox; i < wid; i++) plot(i, ht-1, "-")       # top
  60.     for (i = oy; i < ht; i++) plot(ox, i, "|")          # left
  61.     for (i = oy; i < ht; i++) plot(wid-1, i, "|")       # right
  62. }
  63. function ticks(     i) {    # creadt tick marks for both axes
  64.     for (i = 1; i <= nb; i++) {
  65.         plot(xscale(bticks[i]), oy, "|")
  66.         splot(xscale(bticks[i])-1, 1, bticks[i])
  67.     }
  68.     for (i = 1; i <= nl; i++) {
  69.         plot(ox, yscale(lticks[i]), "-")
  70.         splot(0, yscale(lticks[i]), lticks[i])
  71.     }
  72. }
  73. function label() {          # center label under x-axis
  74.     splot(int((wid + ox - length(botlab))/2), 0, botlab)
  75. }
  76. function data(      i) {    # create data points
  77.     for (i = 1; i <= nd; i++)
  78.         plot(xscale(x[i]), yscale(y[i]), ch[i]=="" ? "*" : ch[i])
  79. }
  80. function draw(      i, j) { # print graph from array
  81.     for (i = ht-1; i >= 0; i--) {
  82.         for (j = 0; j < wid; j++)
  83.             printf((j,i) in array ? array[j,i] : " ")
  84.         printf("\n")
  85.     }
  86. }
  87. function xscale(x) {        # scale x-value
  88.     return int((x-xmin)/(xmax-xmin) * (wid-1-ox) + ox + 0.5)
  89. }
  90. function yscale(y) {        # scale y-value
  91.     return int((y-ymin)/(ymax-ymin) * (ht-1-oy) + oy + 0.5)
  92. }
  93. function plot(x, y, c) {    # put character c in array
  94.     array[x,y] = c
  95. }
  96. function splot(x, y, s,     i, n) { # put string s in array
  97.     n = length(s)
  98.     for (i = 0; i < n; i++)
  99.         array[x+i, y] = substr(s, i+1, 1)
  100. }
  101.  
  102.