widgets_stats.js 111 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585
  1. /* ------------------------------------------------------------------------------
  2. *
  3. * # Statistics widgets
  4. *
  5. * Demo JS code for widgets_stats.html page
  6. *
  7. * ---------------------------------------------------------------------------- */
  8. // Setup module
  9. // ------------------------------
  10. var StatisticWidgets = function() {
  11. //
  12. // Setup module components
  13. //
  14. // Messages area chart
  15. var _areaChartWidget = function(element, chartHeight, color) {
  16. if (typeof d3 == 'undefined') {
  17. console.warn('Warning - d3.min.js is not loaded.');
  18. return;
  19. }
  20. // Initialize chart only if element exsists in the DOM
  21. if(element) {
  22. // Basic setup
  23. // ------------------------------
  24. // Define main variables
  25. var d3Container = d3.select(element),
  26. margin = {top: 0, right: 0, bottom: 0, left: 0},
  27. width = d3Container.node().getBoundingClientRect().width - margin.left - margin.right,
  28. height = chartHeight - margin.top - margin.bottom;
  29. // Date and time format
  30. var parseDate = d3.time.format('%Y-%m-%d').parse;
  31. // Create SVG
  32. // ------------------------------
  33. // Container
  34. var container = d3Container.append('svg');
  35. // SVG element
  36. var svg = container
  37. .attr('width', width + margin.left + margin.right)
  38. .attr('height', height + margin.top + margin.bottom)
  39. .append("g")
  40. .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  41. // Construct chart layout
  42. // ------------------------------
  43. // Area
  44. var area = d3.svg.area()
  45. .x(function(d) { return x(d.date); })
  46. .y0(height)
  47. .y1(function(d) { return y(d.value); })
  48. .interpolate('monotone');
  49. // Construct scales
  50. // ------------------------------
  51. // Horizontal
  52. var x = d3.time.scale().range([0, width ]);
  53. // Vertical
  54. var y = d3.scale.linear().range([height, 0]);
  55. // Load data
  56. // ------------------------------
  57. d3.json("../../../../global_assets/demo_data/dashboard/monthly_sales.json", function (error, data) {
  58. // Show what's wrong if error
  59. if (error) return console.error(error);
  60. // Pull out values
  61. data.forEach(function (d) {
  62. d.date = parseDate(d.date);
  63. d.value = +d.value;
  64. });
  65. // Get the maximum value in the given array
  66. var maxY = d3.max(data, function(d) { return d.value; });
  67. // Reset start data for animation
  68. var startData = data.map(function(datum) {
  69. return {
  70. date: datum.date,
  71. value: 0
  72. };
  73. });
  74. // Set input domains
  75. // ------------------------------
  76. // Horizontal
  77. x.domain(d3.extent(data, function(d, i) { return d.date; }));
  78. // Vertical
  79. y.domain([0, d3.max( data, function(d) { return d.value; })]);
  80. //
  81. // Append chart elements
  82. //
  83. // Add area path
  84. svg.append("path")
  85. .datum(data)
  86. .attr("class", "d3-area")
  87. .style('fill', color)
  88. .attr("d", area)
  89. .transition() // begin animation
  90. .duration(1000)
  91. .attrTween('d', function() {
  92. var interpolator = d3.interpolateArray(startData, data);
  93. return function (t) {
  94. return area(interpolator (t));
  95. };
  96. });
  97. // Resize chart
  98. // ------------------------------
  99. // Call function on window resize
  100. $(window).on('resize', messagesAreaResize);
  101. // Call function on sidebar width change
  102. $(document).on('click', '.sidebar-control', messagesAreaResize);
  103. // Resize function
  104. //
  105. // Since D3 doesn't support SVG resize by default,
  106. // we need to manually specify parts of the graph that need to
  107. // be updated on window resize
  108. function messagesAreaResize() {
  109. // Layout variables
  110. width = d3Container.node().getBoundingClientRect().width - margin.left - margin.right;
  111. // Layout
  112. // -------------------------
  113. // Main svg width
  114. container.attr("width", width + margin.left + margin.right);
  115. // Width of appended group
  116. svg.attr("width", width + margin.left + margin.right);
  117. // Horizontal range
  118. x.range([0, width]);
  119. // Chart elements
  120. // -------------------------
  121. // Area path
  122. svg.selectAll('.d3-area').datum( data ).attr("d", area);
  123. }
  124. });
  125. }
  126. };
  127. // Simple bar charts
  128. var _barChartWidget = function(element, barQty, height, animate, easing, duration, delay, color, tooltip) {
  129. if (typeof d3 == 'undefined') {
  130. console.warn('Warning - d3.min.js is not loaded.');
  131. return;
  132. }
  133. // Initialize chart only if element exsists in the DOM
  134. if(element) {
  135. // Basic setup
  136. // ------------------------------
  137. // Add data set
  138. var bardata = [];
  139. for (var i=0; i < barQty; i++) {
  140. bardata.push(Math.round(Math.random() * 10) + 10);
  141. }
  142. // Main variables
  143. var d3Container = d3.select(element),
  144. width = d3Container.node().getBoundingClientRect().width;
  145. // Construct scales
  146. // ------------------------------
  147. // Horizontal
  148. var x = d3.scale.ordinal()
  149. .rangeBands([0, width], 0.3);
  150. // Vertical
  151. var y = d3.scale.linear()
  152. .range([0, height]);
  153. // Set input domains
  154. // ------------------------------
  155. // Horizontal
  156. x.domain(d3.range(0, bardata.length));
  157. // Vertical
  158. y.domain([0, d3.max(bardata)]);
  159. // Create chart
  160. // ------------------------------
  161. // Add svg element
  162. var container = d3Container.append('svg');
  163. // Add SVG group
  164. var svg = container
  165. .attr('width', width)
  166. .attr('height', height)
  167. .append('g');
  168. //
  169. // Append chart elements
  170. //
  171. // Bars
  172. var bars = svg.selectAll('rect')
  173. .data(bardata)
  174. .enter()
  175. .append('rect')
  176. .attr('class', 'd3-random-bars')
  177. .attr('width', x.rangeBand())
  178. .attr('x', function(d,i) {
  179. return x(i);
  180. })
  181. .style('fill', color);
  182. // Tooltip
  183. // ------------------------------
  184. // Initiate
  185. var tip = d3.tip()
  186. .attr('class', 'd3-tip')
  187. .offset([-10, 0]);
  188. // Show and hide
  189. if(tooltip == "hours" || tooltip == "goal" || tooltip == "members") {
  190. bars.call(tip)
  191. .on('mouseover', tip.show)
  192. .on('mouseout', tip.hide);
  193. }
  194. // Daily meetings tooltip content
  195. if(tooltip == "hours") {
  196. tip.html(function (d, i) {
  197. return "<div class='text-center'>" +
  198. "<h6 class='mb-0'>" + d + "</h6>" +
  199. "<span class='font-size-sm'>meetings</span>" +
  200. "<div class='font-size-sm'>" + i + ":00" + "</div>" +
  201. "</div>";
  202. });
  203. }
  204. // Statements tooltip content
  205. if(tooltip == "goal") {
  206. tip.html(function (d, i) {
  207. return "<div class='text-center'>" +
  208. "<h6 class='mb-0'>" + d + "</h6>" +
  209. "<span class='font-size-sm'>statements</span>" +
  210. "<div class='font-size-sm'>" + i + ":00" + "</div>" +
  211. "</div>";
  212. });
  213. }
  214. // Online members tooltip content
  215. if(tooltip == "members") {
  216. tip.html(function (d, i) {
  217. return "<div class='text-center'>" +
  218. "<h6 class='mb-0'>" + d + "0" + "</h6>" +
  219. "<span class='font-size-sm'>members</span>" +
  220. "<div class='font-size-sm'>" + i + ":00" + "</div>" +
  221. "</div>";
  222. });
  223. }
  224. // Bar loading animation
  225. // ------------------------------
  226. // Choose between animated or static
  227. if(animate) {
  228. withAnimation();
  229. } else {
  230. withoutAnimation();
  231. }
  232. // Animate on load
  233. function withAnimation() {
  234. bars
  235. .attr('height', 0)
  236. .attr('y', height)
  237. .transition()
  238. .attr('height', function(d) {
  239. return y(d);
  240. })
  241. .attr('y', function(d) {
  242. return height - y(d);
  243. })
  244. .delay(function(d, i) {
  245. return i * delay;
  246. })
  247. .duration(duration)
  248. .ease(easing);
  249. }
  250. // Load without animateion
  251. function withoutAnimation() {
  252. bars
  253. .attr('height', function(d) {
  254. return y(d);
  255. })
  256. .attr('y', function(d) {
  257. return height - y(d);
  258. });
  259. }
  260. // Resize chart
  261. // ------------------------------
  262. // Call function on window resize
  263. $(window).on('resize', barsResize);
  264. // Call function on sidebar width change
  265. $(document).on('click', '.sidebar-control', barsResize);
  266. // Resize function
  267. //
  268. // Since D3 doesn't support SVG resize by default,
  269. // we need to manually specify parts of the graph that need to
  270. // be updated on window resize
  271. function barsResize() {
  272. // Layout variables
  273. width = d3Container.node().getBoundingClientRect().width;
  274. // Layout
  275. // -------------------------
  276. // Main svg width
  277. container.attr("width", width);
  278. // Width of appended group
  279. svg.attr("width", width);
  280. // Horizontal range
  281. x.rangeBands([0, width], 0.3);
  282. // Chart elements
  283. // -------------------------
  284. // Bars
  285. svg.selectAll('.d3-random-bars')
  286. .attr('width', x.rangeBand())
  287. .attr('x', function(d,i) {
  288. return x(i);
  289. });
  290. }
  291. }
  292. };
  293. // Simple line chart
  294. var _lineChartWidget = function(element, chartHeight, lineColor, pathColor, pointerLineColor, pointerBgColor) {
  295. if (typeof d3 == 'undefined') {
  296. console.warn('Warning - d3.min.js is not loaded.');
  297. return;
  298. }
  299. // Initialize chart only if element exsists in the DOM
  300. if(element) {
  301. // Basic setup
  302. // ------------------------------
  303. // Add data set
  304. var dataset = [
  305. {
  306. "date": "04/13/14",
  307. "alpha": "60"
  308. }, {
  309. "date": "04/14/14",
  310. "alpha": "35"
  311. }, {
  312. "date": "04/15/14",
  313. "alpha": "65"
  314. }, {
  315. "date": "04/16/14",
  316. "alpha": "50"
  317. }, {
  318. "date": "04/17/14",
  319. "alpha": "65"
  320. }, {
  321. "date": "04/18/14",
  322. "alpha": "20"
  323. }, {
  324. "date": "04/19/14",
  325. "alpha": "60"
  326. }
  327. ];
  328. // Main variables
  329. var d3Container = d3.select(element),
  330. margin = {top: 0, right: 0, bottom: 0, left: 0},
  331. width = d3Container.node().getBoundingClientRect().width - margin.left - margin.right,
  332. height = chartHeight - margin.top - margin.bottom,
  333. padding = 20;
  334. // Format date
  335. var parseDate = d3.time.format("%m/%d/%y").parse,
  336. formatDate = d3.time.format("%a, %B %e");
  337. // Add tooltip
  338. // ------------------------------
  339. var tooltip = d3.tip()
  340. .attr('class', 'd3-tip')
  341. .html(function (d) {
  342. return "<ul class='list-unstyled mb-1'>" +
  343. "<li>" + "<div class='font-size-base my-1'><i class='icon-check2 mr-2'></i>" + formatDate(d.date) + "</div>" + "</li>" +
  344. "<li>" + "Sales: &nbsp;" + "<span class='font-weight-semibold float-right'>" + d.alpha + "</span>" + "</li>" +
  345. "<li>" + "Revenue: &nbsp; " + "<span class='font-weight-semibold float-right'>" + "$" + (d.alpha * 25).toFixed(2) + "</span>" + "</li>" +
  346. "</ul>";
  347. });
  348. // Create chart
  349. // ------------------------------
  350. // Add svg element
  351. var container = d3Container.append('svg');
  352. // Add SVG group
  353. var svg = container
  354. .attr('width', width + margin.left + margin.right)
  355. .attr('height', height + margin.top + margin.bottom)
  356. .append("g")
  357. .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
  358. .call(tooltip);
  359. // Load data
  360. // ------------------------------
  361. dataset.forEach(function (d) {
  362. d.date = parseDate(d.date);
  363. d.alpha = +d.alpha;
  364. });
  365. // Construct scales
  366. // ------------------------------
  367. // Horizontal
  368. var x = d3.time.scale()
  369. .range([padding, width - padding]);
  370. // Vertical
  371. var y = d3.scale.linear()
  372. .range([height, 5]);
  373. // Set input domains
  374. // ------------------------------
  375. // Horizontal
  376. x.domain(d3.extent(dataset, function (d) {
  377. return d.date;
  378. }));
  379. // Vertical
  380. y.domain([0, d3.max(dataset, function (d) {
  381. return Math.max(d.alpha);
  382. })]);
  383. // Construct chart layout
  384. // ------------------------------
  385. // Line
  386. var line = d3.svg.line()
  387. .x(function(d) {
  388. return x(d.date);
  389. })
  390. .y(function(d) {
  391. return y(d.alpha);
  392. });
  393. //
  394. // Append chart elements
  395. //
  396. // Add mask for animation
  397. // ------------------------------
  398. // Add clip path
  399. var clip = svg.append("defs")
  400. .append("clipPath")
  401. .attr("id", "clip-line-small");
  402. // Add clip shape
  403. var clipRect = clip.append("rect")
  404. .attr('class', 'clip')
  405. .attr("width", 0)
  406. .attr("height", height);
  407. // Animate mask
  408. clipRect
  409. .transition()
  410. .duration(1000)
  411. .ease('linear')
  412. .attr("width", width);
  413. // Line
  414. // ------------------------------
  415. // Path
  416. var path = svg.append('path')
  417. .attr({
  418. 'd': line(dataset),
  419. "clip-path": "url(#clip-line-small)",
  420. 'class': 'd3-line d3-line-medium'
  421. })
  422. .style('stroke', lineColor);
  423. // Animate path
  424. svg.select('.line-tickets')
  425. .transition()
  426. .duration(1000)
  427. .ease('linear');
  428. // Add vertical guide lines
  429. // ------------------------------
  430. // Bind data
  431. var guide = svg.append('g')
  432. .selectAll('.d3-line-guides-group')
  433. .data(dataset);
  434. // Append lines
  435. guide
  436. .enter()
  437. .append('line')
  438. .attr('class', 'd3-line-guides')
  439. .attr('x1', function (d, i) {
  440. return x(d.date);
  441. })
  442. .attr('y1', function (d, i) {
  443. return height;
  444. })
  445. .attr('x2', function (d, i) {
  446. return x(d.date);
  447. })
  448. .attr('y2', function (d, i) {
  449. return height;
  450. })
  451. .style('stroke', pathColor)
  452. .style('stroke-dasharray', '4,2')
  453. .style('shape-rendering', 'crispEdges');
  454. // Animate guide lines
  455. guide
  456. .transition()
  457. .duration(1000)
  458. .delay(function(d, i) { return i * 150; })
  459. .attr('y2', function (d, i) {
  460. return y(d.alpha);
  461. });
  462. // Alpha app points
  463. // ------------------------------
  464. // Add points
  465. var points = svg.insert('g')
  466. .selectAll('.d3-line-circle')
  467. .data(dataset)
  468. .enter()
  469. .append('circle')
  470. .attr('class', 'd3-line-circle d3-line-circle-medium')
  471. .attr("cx", line.x())
  472. .attr("cy", line.y())
  473. .attr("r", 3)
  474. .style({
  475. 'stroke': pointerLineColor,
  476. 'fill': pointerBgColor
  477. });
  478. // Animate points on page load
  479. points
  480. .style('opacity', 0)
  481. .transition()
  482. .duration(250)
  483. .ease('linear')
  484. .delay(1000)
  485. .style('opacity', 1);
  486. // Add user interaction
  487. points
  488. .on("mouseover", function (d) {
  489. tooltip.offset([-10, 0]).show(d);
  490. // Animate circle radius
  491. d3.select(this).transition().duration(250).attr('r', 4);
  492. })
  493. // Hide tooltip
  494. .on("mouseout", function (d) {
  495. tooltip.hide(d);
  496. // Animate circle radius
  497. d3.select(this).transition().duration(250).attr('r', 3);
  498. });
  499. // Change tooltip direction of first point
  500. d3.select(points[0][0])
  501. .on("mouseover", function (d) {
  502. tooltip.offset([0, 10]).direction('e').show(d);
  503. // Animate circle radius
  504. d3.select(this).transition().duration(250).attr('r', 4);
  505. })
  506. .on("mouseout", function (d) {
  507. tooltip.direction('n').hide(d);
  508. // Animate circle radius
  509. d3.select(this).transition().duration(250).attr('r', 3);
  510. });
  511. // Change tooltip direction of last point
  512. d3.select(points[0][points.size() - 1])
  513. .on("mouseover", function (d) {
  514. tooltip.offset([0, -10]).direction('w').show(d);
  515. // Animate circle radius
  516. d3.select(this).transition().duration(250).attr('r', 4);
  517. })
  518. .on("mouseout", function (d) {
  519. tooltip.direction('n').hide(d);
  520. // Animate circle radius
  521. d3.select(this).transition().duration(250).attr('r', 3);
  522. });
  523. // Resize chart
  524. // ------------------------------
  525. // Call function on window resize
  526. $(window).on('resize', lineChartResize);
  527. // Call function on sidebar width change
  528. $(document).on('click', '.sidebar-control', lineChartResize);
  529. // Resize function
  530. //
  531. // Since D3 doesn't support SVG resize by default,
  532. // we need to manually specify parts of the graph that need to
  533. // be updated on window resize
  534. function lineChartResize() {
  535. // Layout variables
  536. width = d3Container.node().getBoundingClientRect().width - margin.left - margin.right;
  537. // Layout
  538. // -------------------------
  539. // Main svg width
  540. container.attr("width", width + margin.left + margin.right);
  541. // Width of appended group
  542. svg.attr("width", width + margin.left + margin.right);
  543. // Horizontal range
  544. x.range([padding, width - padding]);
  545. // Chart elements
  546. // -------------------------
  547. // Mask
  548. clipRect.attr("width", width);
  549. // Line path
  550. svg.selectAll('.d3-line').attr("d", line(dataset));
  551. // Circles
  552. svg.selectAll('.d3-line-circle').attr("cx", line.x());
  553. // Guide lines
  554. svg.selectAll('.d3-line-guides')
  555. .attr('x1', function (d, i) {
  556. return x(d.date);
  557. })
  558. .attr('x2', function (d, i) {
  559. return x(d.date);
  560. });
  561. }
  562. }
  563. };
  564. // Simple sparklines
  565. var _sparklinesWidget = function(element, chartType, qty, chartHeight, interpolation, duration, interval, color) {
  566. if (typeof d3 == 'undefined') {
  567. console.warn('Warning - d3.min.js is not loaded.');
  568. return;
  569. }
  570. // Initialize chart only if element exsists in the DOM
  571. if(element) {
  572. // Basic setup
  573. // ------------------------------
  574. // Define main variables
  575. var d3Container = d3.select(element),
  576. margin = {top: 0, right: 0, bottom: 0, left: 0},
  577. width = d3Container.node().getBoundingClientRect().width - margin.left - margin.right,
  578. height = chartHeight - margin.top - margin.bottom;
  579. // Generate random data (for demo only)
  580. var data = [];
  581. for (var i=0; i < qty; i++) {
  582. data.push(Math.floor(Math.random() * qty) + 5);
  583. }
  584. // Construct scales
  585. // ------------------------------
  586. // Horizontal
  587. var x = d3.scale.linear().range([0, width]);
  588. // Vertical
  589. var y = d3.scale.linear().range([height - 5, 5]);
  590. // Set input domains
  591. // ------------------------------
  592. // Horizontal
  593. x.domain([1, qty - 3]);
  594. // Vertical
  595. y.domain([0, qty]);
  596. // Construct chart layout
  597. // ------------------------------
  598. // Line
  599. var line = d3.svg.line()
  600. .interpolate(interpolation)
  601. .x(function(d, i) { return x(i); })
  602. .y(function(d, i) { return y(d); });
  603. // Area
  604. var area = d3.svg.area()
  605. .interpolate(interpolation)
  606. .x(function(d,i) {
  607. return x(i);
  608. })
  609. .y0(height)
  610. .y1(function(d) {
  611. return y(d);
  612. });
  613. // Create SVG
  614. // ------------------------------
  615. // Container
  616. var container = d3Container.append('svg');
  617. // SVG element
  618. var svg = container
  619. .attr('width', width + margin.left + margin.right)
  620. .attr('height', height + margin.top + margin.bottom)
  621. .append("g")
  622. .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  623. // Add mask for animation
  624. // ------------------------------
  625. // Add clip path
  626. var clip = svg.append("defs")
  627. .append("clipPath")
  628. .attr('id', function(d, i) { return "load-clip-" + element.substring(1); });
  629. // Add clip shape
  630. var clips = clip.append("rect")
  631. .attr('class', 'load-clip')
  632. .attr("width", 0)
  633. .attr("height", height);
  634. // Animate mask
  635. clips
  636. .transition()
  637. .duration(1000)
  638. .ease('linear')
  639. .attr("width", width);
  640. //
  641. // Append chart elements
  642. //
  643. // Main path
  644. var path = svg.append("g")
  645. .attr("clip-path", function(d, i) { return "url(#load-clip-" + element.substring(1) + ")"; })
  646. .append("path")
  647. .datum(data)
  648. .attr("transform", "translate(" + x(0) + ",0)");
  649. // Add path based on chart type
  650. if(chartType == "area") {
  651. path.attr("d", area).attr('class', 'd3-area').style("fill", color); // area
  652. }
  653. else {
  654. path.attr("d", line).attr("class", "d3-line d3-line-medium").style('stroke', color); // line
  655. }
  656. // Animate path
  657. path
  658. .style('opacity', 0)
  659. .transition()
  660. .duration(500)
  661. .style('opacity', 1);
  662. // Set update interval. For demo only
  663. // ------------------------------
  664. setInterval(function() {
  665. // push a new data point onto the back
  666. data.push(Math.floor(Math.random() * qty) + 5);
  667. // pop the old data point off the front
  668. data.shift();
  669. update();
  670. }, interval);
  671. // Update random data. For demo only
  672. // ------------------------------
  673. function update() {
  674. // Redraw the path and slide it to the left
  675. path
  676. .attr("transform", null)
  677. .transition()
  678. .duration(duration)
  679. .ease("linear")
  680. .attr("transform", "translate(" + x(0) + ",0)");
  681. // Update path type
  682. if(chartType == "area") {
  683. path.attr("d", area).attr('class', 'd3-area').style("fill", color);
  684. }
  685. else {
  686. path.attr("d", line).attr("class", "d3-line d3-line-medium").style('stroke', color);
  687. }
  688. }
  689. // Resize chart
  690. // ------------------------------
  691. // Call function on window resize
  692. $(window).on('resize', resizeSparklines);
  693. // Call function on sidebar width change
  694. $(document).on('click', '.sidebar-control', resizeSparklines);
  695. // Resize function
  696. //
  697. // Since D3 doesn't support SVG resize by default,
  698. // we need to manually specify parts of the graph that need to
  699. // be updated on window resize
  700. function resizeSparklines() {
  701. // Layout variables
  702. width = d3Container.node().getBoundingClientRect().width - margin.left - margin.right;
  703. // Layout
  704. // -------------------------
  705. // Main svg width
  706. container.attr("width", width + margin.left + margin.right);
  707. // Width of appended group
  708. svg.attr("width", width + margin.left + margin.right);
  709. // Horizontal range
  710. x.range([0, width]);
  711. // Chart elements
  712. // -------------------------
  713. // Clip mask
  714. clips.attr("width", width);
  715. // Line
  716. svg.select(".d3-line").attr("d", line);
  717. // Area
  718. svg.select(".d3-area").attr("d", area);
  719. }
  720. }
  721. };
  722. // Animated progress with icon
  723. var _progressIcon = function(element, radius, border, backgroundColor, foregroundColor, end, iconClass) {
  724. if (typeof d3 == 'undefined') {
  725. console.warn('Warning - d3.min.js is not loaded.');
  726. return;
  727. }
  728. // Initialize chart only if element exsists in the DOM
  729. if(element) {
  730. // Basic setup
  731. // ------------------------------
  732. // Main variables
  733. var d3Container = d3.select(element),
  734. startPercent = 0,
  735. iconSize = 32,
  736. endPercent = end,
  737. twoPi = Math.PI * 2,
  738. formatPercent = d3.format('.0%'),
  739. boxSize = radius * 2;
  740. // Values count
  741. var count = Math.abs((endPercent - startPercent) / 0.01);
  742. // Values step
  743. var step = endPercent < startPercent ? -0.01 : 0.01;
  744. // Create chart
  745. // ------------------------------
  746. // Add SVG element
  747. var container = d3Container.append('svg');
  748. // Add SVG group
  749. var svg = container
  750. .attr('width', boxSize)
  751. .attr('height', boxSize)
  752. .append('g')
  753. .attr('transform', 'translate(' + (boxSize / 2) + ',' + (boxSize / 2) + ')');
  754. // Construct chart layout
  755. // ------------------------------
  756. // Arc
  757. var arc = d3.svg.arc()
  758. .startAngle(0)
  759. .innerRadius(radius)
  760. .outerRadius(radius - border)
  761. .cornerRadius(20);
  762. //
  763. // Append chart elements
  764. //
  765. // Paths
  766. // ------------------------------
  767. // Background path
  768. svg.append('path')
  769. .attr('class', 'd3-progress-background')
  770. .attr('d', arc.endAngle(twoPi))
  771. .style('fill', backgroundColor);
  772. // Foreground path
  773. var foreground = svg.append('path')
  774. .attr('class', 'd3-progress-foreground')
  775. .attr('filter', 'url(#blur)')
  776. .style({
  777. 'fill': foregroundColor,
  778. 'stroke': foregroundColor
  779. });
  780. // Front path
  781. var front = svg.append('path')
  782. .attr('class', 'd3-progress-front')
  783. .style({
  784. 'fill': foregroundColor,
  785. 'fill-opacity': 1
  786. });
  787. // Text
  788. // ------------------------------
  789. // Percentage text value
  790. var numberText = d3.select('.progress-percentage')
  791. .attr('class', 'pt-1 mt-2 mb-1');
  792. // Icon
  793. d3.select(element)
  794. .append("i")
  795. .attr("class", iconClass + " counter-icon")
  796. .style({
  797. 'color': foregroundColor,
  798. 'top': ((boxSize - iconSize) / 2) + 'px'
  799. });
  800. // Animation
  801. // ------------------------------
  802. // Animate path
  803. function updateProgress(progress) {
  804. foreground.attr('d', arc.endAngle(twoPi * progress));
  805. front.attr('d', arc.endAngle(twoPi * progress));
  806. numberText.text(formatPercent(progress));
  807. }
  808. // Animate text
  809. var progress = startPercent;
  810. (function loops() {
  811. updateProgress(progress);
  812. if (count > 0) {
  813. count--;
  814. progress += step;
  815. setTimeout(loops, 10);
  816. }
  817. })();
  818. }
  819. };
  820. // Animated progress with percentage count
  821. var _progressPercentage = function(element, radius, border, backgroundColor, foregroundColor, end) {
  822. if (typeof d3 == 'undefined') {
  823. console.warn('Warning - d3.min.js is not loaded.');
  824. return;
  825. }
  826. // Initialize chart only if element exsists in the DOM
  827. if(element) {
  828. // Basic setup
  829. // ------------------------------
  830. // Main variables
  831. var d3Container = d3.select(element),
  832. startPercent = 0,
  833. fontSize = 22,
  834. endPercent = end,
  835. twoPi = Math.PI * 2,
  836. formatPercent = d3.format('.0%'),
  837. boxSize = radius * 2;
  838. // Values count
  839. var count = Math.abs((endPercent - startPercent) / 0.01);
  840. // Values step
  841. var step = endPercent < startPercent ? -0.01 : 0.01;
  842. // Create chart
  843. // ------------------------------
  844. // Add SVG element
  845. var container = d3Container.append('svg');
  846. // Add SVG group
  847. var svg = container
  848. .attr('width', boxSize)
  849. .attr('height', boxSize)
  850. .append('g')
  851. .attr('transform', 'translate(' + radius + ',' + radius + ')');
  852. // Construct chart layout
  853. // ------------------------------
  854. // Arc
  855. var arc = d3.svg.arc()
  856. .startAngle(0)
  857. .innerRadius(radius)
  858. .outerRadius(radius - border)
  859. .cornerRadius(20);
  860. //
  861. // Append chart elements
  862. //
  863. // Paths
  864. // ------------------------------
  865. // Background path
  866. svg.append('path')
  867. .attr('class', 'd3-progress-background')
  868. .attr('d', arc.endAngle(twoPi))
  869. .style('fill', backgroundColor);
  870. // Foreground path
  871. var foreground = svg.append('path')
  872. .attr('class', 'd3-progress-foreground')
  873. .attr('filter', 'url(#blur)')
  874. .style({
  875. 'fill': foregroundColor,
  876. 'stroke': foregroundColor
  877. });
  878. // Front path
  879. var front = svg.append('path')
  880. .attr('class', 'd3-progress-front')
  881. .style({
  882. 'fill': foregroundColor,
  883. 'fill-opacity': 1
  884. });
  885. // Text
  886. // ------------------------------
  887. // Percentage text value
  888. var numberText = svg
  889. .append('text')
  890. .attr('dx', 0)
  891. .attr('dy', (fontSize / 2) - border)
  892. .style({
  893. 'font-size': fontSize + 'px',
  894. 'line-height': 1,
  895. 'fill': foregroundColor,
  896. 'text-anchor': 'middle'
  897. });
  898. // Animation
  899. // ------------------------------
  900. // Animate path
  901. function updateProgress(progress) {
  902. foreground.attr('d', arc.endAngle(twoPi * progress));
  903. front.attr('d', arc.endAngle(twoPi * progress));
  904. numberText.text(formatPercent(progress));
  905. }
  906. // Animate text
  907. var progress = startPercent;
  908. (function loops() {
  909. updateProgress(progress);
  910. if (count > 0) {
  911. count--;
  912. progress += step;
  913. setTimeout(loops, 10);
  914. }
  915. })();
  916. }
  917. };
  918. // Simple pie
  919. var _animatedPie = function(element, size) {
  920. if (typeof d3 == 'undefined') {
  921. console.warn('Warning - d3.min.js is not loaded.');
  922. return;
  923. }
  924. // Initialize chart only if element exsists in the DOM
  925. if(element) {
  926. // Add data set
  927. var data = [
  928. {
  929. "status": "Pending tickets",
  930. "icon": "<i class='badge badge-mark border-blue-300 mr-2'></i>",
  931. "value": 938,
  932. "color": "#29B6F6"
  933. }, {
  934. "status": "Resolved tickets",
  935. "icon": "<i class='badge badge-mark border-success-300 mr-2'></i>",
  936. "value": 490,
  937. "color": "#66BB6A"
  938. }, {
  939. "status": "Closed tickets",
  940. "icon": "<i class='badge badge-mark border-danger-300 mr-2'></i>",
  941. "value": 789,
  942. "color": "#EF5350"
  943. }
  944. ];
  945. // Main variables
  946. var d3Container = d3.select(element),
  947. distance = 2, // reserve 2px space for mouseover arc moving
  948. radius = (size/2) - distance,
  949. sum = d3.sum(data, function(d) { return d.value; });
  950. // Tooltip
  951. // ------------------------------
  952. var tip = d3.tip()
  953. .attr('class', 'd3-tip')
  954. .offset([-10, 0])
  955. .direction('e')
  956. .html(function (d) {
  957. return "<ul class='list-unstyled mb-1'>" +
  958. "<li>" + "<div class='font-size-base my-1'>" + d.data.icon + d.data.status + "</div>" + "</li>" +
  959. "<li>" + "Total: &nbsp;" + "<span class='font-weight-semibold float-right'>" + d.value + "</span>" + "</li>" +
  960. "<li>" + "Share: &nbsp;" + "<span class='font-weight-semibold float-right'>" + (100 / (sum / d.value)).toFixed(2) + "%" + "</span>" + "</li>" +
  961. "</ul>";
  962. });
  963. // Create chart
  964. // ------------------------------
  965. // Add svg element
  966. var container = d3Container.append("svg").call(tip);
  967. // Add SVG group
  968. var svg = container
  969. .attr("width", size)
  970. .attr("height", size)
  971. .append("g")
  972. .attr("transform", "translate(" + (size / 2) + "," + (size / 2) + ")");
  973. // Construct chart layout
  974. // ------------------------------
  975. // Pie
  976. var pie = d3.layout.pie()
  977. .sort(null)
  978. .startAngle(Math.PI)
  979. .endAngle(3 * Math.PI)
  980. .value(function (d) {
  981. return d.value;
  982. });
  983. // Arc
  984. var arc = d3.svg.arc()
  985. .outerRadius(radius);
  986. //
  987. // Append chart elements
  988. //
  989. // Group chart elements
  990. var arcGroup = svg.selectAll(".d3-arc")
  991. .data(pie(data))
  992. .enter()
  993. .append("g")
  994. .attr("class", "d3-arc")
  995. .style({
  996. 'stroke': '#fff',
  997. 'stroke-width': 2,
  998. 'cursor': 'pointer'
  999. });
  1000. // Append path
  1001. var arcPath = arcGroup
  1002. .append("path")
  1003. .style("fill", function (d) {
  1004. return d.data.color;
  1005. });
  1006. // Add tooltip
  1007. arcPath
  1008. .on('mouseover', function (d, i) {
  1009. // Transition on mouseover
  1010. d3.select(this)
  1011. .transition()
  1012. .duration(500)
  1013. .ease('elastic')
  1014. .attr('transform', function (d) {
  1015. d.midAngle = ((d.endAngle - d.startAngle) / 2) + d.startAngle;
  1016. var x = Math.sin(d.midAngle) * distance;
  1017. var y = -Math.cos(d.midAngle) * distance;
  1018. return 'translate(' + x + ',' + y + ')';
  1019. });
  1020. })
  1021. .on("mousemove", function (d) {
  1022. // Show tooltip on mousemove
  1023. tip.show(d)
  1024. .style("top", (d3.event.pageY - 40) + "px")
  1025. .style("left", (d3.event.pageX + 30) + "px");
  1026. })
  1027. .on('mouseout', function (d, i) {
  1028. // Mouseout transition
  1029. d3.select(this)
  1030. .transition()
  1031. .duration(500)
  1032. .ease('bounce')
  1033. .attr('transform', 'translate(0,0)');
  1034. // Hide tooltip
  1035. tip.hide(d);
  1036. });
  1037. // Animate chart on load
  1038. arcPath
  1039. .transition()
  1040. .delay(function(d, i) { return i * 500; })
  1041. .duration(500)
  1042. .attrTween("d", function(d) {
  1043. var interpolate = d3.interpolate(d.startAngle,d.endAngle);
  1044. return function(t) {
  1045. d.endAngle = interpolate(t);
  1046. return arc(d);
  1047. };
  1048. });
  1049. //
  1050. // Append counter
  1051. //
  1052. // Append element
  1053. d3Container
  1054. .append('h2')
  1055. .attr('class', 'pt-1 mt-2 mb-1 font-weight-semibold');
  1056. // Animate counter
  1057. d3Container.select('h2')
  1058. .transition()
  1059. .duration(1500)
  1060. .tween("text", function(d) {
  1061. var i = d3.interpolate(this.textContent, sum);
  1062. return function(t) {
  1063. this.textContent = d3.format(",d")(Math.round(i(t)));
  1064. };
  1065. });
  1066. }
  1067. };
  1068. // Pie with legend
  1069. var _animatedPieWithLegend = function(element, size) {
  1070. if (typeof d3 == 'undefined') {
  1071. console.warn('Warning - d3.min.js is not loaded.');
  1072. return;
  1073. }
  1074. // Initialize chart only if element exsists in the DOM
  1075. if(element) {
  1076. // Add data set
  1077. var data = [
  1078. {
  1079. "status": "New",
  1080. "value": 578,
  1081. "color": "#29B6F6"
  1082. }, {
  1083. "status": "Pending",
  1084. "value": 983,
  1085. "color": "#66BB6A"
  1086. }, {
  1087. "status": "Shipped",
  1088. "value": 459,
  1089. "color": "#EF5350"
  1090. }
  1091. ];
  1092. // Main variables
  1093. var d3Container = d3.select(element),
  1094. distance = 2, // reserve 2px space for mouseover arc moving
  1095. radius = (size/2) - distance,
  1096. sum = d3.sum(data, function(d) { return d.value; });
  1097. // Create chart
  1098. // ------------------------------
  1099. // Add svg element
  1100. var container = d3Container.append("svg");
  1101. // Add SVG group
  1102. var svg = container
  1103. .attr("width", size)
  1104. .attr("height", size)
  1105. .append("g")
  1106. .attr("transform", "translate(" + (size / 2) + "," + (size / 2) + ")");
  1107. // Construct chart layout
  1108. // ------------------------------
  1109. // Pie
  1110. var pie = d3.layout.pie()
  1111. .sort(null)
  1112. .startAngle(Math.PI)
  1113. .endAngle(3 * Math.PI)
  1114. .value(function (d) {
  1115. return d.value;
  1116. });
  1117. // Arc
  1118. var arc = d3.svg.arc()
  1119. .outerRadius(radius);
  1120. //
  1121. // Append chart elements
  1122. //
  1123. // Group chart elements
  1124. var arcGroup = svg.selectAll(".d3-arc")
  1125. .data(pie(data))
  1126. .enter()
  1127. .append("g")
  1128. .attr("class", "d3-arc")
  1129. .style({
  1130. 'stroke': '#fff',
  1131. 'stroke-width': 2,
  1132. 'cursor': 'pointer'
  1133. });
  1134. // Append path
  1135. var arcPath = arcGroup
  1136. .append("path")
  1137. .style("fill", function (d) {
  1138. return d.data.color;
  1139. });
  1140. // Add interactions
  1141. arcPath
  1142. .on('mouseover', function (d, i) {
  1143. // Transition on mouseover
  1144. d3.select(this)
  1145. .transition()
  1146. .duration(500)
  1147. .ease('elastic')
  1148. .attr('transform', function (d) {
  1149. d.midAngle = ((d.endAngle - d.startAngle) / 2) + d.startAngle;
  1150. var x = Math.sin(d.midAngle) * distance;
  1151. var y = -Math.cos(d.midAngle) * distance;
  1152. return 'translate(' + x + ',' + y + ')';
  1153. });
  1154. // Animate legend
  1155. $(element + ' [data-slice]').css({
  1156. 'opacity': 0.3,
  1157. 'transition': 'all ease-in-out 0.15s'
  1158. });
  1159. $(element + ' [data-slice=' + i + ']').css({'opacity': 1});
  1160. })
  1161. .on('mouseout', function (d, i) {
  1162. // Mouseout transition
  1163. d3.select(this)
  1164. .transition()
  1165. .duration(500)
  1166. .ease('bounce')
  1167. .attr('transform', 'translate(0,0)');
  1168. // Revert legend animation
  1169. $(element + ' [data-slice]').css('opacity', 1);
  1170. });
  1171. // Animate chart on load
  1172. arcPath
  1173. .transition()
  1174. .delay(function(d, i) { return i * 500; })
  1175. .duration(500)
  1176. .attrTween("d", function(d) {
  1177. var interpolate = d3.interpolate(d.startAngle,d.endAngle);
  1178. return function(t) {
  1179. d.endAngle = interpolate(t);
  1180. return arc(d);
  1181. };
  1182. });
  1183. //
  1184. // Append counter
  1185. //
  1186. // Append element
  1187. d3Container
  1188. .append('h2')
  1189. .attr('class', 'pt-1 mt-2 mb-1 font-weight-semibold');
  1190. // Animate counter
  1191. d3Container.select('h2')
  1192. .transition()
  1193. .duration(1500)
  1194. .tween("text", function(d) {
  1195. var i = d3.interpolate(this.textContent, sum);
  1196. return function(t) {
  1197. this.textContent = d3.format(",d")(Math.round(i(t)));
  1198. };
  1199. });
  1200. //
  1201. // Append legend
  1202. //
  1203. // Add element
  1204. var legend = d3.select(element)
  1205. .append('ul')
  1206. .attr('class', 'chart-widget-legend')
  1207. .selectAll('li').data(pie(data))
  1208. .enter().append('li')
  1209. .attr('data-slice', function(d, i) {
  1210. return i;
  1211. })
  1212. .attr('style', function(d, i) {
  1213. return 'border-bottom: 2px solid ' + d.data.color;
  1214. })
  1215. .text(function(d, i) {
  1216. return d.data.status + ': ';
  1217. });
  1218. // Add value
  1219. legend.append('span')
  1220. .text(function(d, i) {
  1221. return d.data.value;
  1222. });
  1223. }
  1224. };
  1225. // Pie arc with legend
  1226. var _pieArcWithLegend = function(element, size) {
  1227. if (typeof d3 == 'undefined') {
  1228. console.warn('Warning - d3.min.js is not loaded.');
  1229. return;
  1230. }
  1231. // Initialize chart only if element exsists in the DOM
  1232. if(element) {
  1233. // Basic setup
  1234. // ------------------------------
  1235. // Add data set
  1236. var data = [
  1237. {
  1238. "status": "Pending",
  1239. "icon": "<i class='badge badge-mark border-blue-300 mr-2'></i>",
  1240. "value": 720,
  1241. "color": "#29B6F6"
  1242. }, {
  1243. "status": "Resolved",
  1244. "icon": "<i class='badge badge-mark border-success-300 mr-2'></i>",
  1245. "value": 990,
  1246. "color": "#66BB6A"
  1247. }, {
  1248. "status": "Closed",
  1249. "icon": "<i class='badge badge-mark border-danger-300 mr-2'></i>",
  1250. "value": 720,
  1251. "color": "#EF5350"
  1252. }
  1253. ];
  1254. // Main variables
  1255. var d3Container = d3.select(element),
  1256. distance = 2, // reserve 2px space for mouseover arc moving
  1257. radius = (size/2) - distance,
  1258. sum = d3.sum(data, function(d) { return d.value; });
  1259. // Tooltip
  1260. // ------------------------------
  1261. var tip = d3.tip()
  1262. .attr('class', 'd3-tip')
  1263. .offset([-10, 0])
  1264. .direction('e')
  1265. .html(function (d) {
  1266. return "<ul class='list-unstyled mb-1'>" +
  1267. "<li>" + "<div class='font-size-base my-1'>" + d.data.icon + d.data.status + "</div>" + "</li>" +
  1268. "<li>" + "Total: &nbsp;" + "<span class='font-weight-semibold float-right'>" + d.value + "</span>" + "</li>" +
  1269. "<li>" + "Share: &nbsp;" + "<span class='font-weight-semibold float-right'>" + (100 / (sum / d.value)).toFixed(2) + "%" + "</span>" + "</li>" +
  1270. "</ul>";
  1271. });
  1272. // Create chart
  1273. // ------------------------------
  1274. // Add svg element
  1275. var container = d3Container.append("svg").call(tip);
  1276. // Add SVG group
  1277. var svg = container
  1278. .attr("width", size)
  1279. .attr("height", size / 2)
  1280. .append("g")
  1281. .attr("transform", "translate(" + (size / 2) + "," + (size / 2) + ")");
  1282. // Construct chart layout
  1283. // ------------------------------
  1284. // Pie
  1285. var pie = d3.layout.pie()
  1286. .sort(null)
  1287. .startAngle(-Math.PI / 2)
  1288. .endAngle(Math.PI / 2)
  1289. .value(function (d) {
  1290. return d.value;
  1291. });
  1292. // Arc
  1293. var arc = d3.svg.arc()
  1294. .outerRadius(radius)
  1295. .innerRadius(radius / 1.3);
  1296. //
  1297. // Append chart elements
  1298. //
  1299. // Group chart elements
  1300. var arcGroup = svg.selectAll(".d3-arc")
  1301. .data(pie(data))
  1302. .enter()
  1303. .append("g")
  1304. .attr("class", "d3-arc")
  1305. .style({
  1306. 'stroke': '#fff',
  1307. 'stroke-width': 2,
  1308. 'cursor': 'pointer'
  1309. });
  1310. // Append path
  1311. var arcPath = arcGroup
  1312. .append("path")
  1313. .style("fill", function (d) {
  1314. return d.data.color;
  1315. });
  1316. //
  1317. // Interactions
  1318. //
  1319. // Mouse
  1320. arcPath
  1321. .on('mouseover', function(d, i) {
  1322. // Transition on mouseover
  1323. d3.select(this)
  1324. .transition()
  1325. .duration(500)
  1326. .ease('elastic')
  1327. .attr('transform', function (d) {
  1328. d.midAngle = ((d.endAngle - d.startAngle) / 2) + d.startAngle;
  1329. var x = Math.sin(d.midAngle) * distance;
  1330. var y = -Math.cos(d.midAngle) * distance;
  1331. return 'translate(' + x + ',' + y + ')';
  1332. });
  1333. $(element + ' [data-slice]').css({
  1334. 'opacity': 0.3,
  1335. 'transition': 'all ease-in-out 0.15s'
  1336. });
  1337. $(element + ' [data-slice=' + i + ']').css({'opacity': 1});
  1338. })
  1339. .on('mouseout', function(d, i) {
  1340. // Mouseout transition
  1341. d3.select(this)
  1342. .transition()
  1343. .duration(500)
  1344. .ease('bounce')
  1345. .attr('transform', 'translate(0,0)');
  1346. $(element + ' [data-slice]').css('opacity', 1);
  1347. });
  1348. // Animate chart on load
  1349. arcPath
  1350. .transition()
  1351. .delay(function(d, i) {
  1352. return i * 500;
  1353. })
  1354. .duration(500)
  1355. .attrTween("d", function(d) {
  1356. var interpolate = d3.interpolate(d.startAngle,d.endAngle);
  1357. return function(t) {
  1358. d.endAngle = interpolate(t);
  1359. return arc(d);
  1360. };
  1361. });
  1362. //
  1363. // Append total text
  1364. //
  1365. svg.append('text')
  1366. .attr('class', 'text-muted')
  1367. .attr({
  1368. 'class': 'half-donut-total',
  1369. 'text-anchor': 'middle',
  1370. 'dy': -33
  1371. })
  1372. .style({
  1373. 'font-size': '12px',
  1374. 'fill': '#999'
  1375. })
  1376. .text('Total');
  1377. //
  1378. // Append count
  1379. //
  1380. // Text
  1381. svg
  1382. .append('text')
  1383. .attr('class', 'half-conut-count')
  1384. .attr('text-anchor', 'middle')
  1385. .attr('dy', -5)
  1386. .style({
  1387. 'font-size': '21px',
  1388. 'font-weight': 500
  1389. });
  1390. // Animation
  1391. svg.select('.half-conut-count')
  1392. .transition()
  1393. .duration(1500)
  1394. .ease('linear')
  1395. .tween("text", function(d) {
  1396. var i = d3.interpolate(this.textContent, sum);
  1397. return function(t) {
  1398. this.textContent = d3.format(",d")(Math.round(i(t)));
  1399. };
  1400. });
  1401. //
  1402. // Legend
  1403. //
  1404. // Add legend list
  1405. var legend = d3.select(element)
  1406. .append('ul')
  1407. .attr('class', 'chart-widget-legend')
  1408. .selectAll('li')
  1409. .data(pie(data))
  1410. .enter()
  1411. .append('li')
  1412. .attr('data-slice', function(d, i) {
  1413. return i;
  1414. })
  1415. .attr('style', function(d, i) {
  1416. return 'border-bottom: solid 2px ' + d.data.color;
  1417. })
  1418. .text(function(d, i) {
  1419. return d.data.status + ': ';
  1420. });
  1421. // Legend text
  1422. legend.append('span')
  1423. .text(function(d, i) {
  1424. return d.data.value;
  1425. });
  1426. }
  1427. };
  1428. // Simple donut
  1429. var _animatedDonut = function(element, size) {
  1430. if (typeof d3 == 'undefined') {
  1431. console.warn('Warning - d3.min.js is not loaded.');
  1432. return;
  1433. }
  1434. // Initialize chart only if element exsists in the DOM
  1435. if(element) {
  1436. // Add data set
  1437. var data = [
  1438. {
  1439. "status": "Pending tickets",
  1440. "icon": "<i class='badge badge-mark border-blue-300 mr-2'></i>",
  1441. "value": 567,
  1442. "color": "#29B6F6"
  1443. }, {
  1444. "status": "Resolved tickets",
  1445. "icon": "<i class='badge badge-mark border-success-300 mr-2'></i>",
  1446. "value": 234,
  1447. "color": "#66BB6A"
  1448. }, {
  1449. "status": "Closed tickets",
  1450. "icon": "<i class='badge badge-mark border-danger-300 mr-2'></i>",
  1451. "value": 642,
  1452. "color": "#EF5350"
  1453. }
  1454. ];
  1455. // Main variables
  1456. var d3Container = d3.select(element),
  1457. distance = 2, // reserve 2px space for mouseover arc moving
  1458. radius = (size/2) - distance,
  1459. sum = d3.sum(data, function(d) { return d.value; });
  1460. // Tooltip
  1461. // ------------------------------
  1462. var tip = d3.tip()
  1463. .attr('class', 'd3-tip')
  1464. .offset([-10, 0])
  1465. .direction('e')
  1466. .html(function (d) {
  1467. return "<ul class='list-unstyled mb-1'>" +
  1468. "<li>" + "<div class='font-size-base my-1'>" + d.data.icon + d.data.status + "</div>" + "</li>" +
  1469. "<li>" + "Total: &nbsp;" + "<span class='font-weight-semibold float-right'>" + d.value + "</span>" + "</li>" +
  1470. "<li>" + "Share: &nbsp;" + "<span class='font-weight-semibold float-right'>" + (100 / (sum / d.value)).toFixed(2) + "%" + "</span>" + "</li>" +
  1471. "</ul>";
  1472. });
  1473. // Create chart
  1474. // ------------------------------
  1475. // Add svg element
  1476. var container = d3Container.append("svg").call(tip);
  1477. // Add SVG group
  1478. var svg = container
  1479. .attr("width", size)
  1480. .attr("height", size)
  1481. .append("g")
  1482. .attr("transform", "translate(" + (size / 2) + "," + (size / 2) + ")");
  1483. // Construct chart layout
  1484. // ------------------------------
  1485. // Pie
  1486. var pie = d3.layout.pie()
  1487. .sort(null)
  1488. .startAngle(Math.PI)
  1489. .endAngle(3 * Math.PI)
  1490. .value(function (d) {
  1491. return d.value;
  1492. });
  1493. // Arc
  1494. var arc = d3.svg.arc()
  1495. .outerRadius(radius)
  1496. .innerRadius(radius / 1.5);
  1497. //
  1498. // Append chart elements
  1499. //
  1500. // Group chart elements
  1501. var arcGroup = svg.selectAll(".d3-arc")
  1502. .data(pie(data))
  1503. .enter()
  1504. .append("g")
  1505. .attr("class", "d3-arc")
  1506. .style({
  1507. 'stroke': '#fff',
  1508. 'stroke-width': 2,
  1509. 'cursor': 'pointer'
  1510. });
  1511. // Append path
  1512. var arcPath = arcGroup
  1513. .append("path")
  1514. .style("fill", function (d) {
  1515. return d.data.color;
  1516. });
  1517. // Add tooltip
  1518. arcPath
  1519. .on('mouseover', function (d, i) {
  1520. // Transition on mouseover
  1521. d3.select(this)
  1522. .transition()
  1523. .duration(500)
  1524. .ease('elastic')
  1525. .attr('transform', function (d) {
  1526. d.midAngle = ((d.endAngle - d.startAngle) / 2) + d.startAngle;
  1527. var x = Math.sin(d.midAngle) * distance;
  1528. var y = -Math.cos(d.midAngle) * distance;
  1529. return 'translate(' + x + ',' + y + ')';
  1530. });
  1531. })
  1532. .on("mousemove", function (d) {
  1533. // Show tooltip on mousemove
  1534. tip.show(d)
  1535. .style("top", (d3.event.pageY - 40) + "px")
  1536. .style("left", (d3.event.pageX + 30) + "px");
  1537. })
  1538. .on('mouseout', function (d, i) {
  1539. // Mouseout transition
  1540. d3.select(this)
  1541. .transition()
  1542. .duration(500)
  1543. .ease('bounce')
  1544. .attr('transform', 'translate(0,0)');
  1545. // Hide tooltip
  1546. tip.hide(d);
  1547. });
  1548. // Animate chart on load
  1549. arcPath
  1550. .transition()
  1551. .delay(function(d, i) { return i * 500; })
  1552. .duration(500)
  1553. .attrTween("d", function(d) {
  1554. var interpolate = d3.interpolate(d.startAngle,d.endAngle);
  1555. return function(t) {
  1556. d.endAngle = interpolate(t);
  1557. return arc(d);
  1558. };
  1559. });
  1560. //
  1561. // Append counter
  1562. //
  1563. // Append text
  1564. svg
  1565. .append('text')
  1566. .attr('text-anchor', 'middle')
  1567. .attr('dy', 6)
  1568. .style({
  1569. 'font-size': '17px',
  1570. 'font-weight': 500
  1571. });
  1572. // Animate text
  1573. svg.select('text')
  1574. .transition()
  1575. .duration(1500)
  1576. .tween("text", function(d) {
  1577. var i = d3.interpolate(this.textContent, sum);
  1578. return function(t) {
  1579. this.textContent = d3.format(",d")(Math.round(i(t)));
  1580. };
  1581. });
  1582. }
  1583. };
  1584. // Donut with legend
  1585. var _animatedDonutWithLegend = function(element, size) {
  1586. if (typeof d3 == 'undefined') {
  1587. console.warn('Warning - d3.min.js is not loaded.');
  1588. return;
  1589. }
  1590. // Initialize chart only if element exsists in the DOM
  1591. if(element) {
  1592. // Add data set
  1593. var data = [
  1594. {
  1595. "status": "New",
  1596. "value": 790,
  1597. "color": "#29B6F6"
  1598. }, {
  1599. "status": "Pending",
  1600. "value": 850,
  1601. "color": "#66BB6A"
  1602. }, {
  1603. "status": "Shipped",
  1604. "value": 760,
  1605. "color": "#EF5350"
  1606. }
  1607. ];
  1608. // Main variables
  1609. var d3Container = d3.select(element),
  1610. distance = 2, // reserve 2px space for mouseover arc moving
  1611. radius = (size/2) - distance,
  1612. sum = d3.sum(data, function(d) { return d.value; });
  1613. // Create chart
  1614. // ------------------------------
  1615. // Add svg element
  1616. var container = d3Container.append("svg");
  1617. // Add SVG group
  1618. var svg = container
  1619. .attr("width", size)
  1620. .attr("height", size)
  1621. .append("g")
  1622. .attr("transform", "translate(" + (size / 2) + "," + (size / 2) + ")");
  1623. // Construct chart layout
  1624. // ------------------------------
  1625. // Pie
  1626. var pie = d3.layout.pie()
  1627. .sort(null)
  1628. .startAngle(Math.PI)
  1629. .endAngle(3 * Math.PI)
  1630. .value(function (d) {
  1631. return d.value;
  1632. });
  1633. // Arc
  1634. var arc = d3.svg.arc()
  1635. .outerRadius(radius)
  1636. .innerRadius(radius / 1.5);
  1637. //
  1638. // Append chart elements
  1639. //
  1640. // Group chart elements
  1641. var arcGroup = svg.selectAll(".d3-arc")
  1642. .data(pie(data))
  1643. .enter()
  1644. .append("g")
  1645. .attr("class", "d3-arc")
  1646. .style({
  1647. 'stroke': '#fff',
  1648. 'stroke-width': 2,
  1649. 'cursor': 'pointer'
  1650. });
  1651. // Append path
  1652. var arcPath = arcGroup
  1653. .append("path")
  1654. .style("fill", function (d) {
  1655. return d.data.color;
  1656. });
  1657. // Add interactions
  1658. arcPath
  1659. .on('mouseover', function (d, i) {
  1660. // Transition on mouseover
  1661. d3.select(this)
  1662. .transition()
  1663. .duration(500)
  1664. .ease('elastic')
  1665. .attr('transform', function (d) {
  1666. d.midAngle = ((d.endAngle - d.startAngle) / 2) + d.startAngle;
  1667. var x = Math.sin(d.midAngle) * distance;
  1668. var y = -Math.cos(d.midAngle) * distance;
  1669. return 'translate(' + x + ',' + y + ')';
  1670. });
  1671. // Animate legend
  1672. $(element + ' [data-slice]').css({
  1673. 'opacity': 0.3,
  1674. 'transition': 'all ease-in-out 0.15s'
  1675. });
  1676. $(element + ' [data-slice=' + i + ']').css({'opacity': 1});
  1677. })
  1678. .on('mouseout', function (d, i) {
  1679. // Mouseout transition
  1680. d3.select(this)
  1681. .transition()
  1682. .duration(500)
  1683. .ease('bounce')
  1684. .attr('transform', 'translate(0,0)');
  1685. // Revert legend animation
  1686. $(element + ' [data-slice]').css('opacity', 1);
  1687. });
  1688. // Animate chart on load
  1689. arcPath
  1690. .transition()
  1691. .delay(function(d, i) {
  1692. return i * 500;
  1693. })
  1694. .duration(500)
  1695. .attrTween("d", function(d) {
  1696. var interpolate = d3.interpolate(d.startAngle,d.endAngle);
  1697. return function(t) {
  1698. d.endAngle = interpolate(t);
  1699. return arc(d);
  1700. };
  1701. });
  1702. //
  1703. // Append counter
  1704. //
  1705. // Append text
  1706. svg
  1707. .append('text')
  1708. .attr('text-anchor', 'middle')
  1709. .attr('dy', 6)
  1710. .style({
  1711. 'font-size': '17px',
  1712. 'font-weight': 500
  1713. });
  1714. // Animate text
  1715. svg.select('text')
  1716. .transition()
  1717. .duration(1500)
  1718. .tween("text", function(d) {
  1719. var i = d3.interpolate(this.textContent, sum);
  1720. return function(t) {
  1721. this.textContent = d3.format(",d")(Math.round(i(t)));
  1722. };
  1723. });
  1724. //
  1725. // Append legend
  1726. //
  1727. // Add element
  1728. var legend = d3.select(element)
  1729. .append('ul')
  1730. .attr('class', 'chart-widget-legend')
  1731. .selectAll('li').data(pie(data))
  1732. .enter().append('li')
  1733. .attr('data-slice', function(d, i) {
  1734. return i;
  1735. })
  1736. .attr('style', function(d, i) {
  1737. return 'border-bottom: 2px solid ' + d.data.color;
  1738. })
  1739. .text(function(d, i) {
  1740. return d.data.status + ': ';
  1741. });
  1742. // Add value
  1743. legend.append('span')
  1744. .text(function(d, i) {
  1745. return d.data.value;
  1746. });
  1747. }
  1748. };
  1749. // Donut with details
  1750. var _donutWithDetails = function(element, size) {
  1751. if (typeof d3 == 'undefined') {
  1752. console.warn('Warning - d3.min.js is not loaded.');
  1753. return;
  1754. }
  1755. // Initialize chart only if element exsists in the DOM
  1756. if(element) {
  1757. // Basic setup
  1758. // ------------------------------
  1759. // Add data set
  1760. var data = [
  1761. {
  1762. "status": "Pending",
  1763. "icon": "<i class='badge badge-mark border-blue-300 mr-2'></i>",
  1764. "value": 720,
  1765. "color": "#29B6F6"
  1766. }, {
  1767. "status": "Resolved",
  1768. "icon": "<i class='badge badge-mark border-success-300 mr-2'></i>",
  1769. "value": 990,
  1770. "color": "#66BB6A"
  1771. }, {
  1772. "status": "Closed",
  1773. "icon": "<i class='badge badge-mark border-danger-300 mr-2'></i>",
  1774. "value": 720,
  1775. "color": "#EF5350"
  1776. }
  1777. ];
  1778. // Main variables
  1779. var d3Container = d3.select(element),
  1780. distance = 2, // reserve 2px space for mouseover arc moving
  1781. radius = (size/2) - distance,
  1782. sum = d3.sum(data, function(d) { return d.value; });
  1783. // Tooltip
  1784. // ------------------------------
  1785. var tip = d3.tip()
  1786. .attr('class', 'd3-tip')
  1787. .offset([-10, 0])
  1788. .direction('e')
  1789. .html(function (d) {
  1790. return "<ul class='list-unstyled mb-1'>" +
  1791. "<li>" + "<div class='font-size-base my-1'>" + d.data.icon + d.data.status + "</div>" + "</li>" +
  1792. "<li>" + "Total: &nbsp;" + "<span class='font-weight-semibold float-right'>" + d.value + "</span>" + "</li>" +
  1793. "<li>" + "Share: &nbsp;" + "<span class='font-weight-semibold float-right'>" + (100 / (sum / d.value)).toFixed(2) + "%" + "</span>" + "</li>" +
  1794. "</ul>";
  1795. });
  1796. // Create chart
  1797. // ------------------------------
  1798. // Add svg element
  1799. var container = d3Container.append("svg").call(tip);
  1800. // Add SVG group
  1801. var svg = container
  1802. .attr("width", size)
  1803. .attr("height", size)
  1804. .append("g")
  1805. .attr("transform", "translate(" + (size / 2) + "," + (size / 2) + ")");
  1806. // Construct chart layout
  1807. // ------------------------------
  1808. // Pie
  1809. var pie = d3.layout.pie()
  1810. .sort(null)
  1811. .startAngle(Math.PI)
  1812. .endAngle(3 * Math.PI)
  1813. .value(function (d) {
  1814. return d.value;
  1815. });
  1816. // Arc
  1817. var arc = d3.svg.arc()
  1818. .outerRadius(radius)
  1819. .innerRadius(radius / 1.35);
  1820. //
  1821. // Append chart elements
  1822. //
  1823. // Group chart elements
  1824. var arcGroup = svg.selectAll(".d3-arc")
  1825. .data(pie(data))
  1826. .enter()
  1827. .append("g")
  1828. .attr("class", "d3-arc")
  1829. .style({
  1830. 'stroke': '#fff',
  1831. 'stroke-width': 2,
  1832. 'cursor': 'pointer'
  1833. });
  1834. // Append path
  1835. var arcPath = arcGroup
  1836. .append("path")
  1837. .style("fill", function (d) {
  1838. return d.data.color;
  1839. });
  1840. //
  1841. // Add interactions
  1842. //
  1843. // Mouse
  1844. arcPath
  1845. .on('mouseover', function(d, i) {
  1846. // Transition on mouseover
  1847. d3.select(this)
  1848. .transition()
  1849. .duration(500)
  1850. .ease('elastic')
  1851. .attr('transform', function (d) {
  1852. d.midAngle = ((d.endAngle - d.startAngle) / 2) + d.startAngle;
  1853. var x = Math.sin(d.midAngle) * distance;
  1854. var y = -Math.cos(d.midAngle) * distance;
  1855. return 'translate(' + x + ',' + y + ')';
  1856. });
  1857. $(element + ' [data-slice]').css({
  1858. 'opacity': 0.3,
  1859. 'transition': 'all ease-in-out 0.15s'
  1860. });
  1861. $(element + ' [data-slice=' + i + ']').css({'opacity': 1});
  1862. })
  1863. .on('mouseout', function(d, i) {
  1864. // Mouseout transition
  1865. d3.select(this)
  1866. .transition()
  1867. .duration(500)
  1868. .ease('bounce')
  1869. .attr('transform', 'translate(0,0)');
  1870. $(element + ' [data-slice]').css('opacity', 1);
  1871. });
  1872. // Animate chart on load
  1873. arcPath
  1874. .transition()
  1875. .delay(function(d, i) {
  1876. return i * 500;
  1877. })
  1878. .duration(500)
  1879. .attrTween("d", function(d) {
  1880. var interpolate = d3.interpolate(d.startAngle,d.endAngle);
  1881. return function(t) {
  1882. d.endAngle = interpolate(t);
  1883. return arc(d);
  1884. };
  1885. });
  1886. //
  1887. // Add text
  1888. //
  1889. // Total
  1890. svg.append('text')
  1891. .attr('class', 'text-muted')
  1892. .attr({
  1893. 'class': 'half-donut-total',
  1894. 'text-anchor': 'middle',
  1895. 'dy': -13
  1896. })
  1897. .style({
  1898. 'font-size': '12px',
  1899. 'fill': '#999'
  1900. })
  1901. .text('Total');
  1902. // Count
  1903. svg
  1904. .append('text')
  1905. .attr('class', 'half-donut-count')
  1906. .attr('text-anchor', 'middle')
  1907. .attr('dy', 14)
  1908. .style({
  1909. 'font-size': '21px',
  1910. 'font-weight': 500
  1911. });
  1912. // Animate count
  1913. svg.select('.half-donut-count')
  1914. .transition()
  1915. .duration(1500)
  1916. .ease('linear')
  1917. .tween("text", function(d) {
  1918. var i = d3.interpolate(this.textContent, sum);
  1919. return function(t) {
  1920. this.textContent = d3.format(",d")(Math.round(i(t)));
  1921. };
  1922. });
  1923. //
  1924. // Add legend
  1925. //
  1926. // Append list
  1927. var legend = d3.select(element)
  1928. .append('ul')
  1929. .attr('class', 'chart-widget-legend')
  1930. .selectAll('li')
  1931. .data(pie(data))
  1932. .enter()
  1933. .append('li')
  1934. .attr('data-slice', function(d, i) {
  1935. return i;
  1936. })
  1937. .attr('style', function(d, i) {
  1938. return 'border-bottom: solid 2px ' + d.data.color;
  1939. })
  1940. .text(function(d, i) {
  1941. return d.data.status + ': ';
  1942. });
  1943. // Append text
  1944. legend.append('span')
  1945. .text(function(d, i) {
  1946. return d.data.value;
  1947. });
  1948. }
  1949. };
  1950. // Progress arc - single color
  1951. var _progressArcSingle = function(element, size) {
  1952. if (typeof d3 == 'undefined') {
  1953. console.warn('Warning - d3.min.js is not loaded.');
  1954. return;
  1955. }
  1956. // Initialize chart only if element exsists in the DOM
  1957. if(element) {
  1958. // Main variables
  1959. var d3Container = d3.select(element),
  1960. radius = size,
  1961. thickness = 20,
  1962. color = '#29B6F6';
  1963. // Create chart
  1964. // ------------------------------
  1965. // Add svg element
  1966. var container = d3Container.append("svg");
  1967. // Add SVG group
  1968. var svg = container
  1969. .attr('width', radius * 2)
  1970. .attr('height', radius + 20)
  1971. .attr('class', 'gauge');
  1972. // Construct chart layout
  1973. // ------------------------------
  1974. // Pie
  1975. var arc = d3.svg.arc()
  1976. .innerRadius(radius - thickness)
  1977. .outerRadius(radius)
  1978. .startAngle(-Math.PI / 2);
  1979. // Append chart elements
  1980. // ------------------------------
  1981. //
  1982. // Group arc elements
  1983. //
  1984. // Group
  1985. var chart = svg.append('g')
  1986. .attr('transform', 'translate(' + radius + ',' + radius + ')');
  1987. // Background
  1988. var background = chart.append('path')
  1989. .datum({
  1990. endAngle: Math.PI / 2
  1991. })
  1992. .attr({
  1993. 'd': arc,
  1994. 'fill': '#eee'
  1995. });
  1996. // Foreground
  1997. var foreground = chart.append('path')
  1998. .datum({
  1999. endAngle: -Math.PI / 2
  2000. })
  2001. .style('fill', color)
  2002. .attr('d', arc);
  2003. // Counter value
  2004. var value = svg.append('g')
  2005. .attr('transform', 'translate(' + radius + ',' + (radius * 0.9) + ')')
  2006. .append('text')
  2007. .text(0 + '%')
  2008. .attr({
  2009. 'text-anchor': 'middle',
  2010. 'fill': '#555'
  2011. })
  2012. .style({
  2013. 'font-size': 19,
  2014. 'font-weight': 400
  2015. });
  2016. //
  2017. // Min and max text
  2018. //
  2019. // Group
  2020. var scale = svg.append('g')
  2021. .attr('transform', 'translate(' + radius + ',' + (radius + 15) + ')')
  2022. .style({
  2023. 'font-size': 12,
  2024. 'fill': '#999'
  2025. });
  2026. // Max
  2027. scale.append('text')
  2028. .text(100)
  2029. .attr({
  2030. 'text-anchor': 'middle',
  2031. 'x': (radius - thickness / 2)
  2032. });
  2033. // Min
  2034. scale.append('text')
  2035. .text(0)
  2036. .attr({
  2037. 'text-anchor': 'middle',
  2038. 'x': -(radius - thickness / 2)
  2039. });
  2040. //
  2041. // Animation
  2042. //
  2043. // Interval
  2044. setInterval(function() {
  2045. update(Math.random() * 100);
  2046. }, 1500);
  2047. // Update
  2048. function update(v) {
  2049. v = d3.format('.0f')(v);
  2050. foreground.transition()
  2051. .duration(750)
  2052. .call(arcTween, v);
  2053. value.transition()
  2054. .duration(750)
  2055. .call(textTween, v);
  2056. }
  2057. // Arc
  2058. function arcTween(transition, v) {
  2059. var newAngle = v / 100 * Math.PI - Math.PI / 2;
  2060. transition.attrTween('d', function(d) {
  2061. var interpolate = d3.interpolate(d.endAngle, newAngle);
  2062. return function(t) {
  2063. d.endAngle = interpolate(t);
  2064. return arc(d);
  2065. };
  2066. });
  2067. }
  2068. // Text
  2069. function textTween(transition, v) {
  2070. transition.tween('text', function() {
  2071. var interpolate = d3.interpolate(this.innerHTML, v),
  2072. split = (v + '').split('.'),
  2073. round = (split.length > 1) ? Math.pow(10, split[1].length) : 1;
  2074. return function(t) {
  2075. this.innerHTML = d3.format('.0f')(Math.round(interpolate(t) * round) / round) + '<tspan>%</tspan>';
  2076. };
  2077. });
  2078. }
  2079. }
  2080. };
  2081. // Progress arc - multiple colors
  2082. var _progressArcMulti = function(element, size, goal) {
  2083. if (typeof d3 == 'undefined') {
  2084. console.warn('Warning - d3.min.js is not loaded.');
  2085. return;
  2086. }
  2087. // Initialize chart only if element exsists in the DOM
  2088. if(element) {
  2089. // Main variables
  2090. var d3Container = d3.select(element),
  2091. radius = size,
  2092. thickness = 20,
  2093. startColor = '#66BB6A',
  2094. midColor = '#FFA726',
  2095. endColor = '#EF5350';
  2096. // Colors
  2097. var color = d3.scale.linear()
  2098. .domain([0, 70, 100])
  2099. .range([startColor, midColor, endColor]);
  2100. // Create chart
  2101. // ------------------------------
  2102. // Add svg element
  2103. var container = d3Container.append("svg");
  2104. // Add SVG group
  2105. var svg = container
  2106. .attr('width', radius * 2)
  2107. .attr('height', radius + 20);
  2108. // Construct chart layout
  2109. // ------------------------------
  2110. // Pie
  2111. var arc = d3.svg.arc()
  2112. .innerRadius(radius - thickness)
  2113. .outerRadius(radius)
  2114. .startAngle(-Math.PI / 2);
  2115. // Append chart elements
  2116. // ------------------------------
  2117. //
  2118. // Group arc elements
  2119. //
  2120. // Group
  2121. var chart = svg.append('g')
  2122. .attr('transform', 'translate(' + radius + ',' + radius + ')');
  2123. // Background
  2124. var background = chart.append('path')
  2125. .datum({
  2126. endAngle: Math.PI / 2
  2127. })
  2128. .attr({
  2129. 'd': arc,
  2130. 'fill': '#eee'
  2131. });
  2132. // Foreground
  2133. var foreground = chart.append('path')
  2134. .datum({
  2135. endAngle: -Math.PI / 2
  2136. })
  2137. .style('fill', startColor)
  2138. .attr('d', arc);
  2139. // Counter value
  2140. var value = svg.append('g')
  2141. .attr('transform', 'translate(' + radius + ',' + (radius * 0.9) + ')')
  2142. .append('text')
  2143. .text(0 + '%')
  2144. .attr({
  2145. 'text-anchor': 'middle',
  2146. 'fill': '#555'
  2147. })
  2148. .style({
  2149. 'font-size': 19,
  2150. 'font-weight': 400
  2151. });
  2152. //
  2153. // Min and max text
  2154. //
  2155. // Group
  2156. var scale = svg.append('g')
  2157. .attr('transform', 'translate(' + radius + ',' + (radius + 15) + ')')
  2158. .style({
  2159. 'font-size': 12,
  2160. 'fill': '#999'
  2161. });
  2162. // Max
  2163. scale.append('text')
  2164. .text(100)
  2165. .attr({
  2166. 'text-anchor': 'middle',
  2167. 'x': (radius - thickness / 2)
  2168. });
  2169. // Min
  2170. scale.append('text')
  2171. .text(0)
  2172. .attr({
  2173. 'text-anchor': 'middle',
  2174. 'x': -(radius - thickness / 2)
  2175. });
  2176. //
  2177. // Animation
  2178. //
  2179. // Interval
  2180. setInterval(function() {
  2181. update(Math.random() * 100);
  2182. }, 1500);
  2183. // Update
  2184. function update(v) {
  2185. v = d3.format('.0f')(v);
  2186. foreground.transition()
  2187. .duration(750)
  2188. .style('fill', function() {
  2189. return color(v);
  2190. })
  2191. .call(arcTween, v);
  2192. value.transition()
  2193. .duration(750)
  2194. .call(textTween, v);
  2195. }
  2196. // Arc
  2197. function arcTween(transition, v) {
  2198. var newAngle = v / 100 * Math.PI - Math.PI / 2;
  2199. transition.attrTween('d', function(d) {
  2200. var interpolate = d3.interpolate(d.endAngle, newAngle);
  2201. return function(t) {
  2202. d.endAngle = interpolate(t);
  2203. return arc(d);
  2204. };
  2205. });
  2206. }
  2207. // Text
  2208. function textTween(transition, v) {
  2209. transition.tween('text', function() {
  2210. var interpolate = d3.interpolate(this.innerHTML, v),
  2211. split = (v + '').split('.'),
  2212. round = (split.length > 1) ? Math.pow(10, split[1].length) : 1;
  2213. return function(t) {
  2214. this.innerHTML = d3.format('.0f')(Math.round(interpolate(t) * round) / round) + '<tspan>%</tspan>';
  2215. };
  2216. });
  2217. }
  2218. }
  2219. };
  2220. // Rounded progress - single arc
  2221. var _roundedProgressSingle = function(element, size, goal, color) {
  2222. if (typeof d3 == 'undefined') {
  2223. console.warn('Warning - d3.min.js is not loaded.');
  2224. return;
  2225. }
  2226. // Initialize chart only if element exsists in the DOM
  2227. if(element) {
  2228. // Add random data
  2229. var dataset = function () {
  2230. return [
  2231. {percentage: Math.random() * 100}
  2232. ];
  2233. };
  2234. // Main variables
  2235. var d3Container = d3.select(element),
  2236. padding = 2,
  2237. strokeWidth = 16,
  2238. width = size,
  2239. height = size,
  2240. τ = 2 * Math.PI;
  2241. // Create chart
  2242. // ------------------------------
  2243. // Add svg element
  2244. var container = d3Container.append("svg");
  2245. // Add SVG group
  2246. var svg = container
  2247. .attr("width", width)
  2248. .attr("height", height)
  2249. .append("g")
  2250. .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
  2251. // Construct chart layout
  2252. // ------------------------------
  2253. // Foreground arc
  2254. var arc = d3.svg.arc()
  2255. .startAngle(0)
  2256. .endAngle(function (d) {
  2257. return d.percentage / 100 * τ;
  2258. })
  2259. .innerRadius((size / 2) - strokeWidth)
  2260. .outerRadius((size / 2) - padding)
  2261. .cornerRadius(20);
  2262. // Background arc
  2263. var background = d3.svg.arc()
  2264. .startAngle(0)
  2265. .endAngle(τ)
  2266. .innerRadius((size / 2) - strokeWidth)
  2267. .outerRadius((size / 2) - padding);
  2268. // Append chart elements
  2269. // ------------------------------
  2270. //
  2271. // Group arc elements
  2272. //
  2273. // Group
  2274. var field = svg.selectAll("g")
  2275. .data(dataset)
  2276. .enter().append("g");
  2277. // Foreground arc
  2278. field
  2279. .append("path")
  2280. .attr("class", "arc-foreground")
  2281. .attr('fill', color);
  2282. // Background arc
  2283. field
  2284. .append("path")
  2285. .attr("d", background)
  2286. .style({
  2287. "fill": color,
  2288. "opacity": 0.2
  2289. });
  2290. //
  2291. // Text
  2292. //
  2293. // Goal
  2294. field
  2295. .append("text")
  2296. .text("Out of " + goal)
  2297. .attr("transform", "translate(0,20)")
  2298. .style({
  2299. 'font-size': 11,
  2300. 'fill': '#999',
  2301. 'font-weight': 500,
  2302. 'text-transform': 'uppercase',
  2303. 'text-anchor': 'middle'
  2304. });
  2305. // Count
  2306. field
  2307. .append("text")
  2308. .attr('class', 'arc-goal-completed')
  2309. .attr("transform", "translate(0,0)")
  2310. .style({
  2311. 'font-size': 23,
  2312. 'font-weight': 500,
  2313. 'text-anchor': 'middle'
  2314. });
  2315. //
  2316. // Animate elements
  2317. //
  2318. // Add transition
  2319. d3.transition().duration(2500).each(update);
  2320. // Animation
  2321. function update() {
  2322. field = field
  2323. .each(function (d) {
  2324. this._value = d.percentage;
  2325. })
  2326. .data(dataset)
  2327. .each(function (d) {
  2328. d.previousValue = this._value;
  2329. });
  2330. // Foreground arc
  2331. field
  2332. .select(".arc-foreground")
  2333. .transition()
  2334. .duration(600)
  2335. .ease("easeInOut")
  2336. .attrTween("d", arcTween);
  2337. // Update count text
  2338. field
  2339. .select(".arc-goal-completed")
  2340. .text(function (d) {
  2341. return Math.round(d.percentage /100 * goal);
  2342. });
  2343. // Animate count text
  2344. svg.select('.arc-goal-completed')
  2345. .transition()
  2346. .duration(600)
  2347. .tween("text", function(d) {
  2348. var i = d3.interpolate(this.textContent, d.percentage);
  2349. return function(t) {
  2350. this.textContent = Math.floor(d.percentage/100 * goal);
  2351. };
  2352. });
  2353. // Update every 4 seconds (for demo)
  2354. setTimeout(update, 4000);
  2355. }
  2356. // Arc animation
  2357. function arcTween(d) {
  2358. var i = d3.interpolateNumber(d.previousValue, d.percentage);
  2359. return function (t) {
  2360. d.percentage = i(t);
  2361. return arc(d);
  2362. };
  2363. }
  2364. }
  2365. };
  2366. // Rounded progress - multiple arcs
  2367. var _roundedProgressMultiple = function(element, size) {
  2368. if (typeof d3 == 'undefined') {
  2369. console.warn('Warning - d3.min.js is not loaded.');
  2370. return;
  2371. }
  2372. // Initialize chart only if element exsists in the DOM
  2373. if(element) {
  2374. // Add random data
  2375. var data = [
  2376. {index: 0, name: 'Memory', percentage: 0},
  2377. {index: 1, name: 'CPU', percentage: 0},
  2378. {index: 2, name: 'Sessions', percentage: 0}
  2379. ];
  2380. // Main variables
  2381. var d3Container = d3.select(element),
  2382. padding = 2,
  2383. strokeWidth = 8,
  2384. width = size,
  2385. height = size,
  2386. τ = 2 * Math.PI;
  2387. // Colors
  2388. var colors = ['#78909C', '#F06292', '#4DB6AC'];
  2389. // Create chart
  2390. // ------------------------------
  2391. // Add svg element
  2392. var container = d3Container.append("svg");
  2393. // Add SVG group
  2394. var svg = container
  2395. .attr("width", width)
  2396. .attr("height", height)
  2397. .append("g")
  2398. .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
  2399. // Construct chart layout
  2400. // ------------------------------
  2401. // Foreground arc
  2402. var arc = d3.svg.arc()
  2403. .startAngle(0)
  2404. .endAngle(function (d) {
  2405. return d.percentage / 100 * τ;
  2406. })
  2407. .innerRadius(function (d) {
  2408. return (size / 2) - d.index * (strokeWidth + padding);
  2409. })
  2410. .outerRadius(function (d) {
  2411. return ((size / 2) - d.index * (strokeWidth + padding)) - strokeWidth;
  2412. })
  2413. .cornerRadius(20);
  2414. // Background arc
  2415. var background = d3.svg.arc()
  2416. .startAngle(0)
  2417. .endAngle(τ)
  2418. .innerRadius(function (d) {
  2419. return (size / 2) - d.index * (strokeWidth + padding);
  2420. })
  2421. .outerRadius(function (d) {
  2422. return ((size / 2) - d.index * (strokeWidth + padding)) - strokeWidth;
  2423. });
  2424. // Append chart elements
  2425. // ------------------------------
  2426. //
  2427. // Group arc elements
  2428. //
  2429. // Group
  2430. var field = svg.selectAll("g")
  2431. .data(data)
  2432. .enter().append("g");
  2433. // Foreground arcs
  2434. field
  2435. .append("path")
  2436. .attr("class", "arc-foreground")
  2437. .style("fill", function (d, i) {
  2438. return colors[i];
  2439. });
  2440. // Background arcs
  2441. field
  2442. .append("path")
  2443. .style("fill", function (d, i) {
  2444. return colors[i];
  2445. })
  2446. .style("opacity", 0.1)
  2447. .attr("d", background);
  2448. //
  2449. // Add legend
  2450. //
  2451. // Append list
  2452. var legend = d3.select(element)
  2453. .append('ul')
  2454. .attr('class', 'chart-widget-legend text-muted')
  2455. .selectAll('li')
  2456. .data(data)
  2457. .enter()
  2458. .append('li')
  2459. .attr('data-slice', function(d, i) {
  2460. return i;
  2461. })
  2462. .attr('style', function(d, i) {
  2463. return 'border-bottom: solid 2px ' + colors[i];
  2464. })
  2465. .text(function(d, i) {
  2466. return d.name;
  2467. });
  2468. //
  2469. // Animate elements
  2470. //
  2471. // Add transition
  2472. d3.transition().each(update);
  2473. // Animation
  2474. function update() {
  2475. field = field
  2476. .each(function (d) {
  2477. this._value = d.percentage;
  2478. })
  2479. .data(data)
  2480. .each(function (d) {
  2481. d.previousValue = this._value;
  2482. d.percentage = Math.round(Math.random() * 100) + 1;
  2483. });
  2484. // Foreground arcs
  2485. field
  2486. .select("path.arc-foreground")
  2487. .transition()
  2488. .duration(750)
  2489. .ease("easeInOut")
  2490. .attrTween("d", arcTween);
  2491. // Update every 4 seconds
  2492. setTimeout(update, 4000);
  2493. }
  2494. // Arc animation
  2495. function arcTween(d) {
  2496. var i = d3.interpolateNumber(d.previousValue, d.percentage);
  2497. return function (t) {
  2498. d.percentage = i(t);
  2499. return arc(d);
  2500. };
  2501. }
  2502. }
  2503. };
  2504. // Pie with progress bar
  2505. var _pieWithProgress = function(element, size) {
  2506. if (typeof d3 == 'undefined') {
  2507. console.warn('Warning - d3.min.js is not loaded.');
  2508. return;
  2509. }
  2510. // Initialize chart only if element exsists in the DOM
  2511. if(element) {
  2512. // Demo dataset
  2513. var dataset = [
  2514. { name: 'New', count: 639 },
  2515. { name: 'Pending', count: 255 },
  2516. { name: 'Shipped', count: 215 }
  2517. ];
  2518. // Main variables
  2519. var d3Container = d3.select(element),
  2520. total = 0,
  2521. width = size,
  2522. height = size,
  2523. progressSpacing = 6,
  2524. progressSize = (progressSpacing + 2),
  2525. arcSize = 20,
  2526. outerRadius = (width / 2),
  2527. innerRadius = (outerRadius - arcSize);
  2528. // Colors
  2529. var color = d3.scale.ordinal()
  2530. .range(['#EF5350', '#29b6f6', '#66BB6A']);
  2531. // Create chart
  2532. // ------------------------------
  2533. // Add svg element
  2534. var container = d3Container.append("svg");
  2535. // Add SVG group
  2536. var svg = container
  2537. .attr("width", width)
  2538. .attr("height", height)
  2539. .append("g")
  2540. .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
  2541. // Construct chart layout
  2542. // ------------------------------
  2543. // Add dataset
  2544. dataset.forEach(function(d){
  2545. total+= d.count;
  2546. });
  2547. // Pie layout
  2548. var pie = d3.layout.pie()
  2549. .value(function(d){ return d.count; })
  2550. .sort(null);
  2551. // Inner arc
  2552. var arc = d3.svg.arc()
  2553. .innerRadius(innerRadius)
  2554. .outerRadius(outerRadius);
  2555. // Line arc
  2556. var arcLine = d3.svg.arc()
  2557. .innerRadius(innerRadius - progressSize)
  2558. .outerRadius(innerRadius - progressSpacing)
  2559. .startAngle(0);
  2560. // Append chart elements
  2561. // ------------------------------
  2562. //
  2563. // Animations
  2564. //
  2565. var arcTween = function(transition, newAngle) {
  2566. transition.attrTween("d", function (d) {
  2567. var interpolate = d3.interpolate(d.endAngle, newAngle);
  2568. var interpolateCount = d3.interpolate(0, dataset[0].count);
  2569. return function (t) {
  2570. d.endAngle = interpolate(t);
  2571. middleCount.text(d3.format(",d")(Math.floor(interpolateCount(t))));
  2572. return arcLine(d);
  2573. };
  2574. });
  2575. };
  2576. //
  2577. // Donut paths
  2578. //
  2579. // Donut
  2580. var path = svg.selectAll('path')
  2581. .data(pie(dataset))
  2582. .enter()
  2583. .append('path')
  2584. .attr('d', arc)
  2585. .attr('fill', function(d, i) {
  2586. return color(d.data.name);
  2587. })
  2588. .style({
  2589. 'stroke': '#fff',
  2590. 'stroke-width': 2,
  2591. 'cursor': 'pointer'
  2592. });
  2593. // Animate donut
  2594. path
  2595. .transition()
  2596. .delay(function(d, i) { return i; })
  2597. .duration(600)
  2598. .attrTween("d", function(d) {
  2599. var interpolate = d3.interpolate(d.startAngle, d.endAngle);
  2600. return function(t) {
  2601. d.endAngle = interpolate(t);
  2602. return arc(d);
  2603. };
  2604. });
  2605. //
  2606. // Line path
  2607. //
  2608. // Line
  2609. var pathLine = svg.append('path')
  2610. .datum({endAngle: 0})
  2611. .attr('d', arcLine)
  2612. .style({
  2613. fill: color('New')
  2614. });
  2615. // Line animation
  2616. pathLine.transition()
  2617. .duration(600)
  2618. .delay(300)
  2619. .call(arcTween, (2 * Math.PI) * (dataset[0].count / total));
  2620. //
  2621. // Add count text
  2622. //
  2623. var middleCount = svg.append('text')
  2624. .datum(0)
  2625. .attr('dy', 6)
  2626. .style({
  2627. 'font-size': '21px',
  2628. 'font-weight': 500,
  2629. 'text-anchor': 'middle'
  2630. })
  2631. .text(function(d){
  2632. return d;
  2633. });
  2634. //
  2635. // Add interactions
  2636. //
  2637. // Mouse
  2638. path
  2639. .on('mouseover', function(d, i) {
  2640. $(element + ' [data-slice]').css({
  2641. 'opacity': 0.3,
  2642. 'transition': 'all ease-in-out 0.15s'
  2643. });
  2644. $(element + ' [data-slice=' + i + ']').css({'opacity': 1});
  2645. })
  2646. .on('mouseout', function(d, i) {
  2647. $(element + ' [data-slice]').css('opacity', 1);
  2648. });
  2649. //
  2650. // Add legend
  2651. //
  2652. // Append list
  2653. var legend = d3.select(element)
  2654. .append('ul')
  2655. .attr('class', 'chart-widget-legend')
  2656. .selectAll('li')
  2657. .data(pie(dataset))
  2658. .enter()
  2659. .append('li')
  2660. .attr('data-slice', function(d, i) {
  2661. return i;
  2662. })
  2663. .attr('style', function(d, i) {
  2664. return 'border-bottom: solid 2px ' + color(d.data.name);
  2665. })
  2666. .text(function(d, i) {
  2667. return d.data.name + ': ';
  2668. });
  2669. // Append legend text
  2670. legend.append('span')
  2671. .text(function(d, i) {
  2672. return d.data.count;
  2673. });
  2674. }
  2675. };
  2676. // Segmented gauge
  2677. var _segmentedGauge = function(element, size, min, max, sliceQty) {
  2678. if (typeof d3 == 'undefined') {
  2679. console.warn('Warning - d3.min.js is not loaded.');
  2680. return;
  2681. }
  2682. // Initialize chart only if element exsists in the DOM
  2683. if(element) {
  2684. // Main variables
  2685. var d3Container = d3.select(element),
  2686. width = size,
  2687. height = (size / 2) + 20,
  2688. radius = (size / 2),
  2689. ringInset = 15,
  2690. ringWidth = 20,
  2691. pointerWidth = 10,
  2692. pointerTailLength = 5,
  2693. pointerHeadLengthPercent = 0.75,
  2694. minValue = min,
  2695. maxValue = max,
  2696. minAngle = -90,
  2697. maxAngle = 90,
  2698. slices = sliceQty,
  2699. range = maxAngle - minAngle,
  2700. pointerHeadLength = Math.round(radius * pointerHeadLengthPercent);
  2701. // Colors
  2702. var colors = d3.scale.linear()
  2703. .domain([0, slices - 1])
  2704. .interpolate(d3.interpolateHsl)
  2705. .range(['#66BB6A', '#EF5350']);
  2706. // Create chart
  2707. // ------------------------------
  2708. // Add SVG element
  2709. var container = d3Container.append('svg');
  2710. // Add SVG group
  2711. var svg = container
  2712. .attr('width', width)
  2713. .attr('height', height);
  2714. // Construct chart layout
  2715. // ------------------------------
  2716. // Donut
  2717. var arc = d3.svg.arc()
  2718. .innerRadius(radius - ringWidth - ringInset)
  2719. .outerRadius(radius - ringInset)
  2720. .startAngle(function(d, i) {
  2721. var ratio = d * i;
  2722. return deg2rad(minAngle + (ratio * range));
  2723. })
  2724. .endAngle(function(d, i) {
  2725. var ratio = d * (i + 1);
  2726. return deg2rad(minAngle + (ratio * range));
  2727. });
  2728. // Linear scale that maps domain values to a percent from 0..1
  2729. var scale = d3.scale.linear()
  2730. .range([0, 1])
  2731. .domain([minValue, maxValue]);
  2732. // Ticks
  2733. var ticks = scale.ticks(slices);
  2734. var tickData = d3.range(slices)
  2735. .map(function() {
  2736. return 1 / slices;
  2737. });
  2738. // Calculate angles
  2739. function deg2rad(deg) {
  2740. return deg * Math.PI / 180;
  2741. }
  2742. // Calculate rotation angle
  2743. function newAngle(d) {
  2744. var ratio = scale(d);
  2745. var newAngle = minAngle + (ratio * range);
  2746. return newAngle;
  2747. }
  2748. // Append chart elements
  2749. // ------------------------------
  2750. //
  2751. // Append arc
  2752. //
  2753. // Wrap paths in separate group
  2754. var arcs = svg.append('g')
  2755. .attr('transform', "translate(" + radius + "," + radius + ")")
  2756. .style({
  2757. 'stroke': '#fff',
  2758. 'stroke-width': 2,
  2759. 'shape-rendering': 'crispEdges'
  2760. });
  2761. // Add paths
  2762. arcs.selectAll('path')
  2763. .data(tickData)
  2764. .enter()
  2765. .append('path')
  2766. .attr('fill', function(d, i) {
  2767. return colors(i);
  2768. })
  2769. .attr('d', arc);
  2770. //
  2771. // Text labels
  2772. //
  2773. // Wrap text in separate group
  2774. var arcLabels = svg.append('g')
  2775. .attr('transform', "translate(" + radius + "," + radius + ")");
  2776. // Add text
  2777. arcLabels.selectAll('text')
  2778. .data(ticks)
  2779. .enter()
  2780. .append('text')
  2781. .attr('transform', function(d) {
  2782. var ratio = scale(d);
  2783. var newAngle = minAngle + (ratio * range);
  2784. return 'rotate(' + newAngle + ') translate(0,' + (10 - radius) + ')';
  2785. })
  2786. .style({
  2787. 'text-anchor': 'middle',
  2788. 'font-size': 11,
  2789. 'fill': '#999'
  2790. })
  2791. .text(function(d) { return d + "%"; });
  2792. //
  2793. // Pointer
  2794. //
  2795. // Line data
  2796. var lineData = [
  2797. [pointerWidth / 2, 0],
  2798. [0, -pointerHeadLength],
  2799. [-(pointerWidth / 2), 0],
  2800. [0, pointerTailLength],
  2801. [pointerWidth / 2, 0]
  2802. ];
  2803. // Create line
  2804. var pointerLine = d3.svg.line()
  2805. .interpolate('monotone');
  2806. // Wrap all lines in separate group
  2807. var pointerGroup = svg
  2808. .append('g')
  2809. .data([lineData])
  2810. .attr('transform', "translate(" + radius + "," + radius + ")");
  2811. // Paths
  2812. pointer = pointerGroup
  2813. .append('path')
  2814. .attr('d', pointerLine)
  2815. .attr('transform', 'rotate(' + minAngle + ')');
  2816. // Random update
  2817. // ------------------------------
  2818. // Update values
  2819. function update() {
  2820. var ratio = scale(Math.random() * max);
  2821. var newAngle = minAngle + (ratio * range);
  2822. pointer.transition()
  2823. .duration(2500)
  2824. .ease('elastic')
  2825. .attr('transform', 'rotate(' + newAngle + ')');
  2826. }
  2827. update();
  2828. // Update values every 5 seconds
  2829. setInterval(function() {
  2830. update();
  2831. }, 5000);
  2832. }
  2833. };
  2834. //
  2835. // Return objects assigned to module
  2836. //
  2837. return {
  2838. init: function() {
  2839. _areaChartWidget("#chart_area_basic", 50, '#5C6BC0');
  2840. _areaChartWidget("#chart_area_color", 50, 'rgba(255,255,255,0.75)');
  2841. _barChartWidget("#chart_bar_basic", 24, 50, true, "elastic", 1200, 50, "#EF5350", "members");
  2842. _barChartWidget("#chart_bar_color", 24, 50, true, "elastic", 1200, 50, "rgba(255,255,255,0.75)", "members");
  2843. _lineChartWidget('#line_chart_simple', 50, '#2196F3', 'rgba(33,150,243,0.5)', '#2196F3', '#fff');
  2844. _lineChartWidget('#line_chart_color', 50, '#fff', 'rgba(255,255,255,0.5)', '#fff', '#29B6F6');
  2845. _sparklinesWidget("#sparklines_basic", "area", 30, 50, "basis", 750, 2000, "#66BB6A");
  2846. _sparklinesWidget("#sparklines_color", "area", 30, 50, "basis", 750, 2000, "rgba(255,255,255,0.75)");
  2847. _progressIcon('#progress_icon_one', 42, 2.5, "#eee", "#EF5350", 0.68, "icon-heart6");
  2848. _progressIcon('#progress_icon_two', 42, 2.5, "#eee", "#5C6BC0", 0.82, "icon-trophy3");
  2849. _progressIcon('#progress_icon_three', 42, 2.5, "#00897B", "#fff", 0.73, "icon-bag");
  2850. _progressIcon('#progress_icon_four', 42, 2.5, "#673AB7", "#fff", 0.49, "icon-truck");
  2851. _progressPercentage('#progress_percentage_one', 46, 3, "#eee", "#2196F3", 0.79);
  2852. _progressPercentage('#progress_percentage_two', 46, 3, "#eee", "#EF5350", 0.62);
  2853. _progressPercentage('#progress_percentage_three', 46, 3, "#039BE5", "#fff", 0.69);
  2854. _progressPercentage('#progress_percentage_four', 46, 3, "#E53935", "#fff", 0.43);
  2855. _animatedPie("#pie_basic", 120);
  2856. _animatedPieWithLegend("#pie_basic_legend", 120);
  2857. _pieArcWithLegend("#pie_arc_legend", 170);
  2858. _animatedDonut("#donut_basic_stats", 120);
  2859. _animatedDonutWithLegend("#donut_basic_legend", 120);
  2860. _donutWithDetails("#donut_basic_details", 146);
  2861. _progressArcSingle("#arc_single", 78);
  2862. _progressArcMulti("#arc_multi", 78, 700);
  2863. _roundedProgressSingle("#rounded_progress_single", 150, 700, '#EC407A');
  2864. _roundedProgressMultiple("#rounded_progress_multiple", 140);
  2865. _pieWithProgress("#pie_progress_bar", 146);
  2866. _segmentedGauge("#segmented_gauge", 200, 0, 100, 5);
  2867. }
  2868. }
  2869. }();
  2870. // Initialize module
  2871. // ------------------------------
  2872. // When content loaded
  2873. document.addEventListener('DOMContentLoaded', function() {
  2874. StatisticWidgets.init();
  2875. });