Skip to content

Instantly share code, notes, and snippets.

@gorhill
Last active May 6, 2019 09:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gorhill/5379768 to your computer and use it in GitHub Desktop.
Save gorhill/5379768 to your computer and use it in GitHub Desktop.
Bar chart experiment for Wikileaks PlusD timeline graph. Uses jQuery, d3. See in action at http://jsfiddle.net/khnxZ/#. Tested on linux Chromium & Firefox. Performance wise, Chromium does better than Firefox. Feel free to use/modify as you wish.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Bar chart experiment for WL_+D</title>
<script src="jquery.min.js"></script>
<script src="d3.v3.min.js"></script>
<style>
/* Nice, we can use CSS to configure appearance */
.d3BarChart {
border: 1px solid #ccc;
padding: 0;
min-height: 16em;
font: 0.8em sans-serif;
}
.d3BarChart svg {
width: 100%;
}
.d3BarChart .perimeter {
stroke: red;
stroke-width: 1px;
fill: transparent;
}
.d3BarChart .axis path,
.d3BarChart .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.d3BarChart .x.axis path {
stroke: #000;
}
.d3BarChart .x.axis text {
fill: black;
font-size: 0.85em;
}
.d3BarChart .plotArea .bar rect {
fill: transparent;
stroke: none;
}
.d3BarChart .plotArea .bar:hover rect {
fill: red;
stroke: none;
stroke-width: 1px;
opacity: 0.3;
}
.d3BarChart .plotArea .bar text {
fill: black;
text-anchor: start;
visibility: hidden;
}
.d3BarChart .plotArea .bar text tspan {
font-weight: bold;
}
.d3BarChart .plotArea .bar:hover text {
visibility: visible;
}
.d3BarChart .plotArea .chartArea {
fill: lightskyblue;
stroke: none;
}
.d3BarChart .plotArea .chartLine {
fill: none;
stroke: black;
stroke-width: 0.5px;
}
}
</style>
</head>
<body>
<div class="d3BarChart"></div>
<script>
$(function(){
// Typical JSON data
var jsonTypicalSet1 = {
"unit": "month",
"tkey_from": 19660000,
"tkey_to": 20101200,
"month": {
"20100200": 4874,
"20100100": 4131,
"20091200": 5003,
"20091100": 4869,
"20091000": 4650,
"20090900": 4698,
"20090800": 3978,
"20090700": 4406,
"20090600": 5276,
"20090500": 4306,
"20090400": 5137,
"20090300": 5434,
"20090200": 4736,
"20090100": 4320,
"20081200": 4829,
"20081100": 4312,
"20081000": 4237,
"20080900": 4095,
"20080800": 3575,
"20080700": 4220,
"20080600": 3963,
"20080500": 4220,
"20080400": 4055,
"20080300": 4179,
"20080200": 4234,
"20080100": 3527,
"20071200": 3619,
"20071100": 4254,
"20071000": 4039,
"20070900": 3298,
"20070800": 3489,
"20070700": 3362,
"20070600": 3534,
"20070500": 4043,
"20070400": 3667,
"20070300": 4221,
"20070200": 3710,
"20070100": 3457,
"20061200": 3633,
"20061100": 3893,
"20061000": 3544,
"20060900": 3370,
"20060800": 3655,
"20060700": 3234,
"20060600": 3869,
"20060500": 3794,
"20060400": 3331,
"20060300": 4308,
"20060200": 3368,
"20060100": 2392,
"20051200": 2469,
"20051100": 2322,
"20051000": 2377,
"20050900": 2195,
"20050800": 1893,
"20050700": 1995,
"20050600": 2174,
"20050500": 1724,
"20050400": 1919,
"20050300": 2057,
"20050200": 1616,
"20050100": 1390,
"20041200": 1356,
"20041100": 1222,
"20041000": 1073,
"20040900": 908,
"20040800": 934,
"20040700": 1032,
"20040600": 914,
"20040500": 840,
"20040400": 970,
"20040300": 1166,
"20040200": 735,
"20040100": 658,
"20031200": 559,
"20031100": 620,
"20031000": 728,
"20030900": 680,
"20030800": 587,
"20030700": 750,
"20030600": 686,
"20030500": 631,
"20030400": 769,
"20030300": 951,
"20030200": 592,
"20030100": 530,
"20021200": 363,
"20021100": 404,
"20021000": 304,
"20020900": 230,
"20020800": 203,
"20020700": 193,
"20020600": 160,
"20020500": 219,
"20020400": 141,
"20020300": 164,
"20020200": 98,
"20020100": 91,
"20011200": 99,
"20011100": 124,
"20011000": 98,
"20010900": 100,
"20010800": 97,
"20010700": 39,
"20010600": 62,
"20010500": 66,
"20010400": 45,
"20010300": 66,
"20010200": 45,
"20010100": 37,
"20001200": 90,
"20001100": 49,
"20001000": 28,
"20000900": 37,
"20000800": 29,
"20000700": 37,
"20000600": 106,
"20000500": 16,
"20000400": 40,
"19991200": 11,
"19991100": 9,
"19991000": 5,
"19990900": 5,
"19990800": 2,
"19990700": 4,
"19990600": 1,
"19990500": 2,
"19990400": 1,
"19990300": 5,
"19990200": 5,
"19990100": 6,
"19981200": 10,
"19981100": 5,
"19981000": 5,
"19980900": 4,
"19980800": 11,
"19980700": 1,
"19980600": 1,
"19980500": 12,
"19980400": 4,
"19980300": 5,
"19980200": 4,
"19971200": 5,
"19971100": 8,
"19971000": 2,
"19970900": 8,
"19970800": 4,
"19970700": 5,
"19970600": 3,
"19970500": 8,
"19970400": 4,
"19970300": 3,
"19970200": 4,
"19970100": 4,
"19961200": 1,
"19961100": 10,
"19961000": 5,
"19960900": 9,
"19960800": 2,
"19960700": 3,
"19960600": 5,
"19960500": 2,
"19960400": 5,
"19960300": 3,
"19960200": 1,
"19960100": 2,
"19951200": 11,
"19951100": 18,
"19951000": 12,
"19950900": 6,
"19950800": 7,
"19950700": 10,
"19950600": 9,
"19950500": 15,
"19950400": 5,
"19950300": 5,
"19950200": 5,
"19950100": 6,
"19941200": 10,
"19941100": 13,
"19941000": 2,
"19940900": 5,
"19940800": 5,
"19940700": 3,
"19940600": 3,
"19940500": 3,
"19940400": 9,
"19940300": 13,
"19940200": 7,
"19940100": 8,
"19931200": 4,
"19931100": 5,
"19931000": 2,
"19930900": 1,
"19930800": 1,
"19930700": 3,
"19930600": 4,
"19930500": 1,
"19930400": 2,
"19930300": 3,
"19930200": 1,
"19930100": 4,
"19921200": 23,
"19921100": 20,
"19921000": 7,
"19920900": 6,
"19920800": 3,
"19920700": 7,
"19920600": 6,
"19920500": 6,
"19920400": 8,
"19920300": 8,
"19920200": 3,
"19920100": 6,
"19911200": 3,
"19911100": 13,
"19911000": 2,
"19910900": 2,
"19910800": 5,
"19910700": 4,
"19910600": 2,
"19910500": 6,
"19910400": 4,
"19910300": 3,
"19910200": 5,
"19910100": 3,
"19901200": 10,
"19901100": 18,
"19901000": 6,
"19900900": 1,
"19900800": 25,
"19900700": 9,
"19900600": 5,
"19900500": 5,
"19900400": 4,
"19900300": 6,
"19900200": 14,
"19900100": 3,
"19891200": 20,
"19891100": 9,
"19891000": 5,
"19890900": 4,
"19890800": 2,
"19890700": 5,
"19890600": 10,
"19890500": 4,
"19890400": 6,
"19890300": 4,
"19890200": 1,
"19890100": 4,
"19881200": 12,
"19881100": 5,
"19881000": 2,
"19880900": 8,
"19880800": 10,
"19880700": 3,
"19880500": 3,
"19880400": 4,
"19880300": 20,
"19880200": 4,
"19880100": 2,
"19871200": 2,
"19871100": 3,
"19871000": 6,
"19870900": 2,
"19870800": 2,
"19870700": 5,
"19870600": 4,
"19870500": 1,
"19870400": 3,
"19870300": 2,
"19870200": 4,
"19870100": 1,
"19861200": 5,
"19861100": 4,
"19861000": 1,
"19860900": 4,
"19860800": 1,
"19860700": 7,
"19860600": 2,
"19860500": 4,
"19860400": 5,
"19860300": 5,
"19860200": 2,
"19860100": 5,
"19851200": 7,
"19851100": 2,
"19851000": 5,
"19850900": 1,
"19850800": 1,
"19850700": 9,
"19850600": 15,
"19850500": 5,
"19850400": 10,
"19850300": 15,
"19850200": 10,
"19850100": 7,
"19791000": 2,
"19790900": 2,
"19790800": 1,
"19780500": 1,
"19780100": 1,
"19761200": 35817,
"19761100": 44075,
"19761000": 42496,
"19760900": 46818,
"19760800": 45065,
"19760700": 47076,
"19760600": 50552,
"19760500": 48975,
"19760400": 52484,
"19760300": 52149,
"19760200": 45414,
"19760100": 43932,
"19751200": 42240,
"19751100": 42914,
"19751000": 47991,
"19750900": 45232,
"19750800": 44317,
"19750700": 46202,
"19750600": 44885,
"19750500": 44975,
"19750400": 47047,
"19750300": 45291,
"19750200": 40164,
"19750100": 39847,
"19741200": 31321,
"19741100": 37315,
"19741000": 38812,
"19740900": 36455,
"19740800": 37759,
"19740700": 38548,
"19740600": 37119,
"19740500": 40068,
"19740400": 38807,
"19740300": 38315,
"19740200": 33075,
"19740100": 34697,
"19731200": 19134,
"19731100": 24000,
"19731000": 23487,
"19730900": 21854,
"19730800": 23725,
"19730700": 21715,
"19730600": 8302,
"19730500": 12134,
"19730400": 13782,
"19730300": 11018,
"19730200": 22,
"19730100": 83,
"19720800": 2,
"19720300": 1,
"19720200": 1,
"19661200": 1
},
"min": 1,
"max": 52484,
"error": "",
"exec_time": 0.20492005348206
};
var jsonTypicalSet2 = {
"unit": "day",
"tkey_from": 19750100,
"tkey_to": 19751130,
"day": {
"19751130": 120,
"19751129": 434,
"19751128": 1908,
"19751127": 393,
"19751126": 2324,
"19751125": 2126,
"19751124": 1612,
"19751123": 103,
"19751122": 567,
"19751121": 2206,
"19751120": 2006,
"19751119": 2098,
"19751118": 2016,
"19751117": 1772,
"19751116": 122,
"19751115": 648,
"19751114": 2493,
"19751113": 2090,
"19751112": 2266,
"19751111": 2131,
"19751110": 1740,
"19751109": 111,
"19751108": 545,
"19751107": 2251,
"19751106": 2039,
"19751105": 2213,
"19751104": 2119,
"19751103": 1768,
"19751102": 156,
"19751101": 537,
"19751031": 2274,
"19751030": 2149,
"19751029": 2251,
"19751028": 1801,
"19751027": 237,
"19751026": 111,
"19751025": 617,
"19751024": 2496,
"19751023": 2160,
"19751022": 2063,
"19751021": 2321,
"19751020": 1798,
"19751019": 185,
"19751018": 584,
"19751017": 2360,
"19751016": 2039,
"19751015": 2111,
"19751014": 1854,
"19751013": 256,
"19751012": 162,
"19751011": 572,
"19751010": 2342,
"19751009": 2088,
"19751008": 2115,
"19751007": 2080,
"19751006": 1743,
"19751005": 119,
"19751004": 489,
"19751003": 2378,
"19751002": 2062,
"19751001": 2174,
"19750930": 2013,
"19750929": 1792,
"19750928": 96,
"19750927": 360,
"19750926": 2157,
"19750925": 2013,
"19750924": 1901,
"19750923": 2002,
"19750922": 1766,
"19750921": 118,
"19750920": 522,
"19750919": 2178,
"19750918": 2144,
"19750917": 1934,
"19750916": 2078,
"19750915": 1740,
"19750914": 110,
"19750913": 555,
"19750912": 2336,
"19750911": 2102,
"19750910": 2058,
"19750909": 1979,
"19750908": 1892,
"19750907": 97,
"19750906": 401,
"19750905": 2318,
"19750904": 2087,
"19750903": 2214,
"19750902": 1750,
"19750901": 519,
"19750831": 180,
"19750830": 429,
"19750829": 2056,
"19750828": 2053,
"19750827": 2055,
"19750826": 2154,
"19750825": 1679,
"19750824": 129,
"19750823": 520,
"19750822": 2151,
"19750821": 2012,
"19750820": 2109,
"19750819": 2014,
"19750818": 1817,
"19750817": 122,
"19750816": 442,
"19750815": 1885,
"19750814": 2032,
"19750813": 1759,
"19750812": 2053,
"19750811": 1762,
"19750810": 99,
"19750809": 459,
"19750808": 2187,
"19750807": 1859,
"19750806": 1926,
"19750805": 1938,
"19750804": 1690,
"19750803": 123,
"19750802": 386,
"19750801": 2237,
"19750731": 2237,
"19750730": 2104,
"19750729": 2114,
"19750728": 1661,
"19750727": 139,
"19750726": 492,
"19750725": 2201,
"19750724": 1906,
"19750723": 1942,
"19750722": 2055,
"19750721": 1558,
"19750720": 121,
"19750719": 421,
"19750718": 2119,
"19750717": 1984,
"19750716": 2077,
"19750715": 1926,
"19750714": 1594,
"19750713": 88,
"19750712": 605,
"19750711": 2257,
"19750710": 2134,
"19750709": 1735,
"19750708": 2025,
"19750707": 1587,
"19750706": 139,
"19750705": 300,
"19750704": 367,
"19750703": 2627,
"19750702": 1899,
"19750701": 1788,
"19750630": 1807,
"19750629": 139,
"19750628": 758,
"19750627": 2098,
"19750626": 1913,
"19750625": 2022,
"19750624": 1839,
"19750623": 1756,
"19750622": 101,
"19750621": 463,
"19750620": 2331,
"19750619": 2024,
"19750618": 1970,
"19750617": 2109,
"19750616": 1991,
"19750615": 127,
"19750614": 436,
"19750613": 2271,
"19750612": 2123,
"19750611": 2121,
"19750610": 1805,
"19750609": 1835,
"19750608": 146,
"19750607": 531,
"19750606": 2142,
"19750605": 1880,
"19750604": 2105,
"19750603": 2175,
"19750602": 1683,
"19750601": 184,
"19750531": 558,
"19750530": 2220,
"19750529": 1908,
"19750528": 2029,
"19750527": 1665,
"19750526": 201,
"19750525": 218,
"19750524": 618,
"19750523": 2248,
"19750522": 2025,
"19750521": 2094,
"19750520": 2089,
"19750519": 1611,
"19750518": 146,
"19750517": 496,
"19750516": 2360,
"19750515": 2067,
"19750514": 2122,
"19750513": 1967,
"19750512": 1782,
"19750511": 132,
"19750510": 477,
"19750509": 2182,
"19750508": 1673,
"19750507": 2137,
"19750506": 2025,
"19750505": 1699,
"19750504": 134,
"19750503": 499,
"19750502": 2059,
"19750501": 1534,
"19750430": 1993,
"19750429": 1990,
"19750428": 2057,
"19750427": 148,
"19750426": 403,
"19750425": 2300,
"19750424": 2027,
"19750423": 2101,
"19750422": 2025,
"19750421": 1807,
"19750420": 126,
"19750419": 489,
"19750418": 2319,
"19750417": 1898,
"19750416": 2110,
"19750415": 2002,
"19750414": 1802,
"19750413": 153,
"19750412": 411,
"19750411": 2097,
"19750410": 2115,
"19750409": 2064,
"19750408": 2033,
"19750407": 1774,
"19750406": 157,
"19750405": 462,
"19750404": 2391,
"19750403": 1958,
"19750402": 2048,
"19750401": 1787,
"19750331": 1448,
"19750330": 108,
"19750329": 384,
"19750328": 1555,
"19750327": 1997,
"19750326": 2050,
"19750325": 2120,
"19750324": 1894,
"19750323": 208,
"19750322": 551,
"19750321": 2138,
"19750320": 2150,
"19750319": 1944,
"19750318": 1997,
"19750317": 1755,
"19750316": 166,
"19750315": 578,
"19750314": 2273,
"19750313": 2141,
"19750312": 2134,
"19750311": 2055,
"19750310": 1804,
"19750309": 210,
"19750308": 671,
"19750307": 2127,
"19750306": 2098,
"19750305": 1990,
"19750304": 2294,
"19750303": 1786,
"19750302": 174,
"19750301": 491,
"19750228": 2189,
"19750227": 2020,
"19750226": 1962,
"19750225": 1911,
"19750224": 1769,
"19750223": 110,
"19750222": 372,
"19750221": 2121,
"19750220": 1979,
"19750219": 2006,
"19750218": 1683,
"19750217": 284,
"19750216": 148,
"19750215": 695,
"19750214": 2282,
"19750213": 2142,
"19750212": 1951,
"19750211": 1869,
"19750210": 1681,
"19750209": 154,
"19750208": 481,
"19750207": 2142,
"19750206": 1981,
"19750205": 1856,
"19750204": 2102,
"19750203": 1649,
"19750202": 140,
"19750201": 485,
"19750131": 2110,
"19750130": 1886,
"19750129": 1921,
"19750128": 1872,
"19750127": 1575,
"19750126": 118,
"19750125": 463,
"19750124": 1971,
"19750123": 1722,
"19750122": 1817,
"19750121": 1739,
"19750120": 1606,
"19750119": 154,
"19750118": 478,
"19750117": 1933,
"19750116": 1851,
"19750115": 1738,
"19750114": 1681,
"19750113": 1530,
"19750112": 132,
"19750111": 413,
"19750110": 1996,
"19750109": 1673,
"19750108": 1655,
"19750107": 1579,
"19750106": 1231,
"19750105": 141,
"19750104": 265,
"19750103": 1448,
"19750102": 1012,
"19750101": 137
},
"min": 88,
"max": 2627,
"error": "",
"exec_time": 0.022441148757935
};
var jsonTypicalSet3 = {
"unit": "day",
"tkey_from": 20051201,
"tkey_to": 20051231,
"day": {
"20051231": 10,
"20051230": 83,
"20051229": 77,
"20051228": 99,
"20051227": 72,
"20051226": 15,
"20051224": 7,
"20051223": 86,
"20051222": 119,
"20051221": 116,
"20051220": 133,
"20051219": 109,
"20051218": 33,
"20051217": 14,
"20051216": 146,
"20051215": 125,
"20051214": 162,
"20051213": 140,
"20051212": 119,
"20051211": 24,
"20051210": 25,
"20051209": 120,
"20051208": 120,
"20051207": 108,
"20051206": 91,
"20051205": 89,
"20051204": 13,
"20051203": 7,
"20051202": 98,
"20051201": 109
},
"min": 7,
"max": 162,
"error": "",
"exec_time": 0.0030479431152344
};
var jsonTypicalSet4 = {
"unit": "month",
"tkey_from": 19660000,
"tkey_to": 20101200,
"month": {
"20100200": 3,
"20100100": 5,
"20091200": 1,
"20091100": 7,
"20091000": 3,
"20090900": 3,
"20090800": 2,
"20090700": 5,
"20090600": 2,
"20090500": 5,
"20090400": 1,
"20090300": 4,
"20090200": 5,
"20090100": 6,
"20081200": 2,
"20081100": 4,
"20081000": 1,
"20080900": 11,
"20080800": 6,
"20080700": 4,
"20080600": 2,
"20080500": 7,
"20080400": 3,
"20080300": 7,
"20080200": 3,
"20080100": 4,
"20071200": 1,
"20071100": 6,
"20071000": 4,
"20070900": 3,
"20070800": 3,
"20070700": 3,
"20070600": 2,
"20070500": 4,
"20070400": 2,
"20070300": 12,
"20070200": 4,
"20070100": 9,
"20061200": 4,
"20061100": 3,
"20061000": 8,
"20060900": 4,
"20060800": 8,
"20060700": 1,
"20060600": 2,
"20060500": 2,
"20060400": 2,
"20060300": 3,
"20060200": 6,
"20060100": 1,
"20051100": 1,
"20050700": 1,
"20050400": 1,
"20050300": 3,
"20050200": 1,
"20050100": 3,
"20041200": 2,
"20041100": 1,
"20040900": 1,
"20040800": 3,
"20040700": 1,
"20040500": 1,
"20040400": 1,
"20040100": 1,
"19760900": 1
},
"min": 1,
"max": 12,
"error": "",
"exec_time": 0.0022180080413818
}
var testingSet = jsonTypicalSet1;
// Helper function to create composite nodes
var embedNewSVG = function(o, where) {
if (!o) {
return null;
}
// result to return
// TODO: is it worth?
var r = {};
// create node
var e;
// DOM node
if (o.text) {
e = document.createTextNode(o.text);
r.text = e;
}
else if (o.name) {
var name = d3.ns.qualify(o.name);
if (name.space) {
e = document.createElementNS(name.space, name.local);
}
else {
e = document.createElementNS(this.namespaceURI, name);
}
r[o.name] = e;
}
if (!e) {
return null;
}
// attributes
for (var k in o) {
if (!o.hasOwnProperty(k)) {
continue;
}
if (k === "name" || k === "text" || k === "children") {
continue;
}
e.setAttribute(k, o[k]);
}
// child elements
var cs = o.children;
if (cs) {
r.children = [];
var n = cs.length;
for (var i=0; i<n; i++) {
r.children.push(embedNewSVG.call(e, cs[i]));
}
}
// embed in caller
if (where) {
if (where === "first") {
this.insertBefore(e, this.firstChild);
}
else {
throw "embedNewSVG()> Unsupported insertion mode";
}
}
else {
this.appendChild(e);
}
return r;
};
// Initialize a bar chart
var d3InitBarChart = function(callback) {
var container = this;
// Try to have good default values for viewport size, good values
// being a 1-to-1 mapping between on screen element and internal
// viewport.
// Use parent size, since this means a 1-to-1 between screen and
// viewport pixel.
var defaultWidth = $(container).width(),
defaultHeight = $(container).height();
// Postpone initialization if container has no dimension yet
if (defaultWidth === 0 || defaultHeight === 0) {
window.setTimeout(function(){
d3InitBarChart.call(container);
}, 200);
return;
}
// The viewport width and height is what we have to deal with,
// whatever is drawn outside won't be visible. The dimension are
// derived from the container's content dimension, although we use
// default minimum dimensions.
var viewportWidth = Math.max(defaultWidth, 400),
viewportHeight = Math.max(defaultHeight, 100)
;
// TODO: Use "data-" on container HTML element to allow
// configuring chart without changing JS code?
// Configurable
// Gutter size. Gutter is outer-most padding within the drawable area.
var gutterSize = {t:16, r:10, b:0, l:10};
// Axes size. Zero means no axis.
var yAxisWidth = 0,
xAxisHeight = 20;
// Not configurable
// The rest is computed from the above.
var yAxisBbox = {
t: gutterSize.t,
l: gutterSize.l + yAxisWidth,
b: viewportHeight - gutterSize.b - xAxisHeight,
r: gutterSize.l + yAxisWidth
};
var xAxisBbox = {
t: viewportHeight - gutterSize.b - xAxisHeight,
l: gutterSize.l + yAxisWidth,
b: viewportHeight - gutterSize.b,
r: viewportWidth - gutterSize.r
};
var plotAreaBbox = {
t: yAxisBbox.t,
l: xAxisBbox.l,
b: yAxisBbox.b,
r: xAxisBbox.r,
w: xAxisBbox.r - xAxisBbox.l,
h: yAxisBbox.b - yAxisBbox.t
};
embedNewSVG.call(container, {
"name": "svg:svg",
"width": viewportWidth,
"height": viewportHeight,
"viewBox": "0 0 " + viewportWidth + " " + viewportHeight,
"preserveAspectRatio": "none",
"children": [{
"name": "g",
"class": "plotArea",
"transform": "translate(" + plotAreaBbox.l + " " + plotAreaBbox.t + ")"
}, {
"name": "g",
"class": "y axis",
"transform": "translate(" + yAxisBbox.l + " " + yAxisBbox.t + ")"
}, {
"name": "g",
"class": "x axis",
"transform": "translate(" + xAxisBbox.l + " " + xAxisBbox.t + ")"
}
]
});
var dateHandlers = {
day: {
format: d3.time.format("%Y%m%d"),
interval: d3.time.day,
fromtkey: function(s) { return this.format.parse(String(s).substr(0,8)); },
totkey: function(d) { return this.format(d); }
},
month: {
format: d3.time.format("%Y%m"),
interval: d3.time.month,
fromtkey: function(s) { return this.format.parse(String(s).substr(0,6)); },
totkey: function(d) { return this.format(d) + "00"; }
}
};
var dateHandler = dateHandlers[testingSet.unit];
// If from_tkey/to_tkey were reliable, I wouldn't need to use a
// transient array...
var tkeys = Object.keys(testingSet[testingSet.unit]);
var xStart = dateHandler.fromtkey(d3.min(tkeys));
var xEnd = dateHandler.fromtkey(d3.max(tkeys));
// In d3, end is exclusive, while we want ours to be inclusive
xEnd = dateHandler.interval.offset(xEnd,1);
// This will be our data, from d3's point of view (while we know
// it is rather the keys to our data.)
var xTimeSlots = dateHandler.interval.range(xStart, xEnd);
var xScale = d3.time.scale()
.range([0, plotAreaBbox.w])
.domain([xStart, xEnd]);
var yFormatNumber = d3.format(",");
var yScale = d3.scale.linear()
.range([plotAreaBbox.h, 0])
.domain([0, d3.max(d3.values(testingSet[testingSet.unit]))]);
// Conditionally create X axis
if (xAxisHeight > 0) {
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
;
d3.select($(".x.axis", container)[0]).call(xAxis);
}
// Conditionally create Y axis
if (yAxisWidth > 0) {
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5)
.tickFormat(d3.format(".2s"))
;
d3.select($(".y.axis", container)[0]).call(yAxis);
}
var chartPathPoints = [],
plotArea = $(".plotArea")[0];
d3.select(plotArea).selectAll(".bar")
.data(xTimeSlots)
.enter()
.select(function(d, i) {
var tkey = dateHandler.totkey(d);
var numCables = testingSet[testingSet.unit][tkey] || 0;
var plotx = xScale(d);
// We use floor() to have at least 1-pixel high bar if count is
// at least one.
var ploty = Math.floor(yScale(numCables));
// Collect data points so that later we can create the chart's
// paths.
chartPathPoints.push({"x": plotx, "y": ploty});
var xlabel = tkey.substr(0, 4) + "-" + tkey.substr(4, 2) + "-" + tkey.substr(6, 2);
// TODO: Consider using cloneNode(deep=true)
var r = embedNewSVG.call(this, {
"name": "g",
"class": "bar",
"children": [{
"name": "rect",
"x": plotx,
"width": xScale(dateHandler.interval.offset(d,1)) - plotx,
"height": plotAreaBbox.h
}, {
"name": "g",
"children": [{
"name": "text",
"children": [{
"text": xlabel.replace("-00", "") + ": "
}, {
"name": "tspan",
"children": [{
"text": yFormatNumber(numCables) + " cable" + (numCables > 1 ? "s" : "")
}
]
}
]
}
]
}
]
});
// We need to do this here because getBBox() returns
// meaningful dimensions only when the SVG nodes are
// actually renderable.
var bbox = r.children[1].g.getBBox();
var tx = plotx * (1 - bbox.width / plotAreaBbox.w),
ty = -4;
r.children[1].g.setAttribute("transform", "translate(" + tx + " " + ty + ")");
return r.g;
});
// Create chart path from collected points.
// We create one set of path data which can be used to both
// generate path data for chart line and chart area, the only
// difference being how they start and end (chart area is a
// closed path while chart line is an open path).
var n = chartPathPoints.length;
if (n) {
var pathData = [chartPathPoints[0].y];
var oldPathPoint = chartPathPoints[0],
newPathPoint;
for (var i=1; i<n; i++) {
newPathPoint = chartPathPoints[i];
// Skip if no vertical movement.
if (newPathPoint.y !== oldPathPoint.y) {
pathData.push("H" + newPathPoint.x + "V" + newPathPoint.y);
oldPathPoint = newPathPoint;
}
}
pathData.push("H" + plotAreaBbox.w);
pathData = pathData.join("");
var branch = {
"name": "g",
"children": [{
"name": "path",
"class": "chartArea",
"d": "M 0 " + plotAreaBbox.h + "V" + pathData + "V" + plotAreaBbox.h + "Z"
}, {
"name": "path",
"class": "chartLine",
"d": "M 0 " + pathData
}
]
};
embedNewSVG.call(plotArea, branch, "first");
}
// Done call callback if any, caller might want to put more stuff
// in chart, like hyperlink on each bar, or whatever.
if (typeof callback === 'function') {
callback.call(container);
}
};
// Launch initialization of bar chart(s) (potentially async)
$(".d3BarChart").each(function(i, e){
d3InitBarChart.call(e, function(){
// Unfortunately, jQuery delegation doesn't work when we select
// using class names, workaround is to use tag name, assuming
// exact knowledge of underlying layout (Had it worked, I
// would have used ".plotArea .bar".)
$(this).delegate("svg > g > g:first-child ~ g", "click", function(){
var t = $("rect:first-child + g > text", this)[0].textContent.replace(/:.+$/, "");
var url =
"https:/" +
"/search.wikileaks.org/plusd/index.php" +
"?qproject%5B%5D=ps" +
"&qproject%5B%5D=cg" +
"&qsort=tasc" +
"&qtfrom=" + t +
"&qtto=" + t +
"#result";
window.location.href = url;
});
});
});
});
</script>
</body>
</html>
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment