#!/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 objectsˆÄon 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 wÜÜÜÜÜÜ      ’’’’’’white¬¬¬¬¬¬¬¬¬¬¬¬€f€Čwdata2columnwidthss110 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 wdata1dataä17.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 wdata1columnnames®consumer 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 total25˜Kknoqtyzƒ›©ķgraphIß# 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 handlerList¶makeGraph 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