#!/bin/sh # MetaCard 2.4 stack # The following is not ASCII text, # so now would be a good time to q out of more exec mc $0 "$@" @{Graph & table objectson preOpenStack # In case this has been opened on a new type of computer from that on which it was # created, or a font is missing, redraw the objects showing initially. lock screen click at the loc of button "Example 2" set the lockRecent to true set the lockMessages to true go to card "table object" click at the loc of button "Example 1" go to card 1 unlock screen set the lockRecent to false set the lockMessages to false pass preOpenStack end preOpenStack on openCard # If the user moved between cards with the arrow key, set the tabbed menu button group appropriately. set the menuHistory of btn "which object" to (the number of this card) pass openCard end openCard wwhitefwdata2columnwidthss110 154 175 191 226 75 122 166 176 268 189 199 199 181 191 191 115 157 169 179 179 102 75 153 224 236 190 151 109 75 121 128 128 139 203 227 175 217 108 194 176 117 174 199 153 181 200 114 199 145 234 191 191 75 99 75 181 272 245 267 254 264 264 231 241 241 203 239 249 249 225 256 219 229 229 161 265 183 257 167 158 202 152 162 162 204 214 214 102 173 165 240 246 242 166 176 176 155 206 181 100 144 163 208 121 75 101 173 161 75 183 137 196 183 142 113 75 142 166 146 173 133 136 165 175 175 205 214 75 213 223 223 185 208 218 218 126 202 232 91 133 187 161 220 270 270 242 145 237 238 238 142 142 142 130 172 129 136 136 147 134 196 119 163 147 218 220 255 240 212 222 222 211 161 149 252 223 253 225 159 125 176 75 141 148 148 159 200 150 200 190 178 132 101 122 237 269 240 205 131 118 128 128 158 216 90 161 153 154 164 164 88 121 142 95 137 170 177 162 75 126 227 189 175 163 wdata1data17.87 4.309e+11 269.3 6.650e+10 29.11 0.1838 1.600e+9 2.000e+12 90.00 18.39 4.405e+11 273.9 6.880e+10 29.34 0.1744 1.608e+9 2.000e+12 89.15 19.01 4.471e+11 276.0 7.161e+10 29.45 0.1690 1.620e+9 1.999e+12 89.15 19.61 4.530e+11 277.3 7.449e+10 29.52 0.1658 1.633e+9 1.999e+12 89.36 20.19 4.587e+11 278.4 7.737e+10 29.57 0.1640 1.648e+9 1.999e+12 89.74 20.73 4.646e+11 279.3 8.020e+10 29.61 0.1630 1.663e+9 1.998e+12 90.23 21.28 4.705e+11 280.3 8.307e+10 29.66 0.1625 1.679e+9 1.998e+12 90.92 21.83 4.766e+11 281.3 8.600e+10 29.71 0.1624 1.694e+9 1.998e+12 91.80 22.38 4.828e+11 282.4 8.900e+10 29.76 0.1626 1.710e+9 1.997e+12 92.84 22.95 4.891e+11 283.5 9.207e+10 29.82 0.1631 1.725e+9 1.997e+12 94.03 23.53 4.956e+11 284.8 9.523e+10 29.88 0.1639 1.740e+9 1.997e+12 95.35 24.12 5.024e+11 286.1 9.847e+10 29.95 0.1649 1.756e+9 1.996e+12 96.79 24.72 5.093e+11 287.5 1.018e+11 30.02 0.1663 1.771e+9 1.996e+12 98.33 25.34 5.164e+11 289.1 1.053e+11 30.11 0.1679 1.787e+9 1.995e+12 99.96 25.97 5.241e+11 290.8 1.089e+11 30.20 0.1699 1.802e+9 1.995e+12 101.7 26.63 5.320e+11 292.7 1.126e+11 30.31 0.1723 1.818e+9 1.994e+12 103.5 27.30 5.401e+11 294.6 1.164e+11 30.41 0.1749 1.833e+9 1.994e+12 105.4 27.99 5.483e+11 296.6 1.204e+11 30.52 0.1779 1.849e+9 1.993e+12 107.4 28.71 5.568e+11 298.6 1.245e+11 30.64 0.1813 1.865e+9 1.993e+12 109.4 29.44 5.653e+11 300.6 1.288e+11 30.75 0.1850 1.881e+9 1.992e+12 111.5 30.20 5.741e+11 302.6 1.332e+11 30.87 0.1890 1.897e+9 1.992e+12 113.7 30.97 5.831e+11 304.8 1.378e+11 31.00 0.1934 1.913e+9 1.991e+12 115.9 31.77 5.923e+11 306.9 1.426e+11 31.13 0.1982 1.930e+9 1.991e+12 118.3 32.59 6.018e+11 309.2 1.475e+11 31.27 0.2033 1.946e+9 1.990e+12 120.7 33.44 6.115e+11 311.5 1.527e+11 31.41 0.2087 1.963e+9 1.989e+12 123.1 34.31 6.216e+11 313.8 1.580e+11 31.55 0.2145 1.981e+9 1.989e+12 125.7 35.20 6.319e+11 316.3 1.636e+11 31.70 0.2206 1.998e+9 1.988e+12 128.3 36.12 6.425e+11 318.7 1.693e+11 31.86 0.2271 2.016e+9 1.987e+12 130.9 37.06 6.535e+11 321.3 1.753e+11 32.02 0.2340 2.034e+9 1.987e+12 133.7 38.02 6.647e+11 323.9 1.815e+11 32.19 0.2412 2.052e+9 1.986e+12 136.5 39.02 6.763e+11 326.6 1.879e+11 32.36 0.2488 2.071e+9 1.985e+12 139.4 40.03 6.883e+11 329.4 1.946e+11 32.54 0.2567 2.090e+9 1.984e+12 142.4 41.08 7.007e+11 332.2 2.015e+11 32.73 0.2650 2.109e+9 1.984e+12 145.4 42.15 7.134e+11 335.1 2.087e+11 32.92 0.2736 2.129e+9 1.983e+12 148.5 43.24 7.265e+11 338.0 2.162e+11 33.12 0.2826 2.149e+9 1.982e+12 151.7 44.37 7.401e+11 341.0 2.239e+11 33.32 0.2921 2.170e+9 1.981e+12 155.0 45.52 7.541e+11 344.1 2.320e+11 33.53 0.3019 2.191e+9 1.980e+12 158.3 46.69 7.685e+11 347.3 2.403e+11 33.75 0.3121 2.213e+9 1.979e+12 161.7 47.90 7.834e+11 350.5 2.490e+11 33.97 0.3227 2.235e+9 1.978e+12 165.2 49.13 7.987e+11 353.8 2.580e+11 34.20 0.3337 2.258e+9 1.977e+12 168.8 50.39 8.146e+11 357.1 2.673e+11 34.44 0.3452 2.281e+9 1.976e+12 172.4 51.48 8.309e+11 359.1 2.770e+11 41.40 0.3571 2.314e+9 1.975e+12 175.5 52.40 8.488e+11 360.4 2.870e+11 41.64 0.3694 2.355e+9 1.973e+12 178.1 53.35 8.675e+11 362.0 2.973e+11 41.91 0.3823 2.396e+9 1.972e+12 180.7 54.33 8.867e+11 363.8 3.079e+11 42.19 0.3956 2.437e+9 1.971e+12 183.5 55.32 9.064e+11 365.6 3.189e+11 42.47 0.4094 2.479e+9 1.970e+12 186.4 56.32 9.266e+11 367.5 3.303e+11 42.77 0.4237 2.521e+9 1.968e+12 189.4 57.35 9.474e+11 369.5 3.420e+11 43.08 0.4385 2.564e+9 1.967e+12 192.4 58.39 9.687e+11 371.5 3.541e+11 43.40 0.4539 2.608e+9 1.965e+12 195.5 59.45 9.906e+11 373.5 3.666e+11 43.73 0.4699 2.652e+9 1.964e+12 198.6 60.52 1.013e+12 375.6 3.796e+11 44.06 0.4865 2.697e+9 1.962e+12 201.8 61.61 1.036e+12 377.8 3.930e+11 44.41 0.5037 2.743e+9 1.961e+12 205.0 62.71 1.060e+12 380.0 4.068e+11 44.76 0.5215 2.790e+9 1.959e+12 208.3 63.83 1.084e+12 382.2 4.212e+11 45.12 0.5400 2.837e+9 1.957e+12 211.6 64.96 1.109e+12 384.5 4.360e+11 45.50 0.5591 2.886e+9 1.955e+12 215.0 66.11 1.136e+12 387.1 4.513e+11 45.90 0.5790 2.935e+9 1.953e+12 218.4 67.27 1.164e+12 389.8 4.671e+11 46.33 0.5996 2.986e+9 1.952e+12 221.8 68.45 1.192e+12 392.5 4.835e+11 46.75 0.6209 3.037e+9 1.950e+12 225.3 69.65 1.221e+12 395.2 5.005e+11 47.18 0.6429 3.090e+9 1.947e+12 228.9 70.86 1.250e+12 397.7 5.180e+11 47.62 0.6657 3.144e+9 1.945e+12 232.4 72.08 1.280e+12 400.3 5.362e+11 48.06 0.6893 3.199e+9 1.943e+12 236.1 73.32 1.311e+12 402.7 5.550e+11 48.50 0.7138 3.255e+9 1.941e+12 239.7 74.57 1.342e+12 405.1 5.744e+11 48.95 0.7391 3.312e+9 1.938e+12 243.4 75.82 1.374e+12 407.5 5.944e+11 49.41 0.7652 3.371e+9 1.936e+12 247.2 77.09 1.406e+12 409.8 6.151e+11 49.87 0.7923 3.431e+9 1.933e+12 250.9 78.37 1.439e+12 412.0 6.364e+11 50.34 0.8203 3.492e+9 1.931e+12 254.7 79.66 1.469e+12 413.4 6.584e+11 50.77 0.8493 3.554e+9 1.928e+12 258.6 80.96 1.502e+12 415.3 6.810e+11 51.25 0.8792 3.617e+9 1.925e+12 262.5 82.28 1.537e+12 417.5 7.044e+11 51.77 0.9101 3.681e+9 1.922e+12 266.5 83.61 1.572e+12 419.8 7.284e+11 52.31 0.9421 3.746e+9 1.919e+12 270.6 84.96 1.609e+12 422.0 7.532e+11 52.87 0.9751 3.812e+9 1.916e+12 274.7 86.33 1.646e+12 424.2 7.788e+11 53.43 1.009 3.879e+9 1.913e+12 278.8 87.70 1.683e+12 426.3 8.051e+11 53.91 1.045 3.948e+9 1.910e+12 283.1 89.08 1.720e+12 428.3 8.321e+11 54.40 1.082 4.017e+9 1.906e+12 287.5 90.45 1.758e+12 430.2 8.598e+11 54.90 1.121 4.087e+9 1.902e+12 292.1 91.83 1.797e+12 432.1 8.882e+11 55.42 1.162 4.159e+9 1.898e+12 296.8 93.22 1.836e+12 434.0 9.173e+11 55.95 1.204 4.232e+9 1.894e+12 301.6 94.61 1.877e+12 435.9 9.473e+11 56.50 1.248 4.306e+9 1.890e+12 306.5 96.00 1.918e+12 437.8 9.781e+11 57.06 1.294 4.381e+9 1.886e+12 311.4 97.40 1.960e+12 439.6 1.010e+12 57.62 1.342 4.458e+9 1.881e+12 316.4 98.81 2.002e+12 441.4 1.042e+12 58.12 1.393 4.536e+9 1.876e+12 321.4 100.2 2.045e+12 443.0 1.076e+12 58.62 1.445 4.615e+9 1.871e+12 326.6 101.6 2.088e+12 444.6 1.110e+12 59.13 1.501 4.695e+9 1.866e+12 331.7 103.1 2.131e+12 446.1 1.145e+12 59.64 1.559 4.777e+9 1.860e+12 336.9 104.5 2.175e+12 447.5 1.181e+12 60.15 1.620 4.860e+9 1.854e+12 342.2 105.9 2.219e+12 448.9 1.218e+12 60.67 1.684 4.944e+9 1.848e+12 347.5 107.4 2.264e+12 450.2 1.256e+12 61.20 1.751 5.028e+9 1.842e+12 352.9 108.9 2.308e+12 451.3 1.295e+12 61.73 1.821 5.114e+9 1.835e+12 358.3 110.3 2.353e+12 452.4 1.335e+12 62.26 1.895 5.201e+9 1.829e+12 363.7 111.8 2.398e+12 453.5 1.375e+12 62.80 1.972 5.289e+9 1.822e+12 369.3 113.3 2.444e+12 454.4 1.417e+12 63.34 2.052 5.378e+9 1.814e+12 374.8 114.8 2.489e+12 455.2 1.460e+12 63.88 2.136 5.468e+9 1.807e+12 380.4 116.3 2.534e+12 455.9 1.503e+12 64.42 2.224 5.558e+9 1.799e+12 386.1 117.8 2.580e+12 456.7 1.548e+12 64.98 2.316 5.650e+9 1.791e+12 391.7 119.3 2.626e+12 457.2 1.593e+12 65.52 2.411 5.743e+9 1.782e+12 397.4 120.8 2.666e+12 456.7 1.640e+12 65.99 2.510 5.837e+9 1.773e+12 403.2 122.3 2.696e+12 454.5 1.687e+12 66.31 2.613 5.932e+9 1.764e+12 409.0 123.7 2.729e+12 452.9 1.734e+12 66.69 2.721 6.027e+9 1.754e+12 414.8 125.2 2.763e+12 451.3 1.782e+12 67.08 2.832 6.122e+9 1.745e+12 420.7 126.7 2.796e+12 449.7 1.831e+12 67.47 2.948 6.217e+9 1.734e+12 426.5 128.1 2.828e+12 448.0 1.880e+12 67.86 3.069 6.312e+9 1.724e+12 432.5 wdata1columnnamesconsumer goods per person (per year) food food per person industrial output life expectancy persistent pollution index population resources (nonrenewable) services per person wdata2dataE15.000e+9 6.051e+8 5.333 1.000 4000 9.000e+8 1.500 1.500 1.000 41.56 2.000 2.000 2.000 14.00 14.00 14.00 901.3 1000 20.00 20.00 20.00 37.00 5.920e+7 1.000 17.87 2.860e+10 0.4065 6.210e+9 32.27 5.163e+7 2.495e+7 1.256e+7 7.407e+6 6.707e+6 41.56 0.1681 3.187 3.800 2.000 1.200 4.800e+9 4.518 271.9 7.200 0.0000 0.7000 1.418 0.5822 0.1229 4000 0.7746 0.7746 0.1229 4.309e+11 269.3 1.171 2.000 0.1429 0.04000 0.001000 0.05000 0.05000 0.05000 0.1090 0.1090 0.1090 0.4300 0.4300 0.4300 0.4300 0.3104 0.3525 0.1086 0.1086 0.1086 0.1600 0.02000 1.000 0.001366 20.00 7.200 3.000 282.0 282.0 282.0 94.03 94.03 94.03 2.100e+11 1.500e+10 2.344e+10 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 6.650e+10 7.900e+11 41.56 400.0 600.0 8.919e+8 0.7500 0.0003700 0.0009667 6.675e+8 0.7500 1.336 2.000 1.000 3.809e+6 9.985e+5 600.0 1.103 0.001838 0.0000 8.000 0.2813 0.7000 0.9013 0.9013 0.9013 4000 7.975e+4 760.0 1.000 1.000 1.000 1.267 1.000 1.000 1.000 1.000 0.0000 0.0000 29.11 28.00 0.9350 1.074 1.036 1.036 1.180 0.9998 20.00 0.06900 82.80 39.93 4.167e+7 2.291e+7 9.130e+6 6.986 12.00 0.03839 0.01795 0.03898 0.1118 0.5463 0.1766 1.000 0.08549 29.11 1.045e+7 1.190e+7 4.800e+6 5.652e+6 1.000 1.000 1.000 1.045e+7 1.360e+8 0.1838 1.000 0.0000 0.0000 20.00 1995 2.500e+7 8.500e-5 1.600e+9 6.500e+8 7.000e+8 1.900e+8 6.000e+7 4000 3.200e+9 6.750e+8 7.770e+7 1.392e+8 2.300e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 2.826e+8 1.000 1.000 1.000 2.000e+12 0.004250 1.440e+11 7.200e+9 7.220e+9 1.000 1.000 1.000 1.440e+11 90.00 20.00 0.07000 1.198 230.0 20.00 7.246e+9 5.075 8.200e+6 10.00 0.005623 8.998e+6 4000 8.117e+9 2.874e+8 8.267 1.000 4000 9.359e+8 1.500 1.500 1.000 50.87 2.000 2.000 2.000 14.00 14.00 14.00 851.6 1000 20.00 20.00 20.00 40.86 7.112e+7 1.000 23.53 4.095e+10 0.3769 8.692e+9 32.02 5.573e+7 2.444e+7 1.294e+7 9.046e+6 9.316e+6 42.23 -0.006656 3.700 3.800 2.000 1.200 4.800e+9 5.241 294.0 7.234 0.07553 0.8133 1.417 0.5976 0.08780 4000 0.7735 0.7735 0.1176 4.956e+11 284.8 1.238 2.000 0.1636 0.04682 0.001000 0.05000 0.05000 0.05000 0.1091 0.1091 0.1091 0.4300 0.4300 0.4300 0.4300 0.3137 0.3325 0.1284 0.1284 0.1284 0.1740 0.02000 0.9983 0.0009207 20.00 7.628 3.000 298.4 298.4 298.4 111.1 111.1 111.1 3.007e+11 2.148e+10 3.166e+10 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 9.523e+10 7.900e+11 54.72 400.0 600.0 6.818e+8 0.4433 0.0003640 0.0009488 7.444e+8 0.7500 0.9159 2.000 0.9292 5.781e+6 1.099e+6 594.8 0.9746 0.001639 0.7861 6.635 0.2925 0.7000 0.8516 0.8516 0.8516 4000 1.033e+5 840.6 1.000 1.000 1.000 1.413 1.000 1.000 1.000 1.000 0.0000 0.0000 29.88 28.00 0.9344 1.102 1.036 1.036 1.181 0.9998 20.00 0.06570 78.15 40.84 4.259e+7 2.462e+7 1.160e+7 7.172 12.00 0.03684 0.01721 0.03752 0.1102 0.3683 0.2325 1.227 0.005375 29.17 1.075e+7 1.061e+7 7.737e+6 8.094e+6 1.000 1.000 1.000 1.583e+7 1.360e+8 0.1639 1.000 0.0000 0.0000 20.00 1995 2.228e+7 8.500e-5 1.740e+9 6.633e+8 7.515e+8 2.411e+8 8.451e+7 4000 3.200e+9 4.149e+8 1.095e+8 1.575e+8 2.253e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 4.047e+8 1.000 1.000 1.000 1.997e+12 0.004250 1.660e+11 8.298e+9 1.223e+10 1.000 1.000 1.000 1.660e+11 95.35 20.00 0.07000 1.197 230.0 20.00 1.039e+10 5.678 9.098e+6 10.00 0.005821 1.013e+7 4000 1.162e+10 4.163e+8 11.25 1.000 4000 9.823e+8 1.500 1.500 1.000 65.27 2.000 2.000 2.000 14.00 14.00 14.00 798.0 1000 20.00 20.00 20.00 40.19 7.624e+7 1.000 30.20 5.728e+10 0.3420 1.246e+10 31.61 5.997e+7 2.523e+7 1.335e+7 9.995e+6 1.140e+7 47.29 -0.005888 3.683 3.800 2.000 1.200 4.800e+9 5.195 365.2 7.670 0.07597 0.8140 1.410 0.6087 0.1155 4000 0.7708 0.7708 0.1038 5.741e+11 302.6 1.316 2.000 0.1461 0.04895 0.001000 0.05000 0.05000 0.05000 0.1095 0.1095 0.1095 0.4300 0.4300 0.4300 0.4300 0.3176 0.3337 0.1268 0.1268 0.1268 0.1897 0.02000 0.9959 0.001015 20.00 9.095 3.000 317.8 317.8 317.8 131.3 131.3 131.3 4.206e+11 3.005e+10 4.445e+10 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 1.332e+11 7.900e+11 70.22 400.0 600.0 6.984e+8 0.3686 0.0003444 0.0008877 8.110e+8 0.7500 0.8612 2.000 0.8729 5.836e+6 1.231e+6 593.6 1.122 0.001890 1.031 6.210 0.3070 0.7000 0.7980 0.7980 0.7980 4000 1.251e+5 927.6 1.000 1.000 1.000 1.563 1.000 1.000 1.000 1.000 0.0000 0.0000 30.87 28.00 0.9351 1.136 1.038 1.038 1.192 0.9998 20.00 0.06234 74.01 36.28 4.567e+7 2.641e+7 1.329e+7 7.305 12.00 0.03552 0.01657 0.03624 0.1083 0.4062 0.2985 1.298 0.008734 29.48 1.283e+7 1.224e+7 1.106e+7 1.132e+7 1.000 1.000 1.000 2.238e+7 1.360e+8 0.1890 1.000 0.0000 0.0000 20.00 1995 2.571e+7 8.500e-5 1.897e+9 7.102e+8 8.056e+8 2.758e+8 1.053e+8 4000 3.200e+9 3.621e+8 1.449e+8 1.914e+8 2.194e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 5.661e+8 1.000 1.000 1.000 1.992e+12 0.004250 2.157e+11 1.078e+10 1.689e+10 1.000 1.000 1.000 2.157e+11 113.7 20.00 0.07000 1.191 230.0 20.00 1.459e+10 5.679 1.023e+7 10.00 0.006053 1.148e+7 4000 1.652e+10 5.818e+8 15.22 1.000 4000 1.029e+9 1.500 1.500 1.000 84.20 2.000 2.000 2.000 14.00 14.00 14.00 726.5 1000 20.00 20.00 20.00 39.64 8.209e+7 1.000 39.02 8.079e+10 0.2958 1.768e+10 30.49 6.313e+7 2.592e+7 1.364e+7 1.057e+7 1.300e+7 57.75 -0.0008582 3.654 3.800 2.000 1.200 4.800e+9 5.112 451.0 8.640 0.07763 0.8164 1.399 0.6236 0.1617 4000 0.7711 0.7711 0.1055 6.763e+11 326.6 1.420 2.000 0.1428 0.05192 0.001000 0.05000 0.05000 0.05000 0.1098 0.1098 0.1098 0.4300 0.4300 0.4300 0.4300 0.3227 0.3367 0.1235 0.1235 0.1235 0.2071 0.02000 0.9926 0.001160 20.00 11.15 3.000 343.4 343.4 343.4 158.0 158.0 158.0 5.934e+11 4.238e+10 6.327e+10 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 1.879e+11 7.900e+11 90.74 400.0 600.0 7.196e+8 0.2908 0.0003184 0.0008020 8.834e+8 0.7500 0.8146 2.000 0.8163 6.531e+6 1.416e+6 592.5 1.474 0.002488 1.336 5.616 0.3215 0.7000 0.7265 0.7265 0.7265 4000 1.556e+5 1044 1.000 1.000 1.000 1.761 1.000 1.000 1.000 1.000 0.0000 0.0000 32.36 28.00 0.9387 1.181 1.043 1.043 1.216 0.9998 20.00 0.05787 68.58 33.05 4.957e+7 2.858e+7 1.481e+7 7.484 12.00 0.03369 0.01566 0.03444 0.1053 0.4640 0.3856 1.397 0.01132 30.11 1.717e+7 1.611e+7 1.566e+7 1.597e+7 1.000 1.000 1.000 3.163e+7 1.360e+8 0.2488 1.000 0.0000 0.0000 20.00 1995 3.383e+7 8.500e-5 2.071e+9 7.694e+8 8.711e+8 3.068e+8 1.235e+8 4000 3.200e+9 2.992e+8 1.889e+8 2.315e+8 2.133e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 7.986e+8 1.000 1.000 1.000 1.985e+12 0.004250 2.887e+11 1.443e+10 2.321e+10 1.000 1.000 1.000 2.887e+11 139.4 20.00 0.07000 1.178 230.0 20.00 2.063e+10 5.655 1.162e+7 10.00 0.006361 1.317e+7 4000 2.340e+10 8.134e+8 20.39 1.000 4000 1.083e+9 1.500 1.500 1.000 108.8 2.000 2.000 2.000 14.00 14.00 14.00 634.0 1000 20.00 20.00 20.00 39.01 8.899e+7 1.000 50.39 1.149e+11 0.2363 2.503e+10 28.63 6.532e+7 2.626e+7 1.373e+7 1.091e+7 1.443e+7 73.29 -0.001503 3.589 3.800 2.000 1.200 4.800e+9 4.982 552.0 10.16 0.07683 0.8152 1.388 0.6444 0.2380 4000 0.7759 0.7759 0.1294 8.146e+11 357.1 1.553 2.000 0.1512 0.05573 0.001000 0.05000 0.05000 0.05000 0.1103 0.1103 0.1103 0.4300 0.4300 0.4300 0.4300 0.3293 0.3390 0.1207 0.1207 0.1207 0.2281 0.02000 0.9878 0.001380 20.00 13.80 3.000 376.5 376.5 376.5 192.3 192.3 192.3 8.442e+11 6.030e+10 9.062e+10 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 2.673e+11 7.900e+11 117.2 400.0 600.0 7.857e+8 0.2520 0.0002849 0.0006919 9.715e+8 0.7500 0.8088 2.000 0.8118 8.077e+6 1.709e+6 590.9 2.040 0.003452 1.869 4.855 0.3386 0.7000 0.6340 0.6340 0.6340 4000 2.033e+5 1193 1.000 1.000 1.000 2.020 1.000 1.000 1.000 1.000 0.0000 0.0000 34.44 28.00 0.9461 1.238 1.051 1.051 1.254 0.9997 20.00 0.05206 61.52 30.89 5.446e+7 3.133e+7 1.654e+7 7.733 12.00 0.03114 0.01439 0.03193 0.1011 0.5520 0.4980 1.524 0.01420 31.16 2.396e+7 2.235e+7 2.209e+7 2.272e+7 1.000 1.000 1.000 4.482e+7 1.360e+8 0.3452 1.000 0.0000 0.0000 20.00 1995 4.694e+7 8.500e-5 2.281e+9 8.431e+8 9.537e+8 3.416e+8 1.427e+8 4000 3.200e+9 2.731e+8 2.405e+8 2.722e+8 2.061e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 1.136e+9 1.000 1.000 1.000 1.976e+12 0.004250 3.934e+11 1.967e+10 3.226e+10 1.000 1.000 1.000 3.934e+11 172.4 20.00 0.07000 1.158 230.0 20.00 2.948e+10 5.599 1.338e+7 10.00 0.006758 1.542e+7 4000 3.342e+10 1.159e+9 27.17 1.000 4000 1.158e+9 1.500 1.500 1.000 133.4 2.000 2.000 2.000 14.00 14.00 14.00 545.1 1000 20.00 20.00 20.00 37.30 1.006e+8 1.000 60.52 1.632e+11 0.1833 3.573e+10 20.37 5.494e+7 2.058e+7 1.017e+7 8.975e+6 1.521e+7 93.82 -0.002678 3.366 3.800 2.000 1.200 4.800e+9 4.584 687.3 12.07 0.05467 0.7820 1.362 0.7203 0.4468 4000 0.7884 0.7884 0.1918 1.013e+12 375.6 1.633 2.000 0.1809 0.05846 0.001000 0.05000 0.05000 0.05000 0.1149 0.1149 0.1149 0.4300 0.4300 0.4300 0.4300 0.3352 0.3361 0.1190 0.1190 0.1190 0.2697 0.02000 0.9811 0.002214 20.00 16.14 3.000 405.9 405.9 405.9 223.0 223.0 223.0 1.199e+12 8.563e+10 1.276e+11 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 3.796e+11 7.900e+11 140.7 400.0 600.0 8.623e+8 0.2000 0.0002551 0.0005971 1.139e+9 0.7500 0.7572 2.000 0.7625 1.148e+7 2.124e+6 588.8 2.864 0.004865 2.603 4.308 0.3619 0.7000 0.5451 0.5451 0.5451 4000 3.197e+5 1389 1.000 1.000 1.000 2.358 1.000 1.000 1.000 1.000 0.0000 0.0000 44.06 28.00 0.9506 1.272 1.302 1.060 1.302 0.9995 20.00 0.04444 52.33 28.86 6.482e+7 3.662e+7 2.003e+7 8.644 12.00 0.02073 0.009172 0.02191 0.08188 0.8857 0.5981 1.615 0.008885 33.82 3.382e+7 3.150e+7 3.146e+7 3.227e+7 1.000 1.000 1.000 6.373e+7 1.360e+8 0.4865 1.000 0.0000 0.0000 20.00 1995 6.616e+7 8.500e-5 2.697e+9 9.930e+8 1.109e+9 4.096e+8 1.858e+8 4000 3.200e+9 2.316e+8 3.058e+8 3.249e+8 1.965e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 1.613e+9 1.000 1.000 1.000 1.962e+12 0.004250 5.442e+11 2.721e+10 4.518e+10 1.000 1.000 1.000 5.442e+11 201.8 20.00 0.07000 1.133 230.0 20.00 4.363e+10 5.443 1.598e+7 10.00 0.007111 1.918e+7 4000 4.713e+10 1.593e+9 35.18 1.000 4000 1.257e+9 1.500 1.500 1.000 159.3 2.000 2.000 2.000 14.00 14.00 14.00 442.6 1000 20.00 20.00 20.00 35.14 1.124e+8 1.000 72.08 2.306e+11 0.1228 5.032e+10 17.68 5.655e+7 1.984e+7 9.659e+6 9.249e+6 1.780e+7 117.0 -0.0001659 3.264 3.800 2.000 1.200 4.800e+9 4.285 943.4 14.24 0.05214 0.7782 1.313 0.7403 0.6333 4000 0.8120 0.8120 0.3102 1.280e+12 400.3 1.740 2.000 0.2039 0.06154 0.001000 0.05000 0.05000 0.05000 0.1179 0.1179 0.1179 0.4300 0.4300 0.4300 0.4300 0.3419 0.3352 0.1170 0.1170 0.1170 0.3199 0.02000 0.9715 0.002683 20.00 18.89 3.000 439.5 439.5 439.5 257.9 257.9 257.9 1.693e+12 1.209e+11 1.797e+11 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 5.362e+11 7.900e+11 167.6 400.0 600.0 1.033e+9 0.2000 0.0002210 0.0005399 1.354e+9 0.7500 0.7633 2.000 0.7636 1.366e+7 2.840e+6 585.9 4.039 0.006893 3.679 3.846 0.3929 0.7000 0.4426 0.4426 0.4426 4000 4.332e+5 1616 1.000 1.000 1.000 2.759 1.000 1.000 1.000 1.000 0.0000 0.0000 48.06 28.00 0.9607 1.318 1.356 1.071 1.356 0.9993 20.00 0.03542 41.50 24.48 7.552e+7 4.334e+7 2.430e+7 8.883 12.00 0.01721 0.007375 0.01867 0.07389 1.073 0.7125 1.718 0.01113 38.71 4.794e+7 4.464e+7 4.423e+7 4.558e+7 1.000 1.000 1.000 8.981e+7 1.360e+8 0.6893 1.000 0.0000 0.0000 20.00 1995 9.375e+7 8.500e-5 3.199e+9 1.153e+9 1.310e+9 4.953e+8 2.410e+8 4000 3.200e+9 2.514e+8 3.742e+8 4.077e+8 1.837e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 2.279e+9 1.000 1.000 1.000 1.943e+12 0.004250 7.551e+11 3.775e+10 6.271e+10 1.000 1.000 1.000 7.551e+11 236.1 20.00 0.07000 1.104 230.0 20.00 6.321e+10 5.149 1.970e+7 10.00 0.007515 2.404e+7 4000 6.656e+10 2.489e+9 45.45 1.000 4000 1.370e+9 1.500 1.500 1.000 188.4 2.000 2.000 2.000 14.00 14.00 14.00 338.8 1000 20.00 20.00 20.00 32.64 1.244e+8 1.000 84.96 3.239e+11 0.05543 7.154e+10 15.09 5.754e+7 1.786e+7 9.005e+6 9.434e+6 2.123e+7 142.0 -0.002851 3.151 3.800 2.000 1.200 4.800e+9 3.986 1299 16.84 0.04878 0.7732 1.265 0.7615 0.8875 4000 0.8432 0.8432 0.4659 1.609e+12 422.0 1.835 2.000 0.2282 0.06448 0.001000 0.05000 0.05000 0.05000 0.1231 0.1231 0.1231 0.4300 0.4300 0.4300 0.4300 0.3494 0.3320 0.1150 0.1150 0.1150 0.3812 0.02000 0.9581 0.003231 20.00 22.96 3.000 477.0 477.0 477.0 296.9 296.9 296.9 2.379e+12 1.699e+11 2.501e+11 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 7.532e+11 7.900e+11 197.6 400.0 600.0 1.207e+9 0.2000 0.0001831 0.0004755 1.622e+9 0.7500 0.7443 2.000 0.7500 1.628e+7 4.044e+6 581.6 5.671 0.009751 5.176 3.552 0.4282 0.7000 0.3388 0.3388 0.3526 4000 5.692e+5 1864 1.000 1.000 1.000 3.204 1.000 1.000 1.000 1.000 0.0000 0.0000 52.87 28.00 0.9789 1.359 1.421 1.084 1.421 0.9990 20.00 0.02796 32.52 20.50 8.766e+7 5.161e+7 2.981e+7 9.138 12.00 0.01340 0.005782 0.01558 0.06713 1.292 0.8398 1.816 0.009452 43.50 6.775e+7 6.315e+7 6.227e+7 6.402e+7 1.000 1.000 1.000 1.263e+8 1.360e+8 0.9751 1.000 0.0000 0.0000 20.00 1995 1.326e+8 8.500e-5 3.812e+9 1.333e+9 1.557e+9 6.056e+8 3.163e+8 4000 3.200e+9 2.740e+8 4.354e+8 4.979e+8 1.686e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 3.201e+9 1.000 1.000 1.000 1.916e+12 0.004250 1.047e+12 5.235e+10 8.659e+10 1.000 1.000 1.000 1.047e+12 274.7 20.00 0.07000 1.073 230.0 20.00 9.269e+10 4.794 2.467e+7 10.00 0.007964 3.036e+7 4000 9.391e+10 3.055e+9 58.86 1.000 4000 1.488e+9 1.524 1.500 1.016 220.1 2.000 2.000 2.000 14.00 14.00 14.00 248.3 1000 20.00 20.00 20.00 30.18 1.369e+8 1.000 98.81 4.482e+11 0.02766 1.000e+11 12.79 5.799e+7 1.466e+7 8.263e+6 9.499e+6 2.557e+7 169.3 -0.001280 3.024 3.800 2.000 1.200 4.800e+9 3.683 1748 20.38 0.04417 0.7663 1.218 0.7825 1.245 4000 0.8668 0.8668 0.6682 2.002e+12 441.4 1.919 2.000 0.2464 0.06710 0.001000 0.05000 0.05000 0.05000 0.1273 0.1273 0.1273 0.4300 0.4300 0.4300 0.4300 0.3574 0.3260 0.1166 0.1166 0.1166 0.4268 0.02000 0.9380 0.003873 20.00 28.57 3.000 511.3 511.3 511.3 350.6 350.6 350.6 3.291e+12 2.351e+11 3.398e+11 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 1.042e+12 7.900e+11 229.8 400.0 600.0 1.431e+9 0.2000 0.0001681 0.0003976 1.943e+9 0.7500 0.7362 2.000 0.7388 1.870e+7 5.993e+6 575.9 8.019 0.01393 7.331 3.290 0.4651 0.7000 0.2483 0.2483 0.3209 4000 9.075e+5 2135 1.000 1.000 1.000 3.707 1.000 1.000 1.000 1.000 0.0000 0.0000 58.12 28.00 0.9882 1.395 1.508 1.106 1.508 0.9986 20.00 0.02293 26.41 17.45 1.011e+8 6.134e+7 3.664e+7 9.390 12.00 0.009573 0.004470 0.01280 0.06188 1.549 1.111 1.903 0.007850 48.17 9.589e+7 8.879e+7 8.761e+7 1.007e+8 1.000 1.000 1.000 1.884e+8 1.360e+8 1.393 1.000 0.0000 0.0000 20.00 1995 1.894e+8 9.666e-5 4.536e+9 1.532e+9 1.849e+9 7.423e+8 4.131e+8 4000 3.200e+9 2.977e+8 5.532e+8 5.797e+8 1.512e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 5.037e+9 1.000 1.000 1.000 1.876e+12 0.004833 1.458e+12 7.290e+10 1.216e+11 1.000 1.000 1.000 1.458e+12 321.4 20.00 0.07000 1.038 230.0 20.00 1.327e+11 4.443 3.194e+7 10.00 0.009042 4.101e+7 4000 1.267e+11 3.480e+9 73.28 1.000 4000 1.609e+9 1.563 1.500 1.042 253.2 2.000 2.000 2.000 14.00 14.00 14.00 158.3 1000 20.00 20.00 20.00 27.43 1.475e+8 1.000 113.3 6.093e+11 0.002388 1.336e+11 10.80 5.806e+7 1.088e+7 6.993e+6 9.656e+6 3.053e+7 199.1 -0.001066 2.894 3.800 2.000 1.200 4.800e+9 3.384 2336 24.93 0.04043 0.7607 1.169 0.8067 1.744 4000 0.8942 0.8942 0.9420 2.444e+12 454.4 1.975 2.000 0.2949 0.06900 0.001000 0.05000 0.05000 0.05000 0.1338 0.1338 0.1338 0.4300 0.4300 0.4300 0.4300 0.3659 0.3200 0.1162 0.1162 0.1162 0.4689 0.02000 0.9071 0.004652 20.00 34.98 3.000 546.7 546.7 546.7 407.9 407.9 407.9 4.475e+12 3.196e+11 4.534e+11 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 1.417e+12 7.900e+11 263.5 400.0 600.0 1.669e+9 0.2000 0.0001546 0.0003252 2.320e+9 0.7500 0.7194 2.000 0.7215 2.393e+7 1.017e+7 567.3 11.64 0.02052 10.55 3.100 0.5029 0.7000 0.1583 0.1583 0.2895 4000 1.239e+6 2410 1.000 1.000 1.000 4.248 1.000 1.000 1.000 1.000 0.0000 0.0000 63.34 28.00 0.9989 1.419 1.599 1.174 1.599 0.9979 20.00 0.01752 19.88 14.74 1.156e+8 7.262e+7 4.492e+7 9.680 12.00 0.006232 0.003199 0.01063 0.05666 1.861 1.405 1.967 0.004448 53.07 1.388e+8 1.275e+8 1.179e+8 1.512e+8 1.000 1.000 1.000 2.691e+8 1.360e+8 2.052 1.000 0.0000 0.0000 20.00 1995 2.791e+8 0.0001067 5.378e+9 1.745e+9 2.186e+9 9.081e+8 5.389e+8 4000 3.200e+9 3.219e+8 6.918e+8 6.555e+8 1.303e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 7.559e+9 1.000 1.000 1.000 1.814e+12 0.005334 2.016e+12 1.008e+11 1.647e+11 1.000 1.000 1.000 2.016e+12 374.8 20.00 0.07000 1.001 230.0 20.00 1.895e+11 4.050 4.259e+7 10.00 0.01022 5.497e+7 4000 1.755e+11 6.699e+9 94.21 1.000 4000 1.735e+9 1.624 1.500 1.083 287.7 2.000 2.000 2.000 14.00 14.00 14.00 127.2 1000 20.00 20.00 20.00 24.45 1.543e+8 1.000 128.1 8.086e+11 -0.02343 1.889e+11 9.326 5.887e+7 6.944e+6 5.417e+6 9.970e+6 3.654e+7 230.9 -0.003094 2.818 3.800 2.000 1.200 4.800e+9 3.152 3210 30.33 0.03549 0.7532 1.118 0.8293 2.503 4000 0.9320 0.9320 1.320 2.828e+12 448.0 1.948 2.000 0.3132 0.06884 0.001000 0.05000 0.05000 0.05000 0.1463 0.1463 0.1463 0.4300 0.4300 0.4300 0.4300 0.3745 0.3092 0.1146 0.1146 0.1146 0.5125 0.02000 0.8620 0.005787 20.00 41.89 3.000 582.8 582.8 582.8 466.4 466.4 466.4 5.938e+12 4.242e+11 5.814e+11 1.000 1.000 3.000 3.000 3.000 3.000 4000 0.1000 10.00 1.880e+12 7.900e+11 297.9 400.0 600.0 1.914e+9 0.2000 0.0001408 0.0002675 2.748e+9 0.7500 0.6965 2.000 0.7026 2.683e+7 1.364e+7 553.1 16.97 0.03069 15.04 3.116 0.5421 0.7000 0.1272 0.1272 0.2806 4000 1.559e+6 2587 1.000 1.000 1.000 4.678 1.000 1.000 1.000 1.000 0.0000 0.0000 67.86 28.00 1.012 1.408 1.707 1.255 1.707 0.9969 20.00 0.01358 15.02 11.51 1.294e+8 8.522e+7 5.459e+7 9.951 12.00 0.003564 0.002114 0.009050 0.05214 2.157 1.707 1.961 -0.006860 58.16 2.004e+8 1.835e+8 1.634e+8 2.155e+8 1.000 1.000 1.000 3.789e+8 1.360e+8 3.069 1.000 0.0000 0.0000 20.00 1995 4.173e+8 0.0001146 6.312e+9 1.948e+9 2.562e+9 1.102e+9 7.007e+8 4000 3.200e+9 3.470e+8 8.363e+8 7.303e+8 1.044e+9 0.1000 30.00 0.0000 1.000 0.0000 4000 1.077e+10 1.000 1.000 1.000 1.724e+12 0.005729 2.730e+12 1.365e+11 2.154e+11 1.000 1.000 1.000 2.730e+12 432.5 20.00 0.07000 0.9846 230.0 20.00 2.750e+11 3.614 5.654e+7 10.00 0.01143 7.213e+7 4000wdata2columnnamesagricultural inputs agricultural inputs change agricultural inputs per hectare agricultural material toxicity index air pollution policy implementation time arable land assimilation half life assimilation half life in 1970 assimilation half life multiplier average industrial output per person [time avg.] average life of agricultural inputs average life of agricultural inputs 1 average life of agricultural inputs 2 average life of industrial capital average life of industrial capital 1 average life of industrial capital 2 average life of land average life of land normal average life of service capital average life of service capital 1 average life of service capital 2 birth rate (crude) births capacity utilization fraction consumer goods per person (per year) consumption (consumer goods per year) crowding multiplier from industry current agricultural inputs death rate (crude) deaths deaths ages 0 to 14 deaths ages 15 to 44 deaths ages 45 to 64 deaths ages 65 and up delayed industrial output per capita delayed labor utilization fraction change desired completed family size desired completed family size normal desired food ratio desired persistent pollution index desired resource usage rate desired total fertility development cost per hectare effective health services per capita family income expectation family response to social norm family size mult. from perc. lifetime fecundity multiplier fertility control allocation per capita fertility control effect time fertility control effectiveness [lower better] fertility control effectiveness table fertility control facilities per capita food food per person food ratio food shortage perception delay fraction of agr. inputs alloc. to land development fraction of agr. inputs for land maintenance fraction of agr. inputs from persistent materials fraction of ind. capital alloc. to obt. resources fraction of ind. capital alloc. to obt. resources 1 fraction of ind. capital alloc. to obt. resources 2 fraction of ind. output alloc. to agriculture fraction of ind. output alloc. to agriculture 1 fraction of ind. output alloc. to agriculture 2 fraction of ind. output alloc. to cons. fraction of ind. output alloc. to cons. const. fraction of ind. output alloc. to cons. const. 1 fraction of ind. output alloc. to cons. const. 2 fraction of ind. output alloc. to cons. var. fraction of ind. output alloc. to ind. investment fraction of ind. output alloc. to services fraction of ind. output alloc. to services 1 fraction of ind. output alloc. to services 2 fraction of population urban fraction of resources from persistent materials fraction of resources remaining fraction of services allocated to fertility control health services impact delay health services per person income expectation averaging time indicated food per person indicated food per person 1 indicated food per person 2 indicated service output per person indicated service output per person 1 indicated service output per person 2 industrial capital industrial capital depreciation industrial capital investment industrial capital out. ratio mult. f. l. y. tech. industrial capital out. ratio mult. f. poll. tech. industrial capital out. ratio mult. f. r. c. tech. industrial capital output ratio industrial capital output ratio 1 industrial capital output ratio 2 industrial equilibrium time industrial material emissions factor industrial material toxicity index industrial output industrial output in 1970 industrial output per person industrial output per person desired inherent land fertility jobs jobs per hectare jobs per industrial capital unit jobs per service capital unit labor force labor force participation fraction labor utilization fraction labor utilization fraction delay time labor utilization fraction delayed land development rate land erosion rate land fertility land fertility degradation land fertility degradation rate land fertility regeneration land fertility regeneration time land fraction cultivated land fraction harvested land life multiplier from yield land life multiplier from yield 1 land life multiplier from yield 2 land life policy implementation time land removal for urban-industrial use land yield land yield multiplier from air pollution land yield multiplier from air pollution 1 land yield multiplier from air pollution 2 land yield multiplier from capital land yield multiplier from technology land yield multiplier from technology 1 land yield multiplier from technology 2 land yield technology land yield technology change rate land yield technology change rate mult. life expectancy life expectancy normal lifetime multiplier from crowding lifetime multiplier from food lifetime multiplier from health services lifetime multiplier from health services t. < 1940 lifetime multiplier from health services t. > 1940 lifetime multiplier from persistent pollution lifetime perception delay marginal land yield multiplier from capital marginal productivity of agricultural inputs marginal productivity of land development maturation age 14 to 15 maturation age 44 to 45 maturation age 64 to 65 maximum total fertility maximum total fertility normal mortality ages 0 to 14 mortality ages 15 to 44 mortality ages 45 to 64 mortality ages 65 and up need for fertility control per capita resource use multiplier perceived food ratio perceived food ratio change perceived life expectancy persistent pollution appearance rate persistent pollution assimilation rate persistent pollution generation by agriculture persistent pollution generation by industry persistent pollution generation factor persistent pollution generation factor 1 persistent pollution generation factor 2 persistent pollution generation rate persistent pollution in 1970 persistent pollution index persistent pollution technology [lower better] persistent pollution technology change persistent pollution technology change mult. persistent pollution transmission delay policy implementation time pollution (persistent) pollution per unit of ind. output population population ages 0 to 14 population ages 15 to 44 population ages 45 to 64 population ages 65 and up population equilibrium switch time potential arable land total potential jobs in agricultural sector potential jobs in industrial sector potential jobs in service sector potentially arable land processing loss reproductive lifetime resource conservation tech. change mult. resource conservation technology [lower better] resource conservation technology change resource extraction technology time resource usage rate resource use factor resource use factor 1 resource use factor 2 resources (nonrenewable) resources used per unit of ind. output service capital service capital depreciation service capital investment service capital output ratio service capital output ratio 1 service capital output ratio 2 service output services per person social adjustment delay social discount social family size norm subsistence food per person technology development delay total agricultural investment total fertility urban-industrial land urban-industrial land development time urban-industrial land per person urban-industrial land required zero population growth timewdata1rownames'1900.0 1901.0 1902.0 1903.0 1904.0 1905.0 1906.0 1907.0 1908.0 1909.0 1910.0 1911.0 1912.0 1913.0 1914.0 1915.0 1916.0 1917.0 1918.0 1919.0 1920.0 1921.0 1922.0 1923.0 1924.0 1925.0 1926.0 1927.0 1928.0 1929.0 1930.0 1931.0 1932.0 1933.0 1934.0 1935.0 1936.0 1937.0 1938.0 1939.0 1940.0 1941.0 1942.0 1943.0 1944.0 1945.0 1946.0 1947.0 1948.0 1949.0 1950.0 1951.0 1952.0 1953.0 1954.0 1955.0 1956.0 1957.0 1958.0 1959.0 1960.0 1961.0 1962.0 1963.0 1964.0 1965.0 1966.0 1967.0 1968.0 1969.0 1970.0 1971.0 1972.0 1973.0 1974.0 1975.0 1976.0 1977.0 1978.0 1979.0 1980.0 1981.0 1982.0 1983.0 1984.0 1985.0 1986.0 1987.0 1988.0 1989.0 1990.0 1991.0 1992.0 1993.0 1994.0 1995.0 1996.0 1997.0 1998.0 1999.0 2000.0 wdata2rownamesW1900.0 1910.0 1920.0 1930.0 1940.0 1950.0 1960.0 1970.0 1980.0 1990.0 2000.0 'Graph and Table Objects for RevolutionU helveticaW helveticaU helvetica U helvetica U helvetica W helvetica U helvetica Utimes WTimes UTimesU helvetica U helvetica UArialUArial UArial UCourier ULucida Grande ULucida Grande ULucida Grande UTimes WVerdana UVerdana UArial ULucida Grande Utimes U helvetica cREVGeneral bookmarks debugObjects handlerListpreOpenStack openCard prevHandleropenCard tempScriptscriptcREVGeometryCachestackID16507 graph object PGon graphClicked n, x, y put "You clicked on curve "& n &" at x = "& x &", y = "& y &"." end graphClicked on graphEdited put the graphYDataEdited of group "graph" into tNewYValue put "You set the volume to "& tNewYValue &"." end graphEdited # The following functions were used during testing of the graph object. function firstItemOnly pS put "" into tR put 0 into i repeat for each item tItem in pS add 1 to i if i=1 then put tItem &"," after tR else put "," after tR end repeat if not (char -1 of pS = ",") then delete char -1 of tR return tR end firstItemOnly function selectedItemsOnly pS, pSelectionList put "" into tR put 0 into i repeat for each item tItem in pS add 1 to i if i is among the items of pSelectionList then put tItem &"," after tR else put "," after tR end repeat if not (char -1 of pS = ",") then delete char -1 of tR return tR end selectedItemsOnly # Return whether a line of comma-separated numbers are ordered (nondecreasing or # nonincreasing). function dataOrdered s put true into tNondecreasing # Assume true until proven false. put true into tNonincreasing # Assume true until proven false. put (item 1 of s) + 0 into tPrevX repeat for each item tXStr in s put tXStr + 0 into tX if tX < tPrevX then put false into tNondecreasing if tX > tPrevX then put false into tNonincreasing if not (tNondecreasing or tNonincreasing) then exit repeat end repeat return (tNondecreasing or tNonincreasing) end dataOrdered function flipOrder s put "" into r put the number of items in s into n repeat with i = n down to 1 put (item i of s) &"," after r end repeat delete char -1 of r return r end flipOrder on flipIt put "10.1,11,10.9,11.4,11.7,12,11.5,11,10,10.3,10,11.5,12,11.5,,11,10,8.5,7.5,10,7,8" into s put flipOrder(s) end flipIt cREVGeometryCacheIDs1169586828424160581166423936986311211695868284251605911664239369873140116642393698837861169586828427160621166423936989378711664239369905504116642393699111442116958682842916063116642393699211856116958685513716055116958685513816060116958685513916061116642393697462961166423936975629511664239369761005116642393697710041166423936981100611664239369821216116642393698326831169586828421160561166423936984269111695868284221605711664239369853034cREVGeometrycacheorder total25 {   ( D,.P> table object P on openCard # Examples 3 and 4 require data in a global variable. Set the global variable if necessary # (this is necessary if someone saved the stack with example 3 or 4 showing and just # started up the stack). global gData, zztbgetUnformattedDataFromGlobal if field "info" contains "Example 3:" then put the wdata1data of this stack into gData else if field "info" contains "Example 4:" then put the wdata2data of this stack into zztbgetUnformattedDataFromGlobal put tbGetColumns(183, the wdata2data of this stack) into gData end if pass openCard end openCard function tbGetColumns pNumColumns, pS set the itemDelimiter to tab put pNumColumns + 0 into tNumColumns put "" into r repeat for each line l in pS put item 1 to tNumColumns of l after r put cr after r end repeat return r delete the last char of r #Delete trailing return. end tbGetColumns on doubleClickOnTable pWhereClicked put "You clicked on the table, part (column, row): "& pWhereClicked end doubleClickOnTable  cREVGeneralscriptChecksum>k@_h bookmarks handlerList(openCard tbGetColumns doubleClickOnTable tempScript prevHandlerdoubleClickOnTablescriptSelectionchar 1016 to 1015script:

on openCard

# Examples 3 and 4 require data in a global variable. Set the global variable if necessary

# (this is necessary if someone saved the stack with example 3 or 4 showing and just

# started up the stack).

global gData, zztbgetUnformattedDataFromGlobal

if field "info" contains "Example 3:" then

put the wdata1data of this stack into gData

else if field "info" contains "Example 4:" then

put the wdata2data of this stack into zztbgetUnformattedDataFromGlobal

put tbGetColumns(183, the wdata2data of this stack) into gData

end if

pass openCard

end openCard

function tbGetColumns pNumColumns, pS

set the itemDelimiter to tab

put pNumColumns + 0 into tNumColumns

put "" into r

repeat for each line l in pS

put item 1 to tNumColumns of l after r

put cr after r

end repeat

return r

delete the last char of r #Delete trailing return.

end tbGetColumns

on doubleClickOnTable pWhereClicked

put "You clicked on the table, part (column, row): "& pWhereClicked

end doubleClickOnTable

cREVGeometryCacheIDs11664249329016260116642493290262651166424932903626611664249329046275116642493290568111166424932906681211664249328966219116642493290768241166424932897625111664249329086814116642493289862541166424932910681611664249329096815116642493289962551166424932911681711664249329126818116642493291368191166424932914682011664249329156821116642493291668221166424932917682311664249329186825116642393697462961166423936975629511664249329006257cREVGeometryCacheorder total25KknoqtyzgraphIß# Copyright (c) Kenneth L. Simons 2000-2003. # All Rights Reserved. # The author hereby allows others to use the graph object according to the following principles: # Anyone may use the graph object for any purpose. # Rights to use of the original object must remain in the public domain. local aNumScaleLabelsCreated local aXScaleTextBottom local aDuplicatedPointNums on makeGraph # 1. Ensure (some of the) properties are okay. ensurePropertiesOkay # 2. Get/Calculate subsidiary information. # 2a. Main graph coordinates. put the graphMainRect of me into tGMR set the rect of button "graph background" of me to tGMR put item 1 of tGMR into a # Left side coordinate of main graph. put item 4 of tGMR into b # Bottom coordinate of main graph. put (item 3 of tGMR) - a into w # Width of main graph. put b - (item 2 of tGMR) into h # Height of main graph. # 2b. Data and axis scales. put "" into aDuplicatedPointNums put the graphX of me into tXData put singleNonmissingItemNum(tXData) into tSingleNonmXItemN if tSingleNonmXItemN <> "" then put ","& (item tSingleNonmXItemN of tXData) after item tSingleNonmXItemN of tXData # If only one data point, make 2 identical DPs for correct graphing. noteDuplicatedPointNum tSingleNonmXItemN end if put the number of items in tXData into tNumXPoints if (char -1 of tXData) = "," then add 1 to tNumXPoints # Include the blank item at the end. put nonBlankItems(tXData) into tXDataNonBlank # Used when finding min and max. put min(tXDataNonBlank) into tXMin if (the graphXMin of me) <> "" then put min(the graphXMin of me,tXMin) into tXMin put max(tXDataNonBlank) into tXMax if (the graphXMax of me) <> "" then put max(the graphXMax of me,tXMax) into tXMax put (tXMin = "" or tXMin > 0) and (the graphXLog of me = true) into tXLogarithmic if tXLogarithmic then put listLn(tXData) into tXData if tXMin <> "" then put ln(tXMin) into tXMin if tXMax <> "" then put ln(tXMax) into tXMax end if if (the graphXRound of me) = "true" then put roundRange(tXMin, tXMax, tXLogarithmic) into tRoundedXRange put item 1 of tRoundedXRange into tXMin put item 2 of tRoundedXRange into tXMax end if if tXMin = tXMax then if tXMin = 0 then put -1 into tXMin put 1 into tXMax else if tXMin > 0 then put tXMin * 2 into tXMax put 0 into tXMin else put 0 into tXMax put tXMin * 2 into tXMin end if end if put (the number of lines in the graphY of me) into tNumCurves repeat with i = 1 to tNumCurves put line i of the graphY of me into tYData[i] # In general this is a line of multiple numbers (so don't use format). end repeat repeat with i = 1 to tNumCurves if tSingleNonmXItemN <> "" then if (the number of items in tYData[i]) >= tSingleNonmXItemN then # This if-then is not crucial, but better with very many data points. put ","& item tSingleNonmXItemN of tYData[i] after item tSingleNonmXItemN of tYData[i] # Duplicate a data point, because it has been duplicated (for correct graphing) in the x-data. end if end if put singleNonmissingItemNum(tYData[i]) into tSingleNonmYItemN if tSingleNonmYItemN <> "" then # If only one data point, make 2 identical DPs for correct graphing. put ","& (item tSingleNonmYItemN of tXData) after item tSingleNonmYItemN of tXData add 1 to tNumXPoints repeat with j = 1 to tNumCurves put ","& (item tSingleNonmYItemN of tYData[j]) after item tSingleNonmYItemN of tYData[j] end repeat noteDuplicatedPointNum tSingleNonmYItemN end if put nonBlankItems(tYData[i]) into thisYDataNonBlank # Used when finding min and max. put line i of the graphYMin of me into tThisGraphYMin put format("%14.12e", min(thisYDataNonBlank)) into tYMin[i] if tThisGraphYMin <> "" then put format("%14.12e", min(tThisGraphYMin,tYMin[i])) into tYMin[i] put line i of the graphYMax of me into tThisGraphYMax put format("%14.12e", max(thisYDataNonBlank)) into tYMax[i] if tThisGraphYMax <> "" then put format("%14.12e", max(tThisGraphYMax,tYMax[i])) into tYMax[i] end repeat repeat with i = 1 to tNumCurves put (tYMin[i] = "" or tYMin[i] > 0) and ((the graphYLog of me) = "true" or (line i of the graphYLog of me) = true) into tYLogarithmic[i] if tYLogarithmic[i] then put listLn(tYData[i]) into tYData[i] if tYMin[i] <> "" then put ln(tYMin[i]) into tYMin[i] if tYMax[i] <> "" then put ln(tYMax[i]) into tYMax[i] end if end repeat put the graphYScaleSame of me into tYScalesSame # Determine whether y-scales forced to be the same. if tYScalesSame = true then # Disallow y-scales same if some logarithmic, some not. repeat with i = 2 to tNumCurves if tYLogarithmic[i] <> tYLogarithmic[1] then put false into tYScalesSame exit repeat end if end repeat end if if tYScalesSame = "true" then # A single ymin and ymax scale for all curves. put tYMin[1] into tYMinAll put tYMax[1] into tYMaxAll repeat with i = 2 to tNumCurves put min(tYMinAll,tYMin[i]) into tYMinAll put max(tYMaxAll,tYMax[i]) into tYMaxAll end repeat if tYMinAll = tYMaxAll then if tYMinAll = 0 then put -1 into tYMinAll put 1 into tYMaxAll else if tYMinAll > 0 then put tYMinAll * 2 into tYMaxAll put 0 into tYMinAll else put 0 into tYMaxAll put tYMinAll * 2 into tYMinAll end if end if if (the graphYRound of me) = "true" then put roundRange(tYMinAll, tYMaxAll, tYLogarithmic[1]) into tRoundedYRange put item 1 of tRoundedYRange into tYMinAll put item 2 of tRoundedYRange into tYMaxAll end if put format("%14.12e", tYMinAll) into tYMinAll put format("%14.12e", tYMaxAll) into tYMaxAll repeat with i = 1 to tNumCurves put tYMinAll into tYMin[i] put tYMaxAll into tYMax[i] end repeat else # Different ymin and ymax scales for different curves. if (the graphYRound of me) = "true" then repeat with i = 1 to tNumCurves put roundRange(tYMin[i], tYMax[i], tYLogarithmic[i]) into tRoundedYRange put format("%14.12e", item 1 of tRoundedYRange) into tYMin[i] put format("%14.12e", item 2 of tRoundedYRange) into tYMax[i] end repeat else repeat with i = 1 to tNumCurves if tYMin[i] = tYMax[i] then if tYMin[i] = 0 then put -1 into tYMin[i] put 1 into tYMax[i] else if tYMin[i] > 0 then put tYMin[i] * 2 into tYMax[i] put 0 into tYMin[i] else put 0 into tYMax[i] put tYMin[i] * 2 into tYMin[i] end if end if end repeat end if end if # 2c. Whether the y-axis scales for multiple variables are the same. if tYScalesSame <> "true" then put true into tYScalesSame # Assume same until proven different. repeat with i = 2 to tNumCurves if tYMin[i] <> tYMin[1] or tYMax[i] <> tYMax[1] then put false into tYScalesSame exit repeat end if end repeat end if # 2d. Scaling factors for plotting data. put w / (tXMax - tXMin) into tXScaleFactor repeat with i = 1 to tNumCurves put format("%14.12e", h / (tYMax[i] - tYMin[i])) into tYScaleFactor[i] end repeat # 2f. X and Y values at which to plot tic marks. if the graphXTicks of me = "none" then put "" into tXTickLocs else if (word 1 of the graphXTicks of me) = "about" then put chooseTickLocs(tXMin, tXMax,(word 2 of the graphXTicks of me),"") into tXTickLocs else if (word 1 of the graphXTicks of me) = "exactly" or (word 1 of the graphXTicks of me) = "exact" then put chooseTickLocs(tXMin, tXMax,"",(word 2 of the graphXTicks of me)) into tXTickLocs else if the graphXTicks of me <> "" then put the graphXTicks of me into tXTickLocs else put tXMin &","& tXMax into tXTickLocs end if if the graphYTicks of me = "none" then put "" into tYTickLocs else if (word 1 of the graphYTicks of me) = "about" then put chooseTickLocs(tYMin[1], tYMax[1],(word 2 of the graphYTicks of me),"") into tYTickLocs else if (word 1 of the graphYTicks of me) = "exactly" or (word 1 of the graphYTicks of me) = "exact" then put chooseTickLocs(tYMin[1], tYMax[1],"",(word 2 of the graphYTicks of me)) into tYTickLocs else if the graphYTicks of me <> "" then put the graphYTicks of me into tYTickLocs else put tYMin[1] &","& tYMax[1] into tYTickLocs # Y tic locs are defined in terms of the first y variable only. end if # 3. Lock the screen before doing anything that affects the display. lock screen # 4. Delete existing graphics and fields in this graph object, and the "graph cover" button if any. put the number of graphics in me into nGraphics repeat with i = nGraphics down to 1 delete graphic i of me end repeat put the number of fields in me into nFields repeat with i = nFields down to 1 delete field i of me end repeat if there is a button "graph cover" of me then delete button "graph cover" of me # 5. Draw axes. reset templateGraphic set the style of the templateGraphic to "polygon" set the lineSize of the templateGraphic to the graphAxisWidth of me set the points of the templateGraphic to a &","& (b-h) & cr & a &","& b & cr & (a+w) &","& b createGraphic "axes" put a &","& (b-h) &","& (a+w) &","& b into tGraphCoverRect # May be used below, for editable graphs. # 6. Draw tick marks. # 6a. Draw major tick marks and labels. put "" into aXScaleTextBottom put 0 into aNumScaleLabelsCreated put "" into tTickPoints put tXTickLocs <> "" and (the graphXTicksVisible of me) <> "false" into tXTicksVisible put tXTickLocs <> "" and (the graphXScaleVisible of me) <> "false" into tXScaleVisible if tXTicksVisible or tXScaleVisible then if the graphXTicksInset of me = "true" or (not tXTicksVisible) then put the graphTickMajorWidth of me into tTickOffset else put 0 into tTickOffset end if repeat for each item thisXLoc in tXTickLocs put round(a + (thisXLoc - tXMin) * tXScaleFactor) into thisXWindowLoc put b + (the graphTickMajorWidth of me) - tTickOffset into tYAtBottomOfTick if tXTicksVisible then put thisXWindowLoc &","& (b-tTickOffset) & cr & thisXWindowLoc &","& tYAtBottomOfTick & cr & cr after tTickPoints if tXScaleVisible then if tXLogarithmic then put exp(thisXLoc) into thisXLoc makeAxisLabel "x", thisXWindowLoc, tYAtBottomOfTick, thisXLoc end if end repeat end if put tYTickLocs <> "" and (the graphYTicksVisible of me) <> "false" into tYTicksVisible put the graphYScaleVisible of me into tGYSVOM if tGYSVOM = "true" then if not tYScalesSame then # When the graphYScaleVisible is true and there are multiple curves with different scales, display scales for each. put "" into tGYSVOM repeat with i = 1 to tNumCurves put i &"," after tGYSVOM end repeat delete the last char of tGYSVOM #Delete trailing comma. end if end if put tYTickLocs <> "" and tGYSVOM <> "false" into tYScaleVisible if tYTicksVisible or tYScaleVisible then if the graphYTicksInset of me = "true" or (not tYTicksVisible) then put the graphTickMajorWidth of me into tTickOffset else put 0 into tTickOffset end if repeat for each item thisYLoc in tYTickLocs # Step through different tick marks. (Recall that tYTickLocs is defined only in terms of the first y-variable.) put round(b - (thisYLoc - tYMin[1]) * tYScaleFactor[1]) into thisYWindowLoc put a - the graphTickMajorWidth of me + tTickOffset into tXAtLeftOfTick if tXTicksVisible then put tXAtLeftOfTick &","& thisYWindowLoc & cr & (a + tTickOffset) &","& thisYWindowLoc & cr & cr after tTickPoints if tYScaleVisible then if tGYSVOM = "true" then if tYLogarithmic[1] then put exp(thisYLoc) into tYLocsForScaleLabel else put thisYLoc into tYLocsForScaleLabel put "" into tYColorsForScaleLabel else if thisYLoc = tYMax[1] then put 1 into tYFrac else put (thisYLoc - tYMin[1]) / (tYMax[1] - tYMin[1]) into tYFrac put "" into tYLocsForScaleLabel put "" into tYColorsForScaleLabel put the number of items in tGYSVOM into n repeat with i = 1 to n # Step through different curves. put item i of tGYSVOM into thisCurveNum put tYMin[thisCurveNum] into tThisMin put tYMax[thisCurveNum] - tThisMin into tThisDiff if tYFrac = 1 then put tYMax[thisCurveNum] into tThisY #Avoid rounding error. else put tThisMin + tThisDiff * tYFrac into tThisY if tYLogarithmic[i] then put exp(tThisY) into tThisY put tThisY & return after tYLocsForScaleLabel put line i of the graphLineColors of me into tGC if tGC = "" then put the effective foregroundColor of me into tGC put tGC & return after tYColorsForScaleLabel end repeat delete the last char of tYLocsForScaleLabel #Delete trailing return. delete the last char of tYColorsForScaleLabel #Delete trailing return. end if makeAxisLabel "y", tXAtLeftOfTick, thisYWindowLoc, tYLocsForScaleLabel, tYColorsForScaleLabel end if end repeat end if if tXTicksVisible or tYTicksVisible then reset templateGraphic set the style of the templateGraphic to "polygon" set the points of the templateGraphic to tTickPoints createGraphic "ticks" end if # 7. Draw data. repeat with i = 1 to tNumCurves put tYScaleFactor[i] into thisYScaleFactor reset templateGraphic set the style of the templateGraphic to "polygon" if (line i of the graphLinesVisible of me) = "false" then put 0 into tGLW else put line i of the graphLineWidths of me into tGLW if tGLW is an integer then set the lineSize of the templateGraphic to tGLW put "" into tPoints repeat with j = 1 to tNumXPoints put item j of tXData into x put item j of tYData[i] into y if x = "" or y = "" then put cr after tPoints else put round(a + (x - tXMin) * tXScaleFactor) &","& round(b - (y - tYMin[i]) * thisYScaleFactor) & cr after tPoints end repeat delete char -1 of tPoints # Delete trailing return. set the points of the templateGraphic to tPoints put line i of the graphLineColors of me into tGC if tGC <> "" then set the foregroundColor of the templateGraphic to tGC put line i of the graphLineDashes of me into tGD if tGD <> "" then set the dashes of the templateGraphic to tGD if the graphClickable of me = "true" then set the script of the templateGraphic to "on mouseUp"& cr &" graphClicked "& i &", ((item 1 of the clickLoc) - "& a &") / "& tXScaleFactor &" + "& tXMin &", ("& b &" - (item 2 of the clickLoc)) / "& thisYScaleFactor &" + "& tYMin[i] & cr &"end mouseUp" end if put graphMarkerLineToPoints(line i of the graphMarkers of me) into tGM if tGM <> "" then put line 1 of tGM into tGMFilled put line 2 to -1 of tGM into tGMPoints set the markerDrawn of the templateGraphic to true set the markerFilled of the templateGraphic to tGMFilled set the markerPoints of the templateGraphic to tGMPoints if tGC <> "" then set the markerColor of the templateGraphic to tGC set the markerFillColor of the templateGraphic to tGC end if end if createGraphic "curve "& i end repeat # 8. Title. put the graphTitle of me into tMainTitle if tMainTitle <> "" then put the graphTitleTextSize of me into tTS if tTS = "" then put 12 into tTS put tTS + 4 into tTH put round(((item 1 of tGMR)+(item 3 of tGMR))/2) into tXLoc put round((item 2 of tGMR) - (the graphTitleGap of me)) into tBottom makeAField "title", tMainTitle, "center", the graphTitleTextFont of me, the graphTitleTextStyle of me, "", tTS, tTH, (tXLoc &","& 0), "", "", "", tBottom end if # 9. Axis variable/label names. put the graphXYLabelTextSize of me into tTS if tTS = "" then put 9 into tTS put tTS + 4 into tTH put the graphXLabel of me into tGXL if tGXL <> "" then put round(((item 1 of tGMR)+(item 3 of tGMR))/2) + (the graphXLabelXNudge of me) into tXLoc if tXTicksVisible then put the graphTickMajorWidth of me into tYOffset else put 0 into tYOffset end if if aXScaleTextBottom <> "" then put aXScaleTextBottom - 1 into tTopOfField else put (item 4 of tGMR) + tYOffset - 1 into tTopOfField end if add the graphXLabelYNudge of me to tTopOfField makeAField "x varname", tGXL, "center", the graphXYLabelTextFont of me, "", "", tTS, tTH, (tXLoc &","& 0), "", tTopOfField, "", "" put the bottom of field "x varname" of me into tXLabelingBottom # Used when making a key. else # No x-axis label was created. if aXScaleTextBottom <> "" then put aXScaleTextBottom into tXLabelingBottom # Used when making a key. else put b into tXLabelingBottom # Used when making a key. end if end if put the graphYLabel of me into tGYL if tGYL <> "" then # The left and bottom chosen here are quite arbitrary; there are certainly better methods to choose them. put (item 1 of tGMR) - 30 into tLeft if tXTicksVisible then subtract the graphTickMajorWidth of me from tLeft end if add the graphYLabelXNudge of me to tLeft put (item 2 of tGMR) - 6 into tBottom add the graphYLabelYNudge of me to tBottom makeAField "y varname", tGYL, "left", the graphXYLabelTextFont of me, "", "", tTS, tTH, "", tLeft, "", "", tBottom end if # 10. Key. # 10a. Whether to create a key, and what its text will say. put the graphYVariableNames of me into tKeyNames put the graphYScalesInKey of me into tIncludeYScalesInKey put the graphKeyLogIndicator of me into tLogIndicator if tLogIndicator <> "" then put " " before tLogIndicator put false into tMakeKey # Assume false until proven true. put "" into tKeyContents put 0 into i repeat for each line tThisKeyName in tKeyNames add 1 to i if tThisKeyName <> "" then put true into tMakeKey put tThisKeyName after tKeyContents if tYLogarithmic[i] then put tLogIndicator after tKeyContents put line i of the graphYUnitsOfMeasureInKey of me into tUnitsOfMeasure if tIncludeYScalesInKey then if tUnitsOfMeasure <> "" then put " " before tUnitsOfMeasure put " ("& displayRange(tYMin[i], tYMax[i]) & tUnitsOfMeasure &")" after tKeyContents # State the range and units of measure for this variable. else if tUnitsOfMeasure <> "" then put " ("& tUnitsOfMeasure &")" after tKeyContents # State the units of measure for this variable. end if put return after tKeyContents end if if i >= tNumCurves then exit repeat end repeat delete char -1 of tKeyContents # Delete trailing return. # 10b. Make key. if tMakeKey then # 10b1. Make the text of the key. put the graphKeyTextSize of me into tTS put tTS + min(0, round(the graphKeyTextSeparation of me)) into tTH put a + 20 + (the graphKeyXNudge of me) into tLeft put tXLabelingBottom + 12 + (the graphKeyYNudge of me) into tTop makeAField "key", tKeyContents, "left", the graphKeyTextFont of me, "plain", "", tTS, tTH, "", tLeft, tTop, "", "" # 10b2. Plot line segments in the key. repeat with i = 1 to tNumCurves put "curve "& i into tCurveName put the points of graphic tCurveName of me into tPoints put tTop + roundUp(tTH/2) + (i-1)*tTH into tLabelLineY put (tLeft - 20) &","& tLabelLineY into tPointA put (tLeft - 5) &","& tLabelLineY into tPointB put cr & cr & tPointA & cr & tPointB after tPoints set the points of graphic tCurveName of me to tPoints end repeat end if # 11. If requested, prepare for editable graph. if (the graphEditable of me) and (tNumCurves > 0) then reset templateButton set the rect of the templateButton to tGraphCoverRect set the script of the templateButton to "on mouseDown"& cr &" graphCoverClicked"& cr &"end mouseDown" set the showName of the templateButton to false set the showBorder of the templateButton to false set the threeD of the templateButton to false set the opaque of the templateButton to false set the traversalOn of the templateButton to false set the autoHilite of the templateButton to false create button "graph cover" in me set the cpEditCurveNum of button "graph cover" of me to tNumCurves set the cpGraphYMin of button "graph cover" of me to tYMin[tNumCurves] set the cpGraphYMax of button "graph cover" of me to tYMax[tNumCurves] # A minor part of setting up is determining whether the x-data are ordered, because # if the x-data are nondecreasing or nonincreasing, processing can be sped up for # editing graphs. put the points of graphic ("curve "& tNumCurves) of me into tPointsOfCurve if tMakeKey then delete line -3 to -1 of tPointsOfCurve # Ignore parts that pertain to the key. set the cpXDataRanges of button "graph cover" of me to clickXRanges(getXVals(tPointsOfCurve)) set the graphYDataEdited of me to tYData[tNumCurves] else set the graphYDataEdited of me to "" end if # 12. Unlock the screen and go back to the browse (hand) tool. reset templateField reset templateGraphic reset templateButton choose browse tool unlock screen end makeGraph on noteDuplicatedPointNum pNewPointNum put the number of items in aDuplicatedPointNums into tN repeat with i = 1 to tN put item i of aDuplicatedPointNums into tPN if pNewPointNum < tPN then put (tPN+1) into item i of aDuplicatedPointNums end repeat put pNewPointNum into item (tN+1) of aDuplicatedPointNums sort items of aDuplicatedPointNums numeric descending end noteDuplicatedPointNum # The following routine creates an axis-label field containing string s. The location of the # field is relative to point pXLoc,pYLoc - which is normally the bottom (for x-ticks) or # left (for y-ticks) point in an axis tick mark. pXOrY is either "x" or "y". The optional # parameter tYColorsForScaleLabel can have color indications in different lines, # to set the colors of different lines s. A multi-line s only makes sense for y-axis scales. on makeAxisLabel pXOrY, pXLoc, pYLoc, s, pTextColors if pXOrY = "x" and (the graphXScaleVisible of me = "false") then exit makeAxisLabel if pXOrY = "y" and (the graphYScaleVisible of me = "false") then exit makeAxisLabel add 1 to aNumScaleLabelsCreated put "sl"& aNumScaleLabelsCreated into tFieldName if pXOrY = "x" then put "center" into tTA else put "right" into tTA put the graphScaleTextSize of me into tTS if tTS = "" then put 9 into tTS put tTS + min(0, round(the graphScaleTextSeparation of me)) into tTH if pXOrY = "x" then put 1 into tXFudge put 1 into tYFudge put round(pXLoc + tXFudge) into pXLocToUse put "" into pRightToUse put round(pYLoc + tYFudge) into pTopToUse else put 5 into tXFudge put -1 into tYFudge put "" into pXLocToUse put round(pXLoc + tXFudge) into pRightToUse put round(pYLoc + tYFudge - tTS/2) into pTopToUse end if put makeNumbersNiceForDisplay(s) into s makeAField tFieldName, s, tTA, the graphScaleTextFont of me, "", pTextColors, tTS, tTH, (pXLocToUse &",0"), "", pTopToUse, pRightToUse, "" if pXOrY = "x" then put the bottom of field tFieldName of me into aXScaleTextBottom end makeAxisLabel # Retun the passed string, ensuring that if it is a number -- or a series of numbers on separate # lines -- the number(s) display nicely. # A disadvantage of how I use this above is, I ought to give enough accuracy to display even # a tiny range between min & max scales. function makeNumbersNiceForDisplay pS put the graphScaleExponentHighThreshold of me into tLargeNumberToExpThreshold put the graphScaleExponentLowThreshold of me into tSmallNumberToExpThreshold put the graphScaleMinimumSignificantDigits of me into tMinimumSignificantDigits put the number of lines in pS into tNumLines repeat with i = 1 to tNumLines put line i of pS into s if s is a number then put s+0 into n if n = 0 then put "0" into s else if abs(n) < tSmallNumberToExpThreshold or abs(n) >= tLargeNumberToExpThreshold then put getMagnitude(n) into m if the graphScaleExponentFormat of me is "^" then put "*10^" into tExponentSeparator else put "e" into tExponentSeparator end if put round(n / 10^m, tMinimumSignificantDigits - 1) & tExponentSeparator & m into s #put format("%3.2g", n / 10^m) & tExponentSeparator & m into s else if n is an integer then put n into s else put getMagnitude(n) into m put min(0, m - (tMinimumSignificantDigits - 1)) into magnitudeAtWhichToRound put round(n, -magnitudeAtWhichToRound) into s #put format("%3.2g", n) into s end if end if put s into line i of pS end repeat return pS end makeNumbersNiceForDisplay # The following routine creates a field as specified. Parameter pFieldName must be unique # on each call. Parameters pTextSize and pTextHeight must be valid positive integers. To # set the location of the field, either pass the location in pLoc, or pass the horizontal location # in one of pLoc (the vertical location in pLoc is arbitrary) / pLeft / pRight and the vertical # location in one of pLoc (the horizontal location in pLoc is arbitrary) / pTop / pBottom. on makeAField pFieldName, pContents, pTextAlign, pTextFont, pTextStyle, pTextColors, pTextSize, pTextHeight, pLoc, pLeft, pTop, pRight, pBottom reset templateField set the threeD of the templateField to false set the showBorder of the templateField to false set the opaque of the templateField to false set the lockText of the templateField to true if pTextAlign <> "" then set the textAlign of the templateField to pTextAlign if pTextFont <> "" then set the textFont of the templateField to pTextFont set the textSize of the templateField to pTextSize # The textSize must be set after the textFont. set the textHeight of the templateField to pTextHeight if pTextStyle <> "" then set the textStyle of the templateField to pTextStyle put the number of lines in pContents into tNumLines put 10000 into h # Take a purposely too high guess at the necessary height to display the string. #put tNumLines * pTextHeight + 8 into h set the height of the templateField to h put 10000 into w # Take a purposely too high guess at the necessary width to display the string. # put maxLineLength(pContents) * pTextSize into w # if pTextStyle contains "bold" then multiply w by 2 set the width of the templateField to w set the autoTab of the templateField to false create field pFieldName in me put pContents into field pFieldName of me put the formattedHeight of field pFieldName of me into h set the height of field pFieldName of me to h put (the formattedWidth of field pFieldName of me) + 10 into w # The formattedWidth is actually not wide enough to deter word wrapping (perhaps because of margins?), so I add 10. set the width of field pFieldName of me to w if pLoc <> "" then set the loc of field pFieldName of me to pLoc if pLeft <> "" then set the left of field pFieldName of me to pLeft if pTop <> "" then set the top of field pFieldName of me to pTop if pRight <> "" then set the right of field pFieldName of me to pRight if pBottom <> "" then set the bottom of field pFieldName of me to pBottom if pTextColors <> "" then put the number of lines in pTextColors into n repeat with i = 1 to n set the textColor of line i of field pFieldName of me to line i of pTextColors end repeat end if end makeAField function maxLineLength pString put 0 into tMaxSoFar repeat for each line l in pString put length(l) into tLineLength if tLineLength > tMaxSoFar then put tLineLength into tMaxSoFar end repeat return tMaxSoFar end maxLineLength function nonBlankItems s put "" into r repeat for each item thisItem in s if thisItem <> "" then put thisItem &"," after r end repeat delete char -1 of r return r end nonBlankItems function graphMarkerLineToPoints s put word 1 of s into w1 if w1 = "" then put false into tFilled put "dot" into s else if w1 = "none" then return "" # No markers. exit graphMarkerLineToPoints else if w1 = "filled" or w1 = "solid" then put true into tFilled delete word 1 of s else if w1 = "empty" or w1 = "hollow" then put false into tFilled delete word 1 of s else #Default is hollow. put false into tFilled end if put word 1 of s into tSizeWord put word 2 of s into tTypeWord if tTypeWord = "" then put tSizeWord into tTypeWord put "small" into tSizeWord end if set the wholeMatches to true put wordOffset(tSizeWord, "tiny small medium large") into tSizeNumberFromWord if tSizeNumberFromWord > 0 then put word tSizeNumberFromWord of "0.1 0.25 0.5 1" into tSizeNumber else if (tSizeWord is a number) then put tSizeWord into tSizeNumber else put 0 into tSizeNumber end if put wordOffset(tTypeWord, "dot + x diamond square triangle circle") into tTypeNumber if tTypeNumber > 0 then if tTypeNumber = 1 then #Dot put "0,0 0,0" into tPoints else if tTypeNumber = 2 then #+ put "0,-12 0,12 -12,0 12,0" into tPoints else if tTypeNumber = 3 then #x put "-12,-12 12,12 -12,12 12,-12" into tPoints else if tTypeNumber = 4 then #Diamond put "0,-12 12,0 0,12 -12,0 0,-12" into tPoints else if tTypeNumber = 5 then #Square put "-12,-12 12,-12 12,12 -12,12 -12,-12" into tPoints else if tTypeNumber = 6 then #Triangle put "0,-12 12,12 -12,12 0,-12" into tPoints else if tTypeNumber = 7 then #Circle put "0,-12 2,-12 5,-11 7,-10 9,-9 10,-7 11,-5 12,-2 12,0 12,2 11,5 10,7 9,9 7,10 5,11 2,12 0,12 -2,12 -5,11 -7,10 -9,9 -10,7 -11,5 -12,2 -12,0 -12,-2 -11,-5 -10,-7 -9,-9 -7,-10 -5,-11 -2,-12 0,-12" into tPoints else if tSizeNumber > 0 or tSizeWord is a number then delete word 1 of s else put 1 into tSizeNumber end if put s into tPoints end if replace " " with cr in tPoints if tSizeNumber <> 1 then put tPoints into tPointsOriginal put "" into tPoints put the number of lines in tPointsOriginal into n repeat with i = 1 to n put line i of tPointsOriginal into l repeat with j = 1 to 2 put round(tSizeNumber * (item j of l)) into item j of l end repeat put l & cr after tPoints end repeat delete char -1 of tPoints #Delete trailing return. end if end if return tFilled & cr & tPoints end graphMarkerLineToPoints on ensurePropertiesOkay # graphAxisWidth if the graphAxisWidth of me is not an integer then set the graphAxisWidth of me to 2 else if the graphAxisWidth of me < 1 then set the graphAxisWidth of me to 1 end if # graphMainRect put the graphMainRect of me into tGMR if tGMR <> "" then put tGMR into tGMRInit put the number of items in tGMR into n if n < 4 then put "" into tGMR else if n > 4 then put item 1 to 4 of tGMR into tGMR else repeat for each item tItem in tGMR if not (tItem is an integer) then put "" into tGMR exit repeat end if end repeat end if end if if tGMR = "" then put the rect of me into tGMR if tGMR <> tGMRInit then set the graphMainRect of me to tGMR # Data - ensure no spaces and no "NaN" values. put the graphX of me into tGX replace " " with "" in tGX replace "NaN" with "" in tGX set the graphX of me to tGX put the graphY of me into tGY replace " " with "" in tGY replace "NaN" with "" in tGY set the graphY of me to tGY # Tic widths. put the graphTickMajorWidth of me into tGTMW if not (tGTMW is an integer) then if tGTMW is a number then put round(tGTMW) into tGTMW else put 4 into tGTMW end if set the graphTickMajorWidth of me to tGTMW end if # Tick labels. put the graphScaleMinimumSignificantDigits of me into tMSD if tMSD is not a number then set the graphScaleMinimumSignificantDigits of me to 3 else if tMSD < 1 then set the graphScaleMinimumSignificantDigits of me to 1 else if tMSD is not an integer then set the graphScaleMinimumSignificantDigits of me to (trunc(tMSD) + 1) end ensurePropertiesOkay on setDefaultProperties set the graphAxisWidth of me to 1 set the graphClickable of me to "false" set the graphEditable of me to "false" set the graphKeyLogIndicator of me to "[logarithmic]" set the graphKeyTextFont of me to "" set the graphKeyTextSeparation of me to 3 set the graphKeyTextSize of me to 10 set the graphKeyXNudge of me to 0 set the graphKeyYNudge of me to 0 set the graphLineColors of me to "" set the graphLineDashes of me to "" set the graphLinesVisible of me to "true" set the graphLineWidths of me to "" set the graphMainRect of me to 50,50,250,150 set the graphMarkers of me to "" set the graphScaleExponentFormat of me to "^" set the graphScaleExponentHighThreshold of me to 100000 set the graphScaleExponentLowThreshold of me to 0.001 set the graphScaleMinimumSignificantDigits of me to 3 set the graphScaleTextSeparation of me to 3 set the graphScaleTextSize of me to 9 set the graphScaleTextFont of me to "" set the graphSendEditMessage of me to false set the graphTickMajorWidth of me to 4 set the graphTitle of me to "" set the graphTitleGap of me to 10 set the graphTitleTextFont of me to "" set the graphTitleTextSize of me to 12 set the graphTitleTextStyle of me to "plain" set the graphX of me to "0,1,2,3,4,5" set the graphXLabel of me to "" set the graphXLabelXNudge of me to 0 set the graphXLabelYNudge of me to 0 set the graphXLog of me to false set the graphXMax of me to "" set the graphXMin of me to "" set the graphXRound of me to false set the graphXScaleVisible of me to true set the graphXTicks of me to "" set the graphXTicksInset of me to false set the graphXTicksVisible of me to true set the graphXYLabelTextFont of me to "" set the graphXYLabelTextSize of me to 9 set the graphY of me to "0,1,2,3,4,5" set the graphYDataEdited of me to "" set the graphYLabel of me to "" set the graphYLabelXNudge of me to 0 set the graphYLabelYNudge of me to 0 set the graphYLog of me to false set the graphYMax of me to "" set the graphYMin of me to "" set the graphYRound of me to false set the graphYScaleSame of me to true set the graphYScaleVisible of me to true set the graphYTicks of me to "" set the graphYTicksInset of me to false set the graphYTicksVisible of me to true set the graphYUnitsOfMeasureInKey of me to "" set the graphYVariableNames of me to "" set the graphYScalesInKey of me to true end setDefaultProperties # The following handlers are used to come up with ranges for graphs. # Included are handlers for scaling numbers & for making them easily readable. # Round the range to use for a graph. Give this min. and max. numbers (in that order) # separated by a comma. This returns the new rounded min. and max., again separated # by a comma. The third argument is true if natural logarithms of the numbers have been # taken but the original numbers (the exponents of the logged numbers) will be displayed. function roundRange pMin, pMax, pLogged put pMin into tMin put pMax into tMax if pLogged <> "true" then if tMin = tMax then put roundDown( ln(abs(tMin)) / 2.3025850929941 ) into magnitude if tMin = 0 then put -1 into tMin put 1 into tMax else if tMin > 0 then put 0 into tMin put 2 * roundUpToMagnitude(tMax, magnitude) into tMax else -- tMin < 0 put 2 * roundDownToMagnitude(tMin, magnitude) into tMin put 0 into tMax end if else put roundDown( ln(abs(tMax - tMin)) / 2.3025850929941 ) into magnitude put roundDownToMagnitude(tMin, magnitude) into tMin put roundUpToMagnitude(tMax, magnitude) into tMax end if else # Deal with the logarithmic case. if tMin = tMax then put tMin - exp(1)/10 into tMin put tMin + exp(1)/10 into tMax else put getMagnitude(tMin) into tMinMagnitude put round(tMin, 1 - tMinMagnitude) into tMinTRounded if tMinTRounded > tMin then put tMinTRounded - 10^(tMinMagnitude - 1) into tMinTRounded put tMinTRounded into tMin put getMagnitude(tMax) into tMaxMagnitude put round(tMax, 1 - tMaxMagnitude) into tMaxTRounded if tMaxTRounded < tMax then put tMaxTRounded + 10^(tMaxMagnitude - 1) into tMaxTRounded put tMaxTRounded into tMax end if end if return tMin &","& tMax end roundRange -- Create a version of the range in readable form. function displayRange pMin, pMax return readableNumber(pMin) &" to "& readableNumber(pMax) end displayRange function readableTwoDigit n return readableNumber(roundToTwoDigits(n)) end readableTwoDigit -- Round to 2 digits of accuracy. function roundToTwoDigits n put getMagnitude(n) into magnitude put 10 ^ (magnitude - 1) into scalingNumber return round( n / scalingNumber ) * scalingNumber end roundToTwoDigits function readableNumber pN put pN + 0 into n if n = 0 then return "0" else put roundDown( ln(abs(n)) / 2.3025850929941 ) into magnitude if magnitude >= 3 and magnitude <= 20 then put magnitude div 3 into powerOfThousand put item powerOfThousand of "thousand,million,billion,trillion,quadrillion,quintillion" into s put 1000 into divisor repeat with i = 2 to powerOfThousand put divisor * 1000 into divisor end repeat put n / divisor into displayN -- if displayN > 0 and displayN < 10 then -- if displayN is an integer then -- put item displayN of "one,two,three,four,five,six,seven,eight,nine" into displayN -- end if -- end if return displayN && s else if magnitude >= -3 and magnitude <= 2 then return n else return (n / 10 ^ magnitude) &" * 10 ^ "& magnitude end if end if end readableNumber function getMagnitude n return roundDown( log10(abs(n)) ) end getMagnitude function roundDownToMagnitude n, magnitude put 10^magnitude into scalingFactor return scalingFactor * roundDown( n / scalingFactor ) end roundDownToMagnitude function roundDown n put trunc( n ) into m if n >= 0 then return m else if n = m then return n else return m - 1 end if end roundDown function roundUpToMagnitude n, magnitude put 10^magnitude into scalingFactor return scalingFactor * roundUp( n / scalingFactor ) end roundUpToMagnitude function roundUp n put trunc( n ) into m if n <= 0 then return m else if n = m then return n else return m + 1 end if end roundUp function roundToMagnitude n, magnitude put 10^magnitude into scalingFactor return scalingFactor * round( n / scalingFactor ) end roundToMagnitude function chooseTickLocs pMin, pMax, pApproxNum, pExactNum put pMin into tMin put pMax into tMax put tMax - tMin into tDiff if pExactNum <> "" then put round(min(max(pExactNum,2),50)) into tNumTicksToUse #Force to be between 2 and 50. else # Choose how many tick marks to use. put round(min(max(pApproxNum,2),50)) into tApproxNum #Force to be between 2 and 50. put 0 into tNumTicksToUse put 0 into tNumTicksToUsePriority2 put 0 into tNumTicksToUsePriority3 put 0 into tNumTicksToUsePriority4 put tDiff / 10^getMagnitude(tDiff) into tDiffInOnesUnits put roundUp(pApproxNum*0.66) into tMinNumTicks put roundDown(pApproxNum*1.515152) into tMaxNumTicks repeat with i = tMinNumTicks to tMaxNumTicks put (i-1) into tNumSteps put round(tDiffInOnesUnits / tNumSteps,4) into tStep if tStep = round(tStep,0) then # This number of tick marks gives a nice round number for the length between tick marks. if tNumTicksToUse = 0 then put i into tNumTicksToUse else if abs(i / tApproxNum - 1) < abs(tNumTicksToUse / tApproxNum - 1) then put i into tNumTicksToUse end if if i >= tApproxNum then exit repeat # The optimal number of ticks has been founded; never choose a higher number than necessary above the "about" number to achieve round-number distances. end if else if tStep = round(tStep,1) then # This number of tick marks gives a fairly nice round number for the length between tick marks. if tNumTicksToUsePriority2 = 0 then put i into tNumTicksToUsePriority2 else if abs(i / tApproxNum - 1) < abs(tNumTicksToUsePriority2 / tApproxNum - 1) then put i into tNumTicksToUsePriority2 end if else if tStep = round(tStep,2) then # This number of tick marks gives a somewhat round number for the length between tick marks. if tNumTicksToUsePriority3 = 0 then put i into tNumTicksToUsePriority3 else if abs(i / tApproxNum - 1) < abs(tNumTicksToUsePriority3 / tApproxNum - 1) then put i into tNumTicksToUsePriority3 end if else if tStep = round(tStep,3) then # This number of tick marks gives a somewhat round number for the length between tick marks. if tNumTicksToUsePriority4 = 0 then put i into tNumTicksToUsePriority4 else if abs(i / tApproxNum - 1) < abs(tNumTicksToUsePriority4 / tApproxNum - 1) then put i into tNumTicksToUsePriority4 end if end if end repeat if tNumTicksToUse = 0 then if tNumTicksToUsePriority2 > 0 then put tNumTicksToUsePriority2 into tNumTicksToUse # Use a fairly-round distance between ticks. else if tNumTicksToUsePriority3 > 0 then put tNumTicksToUsePriority3 into tNumTicksToUse # Use a slightly-round distance between ticks. else if tNumTicksToUsePriority4 > 0 then put tNumTicksToUsePriority4 into tNumTicksToUse # Use a marginally-round distance between ticks. else put tApproxNum into tNumTicksToUse # Couldn't find a round distance between ticks. end if end if end if # Determine the tick mark locations. put "" into tR put tDiff / (tNumTicksToUse - 1) into tStep repeat with i = 1 to tNumTicksToUse if i < tNumTicksToUse then put (tMin + (i - 1) * tStep) &"," after tR else put tMax after tR end repeat return tR end chooseTickLocs # Handle editing of the graph. on graphCoverClicked # Get info needed to control editing. put the left of button "graph cover" of me into tXLeft put the right of button "graph cover" of me into tXRight put the top of button "graph cover" of me into tYTop put the bottom of button "graph cover" of me into tYBottom put the cpEditCurveNum of button "graph cover" of me into tCurveNum put the points of graphic ("curve "& tCurveNum) of me into tPoints put tPoints into tPointsOriginal put (the cpXDataRanges of button "graph cover" of me) into tXValRanges # Do the editing - loop while the mouse is down.. repeat while the mouse is down # Get the mouse location, constrained on the y-axis to the plot region. put the mouseLoc into tMouseLoc put item 1 of tMouseLoc into tMouseX put max(min(item 2 of tMouseLoc, tYBottom), tYTop) into tMouseY # Revise the curve based on the mouse location. if tMouseX >= (tXLeft - 6) and tMouseX <= (tXRight + 6) then # 6 is the amount to left or right of graph where editing still occurs. # Loop through points on the curve. put 0 into tPointNum repeat for each line tXVR in tXValRanges add 1 to tPointNum put item 1 of tXVR into tMinOwnedRange if tMinOwnedRange = "" then next repeat # Ignore line segment in key. if tMinOwnedRange <> "-INF" then if tMouseX < tMinOwnedRange then next repeat end if put item 2 of tXVR into tMaxOwnedRange if tMaxOwnedRange <> "+INF" then if tMouseX > tMaxOwnedRange then next repeat end if put tMouseY into item 2 of line tPointNum of tPoints set the points of graphic ("curve "& tCurveNum) of me to tPoints end repeat end if end repeat # The mouse button is no longer down. Update y-data based on the edited graph. if tPoints <> tPointsOriginal then put tYBottom - tYTop into tYDiff put the cpGraphYMin of button "graph cover" of me into tYValsMin put the cpGraphYMax of button "graph cover" of me into tYValsMax put tYValsMax - tYValsMin into tYValsDiff put the number of lines in tXValRanges into tNumPoints put "" into tNewYData put 0 into tPointNum repeat for each line tP in tPoints add 1 to tPointNum if tP = tNumPoints then exit repeat # The curve may have more points, but they belong to the line segment in the key, and must not be edited. put item 2 of tP into tPY put tYValsMin + tYValsDiff * (tYBottom - tPY) / tYDiff into tYVal put tYVal &"," after tNewYData end repeat delete the last char of tNewYData # Delete trailing comma. repeat for each item tDuplicatedPointNum in aDuplicatedPointNums # These have already been sorted in reverse order. delete item tDuplicatedPointNum of tNewYData # Some points may have been duplicated for internal purposes, to ensure graphs can be drawn correctly when there is only one datum, but the user must not be passed back data that include duplicates. end repeat set the graphYDataEdited of me to tNewYData if (the graphSendEditMessage of me) = "true" then send "graphEdited" to this card end if end graphCoverClicked # Given a string of lines each containing an x-value as its first (comma-separated) item, return a comma-separated list of the x-values. function getXVals pS put "" into tR repeat for each line tL in pS put (item 1 of tL) &"," after tR end repeat delete char -1 of tR return tR end getXVals # Given a list of x-data, return "owned" ranges around each data point, i.e. the x-values for which the nearest data point is each point. # The result will be a string with one line of comma-separated data for each x-data point. In each line, the first item is the minimum owned # and the second item is the maximum owned value. "-INF" or "+INF" is used where the minimum or maximum owned value is negative # or positive infinity. function clickXRanges pXData # Get the x-data in sorted order. put nonBlankItems(pXData) into tXDataSorted sort items of tXDataSorted numeric # In case of small round-off errors in numbers, ensure that the min. and max. parameters are not inside the x data points. put item 1 of tXDataSorted into tXMin put item -1 of tXDataSorted into tXMax # Prepare lists of the relevant min. and max. values, by looping through each data point and adding its information to the lists. put "" into tRangesOwned repeat for each item tN in pXData if tN = "" then put "" into tThisRangeMinOwned put "" into tThisRangeMaxOwned else # Find the greatest point below this x-value, or the overall min. if no points are below. put tXMin into tThisRangeMin repeat for each item tSortedN in tXDataSorted if tSortedN < tN then put tSortedN into tThisRangeMin else exit repeat end repeat # Find the smallest point above this x-value, or the overall max. if no points are above. if (item -1 of tXDataSorted) = tN then put tXMax into tThisRangeMax else repeat for each item tSortedN in tXDataSorted if tSortedN > tN then put tSortedN into tThisRangeMax exit repeat end if end repeat end if # In the range just found, if the point is in between other points, half the ranges belongs to this point and half to other points. if tN=tXMin then put "-INF" into tThisRangeMinOwned else put (tN + tThisRangeMin) / 2 into tThisRangeMinOwned end if if tN=tXMax then put "+INF" into tThisRangeMaxOwned else put (tThisRangeMax + tN) / 2 into tThisRangeMaxOwned end if end if # Add information to the lists of ranges owned. put tThisRangeMinOwned &","& tThisRangeMaxOwned & cr after tRangesOwned # Use &","& tN to include the x-value as well. end repeat delete char -1 of tRangesOwned if (char -1 of pXData) = "," then put cr &"," after tRangesOwned #The trailing comma corresponds to a blank item. return tRangesOwned end clickXRanges # Given a list of items, take the natural logarithm of all nonblank items. function listLn s put "" into r repeat for each item tItem in s if tItem <> "" then put ln(tItem) into tItem put tItem &"," after r end repeat delete char -1 of r return r end listLn # Given a list of items, if exactly one is non-null then return the item number, else return null. function singleNonmissingItemNum s put "" into tR put 0 into i repeat for each item tItem in s add 1 to i if tItem <> "" then if tR = "" then put i into tR else put "" into tR exit repeat end if end if end repeat return tR end singleNonmissingItemNum on createGraphic pName put the lockMessages into tOrigLockMessages set the lockMessages to true # Revolution has a "feature" that alters small graphic objects, but we don't want that here. create graphic pName in me set the lockMessages to tOrigLockMessages end createGraphic .<graphLineDashes graphYRoundfalsegraphLinesVisibletruegraphYTicksInsetfalsegraphEditablefalsegraphLineWidthsgraphXLabelXNudge0 graphXMingraphSendEditMessagefalsegraphYLabelYNudge6 graphXMaxgraphXScaleVisibletrue graphXTicksgraphScaleExponentFormat^graphMainRect 50,80,250,180graphKeyXNudge0graphKeyLogIndicator [logarithmic] graphYLabel!Major oil tanker spills worldwidegraphXYLabelTextSize12graphTitleTextSize12graphYVariableNamesgraphYTicksVisibletruegraphXYLabelTextFont graphMarkerstiny +graphAxisWidth1graphTitleTextFontgraphYScaleSametruegraphScaleTextSize9graphTitleTextStyleplain graphXRoundfalsegraphClickablefalse graphTitlegraphScaleTextSeparation3graphYLabelXNudge0graphScaleTextFont graphYMin graphScaleExponentHighThreshold100000 graphYMax graphXLogfalsegraphLineColorsredgraphYScaleVisibletrue graphXLabelYeargraphYDataEditedgraphTitleGap10graphKeyTextSeparation3graphXLabelYNudge-18#graphScaleMinimumSignificantDigits3 graphYTicksgraphXTicksInsetfalsegraphYScalesInKeytruegraphXTicksVisibletruegraphKeyYNudge0graphScaleExponentLowThreshold0.001graphXr1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997graphY.8,6,6,6,11,4,2,0,5,0,2,0,0,0,3,0,2,1,1,2,1,1,2graphKeyTextSize10 graphYLogfalsegraphYUnitsOfMeasureInKeygraphTickMajorWidth4graphKeyTextFont cREVGeneral scriptChecksum 7{հئb bookmarks revUniqueID 1166423936976 breakPoints handlerListmakeGraph noteDuplicatedPointNum makeAxisLabel makeNumbersNiceForDisplay makeAField maxLineLength nonBlankItems graphMarkerLineToPoints ensurePropertiesOkay setDefaultProperties roundRange displayRange readableTwoDigit roundToTwoDigits readableNumber getMagnitude roundDownToMagnitude roundDown roundUpToMagnitude roundUp roundToMagnitude chooseTickLocs graphCoverClicked getXVals clickXRanges listLn singleNonmissingItemNum createGraphicscriptSelectionchar 14644 to 14643 prevHandlerchooseTickLocs tempScriptscript

# Copyright (c) Kenneth L. Simons 2000-2003.

# All Rights Reserved.

# The author hereby allows others to use the graph object according to the following principles:

# Anyone may use the graph object for any purpose.

# Rights to use of the original object must remain in the public domain.

local aNumScaleLabelsCreated

local aXScaleTextBottom

local aDuplicatedPointNums

on makeGraph

# 1. Ensure (some of the) properties are okay.

ensurePropertiesOkay

# 2. Get/Calculate subsidiary information.

# 2a. Main graph coordinates.

put the graphMainRect of me into tGMR

set the rect of button "graph background" of me to tGMR

put item 1 of tGMR into a # Left side coordinate of main graph.

put item 4 of tGMR into b # Bottom coordinate of main graph.

put (item 3 of tGMR) - a into w # Width of main graph.

put b - (item 2 of tGMR) into h # Height of main graph.

# 2b. Data and axis scales.

put "" into aDuplicatedPointNums

put the graphX of me into tXData

put singleNonmissingItemNum(tXData) into tSingleNonmXItemN

if tSingleNonmXItemN <> "" then

put ","& (item tSingleNonmXItemN of tXData) after item tSingleNonmXItemN of tXData # If only one data point, make 2 identical DPs for correct graphing.

noteDuplicatedPointNum tSingleNonmXItemN

end if

put the number of items in tXData into tNumXPoints

if (char -1 of tXData) = "," then add 1 to tNumXPoints # Include the blank item at the end.

put nonBlankItems(tXData) into tXDataNonBlank # Used when finding min and max.

put min(tXDataNonBlank) into tXMin

if (the graphXMin of me) <> "" then put min(the graphXMin of me,tXMin) into tXMin

put max(tXDataNonBlank) into tXMax

if (the graphXMax of me) <> "" then put max(the graphXMax of me,tXMax) into tXMax

put (tXMin = "" or tXMin > 0) and (the graphXLog of me = true) into tXLogarithmic

if tXLogarithmic then

put listLn(tXData) into tXData

if tXMin <> "" then put ln(tXMin) into tXMin

if tXMax <> "" then put ln(tXMax) into tXMax

end if

if (the graphXRound of me) = "true" then

put roundRange(tXMin, tXMax, tXLogarithmic) into tRoundedXRange

put item 1 of tRoundedXRange into tXMin

put item 2 of tRoundedXRange into tXMax

end if

if tXMin = tXMax then

if tXMin = 0 then

put -1 into tXMin

put 1 into tXMax

else if tXMin > 0 then

put tXMin * 2 into tXMax

put 0 into tXMin

else

put 0 into tXMax

put tXMin * 2 into tXMin

end if

end if

put (the number of lines in the graphY of me) into tNumCurves

repeat with i = 1 to tNumCurves

put line i of the graphY of me into tYData[i] # In general this is a line of multiple numbers (so don't use format).

end repeat

repeat with i = 1 to tNumCurves

if tSingleNonmXItemN <> "" then

if (the number of items in tYData[i]) >= tSingleNonmXItemN then # This if-then is not crucial, but better with very many data points.

put ","& item tSingleNonmXItemN of tYData[i] after item tSingleNonmXItemN of tYData[i] # Duplicate a data point, because it has been duplicated (for correct graphing) in the x-data.

end if

end if

put singleNonmissingItemNum(tYData[i]) into tSingleNonmYItemN

if tSingleNonmYItemN <> "" then # If only one data point, make 2 identical DPs for correct graphing.

put ","& (item tSingleNonmYItemN of tXData) after item tSingleNonmYItemN of tXData

add 1 to tNumXPoints

repeat with j = 1 to tNumCurves

put ","& (item tSingleNonmYItemN of tYData[j]) after item tSingleNonmYItemN of tYData[j]

end repeat

noteDuplicatedPointNum tSingleNonmYItemN

end if

put nonBlankItems(tYData[i]) into thisYDataNonBlank # Used when finding min and max.

put line i of the graphYMin of me into tThisGraphYMin

put format("%14.12e", min(thisYDataNonBlank)) into tYMin[i]

if tThisGraphYMin <> "" then put format("%14.12e", min(tThisGraphYMin,tYMin[i])) into tYMin[i]

put line i of the graphYMax of me into tThisGraphYMax

put format("%14.12e", max(thisYDataNonBlank)) into tYMax[i]

if tThisGraphYMax <> "" then put format("%14.12e", max(tThisGraphYMax,tYMax[i])) into tYMax[i]

end repeat

repeat with i = 1 to tNumCurves

put (tYMin[i] = "" or tYMin[i] > 0) and ((the graphYLog of me) = "true" or (line i of the graphYLog of me) = true) into tYLogarithmic[i]

if tYLogarithmic[i] then

put listLn(tYData[i]) into tYData[i]

if tYMin[i] <> "" then put ln(tYMin[i]) into tYMin[i]

if tYMax[i] <> "" then put ln(tYMax[i]) into tYMax[i]

end if

end repeat

put the graphYScaleSame of me into tYScalesSame # Determine whether y-scales forced to be the same.

if tYScalesSame = true then # Disallow y-scales same if some logarithmic, some not.

repeat with i = 2 to tNumCurves

if tYLogarithmic[i] <> tYLogarithmic[1] then

put false into tYScalesSame

exit repeat

end if

end repeat

end if

if tYScalesSame = "true" then # A single ymin and ymax scale for all curves.

put tYMin[1] into tYMinAll

put tYMax[1] into tYMaxAll

repeat with i = 2 to tNumCurves

put min(tYMinAll,tYMin[i]) into tYMinAll

put max(tYMaxAll,tYMax[i]) into tYMaxAll

end repeat

if tYMinAll = tYMaxAll then

if tYMinAll = 0 then

put -1 into tYMinAll

put 1 into tYMaxAll

else if tYMinAll > 0 then

put tYMinAll * 2 into tYMaxAll

put 0 into tYMinAll

else

put 0 into tYMaxAll

put tYMinAll * 2 into tYMinAll

end if

end if

if (the graphYRound of me) = "true" then

put roundRange(tYMinAll, tYMaxAll, tYLogarithmic[1]) into tRoundedYRange

put item 1 of tRoundedYRange into tYMinAll

put item 2 of tRoundedYRange into tYMaxAll

end if

put format("%14.12e", tYMinAll) into tYMinAll

put format("%14.12e", tYMaxAll) into tYMaxAll

repeat with i = 1 to tNumCurves

put tYMinAll into tYMin[i]

put tYMaxAll into tYMax[i]

end repeat

else # Different ymin and ymax scales for different curves.

if (the graphYRound of me) = "true" then

repeat with i = 1 to tNumCurves

put roundRange(tYMin[i], tYMax[i], tYLogarithmic[i]) into tRoundedYRange

put format("%14.12e", item 1 of tRoundedYRange) into tYMin[i]

put format("%14.12e", item 2 of tRoundedYRange) into tYMax[i]

end repeat

else

repeat with i = 1 to tNumCurves

if tYMin[i] = tYMax[i] then

if tYMin[i] = 0 then

put -1 into tYMin[i]

put 1 into tYMax[i]

else if tYMin[i] > 0 then

put tYMin[i] * 2 into tYMax[i]

put 0 into tYMin[i]

else

put 0 into tYMax[i]

put tYMin[i] * 2 into tYMin[i]

end if

end if

end repeat

end if

end if

# 2c. Whether the y-axis scales for multiple variables are the same.

if tYScalesSame <> "true" then

put true into tYScalesSame # Assume same until proven different.

repeat with i = 2 to tNumCurves

if tYMin[i] <> tYMin[1] or tYMax[i] <> tYMax[1] then

put false into tYScalesSame

exit repeat

end if

end repeat

end if

# 2d. Scaling factors for plotting data.

put w / (tXMax - tXMin) into tXScaleFactor

repeat with i = 1 to tNumCurves

put format("%14.12e", h / (tYMax[i] - tYMin[i])) into tYScaleFactor[i]

end repeat

# 2f. X and Y values at which to plot tic marks.

if the graphXTicks of me = "none" then

put "" into tXTickLocs

else if (word 1 of the graphXTicks of me) = "about" then

put chooseTickLocs(tXMin, tXMax,(word 2 of the graphXTicks of me),"") into tXTickLocs

else if (word 1 of the graphXTicks of me) = "exactly" or (word 1 of the graphXTicks of me) = "exact" then

put chooseTickLocs(tXMin, tXMax,"",(word 2 of the graphXTicks of me)) into tXTickLocs

else if the graphXTicks of me <> "" then

put the graphXTicks of me into tXTickLocs

else

put tXMin &","& tXMax into tXTickLocs

end if

if the graphYTicks of me = "none" then

put "" into tYTickLocs

else if (word 1 of the graphYTicks of me) = "about" then

put chooseTickLocs(tYMin[1], tYMax[1],(word 2 of the graphYTicks of me),"") into tYTickLocs

else if (word 1 of the graphYTicks of me) = "exactly" or (word 1 of the graphYTicks of me) = "exact" then

put chooseTickLocs(tYMin[1], tYMax[1],"",(word 2 of the graphYTicks of me)) into tYTickLocs

else if the graphYTicks of me <> "" then

put the graphYTicks of me into tYTickLocs

else

put tYMin[1] &","& tYMax[1] into tYTickLocs # Y tic locs are defined in terms of the first y variable only.

end if

# 3. Lock the screen before doing anything that affects the display.

lock screen

# 4. Delete existing graphics and fields in this graph object, and the "graph cover" button if any.

put the number of graphics in me into nGraphics

repeat with i = nGraphics down to 1

delete graphic i of me

end repeat

put the number of fields in me into nFields

repeat with i = nFields down to 1

delete field i of me

end repeat

if there is a button "graph cover" of me then delete button "graph cover" of me

# 5. Draw axes.

reset templateGraphic

set the style of the templateGraphic to "polygon"

set the lineSize of the templateGraphic to the graphAxisWidth of me

set the points of the templateGraphic to a &","& (b-h) & cr & a &","& b & cr & (a+w) &","& b

createGraphic "axes"

put a &","& (b-h) &","& (a+w) &","& b into tGraphCoverRect # May be used below, for editable graphs.

# 6. Draw tick marks.

# 6a. Draw major tick marks and labels.

put "" into aXScaleTextBottom

put 0 into aNumScaleLabelsCreated

put "" into tTickPoints

put tXTickLocs <> "" and (the graphXTicksVisible of me) <> "false" into tXTicksVisible

put tXTickLocs <> "" and (the graphXScaleVisible of me) <> "false" into tXScaleVisible

if tXTicksVisible or tXScaleVisible then

if the graphXTicksInset of me = "true" or (not tXTicksVisible) then

put the graphTickMajorWidth of me into tTickOffset

else

put 0 into tTickOffset

end if

repeat for each item thisXLoc in tXTickLocs

put round(a + (thisXLoc - tXMin) * tXScaleFactor) into thisXWindowLoc

put b + (the graphTickMajorWidth of me) - tTickOffset into tYAtBottomOfTick

if tXTicksVisible then put thisXWindowLoc &","& (b-tTickOffset) & cr & thisXWindowLoc &","& tYAtBottomOfTick & cr & cr after tTickPoints

if tXScaleVisible then

if tXLogarithmic then put exp(thisXLoc) into thisXLoc

makeAxisLabel "x", thisXWindowLoc, tYAtBottomOfTick, thisXLoc

end if

end repeat

end if

put tYTickLocs <> "" and (the graphYTicksVisible of me) <> "false" into tYTicksVisible

put the graphYScaleVisible of me into tGYSVOM

if tGYSVOM = "true" then

if not tYScalesSame then # When the graphYScaleVisible is true and there are multiple curves with different scales, display scales for each.

put "" into tGYSVOM

repeat with i = 1 to tNumCurves

put i &"," after tGYSVOM

end repeat

delete the last char of tGYSVOM #Delete trailing comma.

end if

end if

put tYTickLocs <> "" and tGYSVOM <> "false" into tYScaleVisible

if tYTicksVisible or tYScaleVisible then

if the graphYTicksInset of me = "true" or (not tYTicksVisible) then

put the graphTickMajorWidth of me into tTickOffset

else

put 0 into tTickOffset

end if

repeat for each item thisYLoc in tYTickLocs # Step through different tick marks. (Recall that tYTickLocs is defined only in terms of the first y-variable.)

put round(b - (thisYLoc - tYMin[1]) * tYScaleFactor[1]) into thisYWindowLoc

put a - the graphTickMajorWidth of me + tTickOffset into tXAtLeftOfTick

if tXTicksVisible then put tXAtLeftOfTick &","& thisYWindowLoc & cr & (a + tTickOffset) &","& thisYWindowLoc & cr & cr after tTickPoints

if tYScaleVisible then

if tGYSVOM = "true" then

if tYLogarithmic[1] then put exp(thisYLoc) into tYLocsForScaleLabel

else put thisYLoc into tYLocsForScaleLabel

put "" into tYColorsForScaleLabel

else

if thisYLoc = tYMax[1] then put 1 into tYFrac

else put (thisYLoc - tYMin[1]) / (tYMax[1] - tYMin[1]) into tYFrac

put "" into tYLocsForScaleLabel

put "" into tYColorsForScaleLabel

put the number of items in tGYSVOM into n

repeat with i = 1 to n # Step through different curves.

put item i of tGYSVOM into thisCurveNum

put tYMin[thisCurveNum] into tThisMin

put tYMax[thisCurveNum] - tThisMin into tThisDiff

if tYFrac = 1 then put tYMax[thisCurveNum] into tThisY #Avoid rounding error.

else put tThisMin + tThisDiff * tYFrac into tThisY

if tYLogarithmic[i] then put exp(tThisY) into tThisY

put tThisY & return after tYLocsForScaleLabel

put line i of the graphLineColors of me into tGC

if tGC = "" then put the effective foregroundColor of me into tGC

put tGC & return after tYColorsForScaleLabel

end repeat

delete the last char of tYLocsForScaleLabel #Delete trailing return.

delete the last char of tYColorsForScaleLabel #Delete trailing return.

end if

makeAxisLabel "y", tXAtLeftOfTick, thisYWindowLoc, tYLocsForScaleLabel, tYColorsForScaleLabel

end if

end repeat

end if

if tXTicksVisible or tYTicksVisible then

reset templateGraphic

set the style of the templateGraphic to "polygon"

set the points of the templateGraphic to tTickPoints

createGraphic "ticks"

end if

# 7. Draw data.

repeat with i = 1 to tNumCurves

put tYScaleFactor[i] into thisYScaleFactor

reset templateGraphic

set the style of the templateGraphic to "polygon"

if (line i of the graphLinesVisible of me) = "false" then put 0 into tGLW

else put line i of the graphLineWidths of me into tGLW

if tGLW is an integer then set the lineSize of the templateGraphic to tGLW

put "" into tPoints

repeat with j = 1 to tNumXPoints

put item j of tXData into x

put item j of tYData[i] into y

if x = "" or y = "" then put cr after tPoints

else put round(a + (x - tXMin) * tXScaleFactor) &","& round(b - (y - tYMin[i]) * thisYScaleFactor) & cr after tPoints

end repeat

delete char -1 of tPoints # Delete trailing return.

set the points of the templateGraphic to tPoints

put line i of the graphLineColors of me into tGC

if tGC <> "" then set the foregroundColor of the templateGraphic to tGC

put line i of the graphLineDashes of me into tGD

if tGD <> "" then set the dashes of the templateGraphic to tGD

if the graphClickable of me = "true" then

set the script of the templateGraphic to "on mouseUp"& cr &" graphClicked "& i &", ((item 1 of the clickLoc) - "& a &") / "& tXScaleFactor &" + "& tXMin &", ("& b &" - (item 2 of the clickLoc)) / "& thisYScaleFactor &" + "& tYMin[i] & cr &"end mouseUp"

end if

put graphMarkerLineToPoints(line i of the graphMarkers of me) into tGM

if tGM <> "" then

put line 1 of tGM into tGMFilled

put line 2 to -1 of tGM into tGMPoints

set the markerDrawn of the templateGraphic to true

set the markerFilled of the templateGraphic to tGMFilled

set the markerPoints of the templateGraphic to tGMPoints

if tGC <> "" then

set the markerColor of the templateGraphic to tGC

set the markerFillColor of the templateGraphic to tGC

end if

end if

createGraphic "curve "& i

end repeat

# 8. Title.

put the graphTitle of me into tMainTitle

if tMainTitle <> "" then

put the graphTitleTextSize of me into tTS

if tTS = "" then put 12 into tTS

put tTS + 4 into tTH

put round(((item 1 of tGMR)+(item 3 of tGMR))/2) into tXLoc

put round((item 2 of tGMR) - (the graphTitleGap of me)) into tBottom

makeAField "title", tMainTitle, "center", the graphTitleTextFont of me, the graphTitleTextStyle of me, "", tTS, tTH, (tXLoc &","& 0), "", "", "", tBottom

end if

# 9. Axis variable/label names.

put the graphXYLabelTextSize of me into tTS

if tTS = "" then put 9 into tTS

put tTS + 4 into tTH

put the graphXLabel of me into tGXL

if tGXL <> "" then

put round(((item 1 of tGMR)+(item 3 of tGMR))/2) + (the graphXLabelXNudge of me) into tXLoc

if tXTicksVisible then

put the graphTickMajorWidth of me into tYOffset

else

put 0 into tYOffset

end if

if aXScaleTextBottom <> "" then

put aXScaleTextBottom - 1 into tTopOfField

else

put (item 4 of tGMR) + tYOffset - 1 into tTopOfField

end if

add the graphXLabelYNudge of me to tTopOfField

makeAField "x varname", tGXL, "center", the graphXYLabelTextFont of me, "", "", tTS, tTH, (tXLoc &","& 0), "", tTopOfField, "", ""

put the bottom of field "x varname" of me into tXLabelingBottom # Used when making a key.

else

# No x-axis label was created.

if aXScaleTextBottom <> "" then

put aXScaleTextBottom into tXLabelingBottom # Used when making a key.

else

put b into tXLabelingBottom # Used when making a key.

end if

end if

put the graphYLabel of me into tGYL

if tGYL <> "" then

# The left and bottom chosen here are quite arbitrary; there are certainly better methods to choose them.

put (item 1 of tGMR) - 30 into tLeft

if tXTicksVisible then

subtract the graphTickMajorWidth of me from tLeft

end if

add the graphYLabelXNudge of me to tLeft

put (item 2 of tGMR) - 6 into tBottom

add the graphYLabelYNudge of me to tBottom

makeAField "y varname", tGYL, "left", the graphXYLabelTextFont of me, "", "", tTS, tTH, "", tLeft, "", "", tBottom

end if

# 10. Key.

# 10a. Whether to create a key, and what its text will say.

put the graphYVariableNames of me into tKeyNames

put the graphYScalesInKey of me into tIncludeYScalesInKey

put the graphKeyLogIndicator of me into tLogIndicator

if tLogIndicator <> "" then put " " before tLogIndicator

put false into tMakeKey # Assume false until proven true.

put "" into tKeyContents

put 0 into i

repeat for each line tThisKeyName in tKeyNames

add 1 to i

if tThisKeyName <> "" then

put true into tMakeKey

put tThisKeyName after tKeyContents

if tYLogarithmic[i] then put tLogIndicator after tKeyContents

put line i of the graphYUnitsOfMeasureInKey of me into tUnitsOfMeasure

if tIncludeYScalesInKey then

if tUnitsOfMeasure <> "" then put " " before tUnitsOfMeasure

put " ("& displayRange(tYMin[i], tYMax[i]) & tUnitsOfMeasure &")" after tKeyContents # State the range and units of measure for this variable.

else if tUnitsOfMeasure <> "" then

put " ("& tUnitsOfMeasure &")" after tKeyContents # State the units of measure for this variable.

end if

put return after tKeyContents

end if

if i >= tNumCurves then exit repeat

end repeat

delete char -1 of tKeyContents # Delete trailing return.

# 10b. Make key.

if tMakeKey then

# 10b1. Make the text of the key.

put the graphKeyTextSize of me into tTS

put tTS + min(0, round(the graphKeyTextSeparation of me)) into tTH

put a + 20 + (the graphKeyXNudge of me) into tLeft

put tXLabelingBottom + 12 + (the graphKeyYNudge of me) into tTop

makeAField "key", tKeyContents, "left", the graphKeyTextFont of me, "plain", "", tTS, tTH, "", tLeft, tTop, "", ""

# 10b2. Plot line segments in the key.

repeat with i = 1 to tNumCurves

put "curve "& i into tCurveName

put the points of graphic tCurveName of me into tPoints

put tTop + roundUp(tTH/2) + (i-1)*tTH into tLabelLineY

put (tLeft - 20) &","& tLabelLineY into tPointA

put (tLeft - 5) &","& tLabelLineY into tPointB

put cr & cr & tPointA & cr & tPointB after tPoints

set the points of graphic tCurveName of me to tPoints

end repeat

end if

# 11. If requested, prepare for editable graph.

if (the graphEditable of me) and (tNumCurves > 0) then

reset templateButton

set the rect of the templateButton to tGraphCoverRect

set the script of the templateButton to "on mouseDown"& cr &" graphCoverClicked"& cr &"end mouseDown"

set the showName of the templateButton to false

set the showBorder of the templateButton to false

set the threeD of the templateButton to false

set the opaque of the templateButton to false

set the traversalOn of the templateButton to false

set the autoHilite of the templateButton to false

create button "graph cover" in me

set the cpEditCurveNum of button "graph cover" of me to tNumCurves

set the cpGraphYMin of button "graph cover" of me to tYMin[tNumCurves]

set the cpGraphYMax of button "graph cover" of me to tYMax[tNumCurves]

# A minor part of setting up is determining whether the x-data are ordered, because

# if the x-data are nondecreasing or nonincreasing, processing can be sped up for

# editing graphs.

put the points of graphic ("curve "& tNumCurves) of me into tPointsOfCurve

if tMakeKey then delete line -3 to -1 of tPointsOfCurve # Ignore parts that pertain to the key.

set the cpXDataRanges of button "graph cover" of me to clickXRanges(getXVals(tPointsOfCurve))

set the graphYDataEdited of me to tYData[tNumCurves]

else

set the graphYDataEdited of me to ""

end if

# 12. Unlock the screen and go back to the browse (hand) tool.

reset templateField

reset templateGraphic

reset templateButton

choose browse tool

unlock screen

end makeGraph

on noteDuplicatedPointNum pNewPointNum

put the number of items in aDuplicatedPointNums into tN

repeat with i = 1 to tN

put item i of aDuplicatedPointNums into tPN

if pNewPointNum < tPN then put (tPN+1) into item i of aDuplicatedPointNums

end repeat

put pNewPointNum into item (tN+1) of aDuplicatedPointNums

sort items of aDuplicatedPointNums numeric descending

end noteDuplicatedPointNum

# The following routine creates an axis-label field containing string s. The location of the

# field is relative to point pXLoc,pYLoc - which is normally the bottom (for x-ticks) or

# left (for y-ticks) point in an axis tick mark. pXOrY is either "x" or "y". The optional

# parameter tYColorsForScaleLabel can have color indications in different lines,

# to set the colors of different lines s. A multi-line s only makes sense for y-axis scales.

on makeAxisLabel pXOrY, pXLoc, pYLoc, s, pTextColors

if pXOrY = "x" and (the graphXScaleVisible of me = "false") then exit makeAxisLabel

if pXOrY = "y" and (the graphYScaleVisible of me = "false") then exit makeAxisLabel

add 1 to aNumScaleLabelsCreated

put "sl"& aNumScaleLabelsCreated into tFieldName

if pXOrY = "x" then put "center" into tTA else put "right" into tTA

put the graphScaleTextSize of me into tTS

if tTS = "" then put 9 into tTS

put tTS + min(0, round(the graphScaleTextSeparation of me)) into tTH

if pXOrY = "x" then

put 1 into tXFudge

put 1 into tYFudge

put round(pXLoc + tXFudge) into pXLocToUse

put "" into pRightToUse

put round(pYLoc + tYFudge) into pTopToUse

else

put 5 into tXFudge

put -1 into tYFudge

put "" into pXLocToUse

put round(pXLoc + tXFudge) into pRightToUse

put round(pYLoc + tYFudge - tTS/2) into pTopToUse

end if

put makeNumbersNiceForDisplay(s) into s

makeAField tFieldName, s, tTA, the graphScaleTextFont of me, "", pTextColors, tTS, tTH, (pXLocToUse &",0"), "", pTopToUse, pRightToUse, ""

if pXOrY = "x" then put the bottom of field tFieldName of me into aXScaleTextBottom

end makeAxisLabel

# Retun the passed string, ensuring that if it is a number -- or a series of numbers on separate

# lines -- the number(s) display nicely.

# A disadvantage of how I use this above is, I ought to give enough accuracy to display even

# a tiny range between min & max scales.

function makeNumbersNiceForDisplay pS

put the graphScaleExponentHighThreshold of me into tLargeNumberToExpThreshold

put the graphScaleExponentLowThreshold of me into tSmallNumberToExpThreshold

put the graphScaleMinimumSignificantDigits of me into tMinimumSignificantDigits

put the number of lines in pS into tNumLines

repeat with i = 1 to tNumLines

put line i of pS into s

if s is a number then

put s+0 into n

if n = 0 then

put "0" into s

else if abs(n) < tSmallNumberToExpThreshold or abs(n) >= tLargeNumberToExpThreshold then

put getMagnitude(n) into m

if the graphScaleExponentFormat of me is "^" then

put "*10^" into tExponentSeparator

else

put "e" into tExponentSeparator

end if

put round(n / 10^m, tMinimumSignificantDigits - 1) & tExponentSeparator & m into s

#put format("%3.2g", n / 10^m) & tExponentSeparator & m into s

else if n is an integer then

put n into s

else

put getMagnitude(n) into m

put min(0, m - (tMinimumSignificantDigits - 1)) into magnitudeAtWhichToRound

put round(n, -magnitudeAtWhichToRound) into s

#put format("%3.2g", n) into s

end if

end if

put s into line i of pS

end repeat

return pS

end makeNumbersNiceForDisplay

# The following routine creates a field as specified. Parameter pFieldName must be unique

# on each call. Parameters pTextSize and pTextHeight must be valid positive integers. To

# set the location of the field, either pass the location in pLoc, or pass the horizontal location

# in one of pLoc (the vertical location in pLoc is arbitrary) / pLeft / pRight and the vertical

# location in one of pLoc (the horizontal location in pLoc is arbitrary) / pTop / pBottom.

on makeAField pFieldName, pContents, pTextAlign, pTextFont, pTextStyle, pTextColors, pTextSize, pTextHeight, pLoc, pLeft, pTop, pRight, pBottom

reset templateField

set the threeD of the templateField to false

set the showBorder of the templateField to false

set the opaque of the templateField to false

set the lockText of the templateField to true

if pTextAlign <> "" then set the textAlign of the templateField to pTextAlign

if pTextFont <> "" then set the textFont of the templateField to pTextFont

set the textSize of the templateField to pTextSize # The textSize must be set after the textFont.

set the textHeight of the templateField to pTextHeight

if pTextStyle <> "" then set the textStyle of the templateField to pTextStyle

put the number of lines in pContents into tNumLines

put 10000 into h # Take a purposely too high guess at the necessary height to display the string.

#put tNumLines * pTextHeight + 8 into h

set the height of the templateField to h

put 10000 into w # Take a purposely too high guess at the necessary width to display the string.

# put maxLineLength(pContents) * pTextSize into w

# if pTextStyle contains "bold" then multiply w by 2

set the width of the templateField to w

set the autoTab of the templateField to false

create field pFieldName in me

put pContents into field pFieldName of me

put the formattedHeight of field pFieldName of me into h

set the height of field pFieldName of me to h

put (the formattedWidth of field pFieldName of me) + 10 into w # The formattedWidth is actually not wide enough to deter word wrapping (perhaps because of margins?), so I add 10.

set the width of field pFieldName of me to w

if pLoc <> "" then set the loc of field pFieldName of me to pLoc

if pLeft <> "" then set the left of field pFieldName of me to pLeft

if pTop <> "" then set the top of field pFieldName of me to pTop

if pRight <> "" then set the right of field pFieldName of me to pRight

if pBottom <> "" then set the bottom of field pFieldName of me to pBottom

if pTextColors <> "" then

put the number of lines in pTextColors into n

repeat with i = 1 to n

set the textColor of line i of field pFieldName of me to line i of pTextColors

end repeat

end if

end makeAField

function maxLineLength pString

put 0 into tMaxSoFar

repeat for each line l in pString

put length(l) into tLineLength

if tLineLength > tMaxSoFar then put tLineLength into tMaxSoFar

end repeat

return tMaxSoFar

end maxLineLength

function nonBlankItems s

put "" into r

repeat for each item thisItem in s

if thisItem <> "" then put thisItem &"," after r

end repeat

delete char -1 of r

return r

end nonBlankItems

function graphMarkerLineToPoints s

put word 1 of s into w1

if w1 = "" then

put false into tFilled

put "dot" into s

else if w1 = "none" then

return "" # No markers.

exit graphMarkerLineToPoints

else if w1 = "filled" or w1 = "solid" then

put true into tFilled

delete word 1 of s

else if w1 = "empty" or w1 = "hollow" then

put false into tFilled

delete word 1 of s

else #Default is hollow.

put false into tFilled

end if

put word 1 of s into tSizeWord

put word 2 of s into tTypeWord

if tTypeWord = "" then

put tSizeWord into tTypeWord

put "small" into tSizeWord

end if

set the wholeMatches to true

put wordOffset(tSizeWord, "tiny small medium large") into tSizeNumberFromWord

if tSizeNumberFromWord > 0 then

put word tSizeNumberFromWord of "0.1 0.25 0.5 1" into tSizeNumber

else if (tSizeWord is a number) then

put tSizeWord into tSizeNumber

else

put 0 into tSizeNumber

end if

put wordOffset(tTypeWord, "dot + x diamond square triangle circle") into tTypeNumber

if tTypeNumber > 0 then

if tTypeNumber = 1 then #Dot

put "0,0 0,0" into tPoints

else if tTypeNumber = 2 then #+

put "0,-12 0,12 -12,0 12,0" into tPoints

else if tTypeNumber = 3 then #x

put "-12,-12 12,12 -12,12 12,-12" into tPoints

else if tTypeNumber = 4 then #Diamond

put "0,-12 12,0 0,12 -12,0 0,-12" into tPoints

else if tTypeNumber = 5 then #Square

put "-12,-12 12,-12 12,12 -12,12 -12,-12" into tPoints

else if tTypeNumber = 6 then #Triangle

put "0,-12 12,12 -12,12 0,-12" into tPoints

else if tTypeNumber = 7 then #Circle

put "0,-12 2,-12 5,-11 7,-10 9,-9 10,-7 11,-5 12,-2 12,0 12,2 11,5 10,7 9,9 7,10 5,11 2,12 0,12 -2,12 -5,11 -7,10 -9,9 -10,7 -11,5 -12,2 -12,0 -12,-2 -11,-5 -10,-7 -9,-9 -7,-10 -5,-11 -2,-12 0,-12" into tPoints

else

if tSizeNumber > 0 or tSizeWord is a number then

delete word 1 of s

else

put 1 into tSizeNumber

end if

put s into tPoints

end if

replace " " with cr in tPoints

if tSizeNumber <> 1 then

put tPoints into tPointsOriginal

put "" into tPoints

put the number of lines in tPointsOriginal into n

repeat with i = 1 to n

put line i of tPointsOriginal into l

repeat with j = 1 to 2

put round(tSizeNumber * (item j of l)) into item j of l

end repeat

put l & cr after tPoints

end repeat

delete char -1 of tPoints #Delete trailing return.

end if

end if

return tFilled & cr & tPoints

end graphMarkerLineToPoints

on ensurePropertiesOkay

# graphAxisWidth

if the graphAxisWidth of me is not an integer then

set the graphAxisWidth of me to 2

else if the graphAxisWidth of me < 1 then

set the graphAxisWidth of me to 1

end if

# graphMainRect

put the graphMainRect of me into tGMR

if tGMR <> "" then

put tGMR into tGMRInit

put the number of items in tGMR into n

if n < 4 then

put "" into tGMR

else if n > 4 then

put item 1 to 4 of tGMR into tGMR

else

repeat for each item tItem in tGMR

if not (tItem is an integer) then

put "" into tGMR

exit repeat

end if

end repeat

end if

end if

if tGMR = "" then put the rect of me into tGMR

if tGMR <> tGMRInit then set the graphMainRect of me to tGMR

# Data - ensure no spaces and no "NaN" values.

put the graphX of me into tGX

replace " " with "" in tGX

replace "NaN" with "" in tGX

set the graphX of me to tGX

put the graphY of me into tGY

replace " " with "" in tGY

replace "NaN" with "" in tGY

set the graphY of me to tGY

# Tic widths.

put the graphTickMajorWidth of me into tGTMW

if not (tGTMW is an integer) then

if tGTMW is a number then

put round(tGTMW) into tGTMW

else

put 4 into tGTMW

end if

set the graphTickMajorWidth of me to tGTMW

end if

# Tick labels.

put the graphScaleMinimumSignificantDigits of me into tMSD

if tMSD is not a number then set the graphScaleMinimumSignificantDigits of me to 3

else if tMSD < 1 then set the graphScaleMinimumSignificantDigits of me to 1

else if tMSD is not an integer then set the graphScaleMinimumSignificantDigits of me to (trunc(tMSD) + 1)

end ensurePropertiesOkay

on setDefaultProperties

set the graphAxisWidth of me to 1

set the graphClickable of me to "false"

set the graphEditable of me to "false"

set the graphKeyLogIndicator of me to "[logarithmic]"

set the graphKeyTextFont of me to ""

set the graphKeyTextSeparation of me to 3

set the graphKeyTextSize of me to 10

set the graphKeyXNudge of me to 0

set the graphKeyYNudge of me to 0

set the graphLineColors of me to ""

set the graphLineDashes of me to ""

set the graphLinesVisible of me to "true"

set the graphLineWidths of me to ""

set the graphMainRect of me to 50,50,250,150

set the graphMarkers of me to ""

set the graphScaleExponentFormat of me to "^"

set the graphScaleExponentHighThreshold of me to 100000

set the graphScaleExponentLowThreshold of me to 0.001

set the graphScaleMinimumSignificantDigits of me to 3

set the graphScaleTextSeparation of me to 3

set the graphScaleTextSize of me to 9

set the graphScaleTextFont of me to ""

set the graphSendEditMessage of me to false

set the graphTickMajorWidth of me to 4

set the graphTitle of me to ""

set the graphTitleGap of me to 10

set the graphTitleTextFont of me to ""

set the graphTitleTextSize of me to 12

set the graphTitleTextStyle of me to "plain"

set the graphX of me to "0,1,2,3,4,5"

set the graphXLabel of me to ""

set the graphXLabelXNudge of me to 0

set the graphXLabelYNudge of me to 0

set the graphXLog of me to false

set the graphXMax of me to ""

set the graphXMin of me to ""

set the graphXRound of me to false

set the graphXScaleVisible of me to true

set the graphXTicks of me to ""

set the graphXTicksInset of me to false

set the graphXTicksVisible of me to true

set the graphXYLabelTextFont of me to ""

set the graphXYLabelTextSize of me to 9

set the graphY of me to "0,1,2,3,4,5"

set the graphYDataEdited of me to ""

set the graphYLabel of me to ""

set the graphYLabelXNudge of me to 0

set the graphYLabelYNudge of me to 0

set the graphYLog of me to false

set the graphYMax of me to ""

set the graphYMin of me to ""

set the graphYRound of me to false

set the graphYScaleSame of me to true

set the graphYScaleVisible of me to true

set the graphYTicks of me to ""

set the graphYTicksInset of me to false

set the graphYTicksVisible of me to true

set the graphYUnitsOfMeasureInKey of me to ""

set the graphYVariableNames of me to ""

set the graphYScalesInKey of me to true

end setDefaultProperties

# The following handlers are used to come up with ranges for graphs.

# Included are handlers for scaling numbers & for making them easily readable.

# Round the range to use for a graph. Give this min. and max. numbers (in that order)

# separated by a comma. This returns the new rounded min. and max., again separated

# by a comma. The third argument is true if natural logarithms of the numbers have been

# taken but the original numbers (the exponents of the logged numbers) will be displayed.

function roundRange pMin, pMax, pLogged

put pMin into tMin

put pMax into tMax

if pLogged <> "true" then

if tMin = tMax then

put roundDown( ln(abs(tMin)) / 2.3025850929941 ) into magnitude

if tMin = 0 then

put -1 into tMin

put 1 into tMax

else if tMin > 0 then

put 0 into tMin

put 2 * roundUpToMagnitude(tMax, magnitude) into tMax

else -- tMin < 0

put 2 * roundDownToMagnitude(tMin, magnitude) into tMin

put 0 into tMax

end if

else

put roundDown( ln(abs(tMax - tMin)) / 2.3025850929941 ) into magnitude

put roundDownToMagnitude(tMin, magnitude) into tMin

put roundUpToMagnitude(tMax, magnitude) into tMax

end if

else

# Deal with the logarithmic case.

if tMin = tMax then

put tMin - exp(1)/10 into tMin

put tMin + exp(1)/10 into tMax

else

put getMagnitude(tMin) into tMinMagnitude

put round(tMin, 1 - tMinMagnitude) into tMinTRounded

if tMinTRounded > tMin then put tMinTRounded - 10^(tMinMagnitude - 1) into tMinTRounded

put tMinTRounded into tMin

put getMagnitude(tMax) into tMaxMagnitude

put round(tMax, 1 - tMaxMagnitude) into tMaxTRounded

if tMaxTRounded < tMax then put tMaxTRounded + 10^(tMaxMagnitude - 1) into tMaxTRounded

put tMaxTRounded into tMax

end if

end if

return tMin &","& tMax

end roundRange

-- Create a version of the range in readable form.

function displayRange pMin, pMax

return readableNumber(pMin) &" to "& readableNumber(pMax)

end displayRange

function readableTwoDigit n

return readableNumber(roundToTwoDigits(n))

end readableTwoDigit

-- Round to 2 digits of accuracy.

function roundToTwoDigits n

put getMagnitude(n) into magnitude

put 10 ^ (magnitude - 1) into scalingNumber

return round( n / scalingNumber ) * scalingNumber

end roundToTwoDigits

function readableNumber pN

put pN + 0 into n

if n = 0 then

return "0"

else

put roundDown( ln(abs(n)) / 2.3025850929941 ) into magnitude

if magnitude >= 3 and magnitude <= 20 then

put magnitude div 3 into powerOfThousand

put item powerOfThousand of "thousand,million,billion,trillion,quadrillion,quintillion" into s

put 1000 into divisor

repeat with i = 2 to powerOfThousand

put divisor * 1000 into divisor

end repeat

put n / divisor into displayN

-- if displayN > 0 and displayN < 10 then

-- if displayN is an integer then

-- put item displayN of "one,two,three,four,five,six,seven,eight,nine" into displayN

-- end if

-- end if

return displayN && s

else if magnitude >= -3 and magnitude <= 2 then

return n

else

return (n / 10 ^ magnitude) &" * 10 ^ "& magnitude

end if

end if

end readableNumber

function getMagnitude n

return roundDown( log10(abs(n)) )

end getMagnitude

function roundDownToMagnitude n, magnitude

put 10^magnitude into scalingFactor

return scalingFactor * roundDown( n / scalingFactor )

end roundDownToMagnitude

function roundDown n

put trunc( n ) into m

if n >= 0 then

return m

else if n = m then

return n

else

return m - 1

end if

end roundDown

function roundUpToMagnitude n, magnitude

put 10^magnitude into scalingFactor

return scalingFactor * roundUp( n / scalingFactor )

end roundUpToMagnitude

function roundUp n

put trunc( n ) into m

if n <= 0 then

return m

else if n = m then

return n

else

return m + 1

end if

end roundUp

function roundToMagnitude n, magnitude

put 10^magnitude into scalingFactor

return scalingFactor * round( n / scalingFactor )

end roundToMagnitude

function chooseTickLocs pMin, pMax, pApproxNum, pExactNum

put pMin into tMin

put pMax into tMax

put tMax - tMin into tDiff

if pExactNum <> "" then

put round(min(max(pExactNum,2),50)) into tNumTicksToUse #Force to be between 2 and 50.

else

# Choose how many tick marks to use.

put round(min(max(pApproxNum,2),50)) into tApproxNum #Force to be between 2 and 50.

put 0 into tNumTicksToUse

put 0 into tNumTicksToUsePriority2

put 0 into tNumTicksToUsePriority3

put 0 into tNumTicksToUsePriority4

put tDiff / 10^getMagnitude(tDiff) into tDiffInOnesUnits

put roundUp(pApproxNum*0.66) into tMinNumTicks

put roundDown(pApproxNum*1.515152) into tMaxNumTicks

repeat with i = tMinNumTicks to tMaxNumTicks

put (i-1) into tNumSteps

put round(tDiffInOnesUnits / tNumSteps,4) into tStep

if tStep = round(tStep,0) then

# This number of tick marks gives a nice round number for the length between tick marks.

if tNumTicksToUse = 0 then

put i into tNumTicksToUse

else if abs(i / tApproxNum - 1) < abs(tNumTicksToUse / tApproxNum - 1) then

put i into tNumTicksToUse

end if

if i >= tApproxNum then

exit repeat # The optimal number of ticks has been founded; never choose a higher number than necessary above the "about" number to achieve round-number distances.

end if

else if tStep = round(tStep,1) then

# This number of tick marks gives a fairly nice round number for the length between tick marks.

if tNumTicksToUsePriority2 = 0 then

put i into tNumTicksToUsePriority2

else if abs(i / tApproxNum - 1) < abs(tNumTicksToUsePriority2 / tApproxNum - 1) then

put i into tNumTicksToUsePriority2

end if

else if tStep = round(tStep,2) then

# This number of tick marks gives a somewhat round number for the length between tick marks.

if tNumTicksToUsePriority3 = 0 then

put i into tNumTicksToUsePriority3

else if abs(i / tApproxNum - 1) < abs(tNumTicksToUsePriority3 / tApproxNum - 1) then

put i into tNumTicksToUsePriority3

end if

else if tStep = round(tStep,3) then

# This number of tick marks gives a somewhat round number for the length between tick marks.

if tNumTicksToUsePriority4 = 0 then

put i into tNumTicksToUsePriority4

else if abs(i / tApproxNum - 1) < abs(tNumTicksToUsePriority4 / tApproxNum - 1) then

put i into tNumTicksToUsePriority4

end if

end if

end repeat

if tNumTicksToUse = 0 then

if tNumTicksToUsePriority2 > 0 then

put tNumTicksToUsePriority2 into tNumTicksToUse # Use a fairly-round distance between ticks.

else if tNumTicksToUsePriority3 > 0 then

put tNumTicksToUsePriority3 into tNumTicksToUse # Use a slightly-round distance between ticks.

else if tNumTicksToUsePriority4 > 0 then

put tNumTicksToUsePriority4 into tNumTicksToUse # Use a marginally-round distance between ticks.

else

put tApproxNum into tNumTicksToUse # Couldn't find a round distance between ticks.

end if

end if

end if

# Determine the tick mark locations.

put "" into tR

put tDiff / (tNumTicksToUse - 1) into tStep

repeat with i = 1 to tNumTicksToUse

if i < tNumTicksToUse then put (tMin + (i - 1) * tStep) &"," after tR

else put tMax after tR

end repeat

return tR

end chooseTickLocs

# Handle editing of the graph.

on graphCoverClicked

# Get info needed to control editing.

put the left of button "graph cover" of me into tXLeft

put the right of button "graph cover" of me into tXRight

put the top of button "graph cover" of me into tYTop

put the bottom of button "graph cover" of me into tYBottom

put the cpEditCurveNum of button "graph cover" of me into tCurveNum

put the points of graphic ("curve "& tCurveNum) of me into tPoints

put tPoints into tPointsOriginal

put (the cpXDataRanges of button "graph cover" of me) into tXValRanges

# Do the editing - loop while the mouse is down..

repeat while the mouse is down

# Get the mouse location, constrained on the y-axis to the plot region.

put the mouseLoc into tMouseLoc

put item 1 of tMouseLoc into tMouseX

put max(min(item 2 of tMouseLoc, tYBottom), tYTop) into tMouseY

# Revise the curve based on the mouse location.

if tMouseX >= (tXLeft - 6) and tMouseX <= (tXRight + 6) then # 6 is the amount to left or right of graph where editing still occurs.

# Loop through points on the curve.

put 0 into tPointNum

repeat for each line tXVR in tXValRanges

add 1 to tPointNum

put item 1 of tXVR into tMinOwnedRange

if tMinOwnedRange = "" then next repeat # Ignore line segment in key.

if tMinOwnedRange <> "-INF" then

if tMouseX < tMinOwnedRange then next repeat

end if

put item 2 of tXVR into tMaxOwnedRange

if tMaxOwnedRange <> "+INF" then

if tMouseX > tMaxOwnedRange then next repeat

end if

put tMouseY into item 2 of line tPointNum of tPoints

set the points of graphic ("curve "& tCurveNum) of me to tPoints

end repeat

end if

end repeat

# The mouse button is no longer down. Update y-data based on the edited graph.

if tPoints <> tPointsOriginal then

put tYBottom - tYTop into tYDiff

put the cpGraphYMin of button "graph cover" of me into tYValsMin

put the cpGraphYMax of button "graph cover" of me into tYValsMax

put tYValsMax - tYValsMin into tYValsDiff

put the number of lines in tXValRanges into tNumPoints

put "" into tNewYData

put 0 into tPointNum

repeat for each line tP in tPoints

add 1 to tPointNum

if tP = tNumPoints then exit repeat # The curve may have more points, but they belong to the line segment in the key, and must not be edited.

put item 2 of tP into tPY

put tYValsMin + tYValsDiff * (tYBottom - tPY) / tYDiff into tYVal

put tYVal &"," after tNewYData

end repeat

delete the last char of tNewYData # Delete trailing comma.

repeat for each item tDuplicatedPointNum in aDuplicatedPointNums # These have already been sorted in reverse order.

delete item tDuplicatedPointNum of tNewYData # Some points may have been duplicated for internal purposes, to ensure graphs can be drawn correctly when there is only one datum, but the user must not be passed back data that include duplicates.

end repeat

set the graphYDataEdited of me to tNewYData

if (the graphSendEditMessage of me) = "true" then send "graphEdited" to this card

end if

end graphCoverClicked

# Given a string of lines each containing an x-value as its first (comma-separated) item, return a comma-separated list of the x-values.

function getXVals pS

put "" into tR

repeat for each line tL in pS

put (item 1 of tL) &"," after tR

end repeat

delete char -1 of tR

return tR

end getXVals

# Given a list of x-data, return "owned" ranges around each data point, i.e. the x-values for which the nearest data point is each point.

# The result will be a string with one line of comma-separated data for each x-data point. In each line, the first item is the minimum owned

# and the second item is the maximum owned value. "-INF" or "+INF" is used where the minimum or maximum owned value is negative

# or positive infinity.

function clickXRanges pXData

# Get the x-data in sorted order.

put nonBlankItems(pXData) into tXDataSorted

sort items of tXDataSorted numeric

# In case of small round-off errors in numbers, ensure that the min. and max. parameters are not inside the x data points.

put item 1 of tXDataSorted into tXMin

put item -1 of tXDataSorted into tXMax

# Prepare lists of the relevant min. and max. values, by looping through each data point and adding its information to the lists.

put "" into tRangesOwned

repeat for each item tN in pXData

if tN = "" then

put "" into tThisRangeMinOwned

put "" into tThisRangeMaxOwned

else

# Find the greatest point below this x-value, or the overall min. if no points are below.

put tXMin into tThisRangeMin

repeat for each item tSortedN in tXDataSorted

if tSortedN < tN then put tSortedN into tThisRangeMin

else exit repeat

end repeat

# Find the smallest point above this x-value, or the overall max. if no points are above.

if (item -1 of tXDataSorted) = tN then put tXMax into tThisRangeMax

else

repeat for each item tSortedN in tXDataSorted

if tSortedN > tN then

put tSortedN into tThisRangeMax

exit repeat

end if

end repeat

end if

# In the range just found, if the point is in between other points, half the ranges belongs to this point and half to other points.

if tN=tXMin then

put "-INF" into tThisRangeMinOwned

else

put (tN + tThisRangeMin) / 2 into tThisRangeMinOwned

end if

if tN=tXMax then

put "+INF" into tThisRangeMaxOwned

else

put (tThisRangeMax + tN) / 2 into tThisRangeMaxOwned

end if

end if

# Add information to the lists of ranges owned.

put tThisRangeMinOwned &","& tThisRangeMaxOwned & cr after tRangesOwned # Use &","& tN to include the x-value as well.

end repeat

delete char -1 of tRangesOwned

if (char -1 of pXData) = "," then put cr &"," after tRangesOwned #The trailing comma corresponds to a blank item.

return tRangesOwned

end clickXRanges

# Given a list of items, take the natural logarithm of all nonblank items.

function listLn s

put "" into r

repeat for each item tItem in s

if tItem <> "" then put ln(tItem) into tItem

put tItem &"," after r

end repeat

delete char -1 of r

return r

end listLn

# Given a list of items, if exactly one is non-null then return the item number, else return null.

function singleNonmissingItemNum s

put "" into tR

put 0 into i

repeat for each item tItem in s

add 1 to i

if tItem <> "" then

if tR = "" then

put i into tR

else

put "" into tR

exit repeat

end if

end if

end repeat

return tR

end singleNonmissingItemNum

on createGraphic pName

put the lockMessages into tOrigLockMessages

set the lockMessages to true # Revolution has a "feature" that alters small graphic objects, but we don't want that here.

create graphic pName in me

set the lockMessages to tOrigLockMessages

end createGraphic

graph background@ 2Pd cREVGeneral revUniqueID 1166423936977  @saxesK1Of2P2 @tsl1* 2 cREVGeneral revUniqueID 1169587553659  1975 @usl2* 2 cREVGeneral revUniqueID 1169587553661  1997 @vsl3,   cREVGeneral revUniqueID 1169587553662  0 @wsl4, K& cREVGeneral revUniqueID 1169587553663  11@xticksK-Oj 22.2.P2P@ycurve 1K redredred/Mj2k;}D}M}VP_ir{ @z x varname*|4 cREVGeneral revUniqueID 1169587553665  Year @{ y varname(2 cREVGeneral revUniqueID 1169587553667  "Major oil tanker spills worldwideRedrawEp:on mouseUp send makeGraph to group "graph" end mouseUp 'Ga cREVGeneral revUniqueID 1166423936981 Graph usage info)h cREVGeneral revUniqueID 1166423936982 cREVTable currentviewU

Graph object

Ken Simons, version 26 April 2003.

Anyone may use the graph object for any purpose. Rights to use of the original object must remain in the public domain.

Contents:

Usage

Properties - Data

Properties - Location in Window

Properties - Line Graphs versus Scatter Plots, Point Markers

Properties - Lines

Properties - Axis Scales

Properties - Tick Marks and Scale Labels

Properties - Axis Labels (Variable Names)

Properties - Key

Properties - Title

Properties - Axis

Properties - Clickable Graphs

Properties - Editable Graphs

Known Bugs and Limitations

Revision Notes

Usage

The graph object presently supports line graphs and scatter plots.

To use the graph object in your MetaCard project, select, copy, and paste where you want it. Then set properties of the graph object (see below) and send the message makeGraph to the graph object. You can send setDefaultProperties to the graph object to reset all properties to their default values. If you need to put graphs on multiple cards, one strategy is to put the graph object in a background (group), place that background on the relevant cards, and have an on preOpenCard handler on each card set the graph object appropriately.

If you create a graph on one computer and port it to another, you may need to redraw the graph, so to be safe send the makeGraph message to graphs upon opening a stack. This is because fonts may need to be substituted, if they are available on one computer but not another, or fonts may be drawn differently on different types of computer; in either case the graph object may need to account for new widths of the text in order for the text to display properly.

Properties - Data

For line graphs and scatter plots, you need data on an x-variable and one or more y-variables. Missing data are allowed by using a blank entry instead of a number.

graphX - The x-values of the data to be plotted, separated by commas. Default: 0,1,2,3,4,5

graphY - The y-values of the data to be plotted, with a separate y-variable on each line, separated by commas within each line. Default: 0,1,2,3,4,5

Properties - Location on Screen

graphMainRect - The rectangle in the stack window in which the graph should be drawn. (This refers to the main part of the graph, where the axes are drawn, not to the tic marks, axis labels, etc.) If this is empty, it will be reset to the rect of the graph object the next time the graph is drawn. Default: 50,50,250,150

Properties - Line Graphs versus Scatter Plots, Point Markers

graphLinesVisible - True or false. Set this to false to hide the lines. Default: true

graphMarkers - One line of text for each y-variable. If the relevant line is empty, a one-pixel dot will be plotted at each data point. Other options are "none" to not draw any markers, or any combination of

[filled-indicator] [size-indicator] type-indicator or

[filled-indicator] [size-indicator] marker-descriptor

The (optional) filled-indicator may be one of:

filled - Markers will be filled.

solid - Same as filled.

empty - Markers will not be filled (default).

hollow - Same as empty.

The (optional) size-indicator may be one of:

tiny - 0.1 times the large size, about 3 pixels wide

small - 0.25 times the large size

medium - 0.5 times the large size

large - 1 times the large size, about 25 pixels wide

# - Any (non-negative) number to multiply by the large size.

The type-indicator may be one of:

dot - No matter what size you specify, this is always one pixel.

+

x

diamond

square

triangle

circle

The marker-descriptor is a series of space-separated points describing a marker. See MetaCard's markerPoints property, but separate the points with spaces instead of returns.

Default: empty (i.e., 1-pixel dots)

Properties - Lines

graphLineColors - The colors of the lines (and corresponding markers) on the graph. This property may have one line for each y-variable; each line may be a color (the usual MetaCard name or trio of numbers), or empty which will mean the stack's default color. Default: empty

graphLineDashes - The dash patterns of the lines on the graph. This property may have one line for each y-variable; each line may be a comma-separated string of numbers specifying in order the number of pixels drawn, the following number of pixels not drawn, etc., or empty for no dashes. MetaCard officially only supports dashes on Unix and NT machines, but you may get some (perhaps odd) response out of these settings on Mac or commonplace Windows machines. Default: empty

graphLineWidths - The widths of the lines on the graph. This property may have one line for each y-variable; each line may be a nonnegative integer, or empty which will use the stack's default lineWidth. Default: empty

Properties - Axis Scales

The values of the x- and y-axis scales will be determined from the data unless you specify otherwise.

graphYScaleSame - When true, the scales of multiple y-variables will be forced to be the same. Default: true

graphXMin - The minimum value for the x-axis scale, or empty to just choose a value from the data. If some data points have lower values, this minimum will be overriden. Default: empty

graphXMax - The maximum value for the x-axis scale, or empty to just choose a value from the data. If some data points have higher values, this maximum will be overriden. Default: empty

graphYMin - The minimum values for the y-axis scale, with one line for each y-variable. Each line may be a number or empty; if it is empty then a value will be chosen from the data. If some data points have lower values, the minimum will be overriden. If graphYScaleSame is true, then similarly other y-variables' data or minimum values may override the minimum for each y-variable. Default: empty

graphYMax - The maximum values for the y-axis scale, with one line for each y-variable. Each line may be a number or empty; if it is empty then a value will be chosen from the data. If some data points have higher values, the maximum will be overriden. If graphYScaleSame is true, then similarly other y-variables' data or maximum values may override the maximum for each y-variable. Default: empty

graphXRound, graphYRound - If these properties are set to true, the ranges used on the graph will be nice round numbers (such that all the data points and the above minimums and maximums are between the numbers), with the minimum and maximum numbers having the same order of magnitude. Default: false

graphXLog, graphYLog - If these properties are set to true, the graph is plotted logarithmically in x- or y-directions. The graphYLog property may alternatively have one line for each y-variable, with true and false indicating whether it should be graphed logarithmically. If any y-values are zero or negative for a variable, graphYLog is ignored for that variable; the graph is not drawn logarithmically. If some y-variables are graphed logarithmically and some not, graphYScaleSame will be ignored (treated as if it were false). If a key is displayed, logarithmically-plotted variables are annoted with the term "[logarithmic]" (this term can be changed to null or to any string by using the graphKeyLogIndicator property). Default: false

Properties - Tick Marks and Scale Labels

graphXTicks, graphYTicks - "none" for no x- or y-axis (respectively) tick marks and scale labels, empty for tick marks and/or scale labels at the start and end of the axis, "exactly #" to specify an integer number (2 to 50) of tick marks, "about #" to specify an approximate integer number (2 to 50) of tick marks so that the distance between tick marks comes out to be a nice round number, or a list of numbers (separated by commas) for the x or y values at which to draw tick marks / scale labels. For y-values, the numbers must be defined in terms of the first y-variable's scale. Default: empty

graphXTicksVisible, graphYTicksVisible - True or false, whether the tick marks are visible. Default: true

graphXTicksInset, graphYTicksInset - True or false, whether tick marks are inset into the rectangle of the graph rather than protruding outside it. Default: false

graphTickMajorWidth - Number of pixels long for tick marks. Default: 4

graphXScaleVisible - True or false, whether numbers labelling the x-axis appear below each x-axis tick mark. (For their placement, see graphXTicks.) Default: true

graphYScaleVisible - True, false, or a comma-separated list of numbers. True shows numbers for the y-axis scale for each y-variable. False causes the scale numbers to be suppressed. If a comma-separated list of numbers is used, scales will be shown for multiple y-variables, in the order given by the list, using the colors of the y-variables (e.g. "2,3" causes y-scale numbers to be displayed for the 2nd and 3rd variables but not the 1st). The latter (and "true" when multiple variables have different scales) works well only for a small number of y-variables, and since each number is shown on a separate line, it is best to have very few tick marks on the y-axis. True causes scales to be shown for each y-variable unless the y-variables share the same scale, in which case it just shows the one scale. Default: true.

graphScaleTextFont - Font name of the text used for the axis scales, or empty for the default font. Default: empty

graphScaleTextSize - Point size of the text used for the axis scales. Default: 9

graphScaleTextSeparation - When displaying y-scales with multiple lines, this is the number of pixels of padding between lines. In MetaCard terminology, it is the number of pixels difference between the textSize and the textHeight in the fields used to display the y-axis scales. Default: 3

graphScaleMinimumSignificantDigits - The minimum number of digits of precision displayed in numbers in axis scales. Default: 3

graphScaleExponentFormat - When numbers on the graph scale are very large or small, they will be displayed with exponents. This can be "e" to display an "e" before the exponent, or "^" to display "*10^" before the exponent. The latter is generally more readable. Default: ^

graphScaleExponentLowThreshold, graphScaleExponentHighThreshold - How small or large do the axis numbers need to be before they use exponential notation? These parameters determine the answer. A number n on the graph scale uses an exponent when abs(n) < low-threshold or abs(n) >= high-threshold. Defaults: 0.001 and 100,000 respectively

Properties - Axis Labels (Variable Names)

graphXLabel, graphYLabel - Name or other label for the x- or y-variables to be displayed beneath the x-axis or at the top left of the graph. Default: empty

graphXYLabelTextFont - Font to be used to display the x- and y-axis variable names, or empty for the default font in use in MetaCard. Default: empty

graphXYLabelTextSize - Font size to be used to display the x- and y-axis variable names. Default: 9

graphXLabelXNudge, graphXLabelYNudge, graphYLabelXNudge, graphYLabelYNudge - Number of pixels by which to nudge the axis labels from their default positions. Default: 0

Properties - Key

graphYVariableNames - Names to be used for the y-variables in the key. If all the names are empty, no key will be created. The names are text strings separated by returns, corresponding to the y-variables plotted. An empty line will result in a null variable name, but the variable will still be included in the key. Default: empty

graphKeyTextFont - Font to be used to display the key, or empty for the default font in use in MetaCard. Default: empty

graphKeyTextSeparation - When displaying keys with multiple y-variables, this is the number of pixels of padding between lines of text in the key. In MetaCard terminology, it is the number of pixels difference between the textSize and the textHeight in the fields used to display the y-axis scales. Default: 3

graphKeyTextSize - Font size to be used to display the key. Default: 10

graphYScalesInKey - True or false, whether the scales of the y-variables are displayed in the key. Default: true

graphYUnitsOfMeasureInKey - Units of measure of variables reported in the key. Give the units of measure for each variable on a separate line. Default: empty

graphKeyLogIndicator - An indicator used to annotate y-variables graphed logarithmically. You may set this to any string (without return characters). Default: "[logarithmic]"

graphKeyXNudge, graphKeyYNudge - Number of pixels by which to change the location of the key from its default location. By default, it will be placed with the its left side adjacent to the vertical axis (with the field containing the key text beginning 20 pixels from the left axis) and with the top of the field containing the key text 12 pixels below all the x-axis labeling. Default: 0

Properties - Title

graphTitle - Title to be displayed above the graph. Default: empty

graphTitleTextFont - Font to be used to display the title, or empty for the default font in use in MetaCard. Default: empty

graphTitleTextSize - Font size to be used to display the title. Default: 12

graphTitleTextStyle - Font style to be used to display the title, "plain" or one or more of "bold", "italic", "underline", and "strikeout". Default: plain

graphTitleGap - Number of pixels between the top of the graph and bottom of the title. Default: 10

Properties - Axis

graphAxisWidth - Width of the lines for the graph axes. Default: 1

Properties - Clickable Graphs

graphClickable - True or false. If this is true, then whenever the user clicks on a line in the graph, a message will be sent to the card script:

graphClicked lineNumber, xValue, yValue

where lineNumber is 1, 2, ... according to whether the user clicked on the first, second, ... y-variable's line. (Higher-numbered lines are overlaid above lower-numbered lines, so if the user clicks at a point with multiple lines, the highest-numbered line will be identified.) The xValue and yValue are the x and y values of the clicked-on variable at the spot where the click occurred (this may be on an actual data point or on a line between data points). These values will be incorrect if the graph object has been moved but not redrawn. If a key is drawn, the user can click on curves in the key as well as in the graph; this can be detected by the fact that the yValue returned will (unless you nudged the key very high) be less than the y-axis minimum. Default: false

Properties - Editable Graphs

graphEditable - True or false. If true, the user can click and drag on the graph to alter the y-values of the uppermost curve in the graph. (The uppermost curve is the last line in the graphY property.) The edited y-values are constrained to lie within the vertical range corresponding to the y-axis of the graph. The updated y-values are stored in the graphYDataEdited property. The graphClickable property will function only through the key if graphEditable is true; that is, users will be able to click on curves in the key (if any) but not in the graph proper. Default: false

graphSendEditMessage - If this property is true, then whenever the user makes a change to the graph and releases the mouse button, the "graphEdited" message will be sent to the current card. Default: false

graphYDataEdited - This is a read-only property for use if the graphEditable property is true. It tells you the updated y-values of the uppermost curve in the graph. If you want to preserve the edited data when sending the makeGraph message, put the graphYDataEdited into the last line of the graphY before sending the makeGraph message.

Known Bugs and Limitations

In old versions of Runtime Revolution (not MetaCard), the hand cursor becomes the arrow cursor after redrawing the graph. The bug in Revolution that caused the problem (the "choose browse tool" command did not work) was fixed beginning with the alpha release version of Revolution circa 8 July 2002. Upgrade your copy of Revolution to solve the problem.

Revision Notes

From version of 20 Nov. 2000 to version 21 Jan. 2001:

1. The code contained a Macintosh-specific not-equal-to character, causing an error message on PCs. This has been fixed.

2. Ranges can now optionally be automatically rounded to nice round numbers, with the minimum and maximum of the range having the same order of magnitude.

3. Keys can now optionally be created, showing the names, units of measure, and/or ranges of the y-variables.

4. A bug was fixed with the "graphClickable" option's returned y values (which before were nonsenical or yielded dvision by zero errors).

5. Better examples are given so new users can see what to do.

From version of 21 Jan 2001 to version of 22 May 2001:

6. Sometimes after being pasted into another setting, the lines in the key would not draw. This was fixed.

7. Accuracy could be lost when dealing with extremely small positive or negative numbers. As a possible side effect, this could cause clickable graphs not to work. The inaccuracy (and its side effect) was fixed.

8. Exponent format on axis scales is now an option (graphScaleExponentFormat).

9. Editable graphs can now be used.

From version of 22 May 2001 to version of 10 May 2002:

10. For graphXTicks and graphYTicks, added the "exactly #" and "about #" options.

From version of 10 May 2002 to version of 24 May 2002:

11. Exponential notation on axis scales now occurs only for numbers larger (in absolute value) than 100,000 or smaller than 0.001, by default. The relevant thresholds can be set (graphScaleExponentLowThreshold, graphScaleExponentHighThreshold). The minimum number of digits displayed can also be set (graphScaleMinimumSignificantDigits).

From version of 24 May 2002 to version of 12 July 2002:

12. Fixed a bug in which graphs with multiple curves, some of which contained only 0 y-values but the rest of which contained only nonnegative values, could receive a minimum y scale of -1 if graphYScaleSame was true.

From version of 12 July 2002 to version of 28 July 2002:

13. The object previously worked properly with missing y-data but not missing x-data; now it works properly with either.

14. Editable graphs now are easier to use - in past the mouse had to be exactly at a data point's x-pixel location to trigger updating of its y value, but now the data point with the nearest x location is updated.

From version of 28 July 2002 to version of 5 August 2002:

15. Graphs with one nonmissing data point could draw oddly when using Revolution; this has been fixed.

From version of 5 August 2002 to version of 27 August 2002:

16. Two or more graphs objects placed on the same card had overlapping keys; this has been fixed.

From version of 27 August 2002 to version of 25 February 2003:

17. When plotting multiple y-variables with different scales and with 3 or more vertical-axis tick marks, the scales reported for the interior tick marks equalled those reported for the lowest tick mark; this has been fixed.

18. Logarithmic axes are now available as options (graphXLog, graphYLog).

From version of 25 February 2003 to version of 26 April 2003:

19. Beginning by Metacard version 2.5 (but after 2.3.1), MetaCard would automatically traverse to (draw a rectangle around) a field within the graph object. This has been fixed.

 Graph object  &Ken Simons, version 18 December 2006. yAnyone may use the graph object for any purpose. Rights to use of the original object must remain in the public domain. Contents: Usage  Properties - Data # Properties - Location in Window @ Properties - Line Graphs versus Scatter Plots, Point Markers  Properties - Lines  Properties - Axis Scales , Properties - Tick Marks and Scale Labels - Properties - Axis Labels (Variable Names)  Properties - Key  Properties - Title  Properties - Axis ! Properties - Clickable Graphs Properties - Editable Graphs  Known Bugs and Limitations  Revision Notes Usage   CThe graph object presently supports line graphs and scatter plots. "To use the graph object in your Revolution project, select it, copy, and paste where you want it. When copying, ensure that Revolution's "Select Grouped Controls" option is turned off in the Edit menu (or set the selectGroupedControls to false); otherwise you will copy only one part of the graph object. After you paste the graph object where you want it, set properties of the graph object (see below) and send the message makeGraph to the graph object. You can send setDefaultProperties to the graph object to reset all properties to their default values. If you need to put graphs on multiple cards, one strategy is to put the graph object in a background (group), place that background on the relevant cards, and have an on preOpenCard handler on each card set the graph object appropriately. c cf   $    9 If you create a graph on one computer and port it to another, you may need to redraw the graph, so to be safe send the makeGraph message to graphs upon opening a stack. This is because fonts may need to be substituted, if they are available on one computer but not another, or fonts may be drawn differently on different types of computer; in either case the graph object may need to account for new widths of the text in order for the text to display properly. w w N Properties - Data   For line graphs and scatter plots, you need data on an x-variable and one or more y-variables. Missing data are allowed by using a blank entry instead of a number. \graphX - The x-values of the data to be plotted, separated by commas. Default: 0,1,2,3,4,5 graphY - The y-values of the data to be plotted, with a separate y-variable on each line, separated by commas within each line. Default: 0,1,2,3,4,5 Properties - Location on Screen   DgraphMainRect - The rectangle in the stack window in which the graph should be drawn. (This refers to the main part of the graph, where the axes are drawn, not to the tic marks, axis labels, etc.) If this is empty, it will be reset to the rect of the graph object the next time the graph is drawn. Default: 50,50,250,150 =Properties - Line Graphs versus Scatter Plots, Point Markers  < XgraphLinesVisible - True or false. Set this to false to hide the lines. Default: true graphMarkers - One line of text for each y-variable. If the relevant line is empty, a one-pixel dot will be plotted at each data point. Other options are "none" to not draw any markers, or any combination of ; [filled-indicator] [size-indicator] type-indicator or 8  8 9 [filled-indicator] [size-indicator] marker-descriptor /The (optional) filled-indicator may be one of: $ filled - Markers will be filled.  solid - Same as filled. 1 empty - Markers will not be filled (default).  hollow - Same as empty. -The (optional) size-indicator may be one of: 8 tiny - 0.1 times the large size, about 3 pixels wide % small - 0.25 times the large size % medium - 0.5 times the large size 8 large - 1 times the large size, about 25 pixels wide @ # - Any (non-negative) number to multiply by the large size. "The type-indicator may be one of: D dot - No matter what size you specify, this is always one pixel.  +  x diamond square triangle circle The marker-descriptor is a series of space-separated points describing a marker. See Revolution's markerPoints property, but separate the points with spaces instead of returns. $Default: empty (i.e., 1-pixel dots) Properties - Lines   graphLineColors - The colors of the lines (and corresponding markers) on the graph. This property may have one line for each y-variable; each line may be a color (the usual Revolution name or trio of numbers), or empty which will mean the stack's default color. Default: empty graphLineDashes - The dash patterns of the lines on the graph. This property may have one line for each y-variable; each line may be a comma-separated string of numbers specifying in order the number of pixels drawn, the following number of pixels not drawn, etc., or empty for no dashes. However, on Windows 95/98 and Mac OS and OS X, the length specified for dashes will be ignored, with the length controlled by the operating system. Default: empty /graphLineWidths - The widths of the lines on the graph. This property may have one line for each y-variable; each line may be a nonnegative integer, or empty which will use the stack's default lineWidth. A line width of 0 yields no line, but markers still appear as in a scatter plot. Default: empty Properties - Axis Scales   fThe values of the x- and y-axis scales will be determined from the data unless you specify otherwise. ngraphYScaleSame - When true, the scales of multiple y-variables will be forced to be the same. Default: true graphXMin - The minimum value for the x-axis scale, or empty to just choose a value from the data. If some data points have lower values, this minimum will be overriden. Default: empty graphXMax - The maximum value for the x-axis scale, or empty to just choose a value from the data. If some data points have higher values, this maximum will be overriden. Default: empty graphYMin - The minimum values for the y-axis scale, with one line for each y-variable. Each line may be a number or empty; if it is empty then a value will be chosen from the data. If some data points have lower values, the minimum will be overriden. If graphYScaleSame is true, then similarly other y-variables' data or minimum values may override the minimum for each y-variable. Default: empty graphYMax - The maximum values for the y-axis scale, with one line for each y-variable. Each line may be a number or empty; if it is empty then a value will be chosen from the data. If some data points have higher values, the maximum will be overriden. If graphYScaleSame is true, then similarly other y-variables' data or maximum values may override the maximum for each y-variable. Default: empty .graphXRound, graphYRound - If these properties are set to true, the ranges used on the graph will be nice round numbers (such that all the data points and the above minimums and maximums are between the numbers), with the minimum and maximum numbers having the same order of magnitude. Default: false graphXLog, graphYLog - If these properties are set to true, the graph is plotted logarithmically in x- or y-directions. The graphYLog property may alternatively have one line for each y-variable, with true and false indicating whether it should be graphed logarithmically. If any y-values are zero or negative for a variable, graphYLog is ignored for that variable; the graph is not drawn logarithmically. If some y-variables are graphed logarithmically and some not, graphYScaleSame will be ignored (treated as if it were false). If a key is displayed, logarithmically-plotted variables are annoted with the term "[logarithmic]" (this term can be changed to null or to any string by using the graphKeyLogIndicator property). Default: false )Properties - Tick Marks and Scale Labels  ( YgraphXTicks, graphYTicks - "none" for no x- or y-axis (respectively) tick marks and scale labels, empty for tick marks and/or scale labels at the start and end of the axis, "exactly #" to specify an integer number (2 to 50) of tick marks, "about #" to specify an approximate integer number (2 to 50) of tick marks so that the distance between tick marks comes out to be a nice round number, or a list of numbers (separated by commas) for the x or y values at which to draw tick marks / scale labels. For y-values, the numbers must be defined in terms of the first y-variable's scale. Default: empty kgraphXTicksVisible, graphYTicksVisible - True or false, whether the tick marks are visible. Default: true graphXTicksInset, graphYTicksInset - True or false, whether tick marks are inset into the rectangle of the graph rather than protruding outside it. Default: false HgraphTickMajorWidth - Number of pixels long for tick marks. Default: 4 graphXScaleVisible - True or false, whether numbers labelling the x-axis appear below each x-axis tick mark. (For their placement, see graphXTicks.) Default: true = high-threshold. Defaults: 0.001 and 100,000 respectively *Properties - Axis Labels (Variable Names)  ) graphXLabel, graphYLabel - Name or other label for the x- or y-variables to be displayed beneath the x-axis or at the top left of the graph. Default: empty graphXYLabelTextFont - Font to be used to display the x- and y-axis variable names, or empty for the default font in use in Revolution. Default: empty egraphXYLabelTextSize - Font size to be used to display the x- and y-axis variable names. Default: 9 graphXLabelXNudge, graphXLabelYNudge, graphYLabelXNudge, graphYLabelYNudge - Number of pixels by which to nudge the axis labels from their default positions. Default: 0 Properties - Key   PgraphYVariableNames - Names to be used for the y-variables in the key. If all the names are empty, no key will be created. The names are text strings separated by returns, corresponding to the y-variables plotted. An empty line will result in a null variable name, but the variable will still be included in the key. Default: empty {graphKeyTextFont - Font to be used to display the key, or empty for the default font in use in Revolution. Default: empty :graphKeyTextSeparation - When displaying keys with multiple y-variables, this is the number of pixels of padding between lines of text in the key. In Revolution terminology, it is the number of pixels difference between the textSize and the textHeight in the fields used to display the y-axis scales. Default: 3 IgraphKeyTextSize - Font size to be used to display the key. Default: 10 rgraphYScalesInKey - True or false, whether the scales of the y-variables are displayed in the key. Default: true graphYUnitsOfMeasureInKey - Units of measure of variables reported in the key. Give the units of measure for each variable on a separate line. Default: empty graphKeyLogIndicator - An indicator used to annotate y-variables graphed logarithmically. You may set this to any string (without return characters). Default: "[logarithmic]" graphKeyXNudge, graphKeyYNudge - Number of pixels by which to change the location of the key from its default location. By default, it will be placed with the its left side adjacent to the vertical axis (with the field containing the key text beginning 20 pixels from the left axis) and with the top of the field containing the key text 12 pixels below all the x-axis labeling. Default: 0 Properties - Title   DgraphTitle - Title to be displayed above the graph. Default: empty graphTitleTextFont - Font to be used to display the title, or empty for the default font in use in Revolution. Default: empty MgraphTitleTextSize - Font size to be used to display the title. Default: 12 graphTitleTextStyle - Font style to be used to display the title, "plain" or one or more of "bold", "italic", "underline", and "strikeout". Default: plain dgraphTitleGap - Number of pixels between the top of the graph and bottom of the title. Default: 10 Properties - Axis   DgraphAxisWidth - Width of the lines for the graph axes. Default: 1 Properties - Clickable Graphs   graphClickable - True or false. If this is true, then whenever the user clicks on a line in the graph, a message will be sent to the card script: + graphClicked lineNumber, xValue, yValue  where lineNumber is 1, 2, ... according to whether the user clicked on the first, second, ... y-variable's line. (Higher-numbered lines are overlaid above lower-numbered lines, so if the user clicks at a point with multiple lines, the highest-numbered line will be identified.) The xValue and yValue are the x and y values of the clicked-on variable at the spot where the click occurred (this may be on an actual data point or on a line between data points). These values will be incorrect if the graph object has been moved but not redrawn. If a key is drawn, the user can click on curves in the key as well as in the graph; this can be detected by the fact that the yValue returned will (unless you nudged the key very high) be less than the y-axis minimum. Default: false Properties - Editable Graphs   JgraphEditable - True or false. If true, the user can click and drag on the graph to alter the y-values of the uppermost curve in the graph. (The uppermost curve is the last line in the graphY property.) The edited y-values are constrained to lie within the vertical range corresponding to the y-axis of the graph. The updated y-values are stored in the graphYDataEdited property. The graphClickable property will function only through the key if graphEditable is true; that is, users will be able to click on curves in the key (if any) but not in the graph proper. Default: false graphSendEditMessage - If this property is true, then whenever the user makes a change to the graph and releases the mouse button, the "graphEdited" message will be sent to the current card. Default: false TgraphYDataEdited - This is a read-only property for use if the graphEditable property is true. It tells you the updated y-values of the uppermost curve in the graph. If you want to preserve the edited data when sending the makeGraph message, put the graphYDataEdited into the last line of the graphY before sending the makeGraph message.  W A J Known Bugs and Limitations   dIn old versions of Runtime Revolution (not MetaCard), the hand cursor becomes the arrow cursor after redrawing the graph. The bug in Revolution that caused the problem (the "choose browse tool" command did not work) was fixed beginning with the alpha release version of Revolution circa 8 July 2002. Upgrade your copy of Revolution to solve the problem. Revision Notes   6From version of 20 Nov. 2000 to version 21 Jan. 2001: z1. The code contained a Macintosh-specific not-equal-to character, causing an error message on PCs. This has been fixed. 2. Ranges can now optionally be automatically rounded to nice round numbers, with the minimum and maximum of the range having the same order of magnitude. n3. Keys can now optionally be created, showing the names, units of measure, and/or ranges of the y-variables. 4. A bug was fixed with the "graphClickable" option's returned y values (which before were nonsenical or yielded dvision by zero errors). >5. Better examples are given so new users can see what to do. 7From version of 21 Jan 2001 to version of 22 May 2001: l6. Sometimes after being pasted into another setting, the lines in the key would not draw. This was fixed. 7. Accuracy could be lost when dealing with extremely small positive or negative numbers. As a possible side effect, this could cause clickable graphs not to work. The inaccuracy (and its side effect) was fixed. O8. Exponent format on axis scales is now an option (graphScaleExponentFormat). $9. Editable graphs can now be used. 7From version of 22 May 2001 to version of 10 May 2002: R10. For graphXTicks and graphYTicks, added the "exactly #" and "about #" options. 7From version of 10 May 2002 to version of 24 May 2002: T11. Exponential notation on axis scales now occurs only for numbers larger (in absolute value) than 100,000 or smaller than 0.001, by default. The relevant thresholds can be set (graphScaleExponentLowThreshold, graphScaleExponentHighThreshold). The minimum number of digits displayed can also be set (graphScaleMinimumSignificantDigits). 8From version of 24 May 2002 to version of 12 July 2002: 12. Fixed a bug in which graphs with multiple curves, some of which contained only 0 y-values but the rest of which contained only nonnegative values, could receive a minimum y scale of -1 if graphYScaleSame was true. 9From version of 12 July 2002 to version of 28 July 2002: y13. The object previously worked properly with missing y-data but not missing x-data; now it works properly with either. 14. Editable graphs now are easier to use - in past the mouse had to be exactly at a data point's x-pixel location to trigger updating of its y value, but now the data point with the nearest x location is updated. :From version of 28 July 2002 to version of 5 August 2002: g15. Graphs with one nonmissing data point could draw oddly when using Revolution; this has been fixed. From version of 25 February 2003 to version of 26 April 2003: 19. Beginning by Metacard version 2.5 (but after 2.3.1), MetaCard would automatically traverse to (draw a rectangle around) a field within the graph object. This has been fixed. >From version of 26 April 2003 to version of 18 December 2006: :20. The description was rewritten for Runtime Revolution. A21. The backgroundBehavior of the graph object was set to false. 22. When using the graphMarker property to set a numeric size number, the number was ignored and a one-pixel dot was displayed. This has been fixed. 23. When using the graphMarker property to to display filled markers, the fill could be a different color (probably black) than the border of the markers. This has been fixed. ` { Example 1Ep\on mouseUp send setDefaultProperties to group "graph" # Here you could set properties of group "graph" to give the type of graph you want. # In this example, only one property is being set: the location of the graph axes on this card. set the graphMainRect of group "graph" to "50,80,250,180" send makeGraph to group "graph" end mouseUp '_a cREVGeneral bookmarks revUniqueID 1166423936983 handlerListmouseUpscriptSelection char 11 to 10 prevHandlermouseUp tempScriptscript  Example 2Epjon mouseUp send setDefaultProperties to group "graph" set the graphMainRect of group "graph" to "50,80,250,180" set the graphX of group "graph" to "1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997" set the graphY of group "graph" to "8,6,6,6,11,4,2,0,5,0,2,0,0,0,3,0,2,1,1,2,1,1,2" set the graphLineColors of group "graph" to "red" set the graphMarkers of group "graph" to "tiny +" set the graphXLabel of group "graph" to "Year" set the graphYLabel of group "graph" to "Major oil tanker spills worldwide" set the graphXYLabelTextSize of group "graph" to 12 set the graphXLabelYNudge of group "graph" to -18 set the graphYLabelYNudge of group "graph" to 6 send makeGraph to group "graph" # This example is based on data from the OECD Environmental Data Compendium 1999. end mouseUp 'wa cREVGeneral bookmarks revUniqueID 1166423936984 handlerListmouseUpscriptSelectionchar 874 to 873 prevHandlermouseUp tempScriptscript  Example 3Epon mouseUp send setDefaultProperties to group "graph" set the graphMainRect of group "graph" to "50,80,250,180" set the graphX of group "graph" to "2930,3350,2640,3250,4080,3670,2230,3280,3880,3400,4330,3900,4290,2110,3690,3180,3220,2750,3430,2120,3600,3600,3740,1800,2650,4840,4720,3830,2580,4060,3720,3370,4130,2830,4060,3310,3300,3690,3370,2730,4030,3260,1800,2200,2520,3330,3700,3470,3210,3200,3420,2690,2830,2070,2650,2370,2020,2280,2750,2130,2240,1760,1980,3420,1830,2050,2410,2200,2670,2160,2040,1930,1990,3170" set the graphY of group "graph" to "22,17,22,20,15,18,26,20,16,19,14,14,21,29,16,22,22,24,19,30,18,16,17,28,21,12,12,14,22,14,15,18,14,20,21,19,19,18,19,24,16,28,34,25,26,18,18,18,19,19,19,24,17,23,25,23,35,24,21,21,25,28,30,14,26,35,18,31,18,23,41,25,25,17" set the graphXLabel of group "graph" to "Weight" set the graphYLabel of group "graph" to "MPG of cars sold in US" set the graphXYLabelTextSize of group "graph" to 12 set the graphXLabelYNudge of group "graph" to -14 set the graphYLabelYNudge of group "graph" to 8 set the graphLinesVisible of group "graph" to false set the graphMarkers of group "graph" to "tiny circle" set the graphYRound of group "graph" to true set the graphYTicks of group "graph" to "about 6" set the graphXTicks of group "graph" to "about 5" set the graphLineColors of group "graph" to "blue" send makeGraph to group "graph" end mouseUp 'a cREVGeneralscriptChecksum3<=9| bookmarks revUniqueID 1166423936985 handlerListmouseUpscriptSelectionchar 1163 to 1162 prevHandlermouseUp tempScriptscriptF

on mouseUp

send setDefaultProperties to group "graph"

set the graphMainRect of group "graph" to "50,80,250,180"

set the graphX of group "graph" to "2930,3350,2640,3250,4080,3670,2230,3280,3880,3400,4330,3900,4290,2110,3690,3180,3220,2750,3430,2120,3600,3600,3740,1800,2650,4840,4720,3830,2580,4060,3720,3370,4130,2830,4060,3310,3300,3690,3370,2730,4030,3260,1800,2200,2520,3330,3700,3470,3210,3200,3420,2690,2830,2070,2650,2370,2020,2280,2750,2130,2240,1760,1980,3420,1830,2050,2410,2200,2670,2160,2040,1930,1990,3170"

set the graphY of group "graph" to "22,17,22,20,15,18,26,20,16,19,14,14,21,29,16,22,22,24,19,30,18,16,17,28,21,12,12,14,22,14,15,18,14,20,21,19,19,18,19,24,16,28,34,25,26,18,18,18,19,19,19,24,17,23,25,23,35,24,21,21,25,28,30,14,26,35,18,31,18,23,41,25,25,17"

set the graphXLabel of group "graph" to "Weight"

set the graphYLabel of group "graph" to "MPG of cars sold in US"

set the graphXYLabelTextSize of group "graph" to 12

set the graphXLabelYNudge of group "graph" to -14

set the graphYLabelYNudge of group "graph" to 8

set the graphLinesVisible of group "graph" to false

set the graphMarkers of group "graph" to "tiny circle"

set the graphYRound of group "graph" to true

set the graphYTicks of group "graph" to "about 6"

set the graphXTicks of group "graph" to "about 5"

set the graphLineColors of group "graph" to "blue"

send makeGraph to group "graph"

end mouseUp

 ( Example 5Epon mouseUp send setDefaultProperties to group "graph" set the graphMainRect of group "graph" to "50,80,250,180" set the graphX of group "graph" to "1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992" set the graphY of group "graph" to "83627000,84869000,86111000,87342000,88584000,89816000,90682000,91537000,92393000,93249000,94104000,94950000,95837000,96818000,97830000,98894000,99792000,100731000,101065000,103183000,104345000,105697000,107188000,108079000,110162000,111940000,112771000,113863000,114898000,115870000,116782000,117648000,118449000,119259000,120018000,120754000,121492000,122091000,122613000,123116000,123537000,123921000,124000000" \ & cr & "1430,1610,1741,1832,1913,2053,2188,2330,2436,2629,2954,3351,3554,3886,4343,4491,4924,5417,6076,6673,7307,7510,8019,8539,8295,8381,8678,8996,9340,9756,10072,10380,10635,10841,11240,11771,11996,12430,13156,13706,14331,14936,15105" \ & cr & "16.5,22.4,17.9,16.5,17.6,18.8,20.6,23.4,20.8,22.6,26,31.5,28.8,30.2,31.4,29.9,30.8,33.8,36.1,37.5,39.9,38.4,38.8,40.6,38.6,35.2,35,34.6,35.1,35.9,34.1,33.6,32.5,30.9,31.3,31.7,32.2,33.6,36,37.7,38.7,38.4,37.4" set the graphLineColors of group "graph" to "red"& cr &"DarkOliveGreen4"& cr &"blue" set the graphYScaleSame of group "graph" to false set the graphTitle of group "graph" to "Japan's Post-War Boom" send makeGraph to group "graph" end mouseUp Ga cREVGeneral bookmarks revUniqueID 1166423936986 handlerListmouseUp prevHandlermouseUp tempScriptscript  D Example 6Epon mouseUp send setDefaultProperties to group "graph" set the graphMainRect of group "graph" to "50,80,250,180" set the graphX of group "graph" to "1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992" set the graphY of group "graph" to "83627000,84869000,86111000,87342000,88584000,89816000,90682000,91537000,92393000,93249000,94104000,94950000,95837000,96818000,97830000,98894000,99792000,100731000,101065000,103183000,104345000,105697000,107188000,108079000,110162000,111940000,112771000,113863000,114898000,115870000,116782000,117648000,118449000,119259000,120018000,120754000,121492000,122091000,122613000,123116000,123537000,123921000,124000000" \ & cr & "1430,1610,1741,1832,1913,2053,2188,2330,2436,2629,2954,3351,3554,3886,4343,4491,4924,5417,6076,6673,7307,7510,8019,8539,8295,8381,8678,8996,9340,9756,10072,10380,10635,10841,11240,11771,11996,12430,13156,13706,14331,14936,15105" \ & cr & "16.5,22.4,17.9,16.5,17.6,18.8,20.6,23.4,20.8,22.6,26,31.5,28.8,30.2,31.4,29.9,30.8,33.8,36.1,37.5,39.9,38.4,38.8,40.6,38.6,35.2,35,34.6,35.1,35.9,34.1,33.6,32.5,30.9,31.3,31.7,32.2,33.6,36,37.7,38.7,38.4,37.4" set the graphLineColors of group "graph" to "red"& cr &"DarkOliveGreen4"& cr &"blue" set the graphYScaleSame of group "graph" to false set the graphYScaleVisible of group "graph" to false set the graphYRound of group "graph" to true set the graphTitle of group "graph" to "Japan's Post-War Boom" set the graphYVariableNames of group "graph" to "Population"& cr &"Real GDP per capita"& cr &"Investment as % of GDP" set the graphYUnitsOfMeasureInKey of group "graph" to "" & cr & "US$" & cr & "" set the graphKeyXNudge of group "graph" to -20 set the graphScaleTextSize of group "graph" to 10 send makeGraph to group "graph" end mouseUp _a cREVGeneralscriptChecksum05H3o+2 bookmarks revUniqueID 1166423936987 handlerListmouseUpscriptSelectionchar 1534 to 1533 prevHandlermouseUp tempScriptscript k

on mouseUp

send setDefaultProperties to group "graph"

set the graphMainRect of group "graph" to "50,80,250,180"

set the graphX of group "graph" to "1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992"

set the graphY of group "graph" to "83627000,84869000,86111000,87342000,88584000,89816000,90682000,91537000,92393000,93249000,94104000,94950000,95837000,96818000,97830000,98894000,99792000,100731000,101065000,103183000,104345000,105697000,107188000,108079000,110162000,111940000,112771000,113863000,114898000,115870000,116782000,117648000,118449000,119259000,120018000,120754000,121492000,122091000,122613000,123116000,123537000,123921000,124000000" \

& cr & "1430,1610,1741,1832,1913,2053,2188,2330,2436,2629,2954,3351,3554,3886,4343,4491,4924,5417,6076,6673,7307,7510,8019,8539,8295,8381,8678,8996,9340,9756,10072,10380,10635,10841,11240,11771,11996,12430,13156,13706,14331,14936,15105" \

& cr & "16.5,22.4,17.9,16.5,17.6,18.8,20.6,23.4,20.8,22.6,26,31.5,28.8,30.2,31.4,29.9,30.8,33.8,36.1,37.5,39.9,38.4,38.8,40.6,38.6,35.2,35,34.6,35.1,35.9,34.1,33.6,32.5,30.9,31.3,31.7,32.2,33.6,36,37.7,38.7,38.4,37.4"

set the graphLineColors of group "graph" to "red"& cr &"DarkOliveGreen4"& cr &"blue"

set the graphYScaleSame of group "graph" to false

set the graphYScaleVisible of group "graph" to false

set the graphYRound of group "graph" to true

set the graphTitle of group "graph" to "Japan's Post-War Boom"

set the graphYVariableNames of group "graph" to "Population"& cr &"Real GDP per capita"& cr &"Investment as % of GDP"

set the graphYUnitsOfMeasureInKey of group "graph" to "" & cr & "US$" & cr & ""

set the graphKeyXNudge of group "graph" to -20

set the graphScaleTextSize of group "graph" to 10

send makeGraph to group "graph"

end mouseUp

 Example 6Epaon mouseUp send setDefaultProperties to group "graph" set the graphX of group "graph" to "1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992" set the graphY of group "graph" to "83627000,84869000,86111000,87342000,88584000,89816000,90682000,91537000,92393000,93249000,94104000,94950000,95837000,96818000,97830000,98894000,99792000,100731000,101065000,103183000,104345000,105697000,107188000,108079000,110162000,111940000,112771000,113863000,114898000,115870000,116782000,117648000,118449000,119259000,120018000,120754000,121492000,122091000,122613000,123116000,123537000,123921000,124000000" \ & cr & "1430,1610,1741,1832,1913,2053,2188,2330,2436,2629,2954,3351,3554,3886,4343,4491,4924,5417,6076,6673,7307,7510,8019,8539,8295,8381,8678,8996,9340,9756,10072,10380,10635,10841,11240,11771,11996,12430,13156,13706,14331,14936,15105" \ & cr & "16.5,22.4,17.9,16.5,17.6,18.8,20.6,23.4,20.8,22.6,26,31.5,28.8,30.2,31.4,29.9,30.8,33.8,36.1,37.5,39.9,38.4,38.8,40.6,38.6,35.2,35,34.6,35.1,35.9,34.1,33.6,32.5,30.9,31.3,31.7,32.2,33.6,36,37.7,38.7,38.4,37.4" set the graphLineColors of group "graph" to "red"& cr &"DarkOliveGreen4"& cr &"blue" set the graphYScaleSame of group "graph" to false set the graphYScaleVisible of group "graph" to false set the graphYRound of group "graph" to true set the graphTitle of group "graph" to "Japan's Post-War Boom" set the graphYVariableNames of group "graph" to "Population"& cr &"Real GDP per capita"& cr &"Investment as % of GDP" set the graphYUnitsOfMeasureInKey of group "graph" to "" & cr & "US$" & cr & "" set the graphKeyXNudge of group "graph" to -20 set the graphScaleTextSize of group "graph" to 10 send makeGraph to group "graph" end mouseUp wa cREVGeneral revUniqueID 1166423936988  Example 7EpGon mouseUp send setDefaultProperties to group "graph" set the graphMainRect of group "graph" to "50,80,250,180" set the graphX of group "graph" to "1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992" set the graphY of group "graph" to "83627000,84869000,86111000,87342000,88584000,89816000,90682000,91537000,92393000,93249000,94104000,94950000,95837000,96818000,97830000,98894000,99792000,100731000,101065000,103183000,104345000,105697000,107188000,108079000,110162000,111940000,112771000,113863000,114898000,115870000,116782000,117648000,118449000,119259000,120018000,120754000,121492000,122091000,122613000,123116000,123537000,123921000,124000000" \ & cr & "1430,1610,1741,1832,1913,2053,2188,2330,2436,2629,2954,3351,3554,3886,4343,4491,4924,5417,6076,6673,7307,7510,8019,8539,8295,8381,8678,8996,9340,9756,10072,10380,10635,10841,11240,11771,11996,12430,13156,13706,14331,14936,15105" \ & cr & "16.5,22.4,17.9,16.5,17.6,18.8,20.6,23.4,20.8,22.6,26,31.5,28.8,30.2,31.4,29.9,30.8,33.8,36.1,37.5,39.9,38.4,38.8,40.6,38.6,35.2,35,34.6,35.1,35.9,34.1,33.6,32.5,30.9,31.3,31.7,32.2,33.6,36,37.7,38.7,38.4,37.4" set the graphLineColors of group "graph" to "red"& cr &"DarkOliveGreen4"& cr &"blue" set the graphYScaleSame of group "graph" to false set the graphYScaleVisible of group "graph" to false set the graphYRound of group "graph" to true set the graphTitle of group "graph" to "CLICKABLE Japan's Post-War Boom" set the graphYVariableNames of group "graph" to "Population"& cr &"Real GDP per capita"& cr &"Investment as % of GDP" set the graphYUnitsOfMeasureInKey of group "graph" to "" & cr & "US$" & cr & "" set the graphKeyXNudge of group "graph" to -20 set the graphScaleTextSize of group "graph" to 10 set the graphClickable of group "graph" to true # See the handler in the card script for an example of how to get messages when the user clicks on the graph. send makeGraph to group "graph" end mouseUp wa cREVGeneral revUniqueID 1166423936989  Example 8Epon mouseUp send setDefaultProperties to group "graph" set the graphMainRect of group "graph" to "50,80,250,180" set the graphX of group "graph" to "0,1,2,3,4,5,6,7,8,9,10" set the graphY of group "graph" to "10,7,4.5,2.5,1,0,1,2.5,4.5,7,10" set the graphLineColors of group "graph" to "blue" set the graphMarkers of group "graph" to "tiny +" set the graphXLabel of group "graph" to "Input" set the graphYLabel of group "graph" to "Output" set the graphXYLabelTextSize of group "graph" to 12 set the graphXLabelYNudge of group "graph" to -28 set the graphYLabelYNudge of group "graph" to 13 set the graphEditable of group "graph" to true set the graphTitle of group "graph" to "Edit Me -- Click & drag in graph" send makeGraph to group "graph" end mouseUp a cREVGeneral bookmarks revUniqueID 1166423936990 handlerListmouseUp prevHandlermouseUp tempScriptscript KTable usage info)h cREVGeneral revUniqueID 1166424932896 > Table object   Tuviah Snyder, 2000.  AAdditions & modifications, Ken Simons, version 18 December 2006. @  Contents:  Usage   Authors and Rights   Properties - Data  % Properties - Row and Column Names $ + Properties - Number of Rows and Columns *  Properties - Column Widths   Properties - Scroll Bars  # Properties - Text Font and Size "  Properties - Colors  2 Properties - Editing, Copying, Double-clicking 1  Properties - Read-only   Known Bugs and Limitations   Revision Notes   Usage   XTo use the table object in your Revolution project, just select it, copy, and paste where you want it. Your table is then operational. When copying, ensure that Revolution's "Select Grouped Controls" option is turned off in the Edit menu (or set the selectGroupedControls to false); otherwise you will copy only one part of the graph object.  f  F  Don't like how the table looks or acts? Set properties of the table object (listed below) and send the message redrawme to the table object. This lets you make all sorts of changes: contents of the table, row and column names if any, numbers of columns and rows, column widths, whether scroll bars appear, text font and size, color scheme, whether the user can edit the table, and more. You can do this using a pallette designed to make changes easy, and then copy the adjusted table. p p xo  Or make changes from scripts. Example scripts are in the buttons at the left. Send setDefaultProperties to the table object if you want to reset all properties to their default values, before making changes from scripts. U U iu  To put tables on multiple cards, paste the table object multiple times and give each a different name. Or if you don't mind doing some programming, here is a more memory-efficient approach: paste the table object once, place the object on relevant cards, have an on preOpenCard handler on each card set the table object appropriately, and have an on closeCard handler on each card save edited contents of the table.   '  F \ h8  To resize or relocate the table by hand: (1) set the lockLocation of the table to false, (2) resize and relocate the table, and (3) send redrawme to the table. To do the same by script, just set the rect of the group and then send the redrawme command.   [    UTo copy the pallette into your stack, you must copy it separately from the table object. The pallette is a substack of this stack; similarly you will need it to be a substack of your stack. To make it a substack of your stack: use the message box to issue the command clone stack "table props", then choose Edit -> Stack Properties..., set the Main Stack of the cloned stack to your own stack, and set its name to "table props" or whatever you like. Then to use the pallette, select the table object to be modified, and open the palette using the palette command (e.g., palette "table props").   ' & = R  Authors and Rights   Tuviah Snyder graciously made his table object available to the MetaCard community circa 2000 (see his "powertable.mc" stack, which was then available for download from the Cross-Worlds web site). He has given me (Ken Simons) permission to modify and use his object and, although he has put a copyright notice on his code, he seems to be willing to let anyone use the table object (including for commercial purposes). I have made various modifications and feature additions to the table object, and have written this documentation. Tuviah included a floating pallette useful for editing; I have updated the pallette to include options that I added.   Properties - Data   There are three ways to enter data into the table. 1. Type it in. 2. Set the tbdata[ ] properties as described below. The data placed in the table will be adjusted to fit given the available column widths. The tbdata[.] properties will be updated whenever someone enters data into the table. 3. Use a global variable. The third option allows rapid display of data but not user-editing nor formatting; it is relatively quick for large amounts of data because formatting takes a long time. Place the data in a global variable and set the tbgetUnformattedDataFromGlobal property to the name of the global; the data will then be placed in the table very quickly but you will need to ensure that column widths are okay.   =  tbdata[1..cols] - The data to be placed in the table. The first column of data goes in tbdata[1], the second in tbdata[2], etc. Within each column, use returns to distinguish the rows of data. The text must not contain tab characters. Default: null   =tbgetUnformattedDataFromGlobal - The name of a global variable containing data to put into the table. If a name is provided, data from the named variable will be used and the tbdata[ ] information will be ignored and editing will not work properly. The advantage of this method is that it is very fast for large amounts of data. The data must be tab-delimited within each line, with lines (rows) separated with return characters. There must be one line of data for each row of the table (blank lines are ok but the carriage returns must be there); otherwise clicking on cells of the table will yield odd behavior; it will not be possible to select a cell. Editing will not be possible; the tbuserCanEdit property automatically will be set to false and needs to be left false. See above for more information. Default: null  "Properties - Row and Column Names  ! htbpadcolumn - Whether column names are displayed at the top of the table, true or false. Default: true mtbpadrow - Whether row names are displayed at the left-hand side of the table, true or false. Default: true  tbcolumnnames - The column names, displayed at the top of the table. Separate the names with return characters. If this is null, the column names will be "column 1", "column 2", etc. Default: null   tbrownames - The row names, displayed at the left-hand side of the table. If this is null, the row names will be "1", "2", etc. Separate the names with return characters. Default: null   (Properties - Number of Rows and Columns  ' The table has a fixed setting for the number of rows and columns. However, you could easily create a button or other tool that adds to the number of rows and/or columns and sends the "redrawme" command to the table.   7tbrows - The number of rows in the table. Default: 20 6  The following properties determine colors used for the table. 8tbcolumncolor - Main body of the table. Default: white :tbcolumntextcolor - Text in the main body. Default: blue Btbcolumnbordercolor - Borders in main body. Default: 196,196,196 tbpadcolor - Row and column name cells. Default: 184,184,184 Ftbpadbordercolor - Borders in row/column names. Default: 100,100,100 ;tbpadtextcolor - Text of row/column names. Default: black Ftbscrollcolor - Arrows and bars for scrollbars. Default: 196,196,196  /Properties - Editing, Copying, Double-Clicking  . ctbuserCanEdit - True or false, whether the user can edit the contents of the table. Default: true stbUserCanResizeColumns - True or false, whether the user can resize the column widths of the table. Default: true tbCopyable - True or false, whether the user can copy text from the table, by pressing control-C (command-C on Macintosh). Default: true tbcopyRowAndColumnNames - "always", "row", "column", "multi", "row multi", "column multi", or "never". This property affects behavior when the user presses control-C (command-C on Macintosh) to copy text from the table. Specifically, this property determines whether and when row and/or column names get copied along with text of the table. If "always", they are always copied; if "never", they are never copied. If "row" or "column", then row or column names respectively are always copied. If "multi", names are copied only when multiple rows and/or columns are selected. The "row multi" and "column multi" alternatives copy only row or column names respectively when multiple rows or columns are selected. Default: never