Skip to content

Instantly share code, notes, and snippets.

@ashenfad
Last active March 8, 2016 01:56
Show Gist options
  • Save ashenfad/59f25114a206d95a2e74 to your computer and use it in GitHub Desktop.
Save ashenfad/59f25114a206d95a2e74 to your computer and use it in GitHub Desktop.
Dynamic Heatmap - Forest Cover

A 2D/3D heatmap of the forest cover dataset (100K sample).

Click and drag to zoom. Single click to zoom out.

{"all_fields": true, "category": 6, "cluster": null, "cluster_status": false, "code": 200, "columns": 15, "correlations": {}, "created": "2016-03-07T23:55:58.516000", "credits": 0.0, "dataset_origin_status": true, "description": "A tidied up version of [UCI's forest cover dataset](https://archive.ics.uci.edu/ml/datasets/Covertype).", "download": {"code": 0, "excluded_input_fields": [], "header": true, "input_fields": [], "message": "", "preview": [], "separator": ","}, "excluded_fields": [], "field_types": {"categorical": 4, "datetime": 0, "effective_fields": 15, "items": 0, "numeric": 11, "preferred": 15, "text": 0, "total": 15}, "fields": {"000000": {"column_number": 0, "datatype": "int16", "name": "Elevation", "optype": "numeric", "order": 0, "preferred": true, "summary": {"bins": [[1893.72789, 147], [1964.26136, 1144], [2029.44693, 1517], [2085.85576, 2579], [2147.47206, 3525], [2201.08315, 2225], [2249.72827, 3923], [2322.43247, 9129], [2383.70512, 4395], [2431.16074, 7366], [2494.11672, 9047], [2568.16672, 20645], [2636.44147, 16778], [2699.54694, 24275], [2776.40066, 44566], [2851.52281, 36174], [2917.1172, 55803], [2981.54578, 65481], [3043.12585, 52243], [3099.2039, 42604], [3152.21453, 45626], [3207.59075, 48372], [3267.04266, 42264], [3319.28805, 12911], [3366.90042, 16529], [3423.69539, 7764], [3497.76232, 2617], [3588.3429, 662], [3659.32468, 231], [3718.4292, 226], [3776.08333, 84], [3827.44375, 160]], "kurtosis": 0.74923, "maximum": 3858, "mean": 2959.3653, "median": 2995.6424, "minimum": 1859, "missing_count": 0, "population": 581012, "skewness": -0.81759, "splits": [2308.57095, 2463.51629, 2566.15537, 2631.81872, 2690.78914, 2734.39545, 2772.78879, 2809.14953, 2841.8178, 2871.80138, 2897.89048, 2921.2394, 2941.31235, 2960.03261, 2977.43014, 2995.6424, 3014.51473, 3033.9162, 3054.11603, 3075.61137, 3097.97319, 3120.23765, 3141.6344, 3163.41173, 3185.20992, 3205.68212, 3227.98408, 3251.49286, 3278.28962, 3315.27451, 3372.88786], "standard_deviation": 279.98473, "sum": 1719426752, "sum_squares": 5133958162274, "variance": 78391.45141}}, "000001": {"column_number": 1, "datatype": "int16", "name": "Aspect", "optype": "numeric", "order": 1, "preferred": true, "summary": {"bins": [[5.07302, 27471], [14.63572, 15853], [23.89765, 29203], [33.49116, 18896], [45.49191, 42315], [61.58006, 39525], [74.85213, 24765], [86.34731, 27278], [97.94504, 22161], [106.56442, 12528], [115.70348, 21277], [126.72546, 17480], [139.82429, 23755], [153.7447, 14865], [165.27736, 13120], [177.00684, 13884], [189.05358, 12374], [199.99883, 10284], [210.26072, 10168], [218.79135, 5689], [228.24045, 10555], [239.69572, 8903], [253.07079, 13887], [267.20597, 11599], [278.69297, 11152], [287.07845, 6692], [296.42806, 15012], [307.42323, 14087], [319.92957, 26097], [330.92591, 12471], [340.39962, 22887], [352.74034, 24779]], "kurtosis": -1.22024, "maximum": 360, "mean": 155.65681, "median": 126.96597, "minimum": 0, "missing_count": 0, "population": 581012, "skewness": 0.40263, "splits": [7.13381, 15.00805, 22.35331, 29.55958, 37.07271, 44.15876, 51.17557, 58.34934, 65.50684, 73.07565, 81.05558, 89.20471, 97.82515, 106.79095, 116.68768, 126.96597, 138.32549, 151.27732, 166.14369, 182.10008, 199.46037, 218.15614, 239.35709, 260.51609, 279.1578, 295.62909, 309.10792, 320.46675, 330.63864, 340.45363, 349.85836], "standard_deviation": 111.91372, "sum": 90438473, "sum_squares": 21354341379, "variance": 12524.68095}}, "000002": {"column_number": 2, "datatype": "int8", "name": "Slope", "optype": "numeric", "order": 2, "preferred": true, "summary": {"bins": [[0.84871, 4336], [2.60064, 19346], [4.5601, 37154], [6.51858, 50899], [8.51543, 62179], [10.50009, 67636], [12.49392, 65636], [14.49028, 59409], [16.46701, 49796], [18.47388, 40149], [20.46379, 31051], [22.45716, 24998], [24.46432, 19340], [26.45551, 14858], [28.45711, 10899], [30.45643, 8010], [32.45603, 5879], [34.45071, 3987], [36.43951, 2455], [38.41956, 1442], [40.41341, 716], [42.41667, 348], [44.45327, 214], [46.42373, 118], [48.50746, 67], [50.425, 40], [52.4, 15], [54.42857, 7], [56.63636, 11], [58.75, 4], [61.22222, 9], [65, 4]], "kurtosis": 0.58118, "maximum": 66, "mean": 14.1037, "median": 12.98549, "minimum": 0, "missing_count": 0, "population": 581012, "skewness": 0.78927, "splits": [2.98587, 4.23348, 5.06326, 5.97301, 6.70306, 7.38368, 8.00983, 8.60095, 9.17143, 9.72434, 10.26329, 10.80018, 11.33801, 11.88074, 12.42943, 12.98549, 13.55573, 14.14877, 14.75892, 15.3878, 16.05382, 16.77491, 17.56682, 18.42592, 19.37064, 20.44632, 21.6972, 23.133, 24.90088, 27.19381, 30.72998], "standard_deviation": 7.48824, "sum": 8194421, "sum_squares": 148151159, "variance": 56.07377}}, "000003": {"column_number": 3, "datatype": "int16", "name": "Dist. to water", "optype": "numeric", "order": 3, "preferred": true, "summary": {"bins": [[0, 24603], [33.60275, 48786], [76.15621, 68509], [120.52176, 48442], [152.88296, 31708], [193.86468, 69493], [242.94146, 40228], [287.7634, 49776], [342.12796, 45365], [391.09932, 26279], [436.26437, 28086], [481.85136, 18609], [523.84539, 17412], [565.19197, 12653], [598.36251, 6957], [629.93955, 8850], [665.99983, 5889], [706.49138, 7717], [752.84921, 4556], [797.20886, 4807], [843.46958, 2860], [892.23636, 3080], [952.78796, 2259], [1006.22823, 1183], [1046.89186, 786], [1090.58547, 895], [1137.53499, 443], [1186.46565, 393], [1242.10345, 232], [1288.05319, 94], [1338.08929, 56], [1387.5, 6]], "kurtosis": 1.36616, "maximum": 1397, "mean": 269.42822, "median": 223.76708, "minimum": 0, "missing_count": 0, "population": 581012, "skewness": 1.14043, "splits": [7.23198, 24.21746, 36.9686, 49.08615, 63.24008, 77.11915, 90.59071, 103.70782, 120.10715, 132.42384, 147.39668, 161.61917, 176.61472, 191.07923, 207.08617, 223.76708, 239.46378, 257.53281, 275.34884, 294.35704, 313.1634, 335.44147, 359.18612, 384.81684, 414.03451, 444.69465, 482.25019, 523.47888, 574.17102, 645.77901, 762.0946], "standard_deviation": 212.54936, "sum": 156541027, "sum_squares": 68425036479, "variance": 45177.22856}}, "000004": {"column_number": 4, "datatype": "int16", "name": "Depth to water", "optype": "numeric", "order": 4, "preferred": true, "summary": {"bins": [[-152.7451, 51], [-127.01056, 284], [-106.20725, 386], [-83.83267, 1004], [-56.86091, 3530], [-37.17141, 4072], [-15.24868, 21566], [5.47148, 191834], [29.4156, 129270], [58.44902, 104217], [88.44529, 43057], [111.02308, 24135], [130.02628, 13775], [148.76029, 11760], [169.38392, 9778], [189.17842, 6709], [208.54092, 5267], [233.74102, 4676], [265.0219, 2192], [291.99611, 1286], [320.28372, 1001], [349.26471, 476], [373.54122, 279], [395.60355, 169], [416.74684, 79], [453.5, 24], [484.54545, 22], [508.10526, 19], [526.4375, 16], [546.44444, 27], [568.56522, 23], [590.17857, 28]], "kurtosis": 5.25024, "maximum": 601, "mean": 46.41886, "median": 30.18289, "minimum": -173, "missing_count": 0, "population": 581012, "skewness": 1.79025, "splits": [-16.60401, -6.40385, -3.0845, -0.65204, 1.36731, 3.34202, 5.35627, 7.41252, 9.51351, 11.70481, 14.16116, 16.81577, 19.72614, 22.99559, 26.64398, 30.18289, 33.62161, 37.02686, 40.86451, 45.52104, 50.87318, 56.28066, 62.54854, 69.03746, 76.46237, 85.00437, 95.28831, 108.26098, 126.35649, 151.52346, 191.20669], "standard_deviation": 58.29523, "sum": 26969912, "sum_squares": 3226381898, "variance": 3398.33403}}, "000005": {"column_number": 5, "datatype": "int16", "name": "Dist. to road", "optype": "numeric", "order": 5, "preferred": true, "summary": {"bins": [[207.74011, 22775], [423.39541, 24395], [621.25318, 32100], [819.55874, 30991], [1014.34678, 36946], [1226.29372, 41345], [1438.9781, 34655], [1679.8144, 43793], [1944.32759, 32535], [2123.55849, 15662], [2294.40133, 27182], [2512.92487, 23973], [2751.2876, 26860], [3003.7982, 24608], [3215.7437, 16555], [3416.13088, 16687], [3616.64762, 12112], [3819.7648, 13193], [4037.24157, 12932], [4308.65726, 18755], [4591.21535, 11609], [4838.70026, 10189], [5037.31507, 6297], [5247.28303, 11730], [5494.07351, 9183], [5711.53542, 8978], [5929.32201, 7804], [6147.22624, 3978], [6344.50462, 1732], [6582.22718, 964], [6822.28392, 398], [7013.21875, 96]], "kurtosis": -0.38372, "maximum": 7117, "mean": 2350.14661, "median": 1997.55037, "minimum": 0, "missing_count": 0, "population": 581012, "skewness": 0.71368, "splits": [281.62987, 434.87676, 564.10708, 682.28828, 798.22905, 902.48076, 1006.61765, 1105.0627, 1202.37446, 1299.68325, 1403.93095, 1509.17768, 1619.37075, 1736.02126, 1866.72843, 1997.55037, 2133.06964, 2278.35631, 2429.78897, 2593.50774, 2768.13211, 2943.117, 3122.14712, 3329.04166, 3566.74781, 3857.49465, 4161.05567, 4482.81853, 4880.93708, 5308.38602, 5742.58205], "standard_deviation": 1559.25487, "sum": 1365463383, "sum_squares": 4621637096965, "variance": 2431275.7493}}, "000006": {"column_number": 6, "datatype": "int16", "name": "Shade at 9am", "optype": "numeric", "order": 6, "preferred": true, "summary": {"bins": [[0, 13], [36, 1], [46, 2], [57.08824, 34], [65.86667, 45], [74.03623, 138], [82.5404, 198], [90.98737, 396], [98.8, 455], [105.32569, 654], [112.07087, 1016], [118.58647, 1330], [125.14966, 2058], [132.09458, 2897], [138.14291, 2806], [144.3106, 4633], [151.76373, 7449], [159.36809, 8449], [165.71703, 8803], [172.65561, 16635], [179.37306, 16831], [185.64801, 23975], [190.842, 17551], [197.89465, 54027], [206.06643, 48580], [211.813, 38358], [217.34132, 60655], [225.25027, 103838], [233.01451, 61212], [239.33217, 52630], [245.32083, 27229], [250.85199, 18114]], "kurtosis": 1.87549, "maximum": 254, "mean": 212.14605, "median": 217.73175, "minimum": 0, "missing_count": 0, "population": 581012, "skewness": -1.18114, "splits": [149.38309, 165.31428, 174.84957, 181.47204, 186.78605, 191.12186, 194.90341, 198.39496, 201.44387, 204.22615, 206.69297, 209.46001, 211.59675, 213.48349, 215.74647, 217.73175, 219.57549, 221.34687, 222.89541, 224.44808, 226.31364, 227.97803, 229.66092, 231.37182, 233.12086, 235.02691, 237.07156, 239.05238, 241.54195, 244.43506, 248.23065], "standard_deviation": 26.76989, "sum": 123259400, "sum_squares": 26565362804, "variance": 716.62695}}, "000007": {"column_number": 7, "datatype": "int16", "name": "Shade at noon", "optype": "numeric", "order": 7, "preferred": true, "summary": {"bins": [[0, 5], [30, 1], [42.33333, 3], [53, 2], [63.5, 2], [69.5, 2], [75.75, 4], [81, 5], [88.8, 15], [98.08108, 37], [104.84783, 46], [111.97222, 72], [119.02885, 104], [124.65789, 114], [132.06582, 471], [139.80998, 521], [146.08161, 870], [152.61459, 1645], [160.81256, 3345], [170.54063, 7014], [178.21018, 6461], [184.93446, 11734], [190.77026, 10969], [196.0971, 17797], [203.23866, 40890], [209.6767, 36761], [215.68785, 66578], [221.94604, 69103], [228.48822, 98286], [235.04354, 71113], [241.34527, 62678], [249.30785, 74364]], "kurtosis": 2.06618, "maximum": 254, "mean": 223.31872, "median": 226.08421, "minimum": 0, "missing_count": 0, "population": 581012, "skewness": -1.06305, "splits": [178.83342, 190.14835, 196.82692, 201.43442, 205.0155, 208.11345, 210.54722, 212.90633, 214.98371, 216.7157, 218.3065, 220.01107, 221.59098, 223.125, 224.72811, 226.08421, 227.34831, 228.69121, 230.06598, 231.33942, 232.74478, 234.33324, 235.83687, 237.44629, 239.16412, 240.8585, 242.85233, 245.04806, 247.05207, 249.2844, 251.78412], "standard_deviation": 19.7687, "sum": 129750854, "sum_squares": 29202854060, "variance": 390.80139}}, "000008": {"column_number": 8, "datatype": "int16", "name": "Shade at 3pm", "optype": "numeric", "order": 8, "preferred": true, "summary": {"bins": [[0.03506, 1369], [6.94536, 183], [14.88016, 509], [22.35922, 721], [32.39851, 2276], [41.90102, 2061], [49.75175, 3001], [57.24987, 3914], [65.03605, 5992], [72.09741, 6221], [81.26397, 15805], [90.80625, 15210], [99.42556, 24885], [107.90183, 29337], [117.51055, 52596], [126.82616, 46791], [134.75841, 51033], [142.74759, 56084], [150.46027, 45349], [158.2927, 45674], [166.6664, 38109], [174.00372, 26877], [181.04127, 29031], [188.96343, 25400], [197.5362, 20845], [206.46307, 12918], [214.95208, 8682], [221.87776, 3354], [228.16096, 3827], [236.36497, 2181], [244.16809, 702], [250.77333, 75]], "kurtosis": 0.39843, "maximum": 254, "mean": 142.52826, "median": 142.75893, "minimum": 0, "missing_count": 0, "population": 581012, "skewness": -0.27705, "splits": [66.55933, 82.91286, 93.35245, 100.36887, 106.32269, 111.0352, 115.37503, 119.22801, 122.5471, 125.83879, 128.90074, 131.89437, 134.7661, 137.47839, 140.1944, 142.75893, 145.4669, 148.24925, 151.1427, 154.13602, 157.38618, 160.83264, 164.43772, 168.21079, 172.42442, 176.85791, 181.46744, 186.57144, 192.61677, 200.1169, 211.52004], "standard_deviation": 38.27453, "sum": 82810631, "sum_squares": 12654001389, "variance": 1464.93959}}, "000009": {"column_number": 9, "datatype": "int16", "name": "Dist. to fire", "optype": "numeric", "order": 9, "preferred": true, "summary": {"bins": [[108.35727, 4568], [271.73436, 17155], [483.86021, 36060], [655.92053, 24388], [830.84726, 44846], [1042.34467, 44228], [1257.69912, 47547], [1480.92601, 49425], [1713.75909, 45930], [1936.49739, 38829], [2189.23318, 50060], [2439.88409, 31697], [2688.71703, 40404], [2963.84769, 18035], [3223.25215, 15324], [3485.31589, 10317], [3718.57494, 6432], [3978.87747, 8912], [4245.84296, 5451], [4421.98558, 2635], [4584.62571, 4419], [4787.50417, 4197], [5009.17147, 4858], [5279.28177, 5068], [5492.22143, 2651], [5677.12572, 4160], [5888.99775, 3115], [6049.00295, 2033], [6220.16066, 3523], [6450.12221, 3633], [6719.88211, 738], [6954.43316, 374]], "kurtosis": 1.64578, "maximum": 7173, "mean": 1980.29123, "median": 1709.08178, "minimum": 0, "missing_count": 0, "population": 581012, "skewness": 1.28864, "splits": [326.19163, 467.46813, 572.96869, 668.88893, 762.42102, 852.69345, 937.63058, 1024.54034, 1109.9599, 1195.52814, 1279.68871, 1362.92756, 1446.3406, 1530.8396, 1618.79161, 1709.08178, 1802.48123, 1899.47469, 1998.79174, 2101.3976, 2208.34937, 2317.27874, 2431.36171, 2550.56314, 2676.30192, 2828.59272, 3043.97168, 3364.89943, 3868.62918, 4595.55588, 5529.97565], "standard_deviation": 1324.19521, "sum": 1150572966, "sum_squares": 3297268244304, "variance": 1753492.9536}}, "00000a": {"column_number": 10, "datatype": "string", "name": "Wilderness Area", "optype": "categorical", "order": 10, "preferred": true, "summary": {"categories": [["Rawah", 260796], ["Comanche Peak", 253364], ["Cache la Poudre", 36968], ["Neota", 29884]], "missing_count": 0}, "term_analysis": {"enabled": true}}, "00000b": {"column_number": 11, "datatype": "string", "name": "Climate", "optype": "categorical", "order": 11, "preferred": true, "summary": {"categories": [["Montane + subalpine", 285199], ["Montane", 93593], ["Lower montane", 35947], ["Montane dry + montane", 602], ["Montane dry", 284]], "missing_count": 165387}, "term_analysis": {"enabled": true}}, "00000c": {"column_number": 12, "datatype": "string", "name": "Geology", "optype": "categorical", "order": 12, "preferred": true, "summary": {"categories": [["Igneous", 302082], ["Glacial", 92272], ["Alluvium", 20987], ["Sedimentary", 284]], "missing_count": 165387}, "term_analysis": {"enabled": true}}, "00000d": {"column_number": 13, "datatype": "string", "name": "Forest Type", "optype": "categorical", "order": 13, "preferred": true, "summary": {"categories": [["Lodgepole Pine", 283301], ["Spruce-Fur", 211840], ["Ponderosa Pine", 35754], ["Krummholz", 20510], ["Douglas-fir", 17367], ["Aspen", 9493], ["Cottonwood-Willow", 2747]], "missing_count": 0}, "term_analysis": {"enabled": true}}, "00000e": {"column_number": 14, "datatype": "double", "description": "", "label": "", "name": "Anomaly Score", "optype": "numeric", "order": 14, "preferred": true, "summary": {"bins": [[0.3286, 1], [0.35281, 523], [0.37062, 2884], [0.38907, 8021], [0.40659, 18021], [0.42424, 38678], [0.44348, 61668], [0.45999, 53173], [0.4784, 91465], [0.49798, 62239], [0.51541, 62535], [0.53367, 49286], [0.5513, 36840], [0.57043, 34920], [0.59124, 21563], [0.61064, 13555], [0.62995, 8953], [0.65163, 6833], [0.674, 3044], [0.69379, 1899], [0.71355, 1429], [0.73963, 1425], [0.76353, 399], [0.7813, 598], [0.80098, 218], [0.81846, 285], [0.83784, 231], [0.85692, 133], [0.88476, 109], [0.91067, 39], [0.93441, 27], [0.95995, 18]], "kurtosis": 2.09925, "maximum": 0.97893, "mean": 0.50197, "median": 0.49398, "minimum": 0.3286, "missing_count": 0, "population": 581012, "skewness": 0.94842, "splits": [0.40494, 0.41807, 0.42714, 0.43458, 0.441, 0.44682, 0.45256, 0.45739, 0.4618, 0.46647, 0.47112, 0.47544, 0.47971, 0.48466, 0.48919, 0.49398, 0.49872, 0.50377, 0.50889, 0.51385, 0.51924, 0.52506, 0.53134, 0.538, 0.54532, 0.55358, 0.56315, 0.57376, 0.58707, 0.60529, 0.63698], "standard_deviation": 0.06405, "sum": 291653.49007, "sum_squares": 148786.52533, "variance": 0.0041}}}, "fields_meta": {"count": 15, "effective_fields": 15, "limit": 1000, "offset": 0, "query_total": 15, "total": 15}, "input_fields": ["000000", "000001", "000002", "000003", "000004", "000005", "000006", "000007", "000008", "000009", "00000a", "00000b", "00000c", "00000d", "00000e"], "locale": "en_US", "missing_numeric_rows": 0, "missing_tokens": [""], "name": "Forest Cover - batchanomalyscore", "new_fields": [], "number_of_anomalies": 0, "number_of_anomalyscores": 0, "number_of_associations": 0, "number_of_associationsets": 0, "number_of_batchanomalyscores": 0, "number_of_batchcentroids": 0, "number_of_batchpredictions": 0, "number_of_centroids": 0, "number_of_clusters": 0, "number_of_correlations": 0, "number_of_ensembles": 0, "number_of_evaluations": 0, "number_of_logisticregressions": 0, "number_of_models": 0, "number_of_predictions": 0, "number_of_statisticaltests": 0, "objective_field": {"column_number": 14, "datatype": "double", "description": "", "id": "00000e", "label": "", "name": "Anomaly Score", "optype": "numeric", "order": 14}, "origin_batch_resource": "batchanomalyscore/56de1498200d5a217c0017f4", "origin_batch_status": true, "output_fields": [], "price": 0.0, "private": true, "project": "project/5671c5dd1d5505103e0008d7", "ranges": null, "refresh_field_types": false, "refresh_preferred": false, "replacements": null, "resource": "dataset/56de150e200d5a217d003e78", "rows": 581012, "sample_rates": null, "seeds": null, "shared": false, "size": 51633668, "source": "source/5564ff5faf447f667b0005af", "source_status": false, "statisticaltest": null, "status": {"bytes": 51633668, "code": 5, "elapsed": 39468, "field_errors": [], "message": "The dataset has been created", "progress": 1.0, "row_format_errors": [], "serialized_rows": 581012, "task": "Done"}, "subscription": true, "tags": ["uci", "forest cover"], "tde_download": {"code": 0, "excluded_input_fields": [], "input_fields": [], "message": "", "preview": []}, "term_limit": 1000, "updated": "2016-03-08T00:55:22.392000", "user_metadata": {}}
var candidateIntervals = [2, 2.5, 5, 10];
function prettyRange (initRange, size) {
var minimum = initRange[0];
var maximum = initRange[1];
if (minimum != maximum) {
var diff = (maximum - minimum) / size;
var tens = Math.floor(Math.log10(diff));
var tscale = Math.pow(10, tens);
var rem = diff / tscale;
var minIndex;
var minDiff = 1E20;
for (i in candidateIntervals) {
var c = candidateIntervals[i];
var cDiff = c - rem;
if (cDiff > 0 && cDiff < minDiff) {
minDiff = cDiff;
minIndex = i;
}
}
var interval = candidateIntervals[minIndex] * tscale;
var newMin = interval * Math.floor(minimum / interval);
var newMax = newMin + interval * size;
if (newMax < maximum) {
return prettyRange([newMin, newMax], size);
} else if (newMax == maximum) {
if (newMax == 0) {
newMax = 1E-8;
} else {
newMax = newMax * 1.000001;
}
return prettyRange([newMin, newMax], size);
} else {
return [newMin, newMax];
}
} else {
return [minimum, maximum];
}
}
function truncate (val) {
return Math.round(1E5 * val) / 1E5;
}
function pickEdges(range, size) {
var newRange = prettyRange(range, size);
var step = truncate((newRange[1] - newRange[0]) / size);
var edges = [];
var truncatedEnd = truncate(range[1]);
for (var i = 0; i <= size; i++) {
var prevEdge = truncate(newRange[0] + (step * (i - 1)));
var edge = truncate(prevEdge + step);
if (prevEdge <= truncatedEnd) {
edges.push(edge);
}
}
return {step: step, edges: edges, range: [edges[0], edges[edges.length - 1]]};
}
function findField(selection, data) {
if (selection.id == null) return null;
var fieldIds = data.fields.map(function (field) {return field.id;});
var column = fieldIds.indexOf(selection.id);
data.fields[column].column = column;
return data.fields[column];
}
function makeAxisIndexer (selection, data, numBins, catBins) {
var field = findField(selection, data);
var range = selection.range;
if (range == null) {
if (field.optype == "numeric") {
range = [field.minimum, field.maximum];
} else {
range = field.categories;
if (range.length > catBins) {
range = range.slice(0, catBins);
}
}
}
var axis;
if (field.optype == "numeric") {
axis = pickEdges(range, numBins);
axis.binCount = axis.edges.length - 1;
var edges = axis.edges;
var minRange = edges[0];
var maxRange = edges[edges.length - 1];
var step = axis.step;
axis.indexer = function (val) {
var index = -1;
if (val != null && val >= minRange && val <= maxRange) {
index = Math.floor(truncate((val - minRange) / step));
}
return index;
}
} else {
axis = {range: range, binCount: range.length};
var indexMap = field.categories.map(function (cat) { return range.indexOf(cat)});
axis.indexer = function (val) {
var index = -1;
if (val != null) {
index = indexMap[val];;
}
return index;
}
}
axis.optype = field.optype;
axis.column = field.column;
return axis;
}
function genHeatmap(data, xSelection, ySelection, cSelection, numBins, catBins) {
var colorField = findField(cSelection, data);
var xIndexInfo = makeAxisIndexer(xSelection, data, numBins, catBins);
var xNumeric = xIndexInfo.optype == "numeric";
var xIndexer = xIndexInfo.indexer;
var yIndexInfo = makeAxisIndexer(ySelection, data, numBins, catBins);
var yNumeric = yIndexInfo.optype == "numeric";
var yIndexer = yIndexInfo.indexer;
var counts = [];
for (var i = 0; i < xIndexInfo.binCount; i++) {
counts.push(new Int32Array(yIndexInfo.binCount));
}
var fullCatCounts = null;
var catCounts = null;
var sums = null;
var targetCat = null;
if (cSelection.targetCat != null) {
targetCat = colorField.categories.indexOf(cSelection.targetCat);
}
if (colorField != null) {
if (colorField.optype == "numeric") {
sums = [];
for (var i = 0; i < xIndexInfo.binCount; i++) {
sums.push(new Float64Array(yIndexInfo.binCount));
}
} else {
if (targetCat != null) {
catCounts = [];
for (var i = 0; i < xIndexInfo.binCount; i++) {
catCounts.push(new Int32Array(yIndexInfo.binCount));
}
} else {
var cats = colorField.categories.length;
fullCatCounts = [];
for (var i = 0; i < xIndexInfo.binCount; i++) {
var row = [];
for (var j = 0; j < yIndexInfo.binCount; j++) {
row.push(new Int32Array(cats));
}
fullCatCounts.push(row);
}
}
}
}
var xData = data.data[xIndexInfo.column];
var yData = data.data[yIndexInfo.column];
var cData = null;
if (colorField != null) {
cData = data.data[colorField.column];
}
var maxBinCount = 0;
var totalCount = 0;
var rowCounts = new Int32Array(xIndexInfo.binCount);
var colCounts = new Int32Array(yIndexInfo.binCount);
for (i in xData) {
var x = xIndexer(xData[i]);
var y = yIndexer(yData[i]);
if (x >= 0 && x < xIndexInfo.binCount && y >= 0 && y < yIndexInfo.binCount) {
if (cData != null && cData[i] == null) {
continue;
}
counts[x][y]++;
rowCounts[x]++;
colCounts[y]++;
totalCount++;
maxBinCount = Math.max(maxBinCount, counts[x][y]);
if (cData != null) {
if (sums != null && cData[i]) {
sums[x][y] += cData[i];
}
if (catCounts != null && cData[i] == targetCat) {
catCounts[x][y]++;
}
if (fullCatCounts != null) {
fullCatCounts[x][y][cData[i]]++;
}
}
}
}
var result = {x: xIndexInfo,
y: yIndexInfo,
c: colorField,
totalCount: totalCount,
counts: counts};
if (sums != null) {
result.sums = sums;
}
if (catCounts != null) {
result.catCounts = catCounts;
}
if (fullCatCounts != null) {
catCounts = [];
var mostCommon = [];
for (var x = 0; x < xIndexInfo.binCount; x++) {
mostCommon.push(new Int16Array(yIndexInfo.binCount));
catCounts.push(new Int32Array(yIndexInfo.binCount));
for (var y = 0; y < yIndexInfo.binCount; y++) {
var dist = fullCatCounts[x][y];
var maxCat = -1;
var maxCount = -1;
for (var z = 0; z < dist.length; z++) {
if (dist[z] > maxCount) {
maxCat = z;
maxCount = dist[z];
}
}
mostCommon[x][y] = maxCat;
catCounts[x][y] = maxCount;
}
}
result.catCounts = catCounts;
result.mostCommon = mostCommon;
}
return result;
}
function differenceSum(counts, xNumeric, yNumeric) {
var rows = counts.length;
var cols = counts[0].length;
var total = 0;
var diff = 0;
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
var pop = counts[i][j];
total += pop;
if (xNumeric) {
if (i < rows - 1) {
diff += Math.abs(pop - counts[i+1][j]);
} else {
diff += pop;
}
if (xNumeric && i > 0) {
diff += Math.abs(pop - counts[i-1][j]);
} else {
diff += pop;
}
}
if (yNumeric) {
if (j < cols - 1) {
diff += Math.abs(pop - counts[i][j+1]);
} else {
diff += pop;
}
if (j > 0) {
diff += Math.abs(pop - counts[i][j-1]);
} else {
diff += pop;
}
}
}
}
return diff / total;
}
function heatmap(data, xSelection, ySelection, cSelection, opts) {
var xNumeric = findField(xSelection, data).optype == "numeric";
var yNumeric = findField(ySelection, data).optype == "numeric";
if (opts.numBins != null || (!xNumeric && !yNumeric)) {
return genHeatmap(data, xSelection, ySelection, cSelection,
opts.numBins, opts.catBins);
} else {
var binCandidates;
if (xNumeric && yNumeric) {
binCandidates = [256, 128, 64, 32, 16, 8, 4];
} else {
binCandidates = [128, 64, 32, 16, 8, 4];
}
var minScore = null;
var bestResult = null;
for (i in binCandidates) {
var result = genHeatmap(data, xSelection, ySelection, cSelection,
binCandidates[i], opts.catBins);
var score = differenceSum(result.counts, xNumeric, yNumeric);
if (minScore == null || minScore >= score) {
minScore = score;
bestResult = result;
}
}
}
return bestResult;
}
function cartesianProduct() {
var args = [].slice.call(arguments);
var end = args.length - 1;
var result = [];
function addTo(curr, start) {
var first = args[start];
var last = (start === end);
for (var i = 0; i < first.length; ++i) {
var copy = curr.slice();
copy.push(first[i]);
if (last) {
result.push(copy);
} else {
addTo(copy, start + 1);
}
}
}
if (args.length) {
addTo([], 0);
} else {
result.push([]);
}
return result;
}
function range (v) {
return Array.apply(null, Array(v)).map(function (_, i) {return i;})
}
function binList (grid) {
return cartesianProduct(range(grid.x.binCount), range(grid.y.binCount));
}
</script>
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.domain {
stroke: none;
fill: none;
}
.field {
cursor: pointer;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.brush .extent {
stroke: #fff;
fill-opacity: .125;
shape-rendering: crispEdges;
}
svg {
-webkit-user-select: none; /* webkit (safari, chrome) browsers */
-moz-user-select: none; /* mozilla browsers */
-khtml-user-select: none; /* webkit (konqueror) browsers */
-ms-user-select: none; /* IE10+ */
}
#shading-slider {
width: 90px;
}
.selector {
margin-bottom: 15px;
}
#axis {
position:absolute;
}
#heatmap {
}
div#pdp {
float: left;
margin-right: 5px;
}
div#sidebar {
padding-top: 20px;
}
div.field-info {
margin-bottom: 10px;
}
div.field-name {
color: #999;
margin-right: 10px;
}
div.field-value {
}
</style>
<body oncontextmenu="return false;">
<div id="pdp"></div>
<div id="sidebar">
<form id="controls-form">
<div class="selector">
<div>X-Axis</div>
<select id="x-select"></select>
</div>
<div class="selector">
<div>Y-Axis</div>
<select id="y-select"></select>
</div>
<div class="selector">
<div>Color Field</div>
<select id="color-select"></select>
</div>
<div class="selector">
<div>Focus Category</div>
<select id="focus-select"></select>
</div>
<div class="selector">
<div>Density Shading</div>
<input id="shading-slider" type="range" min="0" max="1" step="0.1" value="0.5"/>
</div>
<div class="selector">
<div>Max Bins</div>
<select id="bins-select">
<option value="dynamic" selected>Dynamic</option>
<option value="256">256</option>
<option value="128">128</option>
<option value="64">64</option>
<option value="32"">32</option>
<option value="16">16</option>
<option value="8">8</option>
</select>
</div>
</form>
<div id="x-field" class="field-info">
<div id="x-name" class="field-name"></div>
<div id="x-value" class="field-value"></div>
</div>
<div id="y-field" class="field-info">
<div id="y-name" class="field-name"></div>
<div id="y-value" class="field-value"></div>
</div>
<div id="c-field" class="field-info">
<div id="c-name" class="field-name"></div>
<div id="c-value" class="field-value"></div>
</div>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="med-cover.js"></script>
<script src="data.js"></script>
<script src="grid.js"></script>
<script>
function toggle_option (selectId, index, disabled) {
document.getElementById(selectId)
.getElementsByTagName("option")[index].disabled = disabled;
}
function getParam(key) {
if(key=(new RegExp('[?&]'+encodeURIComponent(key)+'=([^&]*)'))
.exec(location.search))
return decodeURIComponent(key[1]);
}
function setParam(key, value) {
key = encodeURI(key); value = encodeURI(value);
var s = document.location.search;
var kvp = key+"="+value;
var r = new RegExp("(&|\\?)"+key+"=[^\&]*");
s = s.replace(r,"$1"+kvp);
if(!RegExp.$1) {s += (s.length>0 ? '&' : '?') + kvp;};
window.history.replaceState({}, "", s);
}
function removeParam(key) {
var sourceURL = document.location.search;
var rtn = sourceURL.split("?")[0],
param,
params_arr = [],
queryString = (sourceURL.indexOf("?") !== -1) ? sourceURL.split("?")[1] : "";
if (queryString !== "") {
params_arr = queryString.split("&");
for (var i = params_arr.length - 1; i >= 0; i -= 1) {
param = params_arr[i].split("=")[0];
if (param === key) {
params_arr.splice(i, 1);
}
}
rtn = rtn + "?" + params_arr.join("&");
}
window.history.replaceState({}, "", rtn);
}
var margin = {bottom: 40, left: 50, right: 20, top: 20};
var width = 640 - margin.left;
var height = 480 - margin.bottom;
var axisSVG = d3.select("#pdp").append("svg")
.attr("id", "axis")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var canvas = d3.select("#pdp").append("canvas")
.attr("id", "heatmap")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top);
var context = canvas.node().getContext("2d");
d3.json("cover-dataset.json", function(error, dataset) {
if ('dataset' in dataset) {
dataset = dataset.dataset;
}
var fields = dataset.fields;
if (!Array.isArray(fields)){
var fieldsArr = [];
for (fid in fields) {
var field = fields[fid];
field.id = fid;
fieldsArr.push(field);
}
fields = fieldsArr;
}
var maxNumBins = 128;
var maxCatBins = 16;
var x = getParam("x");
if (x == null) x = 0;
x = Number(x);
setParam("x", x);
var y = getParam("y");
if (y == null) y = 5;
y = Number(y);
setParam("y", y);
var c = getParam("c");
if (c == null) c = fields.length - 2;
c = Number(c);
setParam("c", c);
var targetFields = [fields[x], fields[y]];
var xSelection = {id: fields[x].id};
var ySelection = {id: fields[y].id};
var cSelection = {};
if (c >= 0) cSelection.id = fields[c].id;
var opts = {maxNumBins: maxNumBins, maxCatBins: maxCatBins};
var binCanvasHeight;
var binCanvasWidth;
var hm;
var colorSelector = d3.select("#color-select");
colorSelector.append("option").attr("value", "#noValue").text("None");
colorSelector.selectAll(".c-option")
.data(fields).enter()
.append("option")
.attr("class", "c-option")
.attr("value", function(d) {return d.id;})
.text(function(d) {return d.name;});
document.getElementById("color-select").selectedIndex = c + 1;
colorSelector.on("change",
function () {
c = this.selectedIndex - 1;
setParam("c", c);
updateColorSelector();
resetFocusSelector();
updateHeatMap();
updateColorFn();
redraw(true);
});
updateColorSelector();
var focusSelector = d3.select("#focus-select");
focusSelector.append("option").attr("value", "#noValue").text("Most common");
focusSelector.on("change",
function () {
if (this.selectedIndex > 0) {
cSelection.targetCat =
fields[c].summary.categories[this.selectedIndex - 1][0];
} else {
delete cSelection.targetCat;
}
setParam("focus", this.selectedIndex - 1);
updateHeatMap();
updateColorFn();
redraw(false);
});
updateFocusSelector();
var focusParam = getParam("focus");
if (focusParam == null) {
focusParam = -1;
}
focusParam = Number(focusParam);
document.getElementById("focus-select").selectedIndex = focusParam + 1;
if (focusParam >= 0) {
cSelection.targetCat = fields[c].summary.categories[focusParam][0];
}
var binsIndex = getParam("bins");
var binSelect = document.getElementById("bins-select");
if (binsIndex == null) binsIndex = 0;
binsIndex = Number(binsIndex);
binSelect.selectedIndex = binsIndex;
if (binsIndex > 0) {
opts.numBins = Number(binSelect.options[binsIndex].value);
}
d3.select("#bins-select")
.on("change",
function () {
if (this.value == "dynamic") {
delete opts.numBins;
} else {
opts.numBins = this.value;
}
setParam("bins", this.selectedIndex);
updateHeatMap();
updateColorFn();
redraw(true);
});
updateHeatMap();
updateColorFn();
d3.select("#x-name").text(fields[x].name);
d3.select("#x-value").text("-");
d3.select("#y-name").text(fields[y].name);
d3.select("#y-value").text("-");
d3.select("#c-name").text("Total Count");
d3.select("#objective-value").text("-");
var xSelector = d3.select("#x-select");
xSelector.selectAll(".x-option")
.data(fields).enter()
.append("option")
.attr("class", "x-option")
.attr("value", function(d) {return d.id;})
.text(function(d) {return d.name;});
document.getElementById("x-select").selectedIndex = x;
toggle_option("x-select", y, true);
xSelector.on("change",
function () {
var oldX = x;
var newX = this.selectedIndex;
toggle_option("y-select", oldX, false);
toggle_option("y-select", newX, true);
document.getElementById("y-select")
.getElementsByTagName("option")[newX].disabled = true;
x = newX;
setParam("x", x);
d3.select("#x-name").text(fields[x].name);
targetFields[0] = fields[x];
xSelection = {id: fields[x].id};
delete ySelection.range;
updateHeatMap();
redraw(true);
});
var ySelector = d3.select("#y-select");
ySelector.selectAll(".y-option")
.data(fields).enter()
.append("option")
.attr("class", "y-option")
.attr("value", function(d) {return d.id;})
.text(function(d) {return d.name;});
document.getElementById("y-select").selectedIndex = y;
toggle_option("y-select", x, true);
ySelector.on("change",
function () {
var oldY = y;
var newY = this.selectedIndex;
toggle_option("x-select", oldY, false);
toggle_option("x-select", newY, true);
document.getElementById("x-select")
.getElementsByTagName("option")[newY].disabled = true;
y = newY;
setParam("y", y);
d3.select("#y-name").text(fields[y].name);
targetFields[1] = fields[y];
ySelection = {id: fields[y].id};
delete xSelection.range;
updateHeatMap();
redraw(true);
});
var shading = getParam("shading");
if (shading == null) {
shading = 3;
}
shading = Number(shading) / 10;
document.getElementById("shading-slider").value = shading;
d3.select("#shading-slider")
.on("input",
function () {
shading = this.value;
setParam("shading", shading * 10);
updateDensityFn();
updateCells();
});
var brushX = d3.scale.identity().domain([0, width]);
var brushY = d3.scale.identity().domain([0, height]);
function brushed() {
brushExtent = brush.extent();
}
function sortNumber(a,b) {
return a - b;
}
function findRange(axis, canvasRange, scale, isX) {
var newRange = [];
if (axis.optype == "numeric") {
newRange.push(scale.invert(canvasRange[0]));
newRange.push(scale.invert(canvasRange[1]));
newRange.sort(sortNumber);
} else {
var tempRange = [];
if (isX) {
tempRange.push(Math.floor(canvasRange[0] / binCanvasWidth));
tempRange.push(Math.floor(canvasRange[1] / binCanvasWidth));
} else {
tempRange.push(Math.floor((height - canvasRange[0]) / binCanvasHeight));
tempRange.push(Math.floor((height - canvasRange[1]) / binCanvasHeight));
}
tempRange.sort(sortNumber);
newRange = axis.range.slice(tempRange[0], tempRange[1] + 1);
}
return newRange;
}
function brushended() {
if (!d3.event.sourceEvent) return; // only transition after input
var canvasX = [brushExtent[0][0], brushExtent[1][0]];
var canvasY = [brushExtent[0][1], brushExtent[1][1]];
if (canvasX[0] == canvasX[1] || canvasY[0] == canvasY[1]) {
delete xSelection.range;
delete ySelection.range;
} else {
xSelection.range = findRange(hm.x, canvasX, xScale, true);
ySelection.range = findRange(hm.y, canvasY, yScale, false);
}
d3.select(this).call(brush.extent([[0, 0], [0, 0]]));
updateHeatMap();
updateColorFn();
redraw(true);
}
var gx, gy;
var xAxis, yAxis;
var xScale;
var yScale;
var predictor;
var densityFn;
var pMin, pMax;
makeAxis();
updateColorSelector();
redraw(true);
var brushExtent;
var brush = d3.svg.brush()
.x(brushX)
.y(brushY)
.on("brush", brushed)
.on("brushend", brushended);
axisSVG.append("g")
.attr("class", "brush")
.on("mousemove",
function(d) {
var coords = d3.mouse(this);
var inputs = [];
var gridIndex = coordsToGridIndex(coords);
var gx = gridIndex[0];
var gy = gridIndex[1];
if (hm.x.optype == "numeric") {
inputs.push(xScale.invert(coords[0]));
} else {
inputs.push(hm.x.range[gx]);
}
if (hm.y.optype == "numeric") {
inputs.push(yScale.invert(coords[1]));
} else {
inputs.push(hm.y.range[gy]);
}
var output;
var xOut;
var yOut;
if (gx < hm.x.binCount && gy < hm.y.binCount) {
if (c < 0) {
output = prettyVal(hm.counts[gx][gy]);
} else {
if (fields[c].optype == "numeric") {
var sum = hm.sums[gx][gy];
var pop = hm.counts[gx][gy];
if (pop == 0) {
output = "No data";
} else {
output = prettyVal(sum / pop) + " (" + pop + " points)";
}
} else {
var cat;
if (cSelection.targetCat == null) {
cat = hm.c.categories[hm.mostCommon[gx][gy]];
} else {
cat = cSelection.targetCat;
}
var total = hm.counts[gx][gy];
if (total > 0) {
var catCount = hm.catCounts[gx][gy];
if (catCount == 0) {
cat = "---";
}
output = cat + " (" + catCount + " of " + total + ")";
} else {
output = "No data";
}
}
}
xOut = binText(inputs[0], hm.x);
yOut = binText(inputs[1], hm.y);
} else {
output = "-";
xOut = "-";
yOut = "-";
}
d3.select("#x-value").text(prettyVal(xOut));
d3.select("#y-value").text(prettyVal(yOut));
d3.select("#c-value").text(output);
})
.on("mouseout", function(d) {
d3.select("#x-value").text("-");
d3.select("#y-value").text("-");
d3.select("#c-value").text("-");
})
.call(brush)
.call(brush.event);
function updateColorSelector() {
if (c >= 0) {
var text = fields[c].name;
if (fields[c].optype == "numeric") {
text += " (mean)";
}
d3.select("#c-name").text(text);
cSelection = {id: fields[c].id};
} else {
d3.select("#c-name").text("Total Count");
cSelection = {};
}
}
function resetFocusSelector() {
updateFocusSelector();
document.getElementById("focus-select").selectedIndex = 0;
setParam("focus", -1);
}
function updateFocusSelector() {
if (c >= 0 && fields[c].optype == "categorical") {
var categories = fields[c].summary.categories.map(function (d) {return d[0];});
focusSelector.selectAll(".f-option").remove();
focusSelector.selectAll(".f-option")
.data(categories).enter()
.append("option")
.attr("class", "f-option")
.attr("value", function(d) {return categories.indexOf(d);})
.text(function(d) {return d});
document.getElementById("focus-select").disabled = false;
} else {
focusSelector.selectAll(".f-option").remove();
document.getElementById("focus-select").disabled = true;
}
}
function binText(val, axis) {
if (axis.optype == "numeric") {
var index = axis.indexer(val);
var edges = axis.edges;
return edges[index] + " to " + edges[index + 1];
} else {
return val;
}
}
function updateDensityMax() {
pMax = -1E20;
var counts;
if (cSelection.targetCat == null) {
counts = hm.counts;
} else {
counts = hm.catCounts;
}
var binIds = binList(hm);
for (var i = 0; i < binIds.length; i++) {
var p = counts[binIds[i][0]][binIds[i][1]];
pMax = Math.max(pMax, p);
}
}
function updateDensityFn() {
var densityScale;
if (shading == 0) {
densityScale = function (d) {return 1};
} else {
densityScale = d3.scale.pow().exponent(shading).domain([0, pMax]);
}
if (cSelection.targetCat == null) {
counts = hm.counts;
} else {
counts = hm.catCounts;
}
densityFn = function (d) {
return densityScale(counts[d[0]][d[1]]);
};
}
var colorFn;
function updateColorFn() {
if (c < 0) {
var white = d3.rgb("#fff");
colorFn = function (d) {return white};
} else if (fields[c].optype == "categorical") {
var catColors;
if (hm.c.categories.length > 10) {
catColors = d3.scale.category20();
} else {
catColors = d3.scale.category10();
}
catColors.domain(hm.c.categories);
colorFn = function (d) {
var cat;
if (hm.catCounts[d[0]][d[1]] == 0) {
return d3.rgb("#000");
} else if (cSelection.targetCat == null) {
cat = hm.c.categories[hm.mostCommon[d[0]][d[1]]]
} else {
cat = cSelection.targetCat;
}
return catColors(cat);
};
} else {
var meanMin = 1E20;
var meanMax = -1E20;
var binIds = binList(hm);
for (var i = 0; i < binIds.length; i++) {
var sum = hm.sums[binIds[i][0]][binIds[i][1]];
var pop = hm.counts[binIds[i][0]][binIds[i][1]];
if (pop > 0) {
var mean = sum / pop;
meanMin = Math.min(meanMin, mean);
meanMax = Math.max(meanMax, mean);
}
}
var numColors = d3.scale.linear().domain([meanMin, meanMax]);
numColors = numColors.range(["#11f", "#f11"]);
var black = d3.rgb("#000");
colorFn = function (d) {
var sum = hm.sums[d[0]][d[1]];
var pop = hm.counts[d[0]][d[1]];
if (pop > 0) {
return numColors(sum / pop);
} else {
return black;
}
};
}
}
function redraw(redrawAxis) {
updateDensityMax();
updateDensityFn();
if (redrawAxis) {
updateScales();
updateAxis();
}
updateCells();
}
function makeAxis() {
gy = axisSVG.append("g").attr("class", "y-axis");
gx = axisSVG.append("g")
.attr("class", "x-axis")
.attr("transform", "translate(" + 0 + "," + height + ")");
}
function updateAxis() {
var currentY = gy.transition().duration(700).call(yAxis);
if (targetFields[1].optype == "categorical") {
currentY.selectAll("text")
.attr("y", (binCanvasHeight / 2) - 10)
.attr("x", 4)
.style("fill", "#fff")
.style("stroke", "#000")
.style("stroke-width", 0.3)
.style("font-size", "13")
.style("font-weight", "bolder")
.style("font-family", "Monospace")
.style("stroke-linecap", "butt")
.style("stroke-linejoin", "miter")
.style("text-anchor", "start");
}
var currentX = gx.transition().duration(700).call(xAxis);
if (targetFields[0].optype == "categorical") {
currentX.selectAll("text")
.attr("y", (binCanvasWidth / 2) - 15)
.attr("x", 4)
.attr("transform", "rotate(-90)")
.style("fill", "#fff")
.style("stroke", "#000")
.style("stroke-width", 0.3)
.style("font-size", "13")
.style("font-weight", "bolder")
.style("font-family", "Monospace")
.style("stroke-linecap", "butt")
.style("stroke-linejoin", "miter")
.style("text-anchor", "start");
}
}
function customAxisFormat(d) {
return d3.format("s")(Math.round(d * 1E4) / 1E4);
}
function updateScales () {
if (targetFields[0].optype == "numeric") {
xScale = d3.scale.linear()
.range([0, width])
.domain([hm.x.range[0],
hm.x.range[1]]);
} else {
xScale = d3.scale.ordinal()
.domain(hm.x.range)
.rangePoints([0, width], 1);
}
if (targetFields[1].optype == "numeric") {
yScale = d3.scale.linear()
.range([height, 0])
.domain([hm.y.range[0],
hm.y.range[1]]);
} else {
yScale = d3.scale.ordinal()
.domain(hm.y.range)
.rangePoints([height, 0], 1);
}
xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
if (targetFields[0].optype == "numeric") {
xAxis.tickFormat(customAxisFormat);
}
if (targetFields[1].optype == "numeric") {
yAxis.tickFormat(customAxisFormat);
}
}
function prettyVal(d) {
if (typeof d === 'string' || d instanceof String) {
return d;
} else {
return d = Math.round(d * 1000) / 1000;
}
}
function densityColorShift(color, loc) {
var density = densityFn(loc);
color = d3.rgb(color);
color.r = Math.round(color.r * density);
color.g = Math.round(color.g * density);
color.b = Math.round(color.b * density);
return color;
}
function updateCells() {
var cxFn = canvasXFn();
var cyFn = canvasYFn();
var maxBins = Math.max(hm.x.binCount, hm.y.binCount);
var alpha = Math.pow(Math.max((220 - maxBins), 0) / 256, 2);
var lineColor = "rgba(0, 0, 0, " + alpha + ")";
context.strokeStyle=lineColor;
binList(hm).forEach(function(d, i) {
context.beginPath();
context.rect(cxFn(d) + margin.left,
cyFn(d) + margin.top,
binCanvasWidth + 1,
binCanvasHeight + 1);
context.fillStyle=densityColorShift(colorFn(d), d);
context.fill();
/* context.stroke(); */
context.closePath();
});
}
function updateHeatMap() {
hm = heatmap(data, xSelection, ySelection, cSelection, opts);
binCanvasWidth = width / hm.x.binCount;
binCanvasHeight = height / hm.y.binCount;
}
function coordsToGridIndex (coords) {
var x = Math.floor(coords[0] / binCanvasWidth);
var y = Math.floor((height - coords[1]) / binCanvasHeight);
return [x, y];
}
function canvasXFn () {
return function(binId) {return binId[0] * binCanvasWidth};
}
function canvasYFn () {
return function(binId) {
return height - binCanvasHeight - (binId[1] * binCanvasHeight)
};
}
});
</script>
</body>
This file has been truncated, but you can view the full file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment