Best JavaScript code snippet using wpt
d3SVGUtil.js
Source:d3SVGUtil.js
1// The point of this util file2// is to centralize common functions on3// graphs such as building axes, etc.4// it relies on the d3 package5// all 'frac' means value between 0 and 16function getSVG(svg_id) {7 //svg_id is str8 9 let svg_d3 = d3.select("#" + svg_id);10 return svg_d311}12function clearSVG(svg_id) {13 //svg_id is str14 let svg_d3 = getSVG(svg_id)15 svg_d3.selectAll("*").remove();16}17function makeSVGAxesAndLabels(svg_id, svg_axes_info, draw_x_axis=true,18 draw_y_axis=true, draw_x_label=true,19 draw_y_label=true) {20 // This function takes the standard form of 21 // SVG graph axes inputs as defined in this package22 // and creates the axis and the labels.23 24 // Args:25 // svg_id: (str) DOM id of svg26 // svg_axes_info: Object27 // graph_i (Where points are plotted)28 // blc <x frac from left, y frac from top>29 // trc <x frac from left, y frac from top>30 // x_i: 31 // x_title_i:32 // blc: <x frac from left, y frac from top>33 // trc: <x frac from left, y frac from top>34 // style_i:35 // name (Str) -> value (str)36 // label: str37 // x_axis_i:38 // lc: <x frac from left, y frac from top>39 // len_frac: Number (frac length of axis)40 // style_i (as above in x_title_i)41 // y_i: Same as x_i with property "bc" instead of "lc"42 let d3svg = getSVG(svg_id)43 // we get a document object model version of the svg for dimensions44 let svg_dobj = document.getElementById(svg_id)45 let dWidth = svg_dobj.clientWidth46 let dHeight = svg_dobj.clientHeight47 let x_i = svg_axes_info["x_i"]48 let y_i = svg_axes_info["y_i"]49 // We create the axis lengths 50 let x_axis_len = x_i["x_axis_i"]["len_frac"]*dWidth;51 let y_axis_len = y_i["y_axis_i"]["len_frac"]*dHeight;52 if (draw_x_axis) {53 // We get the location of the bottom left corner of where the 54 // x values start55 let x_axis_org = [x_i["x_axis_i"]["lc"][0] * dWidth, 56 x_i["x_axis_i"]["lc"][1] * dHeight]57 //Making X axis line (no ticks)58 makeLine(d3svg, "black", x_axis_org[0], x_axis_org[1], 59 x_axis_org[0] + x_axis_len, x_axis_org[1], 60 x_i["x_axis_i"]["style_i"]["strokeWidth"]);61 }62 if (draw_y_axis) {63 // We get the location of the bottom left corner of where the 64 // y values start65 let y_axis_org = [y_i["y_axis_i"]["bc"][0] * dWidth, 66 y_i["y_axis_i"]["bc"][1] * dHeight]67 //Making Y axis line (no ticks)68 makeLine(d3svg, "black", y_axis_org[0], y_axis_org[1], 69 y_axis_org[0], y_axis_org[1] - y_axis_len, 70 y_i["y_axis_i"]["style_i"]["strokeWidth"]);71 }72 73 let graph_blc = [svg_axes_info["graph_i"]["blc"][0]*dWidth,74 svg_axes_info["graph_i"]["blc"][1]*dHeight];75 let graph_trc = [svg_axes_info["graph_i"]["trc"][0]*dWidth,76 svg_axes_info["graph_i"]["trc"][1]*dHeight];77 // Labels78 if (draw_x_label) {79 let xt = x_i["x_title_i"]80 // X-Axis Text Label81 makeText(d3svg, xt["style_i"]["fontWeight"], xt["style_i"]["fontSize"],82 graph_blc[0] + x_axis_len*xt["blc"][0],83 dHeight*xt["blc"][1], xt["label"], xt["style_i"]["fontColor"])84 }85 if (draw_y_label) {86 let yt = y_i["y_title_i"]87 makeYAxisLabel(d3svg, dWidth, dHeight, yt);88 }89 ret_d = {90 "x_axis_len": x_axis_len,91 "y_axis_len": y_axis_len,92 "graph_blc": graph_blc,93 "graph_trc": graph_trc94 }95 if (draw_x_axis) {96 ret_d["x_axis_start"] = [x_i["x_axis_i"]["lc"][0] * dWidth, 97 x_i["x_axis_i"]["lc"][1] * dHeight]98 }99 if (draw_y_axis) {100 ret_d["y_axis_start"] = [y_i["y_axis_i"]["bc"][0] * dWidth, 101 y_i["y_axis_i"]["bc"][1] * dHeight]102 }103 return ret_d104}105function makeDashedLine(d3svg, start_coordinates, end_coordinates,106 dash_length, break_length,107 color, stroke_width) {108 /*109 * In order to draw a dashed line we need110 * the slope of the line111 *112 *113 *114 */115 116 let stroke_break_str = dash_length.toString() + ", " + 117 break_length.toString();118 119 d3svg.append("line")120 .attr('x1', start_coordinates[0])121 .attr('y1', start_coordinates[1])122 .attr('x2', end_coordinates[0])123 .attr('y2', end_coordinates[1])124 .attr("stroke", color)125 .attr("stroke-width", stroke_width)126 .style("stroke-dasharray", (stroke_break_str)); 127 // ^ This line here!!128}129function makeYAxisLabel(d3svg, svgWidth, svgHeight, yt) {130 // yt: 131 // blc: <x frac from left, y frac from top>132 // trc: <x frac from left, y frac from top>133 // style_i:134 // name (Str) -> value (str)135 // label: str136 // Yx and Yy refer to the Y label location x and y coordinates137 let Yx = svgWidth * (yt["blc"][0] + yt["trc"][0]) * (0.5)138 let Yy = svgHeight * (yt["blc"][1] + yt["trc"][1]) * (0.5)139 let ax_tsl = Yx.toString() + "," + Yy.toString()140 141 let font_weight = yt["style_i"]["fontWeight"]142 if (font_weight == null) {143 font_weight = "bold"144 }145 let font_color = yt["style_i"]["fontColor"]146 if (font_color == null) {147 font_color = "black"148 }149 150 d3svg.append('text')151 .attr('font-weight', font_weight )152 .attr("transform", "translate(" + ax_tsl + ") rotate(270)")153 .attr('font-size', yt["style_i"]["fontSize"])154 .attr('fill', font_color)155 .text(yt["label"]);156}157function makeAxisTicksAndTickLabels(svg_id, axis_type,158 axis_start_loc, axis_end_loc,159 tick_info_list) {160 // This function takes the starting and ending points of 161 // an axis and adds ticks with information coming162 // from the 'tick_info_list'163 //164 // Args:165 // svg_id: (str) The id of the svg object we want to add to166 // axis_start_loc: list< x_val (Number), y_val (Number)>167 // axis_end_loc: list< x_val (Number), y_val (Number)>168 // axis_type: (str) fixed vocab ["x" (horizontal), or "y" (vertical)]169 // tick_info_list: list<tick_info>170 // tick_info: list<frac (Number), tick_length (Number), tick_style,171 // tick_color, tick_stroke_width (Number),172 // label_style (s), label_text (s), label_color (s)173 // label_font_size (Number), label_dist (Number)>174 // frac: The TOTAL fraction of the axis where this tick lies175 // tick_length: The length of the tick within the SVG176 // tick_style: str fixed vocab: ["top", "cross", "bottom"]177 // this refers to if the tick points up from the axis,178 // crosses the axis, or protrudes from the bottom of179 // the axis.180 // tick_color: str (CSS color)181 // label_style: str fixed vocab ["above", "below"]182 // label_text: str The actual label value.183 184 let d3svg = getSVG(svg_id)185 let axis_length = null186 if (axis_type == "x") {187 axis_length = axis_end_loc[0] - axis_start_loc[0]188 } else if (axis_type == "y") {189 axis_length = axis_start_loc[1] - axis_end_loc[1]190 } else {191 throw "unknown axis type: " + axis_type192 }193 // Here we add the ticks194 for (let i=0; i < tick_info_list.length; i++) {195 let crnt_tick_info = tick_info_list[i];196 // This variable holds the [x,y] location of tick center197 let tick_axis_loc = null198 if (axis_type == "x") {199 tick_axis_loc = [axis_start_loc[0] + crnt_tick_info[0]*axis_length,200 axis_start_loc[1]]201 } else if (axis_type == "y") {202 tick_axis_loc = [axis_start_loc[0],203 axis_start_loc[1] - crnt_tick_info[0]*axis_length ]204 }205 addTickAndLabel(d3svg, axis_type, crnt_tick_info, tick_axis_loc)206 }207}208function addTickAndLabel(d3svg, axis_type, tick_info, tick_axis_loc) {209 // Info regarding params comes from function 210 // makeAxisTicksAndTickLabels211 // tick_axis_loc: list<x (Num), y (Num)>212 // tick_info: list<frac (Number), tick_length (Number), tick_style,213 // tick_color, tick_stroke_width,214 // label_style, label_text, label_color,215 // label_font_size, label_dist>216 let tick_start_loc = null217 let tick_end_loc = null218 if (axis_type == "x") {219 if (tick_info[2] == "top") {220 tick_start_loc = tick_axis_loc221 tick_end_loc = [tick_axis_loc[0], tick_axis_loc[1] - tick_info[1]]222 } else if (tick_info[2] == "cross") {223 tick_start_loc = [tick_axis_loc[0], tick_axis_loc[1] + tick_info[1]/2]224 tick_end_loc = [tick_axis_loc[0], tick_axis_loc[1] - tick_info[1]/2]225 } else if (tick_info[2] == "bottom") {226 tick_start_loc = tick_axis_loc227 tick_end_loc = [tick_axis_loc[0], tick_axis_loc[1] + tick_info[1]]228 }229 makeLine(d3svg, tick_info[3], tick_start_loc[0],230 tick_start_loc[1], tick_end_loc[0], 231 tick_end_loc[1], tick_info[4])232 // Label - checking label style ("top" or "bottom")233 let init_label_loc = null;234 if (tick_info[5] == "top") {235 init_label_loc = [tick_axis_loc[0], tick_axis_loc[1] - tick_info[9]]236 } else if (tick_info[5] == "bottom") {237 init_label_loc = [tick_axis_loc[0], tick_axis_loc[1] + tick_info[9]]238 } else {239 console.log(" label style needs to be top or bottom!")240 }241 makeText(d3svg, "normal", tick_info[8], init_label_loc[0] - 3,242 init_label_loc[1], tick_info[6], tick_info[7])243 } else if (axis_type == "y") {244 if (tick_info[2] == "top") {245 tick_start_loc = tick_axis_loc246 tick_end_loc = [tick_axis_loc[0] + tick_info[1], tick_axis_loc[1]]247 } else if (tick_info[2] == "cross") {248 tick_start_loc = [tick_axis_loc[0] - tick_info[1]/2, tick_axis_loc[1]]249 tick_end_loc = [tick_axis_loc[0] + tick_info[1]/2, tick_axis_loc[1]]250 } else if (tick_info[2] == "bottom") {251 tick_start_loc = tick_axis_loc252 tick_end_loc = [tick_axis_loc[0] - tick_info[1], tick_axis_loc[1]]253 }254 255 makeLine(d3svg, tick_info[3], tick_start_loc[0],256 tick_start_loc[1], tick_end_loc[0], 257 tick_end_loc[1], tick_info[4])258 // Label - checking label style ("top" or "bottom")259 let init_label_loc = null;260 if (tick_info[5] == "top") {261 init_label_loc = [tick_axis_loc[0] + tick_info[9], tick_axis_loc[1]]262 } else if (tick_info[5] == "bottom") {263 let label_distance_addition = 0;264 if (tick_info[6][0] == "-") {265 label_distance_addition = 3;266 }267 init_label_loc = [tick_axis_loc[0] - tick_info[9] - label_distance_addition,268 tick_axis_loc[1]]269 }270 makeText(d3svg, "normal", tick_info[8], init_label_loc[0],271 init_label_loc[1] + 3, tick_info[6], tick_info[7])272 }273}274function makeLine(d3svg, color, x1, y1, x2, y2, stroke_width ) {275 /*276 * Args: 277 * d3svg: A d3 svg object278 * color: str, like "black"279 * x1 - y2, Numbers280 * stroke_width: width of line, Number281 *282 * Note: We need to make sure the numbers are relatively close to integers283 */284 return d3svg.append('line')285 .attr('x1', x1.toFixed(2))286 .attr('y1', y1.toFixed(2))287 .attr('x2', x2.toFixed(2))288 .attr('y2', y2.toFixed(2))289 .attr('stroke', color)290 .attr('stroke-width', stroke_width)291 .attr('position', 'absolute')292 ;293}294function makeText(d3svg, font_weight, font_size, x, y, text_str, font_color, id_txt=null) {295 /*296 * Args:297 * 298 * d3svg: A d3 svg object299 * font_weight: (str) like "bold", "normal",300 * font_size, x, y: Number301 * text_str: (str) Text you want to make302 *303 */304 if (font_color == null) {305 font_color = "black"306 }307 if (text_str == null) {308 text_str = "Default Text"309 }310 if (id_txt == null) {311 d3svg.append('text')312 .attr('font-weight', font_weight)313 .attr('font-size', font_size)314 .attr('fill', font_color)315 .attr('x', x)316 .attr('y', y)317 .text(text_str);318 } else {319 d3svg.append('text')320 .attr('font-weight', font_weight)321 .attr('font-size', font_size)322 .attr('fill', font_color)323 .attr('x', x)324 .attr('y', y)325 .attr('id', id_txt) 326 .text(text_str);327 }328}329function GetProperTicks(start_val, end_val) {330 /*331 This function is to get properly spread ticks between332 two INTEGER values where end_val > start_val333 Min ticks in axis is ~ 8, Max is ~ 16334 Note: dif must be an integer value335 start_val: Number336 end_val Number337 Returns:338 ticks_list = [start_val, start_val + subdivs, start_val + 2subdivs,..., end_val]339 */340 // Checking inputs341 if ( (Math.floor(start_val) != start_val) || 342 (Math.floor(end_val) != end_val) ) {343 console.log(start_val)344 console.log(end_val)345 throw "start_val and end_val must be integers"346 }347 let tick_values = null;348 let subdivs = null;349 let dif = end_val - start_val350 if (dif >= 16) {351 subdivs = ConvertValueIntoSubDivs(dif);352 } else {353 if (dif >= 8) {354 subdivs = 1355 } else if (dif >= 4) {356 subdivs = .5;357 } else if (dif >= 2) {358 subdivs = .25;359 } else if (dif == 1) {360 subdivs = .1361 } else {362 throw "end_val must be greater than start_val in GetProperTicks"363 }364 }365 tick_values = GetTickValues(start_val, end_val, subdivs);366 return tick_values;367}368function ConvertValueIntoSubDivs(Val) {369 /*370 *371 * Args: 372 * Val is a positive integer373 Important Questions:374 1. Max ticks in axis assuming no more than 3 digits per value?375 Answer: 16376 2. Min ticks in axis?377 Answer: 8378 Meaning: 379 if N = d * 10^n, d > 5 implies division is 5 * 10^(n-2)380 4 < d < 5 implies division is 2.5 * 10^(n-2)381 2 < d < 4 implies division is 2 * 10^(n-2)382 1 < d < 2 implies division is 1 * 10^(n-2)383 */384 let val_info = BaseNotation(Val, 10, 20);385 let dig = val_info[0];386 let power = val_info[1];387 let subdivs = null;388 if (power === 0) {389 subdivs = 1 ;390 } else {391 if (dig >=8) { 392 subdivs = Math.pow(10,power);393 } else if (dig >= 6) { 394 subdivs = 5 * Math.pow(10, power-1);395 } else {396 subdivs = Math.floor(dig) * Math.pow(10, power-1);397 }398 }399 return subdivs;400}401function BaseNotation(N, base, max_power) {402 /* We get power of base and digit multiplier.403 Eg. if N = 346, base = 10 we return [3.46, 2] because404 3.46 * 10^2 = 346 405 Args:406 N: int, number to find bounds for. MUST BE > 0407 base: int 408 max_power: int (limit so function doesn't run forever with while loop)409 Returns:410 [a, b (power of 10)] where a*10^b = N411 OR [-1, -1] if it failed for some reason412 */413 if (N <= 0) {414 return [-1, -1]415 }416 for (i=0; i < max_power + 1 ;i++){417 if (N >= Math.pow(base,i) && N < Math.pow(base,i+1)) {418 return [ N/Math.pow(base,i), i]419 }420 }421 return [-1, -1]422}423function GetTickValues(start_val, end_val, subdivs) {424 /* Simple function that adds subdivs from start val 425 * until it reaches end_val426 * We go from a value and subdivs to actual graph ticks427 Args:428 start_val: (int)429 end_val: (int)430 subdivs: (int)431 Returns:432 ticks_list = [start_val, start_val + subdivs, start_val + 2subdivs,...]433 Specifically, this function starts from start_val and adds subdiv until reaching434 end_val. Note that difference between start_val and end_val does not 435 need t436 */437 // First we get a list of just each tick, not the start and end ticks (no dbl)438 let init_tick_list = [start_val];439 let crnt_val = start_val + subdivs;440 while (crnt_val < end_val){441 init_tick_list.push(crnt_val);442 crnt_val = crnt_val + subdivs;443 }444 init_tick_list.push(end_val);445 return init_tick_list;446}447function makeStandardTickInfoListFromTicks(tick_list, label_font_size,448 tick_length=8, tick_width=2,449 tick_style="bottom",450 tick_color="black",451 label_style="bottom",452 label_color="black",453 label_dist=20) {454 /*455 *456 * Args: tick_list: list<Num> (increasing order (?))457 * We return:458 tick_info_list: list<tick_info>459 tick_info: list<frac (Number), tick_length (Number), tick_style,460 tick_color, tick_stroke_width (Number),461 label_style, label_text, label_color462 label_font_size (Number), label_dist (Number)>463 ^ * all string except those labelled Number464 frac: The TOTAL fraction of the axis where this tick lies465 tick_length: The length of the tick within the SVG466 tick_style: str fixed vocab: ["top", "cross", "bottom"]467 this refers to if the tick points up from the axis,468 crosses the axis, or protrudes from the bottom of469 the axis.470 tick_color: str (CSS color)471 label_style: str fixed vocab ["above", "below"]472 label_text: str The actual label value.473 *474 *475 */476 let total_tick_range = tick_list[tick_list.length -1] - tick_list[0];477 let low_val = tick_list[0];478 let tick_info_list = [];479 for (let i=0; i<tick_list.length; i++) {480 let new_tick_info = [481 (tick_list[i] - low_val)/total_tick_range,482 tick_length,483 tick_style,484 tick_color,485 tick_width,486 label_style,487 tick_list[i].toString(),488 label_color,489 label_font_size,490 label_dist 491 ]492 tick_info_list.push(new_tick_info) 493 }494 return tick_info_list495}496function addManyPointsToPlot(d3svg,497 point_list,498 total_x_range,499 x_axis_len,500 x_axis_start,501 lowest_x,502 total_y_range,503 y_axis_len,504 y_axis_start,505 lowest_y,506 point_radius,507 async=false,508 quadrant_coloration=null,509 point_contains_data=false,510 point_click_function=null,511 point_opacity=0.25,512 point_color="black",513 point_shape="circle"514 ) {515 /*516 * This function simultaneously adds multiple points517 * in coordinate form (values related to the plot,518 * not the svg). Points are in list point_list.519 *520 * point_list: list<Coordinate + data, Coord...>521 * Coordinate: list<x (Num), y (Num), [data]> (NOT SVG, but graph vals)522 * total_x_range: (Num) Distance from lowest x value to highest523 * x_axis_len: (Num) in svg terms, length of axis524 * x_axis_start: coordinates in svg terms525 * lowest_x: (Num) Lowest X value526 * total_y_range: (Num) Distance from lowest y value to highest527 * y_axis_len: (Num) in svg terms, length of axis528 * y_axis_start: coordinates in svg terms529 * lowest_y: (Num) Lowest Y value530 * point_radius: Num531 * async: (bool) If true, we return a Promise532 * quadrant_coloration: (Object) Choose colors per quadrant533 * 'q1' -> q1 color (str)534 * 'q2' -> q2 color, ... etc535 * point_opacity: (Num)536 *537 * point_click_function: (javascript function)538 * point_contains_data: boolean if point has data at 3rd index539 *540 *541 * Returns:542 * fulfilled Promise if it succeeds543 */544 // Add dots545 if (point_shape == "circle") {546 d3svg.append('g')547 .selectAll('dot')548 .data(point_list)549 .enter()550 .append('circle')551 .attr('cx', function (d) { 552 return x_axis_start[0] + (553 (d[0] - lowest_x)/total_x_range)*x_axis_len;} )554 .attr('cy', function (d) { 555 return y_axis_start[1] - (556 (d[1] - lowest_y)/total_y_range)*y_axis_len;} )557 .attr('r', point_radius)558 .attr('fill', function(d) {559 if (quadrant_coloration == null) {560 return point_color561 } else {562 if (d[0]*d[1] >= 0) {563 if (d[0] > 0) {564 return quadrant_coloration['q1']565 } else {566 return quadrant_coloration['q3']567 }568 } else {569 if (d[0] > 0) {570 return quadrant_coloration['q4']571 } else {572 return quadrant_coloration['q2']573 }574 }575 }576 })577 .attr('opacity', point_opacity)578 .on('click', function(d) {579 if (point_click_function != null) {580 if (point_contains_data) {581 point_click_function(d[2])582 } else {583 return point_click_function(d)584 }585 }586 }); 587 }588 if (async == true) {589 return new Promise((resolve, reject) => {590 resolve(true)591 })592 } else {593 return true594 }595}596 597function addSinglePointToPlot(d3svg,598 point_coordinates, 599 point_color,600 point_shape,601 point_radius,602 point_opacity,603 point_data,604 point_click_function) {605 /*606 * d3svg: d3 svg object607 * point_coordinates: [x (Num), y (Num)]608 * point_color: (str)609 * point_shape: (str) ["circle", "square", "triangle"]610 * point_radius: (Num) distance from center to corner611 * point_opacity: (Num)612 * point_data: list<>613 * point_click_function: function614 *615 */616 if (point_shape == "circle") {617 if (point_data.length > 0) {618 d3svg.append("circle")619 .attr("cx", point_coordinates[0])620 .attr("cy", point_coordinates[1])621 .attr("r", point_radius)622 .attr("fill", point_color)623 .attr("opacity", point_opacity)624 .data(point_data)625 .on("click", function(d) {626 point_click_function(d); 627 });} else {628 d3svg.append("circle")629 .attr("cx", point_coordinates[0])630 .attr("cy", point_coordinates[1])631 .attr("r", point_radius)632 .attr("fill", point_color)633 .attr("opacity", point_opacity);634 }635 } else {636 throw "No code written for adding rects or triangles yet"637 }638 639}640/*641function sleep(ms) {642 return new Promise(resolve => setTimeout(resolve, ms));643}...
player.js
Source:player.js
2 setup(function() {3 webAnimationsMinifill.timeline._players = [];4 });5 test('zero duration animation works', function() {6 tick(90);7 var p = document.body.animate([], 0);8 tick(100);9 assert.equal(p.startTime, 100);10 assert.equal(p.currentTime, 0);11 });12 test('playing works as expected', function() {13 tick(90);14 var p = document.body.animate([], 2000);15 tick(100);16 assert.equal(p.startTime, 100);17 assert.equal(p.currentTime, 0);18 tick(300);19 assert.equal(p.startTime, 100);20 assert.equal(p.currentTime, 200);21 });22 test('pause at start of play', function() {23 tick(90);24 var p = document.body.animate([], 2000);25 p.pause();26 tick(100);27 assert.equal(p.currentTime, 0);28 tick(300);29 p.play();30 assert.equal(p.currentTime, 0);31 tick(310);32 assert.equal(p.currentTime, 0);33 assert.equal(p.startTime, 310);34 var p = document.body.animate([], 2000);35 p.startTime = -690;36 p.pause();37 assert.equal(p.currentTime, null);38 tick(700);39 p.play();40 tick(701);41 assert.equal(p.currentTime, 1000);42 tick(800);43 assert.equal(p.currentTime, 1099);44 assert.equal(p.startTime, -299);45 });46 test('pausing works as expected', function() {47 tick(190);48 var p = document.body.animate([], 3000);49 tick(200);50 tick(1500);51 assert.equal(p.startTime, 200);52 assert.equal(p.currentTime, 1300);53 p.pause();54 assert.equal(p.startTime, null);55 assert.equal(p.currentTime, null);56 tick(2500);57 assert.equal(p.startTime, null);58 assert.equal(p.currentTime, 1300);59 p.play();60 tick(2510);61 assert.equal(p.startTime, 1210);62 assert.equal(p.currentTime, 1300);63 tick(3500);64 assert.equal(p.startTime, 1210);65 assert.equal(p.currentTime, 2290);66 });67 test('reversing works as expected', function() {68 tick(290);69 var p = document.body.animate([], 1000);70 tick(300);71 assert.equal(p.startTime, 300);72 assert.equal(p.currentTime, 0);73 tick(600);74 assert.equal(p.startTime, 300);75 assert.equal(p.currentTime, 300);76 assert.equal(p.playbackRate, 1);77 p.reverse();78 tick(600);79 assert.equal(p.startTime, 900);80 assert.equal(p.currentTime, 300);81 assert.equal(p.playbackRate, -1);82 tick(700);83 assert.equal(p.startTime, 900);84 assert.equal(p.currentTime, 200);85 });86 test('reversing after pausing', function() {87 tick(90);88 var p = document.body.animate([], 1000);89 tick(100);90 tick(600);91 p.reverse();92 tick(601);93 tick(700);94 assert.equal(p.startTime, 1101);95 assert.equal(p.currentTime, 401);96 });97 test('reversing after finishing works as expected', function() {98 tick(90);99 var p = document.body.animate([], 1000);100 tick(100);101 tick(1200);102 assert.equal(p.finished, true);103 assert.equal(p.startTime, 100);104 assert.equal(p.currentTime, 1000);105 tick(1500);106 assert.equal(p.currentTime, 1000);107 assert.equal(isTicking(), false);108 p.reverse();109 assert.equal(p._startTime, null);110 assert.equal(p.currentTime, 1000);111 tick(1600);112 assert.equal(p.startTime, 2600);113 assert.equal(p.currentTime, 1000);114 });115 test('playing after finishing works as expected', function() {116 tick(90);117 var p = document.body.animate([], 1000);118 tick(100);119 tick(1200);120 assert.equal(p.finished, true);121 assert.equal(p.startTime, 100);122 assert.equal(p.currentTime, 1000);123 tick(1500);124 assert.equal(p.currentTime, 1000);125 assert.equal(isTicking(), false);126 p.play();127 assert.equal(p.startTime, null);128 assert.equal(p.currentTime, 0);129 tick(1600);130 assert.equal(p.startTime, 1600);131 assert.equal(p.currentTime, 0);132 });133 test('limiting works as expected', function() {134 tick(390);135 var p = document.body.animate([], 1000);136 tick(400);137 assert.equal(p.startTime, 400);138 assert.equal(p.currentTime, 0);139 tick(900);140 assert.equal(p.startTime, 400);141 assert.equal(p.currentTime, 500);142 tick(1400);143 assert.equal(p.startTime, 400);144 assert.equal(p.currentTime, 1000);145 tick(1500);146 assert.equal(p.startTime, 400);147 assert.equal(p.currentTime, 1000);148 p.reverse();149 assert.equal(p.playbackRate, -1);150 assert.equal(p.currentTime, 1000);151 assert.equal(p._startTime, null);152 tick(2000);153 assert.equal(p.currentTime, 1000);154 assert.equal(p.startTime, 3000);155 tick(2200);156 assert.equal(p.currentTime, 800);157 assert.equal(p.startTime, 3000);158 tick(3200);159 assert.equal(p.currentTime, 0);160 assert.equal(p.startTime, 3000);161 tick(3500);162 assert.equal(p.currentTime, 0);163 assert.equal(p.startTime, 3000);164 });165 test('play after limit works as expected', function() {166 tick(490);167 var p = document.body.animate([], 2000);168 tick(500);169 tick(2600);170 assert.equal(p.currentTime, 2000);171 assert.equal(p.startTime, 500);172 assert.equal(p.finished, true);173 assert.equal(p.playbackRate, 1);174 setTicking(true);175 p.play();176 tick(2700);177 assert.equal(p.startTime, 2700);178 assert.equal(p.currentTime, 0);179 assert.equal(p.finished, false);180 assert.equal(p.playbackRate, 1);181 });182 test('play after limit works as expected (reversed)', function() {183 tick(590);184 var p = document.body.animate([], 3000);185 tick(600);186 tick(700);187 p.reverse();188 tick(701);189 tick(900);190 assert.equal(p.startTime, 801);191 assert.equal(p.currentTime, 0);192 assert.equal(p.finished, true);193 assert.equal(p.playbackRate, -1);194 setTicking(true);195 p.play();196 tick(1000);197 assert.equal(p.startTime, 4000);198 assert.equal(p.currentTime, 3000);199 assert.equal(p.finished, false);200 assert.equal(p.playbackRate, -1);201 });202 test('seeking works as expected', function() {203 tick(690);204 var p = document.body.animate([], 2000);205 tick(700);206 tick(900);207 assert.equal(p.currentTime, 200);208 p.currentTime = 600;209 assert.equal(p.currentTime, 600);210 assert.equal(p.startTime, 300);211 p.reverse();212 tick(1000);213 assert.equal(p.startTime, 1600);214 p.currentTime = 300;215 assert.equal(p.currentTime, 300);216 assert.equal(p.startTime, 1300);217 });218 test('seeking while paused works as expected', function() {219 tick(790);220 var p = document.body.animate([], 1000);221 tick(800);222 tick(1000);223 p.pause();224 assert.equal(p.currentTime, null);225 assert.equal(p.startTime, null);226 assert.equal(p.paused, true);227 p.currentTime = 500;228 assert.equal(p.startTime, null);229 assert.equal(p.paused, true);230 });231 test('setting start time while paused is ignored', function() {232 tick(900);233 var p = document.body.animate([], 1234);234 p.pause();235 assert.equal(p.startTime, null);236 assert.equal(p.currentTime, null);237 p.startTime = 2232;238 assert.equal(p.startTime, null);239 assert.equal(p.currentTime, null);240 });241 test('finishing works as expected', function() {242 tick(1000);243 var p = document.body.animate([], 2000);244 p.finish();245 assert.equal(p.startTime, 0);246 assert.equal(p.currentTime, 2000);247 p.reverse();248 p.finish();249 assert.equal(p.currentTime, 0);250 assert.equal(p.startTime, 2000);251 tick(2000);252 });253 test('cancelling clears all effects', function() {254 tick(0);255 var target = document.createElement('div');256 document.documentElement.appendChild(target);257 var player = target.animate([{marginLeft: '50px'}, {marginLeft: '50px'}], 1000);258 tick(10);259 tick(110);260 assert.equal(getComputedStyle(target).marginLeft, '50px');261 player.cancel();262 // getComputedStyle forces a tick.263 assert.equal(getComputedStyle(target).marginLeft, '0px');264 assert.deepEqual(webAnimationsMinifill.timeline._players, []);265 tick(120);266 assert.equal(getComputedStyle(target).marginLeft, '0px');267 assert.deepEqual(webAnimationsMinifill.timeline._players, []);268 document.documentElement.removeChild(target);269 });270 test('startTime is set on first tick if timeline hasn\'t started', function() {271 webAnimationsMinifill.timeline.currentTime = undefined;272 var p = document.body.animate([], 1000);273 tick(0);274 tick(100);275 assert.equal(p.startTime, 0);276 });277 test('players which are finished and not filling get discarded', function() {278 tick(90);279 var nofill = document.body.animate([], 100);280 var fill = document.body.animate([], {duration: 100, fill: 'forwards'});281 assert.deepEqual(webAnimationsMinifill.timeline._players, [nofill._player || nofill, fill._player || fill]);282 tick(100);283 assert.deepEqual(webAnimationsMinifill.timeline._players, [nofill._player || nofill, fill._player || fill]);284 tick(400);285 assert.deepEqual(webAnimationsMinifill.timeline._players, [fill._player || fill]);286 });287 test('discarded players get re-added on modification', function() {288 tick(90);289 var player = document.body.animate([], 100);290 tick(100);291 tick(400);292 assert.deepEqual(webAnimationsMinifill.timeline._players, []);293 player.currentTime = 0;294 assert.deepEqual(webAnimationsMinifill.timeline._players, [player._player || player]);295 });296 test('players in the before phase are not discarded', function() {297 tick(100);298 var player = document.body.animate([], 100);299 player.currentTime = -50;300 tick(110);301 assert.deepEqual(webAnimationsMinifill.timeline._players, [player._player || player]);302 });303 test('players that go out of effect should not clear the effect of players that are in effect', function() {304 var target = document.createElement('div');305 document.body.appendChild(target);306 tick(0);307 var playerBehind = target.animate([{marginLeft: '200px'}, {marginLeft: '200px'}], 200);308 var playerInfront = target.animate([{marginLeft: '100px'}, {marginLeft: '100px'}], 100);309 tick(50);310 assert.equal(getComputedStyle(target).marginLeft, '100px', 't = 50');311 tick(150);312 assert.equal(getComputedStyle(target).marginLeft, '200px', 't = 150');313 tick(250);314 assert.equal(getComputedStyle(target).marginLeft, '0px', 't = 250');315 document.body.removeChild(target);316 });317 test('player modifications should update CSS effects immediately', function() {318 var target = document.createElement('div');319 document.body.appendChild(target);320 tick(0);321 var playerBehind = target.animate([{width: '1234px'}, {width: '1234px'}], {duration: 1, fill: 'both'});322 var playerInfront = target.animate([{width: '0px'}, {width: '100px'}], 100);323 assert.equal(getComputedStyle(target).width, '0px');324 playerInfront.currentTime = 50;325 assert.equal(getComputedStyle(target).width, '50px');326 playerInfront.currentTime = 100;327 assert.equal(getComputedStyle(target).width, '1234px');328 playerInfront.play();329 assert.equal(getComputedStyle(target).width, '0px');330 playerInfront.startTime = -50;331 assert.equal(getComputedStyle(target).width, '50px');332 document.body.removeChild(target);333 });334 test('Player that hasn\'t been played has playState \'idle\'', function() {335 var source = new minifillAnimation(document.body, [], 1000);336 var p = new Player(source);337 assert.equal(p.playState, 'idle');338 });339 test('playState works for a simple animation', function() {340 var p = document.body.animate([], 1000);341 tick(0);342 assert.equal(p.playState, 'running');343 tick(100);344 assert.equal(p.playState, 'running');345 p.pause();346 assert.equal(p.playState, 'pending');347 tick(101);348 assert.equal(p.playState, 'paused');349 p.play();350 assert.equal(p.playState, 'pending');351 tick(102);352 assert.equal(p.playState, 'running');353 tick(1002);354 assert.equal(p.playState, 'finished');355 });356 test('Play after cancel', function() {357 var p = document.body.animate([], 1000);358 assert.equal(p.playState, 'pending');359 tick(0);360 p.cancel();361 assert.equal(p.playState, 'idle');362 assert.equal(p.currentTime, null);363 assert.equal(p.startTime, null);364 tick(1);365 assert.equal(p.playState, 'idle');366 assert.equal(p.currentTime, null);367 assert.equal(p.startTime, null);368 p.play();369 assert.equal(p.playState, 'pending');370 assert.equal(p.currentTime, 0);371 assert.equal(p.startTime, null);372 tick(10);373 assert.equal(p.playState, 'running');374 assert.equal(p.currentTime, 0);375 assert.equal(p.startTime, 10);376 });377 test('Reverse after cancel', function() {378 var p = document.body.animate([], 300);379 tick(0);380 p.cancel();381 assert.equal(p.playState, 'idle');382 assert.equal(p.currentTime, null);383 assert.equal(p.startTime, null);384 tick(1);385 p.reverse();386 assert.equal(p.playState, 'pending');387 assert.equal(p.currentTime, 300);388 assert.equal(p.startTime, null);389 tick(100);390 assert.equal(p.playState, 'running');391 assert.equal(p.currentTime, 300);392 assert.equal(p.startTime, 400);393 tick(300);394 assert.equal(p.playState, 'running');395 assert.equal(p.currentTime, 100);396 assert.equal(p.startTime, 400);397 tick(400);398 assert.equal(p.playState, 'finished');399 assert.equal(p.currentTime, 0);400 assert.equal(p.startTime, 400);401 });402 test('Finish after cancel', function() {403 var p = document.body.animate([], 300);404 tick(0);405 p.cancel();406 assert.equal(p.playState, 'idle');407 assert.equal(p.currentTime, null);408 assert.equal(p.startTime, null);409 tick(1);410 p.finish();411 assert.equal(p.playState, 'idle');412 assert.equal(p.currentTime, null);413 assert.equal(p.startTime, null);414 tick(2);415 assert.equal(p.playState, 'idle');416 assert.equal(p.currentTime, null);417 assert.equal(p.startTime, null);418 });419 test('Pause after cancel', function() {420 var p = document.body.animate([], 300);421 tick(0);422 p.cancel();423 assert.equal(p.playState, 'idle');424 assert.equal(p.currentTime, null);425 assert.equal(p.startTime, null);426 tick(1);427 p.pause();428 assert.equal(p.playState, 'idle');429 assert.equal(p.currentTime, null);430 assert.equal(p.startTime, null);431 });432 test('Players ignore NaN times', function() {433 var p = document.body.animate([], 300);434 p.startTime = 100;435 tick(110);436 assert.equal(p.currentTime, 10);437 p.startTime = NaN;438 assert.equal(p.startTime, 100);439 p.currentTime = undefined;440 assert.equal(p.currentTime, 10);441 });442 test('play() should not set a start time', function() {443 var p = document.body.animate([], 1000);444 p.cancel();445 assert.equal(p.startTime, null);446 assert.equal(p.playState, 'idle');447 p.play();448 assert.equal(p.startTime, null);449 assert.equal(p.playState, 'pending');...
grouped-categories.js
Source:grouped-categories.js
1/**2 * Grouped Categories v1.0.13 (2016-01-13)3 *4 * (c) 2012-2016 Black Label5 *6 * License: Creative Commons Attribution (CC)7 */8(function(HC){9/*jshint expr:true, boss:true */10var UNDEFINED = void 0,11 mathRound = Math.round,12 mathMin = Math.min,13 mathMax = Math.max,14 merge = HC.merge,15 pick = HC.pick,16 // #74, since Highcharts 4.1.10 HighchartsAdapter is only provided by the Highcharts Standalone Framework17 inArray = (window.HighchartsAdapter && window.HighchartsAdapter.inArray) || HC.inArray,18 // cache prototypes19 axisProto = HC.Axis.prototype,20 tickProto = HC.Tick.prototype,21 // cache original methods22 _axisInit = axisProto.init,23 _axisRender = axisProto.render,24 _axisSetCategories = axisProto.setCategories,25 _tickGetLabelSize = tickProto.getLabelSize,26 _tickAddLabel = tickProto.addLabel,27 _tickDestroy = tickProto.destroy,28 _tickRender = tickProto.render;29function Category(obj, parent) {30 this.userOptions = deepClone(obj);31 this.name = obj.name || obj;32 this.parent = parent;33 return this;34}35Category.prototype.toString = function () {36 var parts = [],37 cat = this;38 while (cat) {39 parts.push(cat.name);40 cat = cat.parent;41 }42 return parts.join(', ');43};44// Highcharts methods45function defined(obj) {46 return obj !== UNDEFINED && obj !== null;47}48// returns sum of an array49function sum(arr) {50 var l = arr.length,51 x = 0;52 while (l--)53 x += arr[l];54 return x;55}56// Builds reverse category tree57function buildTree(cats, out, options, parent, depth) {58 var len = cats.length,59 cat;60 depth || (depth = 0);61 options.depth || (options.depth = 0);62 while (len--) {63 cat = cats[len];64 if (parent)65 cat.parent = parent;66 if (cat.categories)67 buildTree(cat.categories, out, options, cat, depth + 1);68 else69 addLeaf(out, cat, parent);70 }71 options.depth = mathMax(options.depth, depth);72}73// Adds category leaf to array74function addLeaf(out, cat, parent) {75 out.unshift(new Category(cat, parent));76 while (parent) {77 parent.leaves++ || (parent.leaves = 1);78 parent = parent.parent;79 }80}81// Pushes part of grid to path82function addGridPart(path, d, width) {83 // Based on crispLine from HC (#65)84 if (d[0] === d[2]) {85 d[0] = d[2] = mathRound(d[0]) - (width % 2 / 2);86 }87 if (d[1] === d[3]) {88 d[1] = d[3] = mathRound(d[1]) + (width % 2 / 2);89 }90 91 path.push(92 'M',93 d[0], d[1],94 'L',95 d[2], d[3]96 );97}98// Destroys category groups99function cleanCategory(category) {100 var tmp;101 while (category) {102 tmp = category.parent;103 if (category.label)104 category.label.destroy();105 delete category.parent;106 delete category.label;107 category = tmp;108 }109}110// Returns tick position111function tickPosition(tick, pos) {112 return tick.getPosition(tick.axis.horiz, pos, tick.axis.tickmarkOffset);113}114function walk(arr, key, fn) {115 var l = arr.length,116 children;117 while (l--) {118 children = arr[l][key];119 if (children)120 walk(children, key, fn);121 fn(arr[l]);122 }123}124function deepClone(thing) {125 return JSON.parse(JSON.stringify(thing));126}127//128// Axis prototype129//130axisProto.init = function (chart, options) {131 // default behaviour132 _axisInit.call(this, chart, options);133 if (typeof options === 'object' && options.categories)134 this.setupGroups(options);135};136// setup required axis options137axisProto.setupGroups = function (options) {138 var categories,139 reverseTree = [],140 stats = {};141 142 categories = deepClone(options.categories);;143 // build categories tree144 buildTree(categories, reverseTree, stats);145 // set axis properties146 this.categoriesTree = categories;147 this.categories = reverseTree;148 this.isGrouped = stats.depth !== 0;149 this.labelsDepth = stats.depth;150 this.labelsSizes = [];151 this.labelsGridPath = [];152 this.tickLength = options.tickLength || this.tickLength || null;153 // #66: tickWidth for x axis defaults to 1, for y to 0154 this.tickWidth = pick(options.tickWidth, this.isXAxis ? 1 : 0);155 this.directionFactor = [-1, 1, 1, -1][this.side];156 this.options.lineWidth = pick(options.lineWidth, 1);157};158axisProto.render = function () {159 // clear grid path160 if (this.isGrouped)161 this.labelsGridPath = [];162 // cache original tick length163 if (this.originalTickLength === UNDEFINED)164 this.originalTickLength = this.options.tickLength;165 // use default tickLength for not-grouped axis166 // and generate grid on grouped axes,167 // use tiny number to force highcharts to hide tick168 this.options.tickLength = this.isGrouped ? 0.001 : this.originalTickLength;169 _axisRender.call(this);170 if (!this.isGrouped) {171 if (this.labelsGrid)172 this.labelsGrid.attr({visibility: 'hidden'});173 return;174 }175 var axis = this,176 options = axis.options,177 top = axis.top,178 left = axis.left,179 right = left + axis.width,180 bottom = top + axis.height,181 visible = axis.hasVisibleSeries || axis.hasData,182 depth = axis.labelsDepth,183 grid = axis.labelsGrid,184 horiz = axis.horiz,185 d = axis.labelsGridPath,186 i = options.drawHorizontalBorders === false ? depth+1 : 0,187 offset = axis.opposite ? (horiz ? top : right) : (horiz ? bottom : left),188 tickWidth = axis.tickWidth,189 part;190 if (axis.userTickLength)191 depth -= 1;192 // render grid path for the first time193 if (!grid) {194 grid = axis.labelsGrid = axis.chart.renderer.path()195 .attr({196 // #58: use tickWidth/tickColor instead of lineWidth/lineColor: 197 strokeWidth: tickWidth, // < 4.0.3198 'stroke-width': tickWidth, // 4.0.3+ #30199 stroke: options.tickColor200 })201 .add(axis.axisGroup);202 }203 // go through every level and draw horizontal grid line204 while (i <= depth) {205 offset += axis.groupSize(i);206 part = horiz ?207 [left, offset, right, offset] :208 [offset, top, offset, bottom];209 addGridPart(d, part, tickWidth);210 i++;211 }212 // draw grid path213 grid.attr({214 d: d,215 visibility: visible ? 'visible' : 'hidden'216 });217 axis.labelGroup.attr({218 visibility: visible ? 'visible' : 'hidden'219 });220 walk(axis.categoriesTree, 'categories', function (group) {221 var tick = group.tick;222 if (!tick)223 return;224 if (tick.startAt + tick.leaves - 1 < axis.min || tick.startAt > axis.max) {225 tick.label.hide();226 tick.destroyed = 0;227 }228 else229 tick.label.attr({230 visibility: visible ? 'visible' : 'hidden'231 });232 });233};234axisProto.setCategories = function (newCategories, doRedraw) {235 if (this.categories)236 this.cleanGroups();237 this.setupGroups({238 categories: newCategories239 });240 this.categories = this.userOptions.categories = newCategories;241 _axisSetCategories.call(this, this.categories, doRedraw);242};243// cleans old categories244axisProto.cleanGroups = function () {245 var ticks = this.ticks,246 n;247 for (n in ticks)248 if (ticks[n].parent)249 delete ticks[n].parent;250 walk(this.categoriesTree, 'categories', function (group) {251 var tick = group.tick,252 n;253 if (!tick)254 return;255 tick.label.destroy();256 for (n in tick)257 delete tick[n];258 delete group.tick;259 });260 this.labelsGrid = null;261};262// keeps size of each categories level263axisProto.groupSize = function (level, position) {264 var positions = this.labelsSizes,265 direction = this.directionFactor,266 groupedOptions = this.options.labels.groupedOptions ? this.options.labels.groupedOptions[level-1] : false,267 userXY = 0;268 269 if(groupedOptions) {270 if(direction == -1) {271 userXY = groupedOptions.x ? groupedOptions.x : 0;272 } else {273 userXY = groupedOptions.y ? groupedOptions.y : 0;274 }275 } 276 277 if (position !== UNDEFINED)278 positions[level] = mathMax(positions[level] || 0, position + 10 + Math.abs(userXY));279 280 if (level === true)281 return sum(positions) * direction;282 else if (positions[level])283 return positions[level] * direction;284 return 0;285};286//287// Tick prototype288//289// Override methods prototypes290tickProto.addLabel = function () {291 var category;292 _tickAddLabel.call(this);293 if (!this.axis.categories ||294 !(category = this.axis.categories[this.pos]))295 return;296 // set label text - but applied after formatter #46297 if (this.label)298 this.label.attr('text', this.axis.labelFormatter.call({299 axis: this.axis,300 chart: this.axis.chart,301 isFirst: this.isFirst,302 isLast: this.isLast,303 value: category.name304 }));305 // create elements for parent categories306 if (this.axis.isGrouped && this.axis.options.labels.enabled)307 this.addGroupedLabels(category);308};309// render ancestor label310tickProto.addGroupedLabels = function (category) {311 var tick = this,312 axis = this.axis,313 chart = axis.chart,314 options = axis.options.labels,315 useHTML = options.useHTML,316 css = options.style,317 userAttr= options.groupedOptions,318 attr = { align: 'center' , rotation: options.rotation, x: 0, y: 0 },319 size = axis.horiz ? 'height' : 'width',320 depth = 0,321 label;322 while (tick) {323 if (depth > 0 && !category.tick) {324 // render label element325 this.value = category.name;326 var name = options.formatter ? options.formatter.call(this, category) : category.name,327 hasOptions = userAttr && userAttr[depth-1],328 mergedAttrs = hasOptions ? merge(attr, userAttr[depth-1] ) : attr,329 mergedCSS = hasOptions && userAttr[depth-1].style ? merge(css, userAttr[depth-1].style ) : css;330 //#63: style is passed in CSS and not as an attribute331 delete mergedAttrs.style;332 333 label = chart.renderer.text(name, 0, 0, useHTML)334 .attr(mergedAttrs)335 .css(mergedCSS)336 .add(axis.labelGroup);337 // tick properties338 tick.startAt = this.pos;339 tick.childCount = category.categories.length;340 tick.leaves = category.leaves;341 tick.visible = this.childCount;342 tick.label = label;343 tick.labelOffsets = {344 x: mergedAttrs.x,345 y: mergedAttrs.y346 };347 // link tick with category348 category.tick = tick;349 }350 // set level size351 axis.groupSize(depth, tick.label.getBBox()[size]);352 // go up to the parent category353 category = category.parent;354 if (category)355 tick = tick.parent = category.tick || {};356 else357 tick = null;358 depth++;359 }360};361// set labels position & render categories grid362tickProto.render = function (index, old, opacity) {363 _tickRender.call(this, index, old, opacity);364 var treeCat = this.axis.categories[this.pos];365 366 if (!this.axis.isGrouped || !treeCat || this.pos > this.axis.max)367 return;368 var tick = this,369 group = tick,370 axis = tick.axis,371 tickPos = tick.pos,372 isFirst = tick.isFirst,373 max = axis.max,374 min = axis.min,375 horiz = axis.horiz,376 cat = axis.categories[tickPos],377 grid = axis.labelsGridPath,378 size = axis.groupSize(0),379 tickLen = axis.tickLength || size,380 tickWidth = axis.tickWidth,381 factor = axis.directionFactor,382 xy = tickPosition(tick, tickPos),383 start = horiz ? xy.y : xy.x,384 baseLine= axis.chart.renderer.fontMetrics(axis.options.labels.style.fontSize).b,385 depth = 1,386 // adjust grid lines for edges387 reverseCrisp = ((horiz && xy.x === axis.pos + axis.len) || (!horiz && xy.y === axis.pos)) ? -1 : 0,388 gridAttrs,389 lvlSize,390 minPos,391 maxPos,392 attrs,393 bBox;394 // render grid for "normal" categories (first-level), render left grid line only for the first category395 if (isFirst) {396 397 gridAttrs = horiz ?398 [axis.left, xy.y, axis.left, xy.y + axis.groupSize(true)] :399 axis.isXAxis ?400 [xy.x, axis.top, xy.x + axis.groupSize(true), axis.top] :401 [xy.x, axis.top + axis.len, xy.x + axis.groupSize(true), axis.top + axis.len];402 addGridPart(grid, gridAttrs, tickWidth);403 }404 405 if(horiz && axis.left < xy.x) {406 addGridPart(grid, [xy.x - reverseCrisp, xy.y, xy.x - reverseCrisp, xy.y + size], tickWidth);407 } else if(!horiz && axis.top <= xy.y){408 addGridPart(grid, [xy.x, xy.y + reverseCrisp, xy.x + size, xy.y + reverseCrisp], tickWidth);409 }410 size = start + size;411 function fixOffset(group, treeCat, tick){412 var ret = 0;413 if(isFirst) {414 ret = inArray(treeCat.name, treeCat.parent.categories);415 ret = ret < 0 ? 0 : ret;416 return ret;417 } 418 return ret;419 }420 while (group = group.parent) {421 var fix = fixOffset(group, treeCat, tick),422 userX = group.labelOffsets.x,423 userY = group.labelOffsets.y;424 425 minPos = tickPosition(tick, mathMax(group.startAt - 1, min - 1));426 maxPos = tickPosition(tick, mathMin(group.startAt + group.leaves - 1 - fix, max));427 bBox = group.label.getBBox(true);428 lvlSize = axis.groupSize(depth);429 // check if on the edge to adjust430 reverseCrisp = ((horiz && maxPos.x === axis.pos + axis.len) || (!horiz && maxPos.y === axis.pos)) ? -1 : 0;431 432 attrs = horiz ? {433 x: (minPos.x + maxPos.x) / 2 + userX,434 y: size + lvlSize / 2 + baseLine - bBox.height / 2 - 4 + userY / 2435 } : {436 x: size + lvlSize / 2 + userX,437 y: (minPos.y + maxPos.y - bBox.height) / 2 + baseLine + userY438 };439 if(!isNaN(attrs.x) && !isNaN(attrs.y)){ 440 group.label.attr(attrs);441 442 if (grid) {443 if(horiz && axis.left < maxPos.x) {444 addGridPart(grid, [maxPos.x - reverseCrisp, size, maxPos.x - reverseCrisp, size + lvlSize], tickWidth);445 } else if(!horiz && axis.top <= maxPos.y){446 addGridPart(grid, [size, maxPos.y + reverseCrisp, size + lvlSize, maxPos.y + reverseCrisp], tickWidth);447 }448 }449 }450 size += lvlSize;451 depth++;452 }453};454tickProto.destroy = function () {455 var group = this;456 while (group = group.parent)457 group.destroyed++ || (group.destroyed = 1);458 _tickDestroy.call(this);459};460// return size of the label (height for horizontal, width for vertical axes)461tickProto.getLabelSize = function () {462 if (this.axis.isGrouped === true) {463 // #72, getBBox might need recalculating when chart is tall464 var size = _tickGetLabelSize.call(this) + 10,465 topLabelSize = this.axis.labelsSizes[0];466 if (topLabelSize < size) {467 this.axis.labelsSizes[0] = size;468 }469 return sum(this.axis.labelsSizes);470 } else471 return _tickGetLabelSize.call(this);472};...
c3.axis.js
Source:c3.axis.js
1// Features:2// 1. category axis3// 2. ceil values of translate/x/y to int for half pixel antialiasing4// 3. multiline tick text5var tickTextCharSize;6function c3_axis(d3, params) {7 var scale = d3.scale.linear(), orient = "bottom", innerTickSize = 6, outerTickSize, tickPadding = 3, tickValues = null, tickFormat, tickArguments;8 var tickOffset = 0, tickCulling = true, tickCentered;9 params = params || {};10 outerTickSize = params.withOuterTick ? 6 : 0;11 function axisX(selection, x) {12 selection.attr("transform", function (d) {13 return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)";14 });15 }16 function axisY(selection, y) {17 selection.attr("transform", function (d) {18 return "translate(0," + Math.ceil(y(d)) + ")";19 });20 }21 function scaleExtent(domain) {22 var start = domain[0], stop = domain[domain.length - 1];23 return start < stop ? [ start, stop ] : [ stop, start ];24 }25 function generateTicks(scale) {26 var i, domain, ticks = [];27 if (scale.ticks) {28 return scale.ticks.apply(scale, tickArguments);29 }30 domain = scale.domain();31 for (i = Math.ceil(domain[0]); i < domain[1]; i++) {32 ticks.push(i);33 }34 if (ticks.length > 0 && ticks[0] > 0) {35 ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));36 }37 return ticks;38 }39 function copyScale() {40 var newScale = scale.copy(), domain;41 if (params.isCategory) {42 domain = scale.domain();43 newScale.domain([domain[0], domain[1] - 1]);44 }45 return newScale;46 }47 function textFormatted(v) {48 var formatted = tickFormat ? tickFormat(v) : v;49 return typeof formatted !== 'undefined' ? formatted : '';50 }51 function getSizeFor1Char(tick) {52 if (tickTextCharSize) {53 return tickTextCharSize;54 }55 var size = {56 h: 11.5,57 w: 5.558 };59 tick.select('text').text(textFormatted).each(function (d) {60 var box = this.getBoundingClientRect(),61 text = textFormatted(d),62 h = box.height,63 w = text ? (box.width / text.length) : undefined;64 if (h && w) {65 size.h = h;66 size.w = w;67 }68 }).text('');69 tickTextCharSize = size;70 return size;71 }72 function transitionise(selection) {73 return params.withoutTransition ? selection : d3.transition(selection);74 }75 function axis(g) {76 g.each(function () {77 var g = axis.g = d3.select(this);78 var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = copyScale();79 var ticks = tickValues ? tickValues : generateTicks(scale1),80 tick = g.selectAll(".tick").data(ticks, scale1),81 tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6),82 // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.83 tickExit = tick.exit().remove(),84 tickUpdate = transitionise(tick).style("opacity", 1),85 tickTransform, tickX, tickY;86 var range = scale.rangeExtent ? scale.rangeExtent() : scaleExtent(scale.range()),87 path = g.selectAll(".domain").data([ 0 ]),88 pathUpdate = (path.enter().append("path").attr("class", "domain"), transitionise(path));89 tickEnter.append("line");90 tickEnter.append("text");91 var lineEnter = tickEnter.select("line"),92 lineUpdate = tickUpdate.select("line"),93 textEnter = tickEnter.select("text"),94 textUpdate = tickUpdate.select("text");95 if (params.isCategory) {96 tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);97 tickX = tickCentered ? 0 : tickOffset;98 tickY = tickCentered ? tickOffset : 0;99 } else {100 tickOffset = tickX = 0;101 }102 var text, tspan, sizeFor1Char = getSizeFor1Char(g.select('.tick')), counts = [];103 var tickLength = Math.max(innerTickSize, 0) + tickPadding,104 isVertical = orient === 'left' || orient === 'right';105 // this should be called only when category axis106 function splitTickText(d, maxWidth) {107 var tickText = textFormatted(d),108 subtext, spaceIndex, textWidth, splitted = [];109 if (Object.prototype.toString.call(tickText) === "[object Array]") {110 return tickText;111 }112 if (!maxWidth || maxWidth <= 0) {113 maxWidth = isVertical ? 95 : params.isCategory ? (Math.ceil(scale1(ticks[1]) - scale1(ticks[0])) - 12) : 110;114 }115 function split(splitted, text) {116 spaceIndex = undefined;117 for (var i = 1; i < text.length; i++) {118 if (text.charAt(i) === ' ') {119 spaceIndex = i;120 }121 subtext = text.substr(0, i + 1);122 textWidth = sizeFor1Char.w * subtext.length;123 // if text width gets over tick width, split by space index or crrent index124 if (maxWidth < textWidth) {125 return split(126 splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)),127 text.slice(spaceIndex ? spaceIndex + 1 : i)128 );129 }130 }131 return splitted.concat(text);132 }133 return split(splitted, tickText + "");134 }135 function tspanDy(d, i) {136 var dy = sizeFor1Char.h;137 if (i === 0) {138 if (orient === 'left' || orient === 'right') {139 dy = -((counts[d.index] - 1) * (sizeFor1Char.h / 2) - 3);140 } else {141 dy = ".71em";142 }143 }144 return dy;145 }146 function tickSize(d) {147 var tickPosition = scale(d) + (tickCentered ? 0 : tickOffset);148 return range[0] < tickPosition && tickPosition < range[1] ? innerTickSize : 0;149 }150 text = tick.select("text");151 tspan = text.selectAll('tspan')152 .data(function (d, i) {153 var splitted = params.tickMultiline ? splitTickText(d, params.tickWidth) : [].concat(textFormatted(d));154 counts[i] = splitted.length;155 return splitted.map(function (s) {156 return { index: i, splitted: s };157 });158 });159 tspan.enter().append('tspan');160 tspan.exit().remove();161 tspan.text(function (d) { return d.splitted; });162 var rotate = params.tickTextRotate;163 function textAnchorForText(rotate) {164 if (!rotate) {165 return 'middle';166 }167 return rotate > 0 ? "start" : "end";168 }169 function textTransform(rotate) {170 if (!rotate) {171 return '';172 }173 return "rotate(" + rotate + ")";174 }175 function dxForText(rotate) {176 if (!rotate) {177 return 0;178 }179 return 8 * Math.sin(Math.PI * (rotate / 180));180 }181 function yForText(rotate) {182 if (!rotate) {183 return tickLength;184 }185 return 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1);186 }187 switch (orient) {188 case "bottom":189 {190 tickTransform = axisX;191 lineEnter.attr("y2", innerTickSize);192 textEnter.attr("y", tickLength);193 lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", tickSize);194 textUpdate.attr("x", 0).attr("y", yForText(rotate))195 .style("text-anchor", textAnchorForText(rotate))196 .attr("transform", textTransform(rotate));197 tspan.attr('x', 0).attr("dy", tspanDy).attr('dx', dxForText(rotate));198 pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize);199 break;200 }201 case "top":202 {203 // TODO: rotated tick text204 tickTransform = axisX;205 lineEnter.attr("y2", -innerTickSize);206 textEnter.attr("y", -tickLength);207 lineUpdate.attr("x2", 0).attr("y2", -innerTickSize);208 textUpdate.attr("x", 0).attr("y", -tickLength);209 text.style("text-anchor", "middle");210 tspan.attr('x', 0).attr("dy", "0em");211 pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize);212 break;213 }214 case "left":215 {216 tickTransform = axisY;217 lineEnter.attr("x2", -innerTickSize);218 textEnter.attr("x", -tickLength);219 lineUpdate.attr("x2", -innerTickSize).attr("y1", tickY).attr("y2", tickY);220 textUpdate.attr("x", -tickLength).attr("y", tickOffset);221 text.style("text-anchor", "end");222 tspan.attr('x', -tickLength).attr("dy", tspanDy);223 pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize);224 break;225 }226 case "right":227 {228 tickTransform = axisY;229 lineEnter.attr("x2", innerTickSize);230 textEnter.attr("x", tickLength);231 lineUpdate.attr("x2", innerTickSize).attr("y2", 0);232 textUpdate.attr("x", tickLength).attr("y", 0);233 text.style("text-anchor", "start");234 tspan.attr('x', tickLength).attr("dy", tspanDy);235 pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize);236 break;237 }238 }239 if (scale1.rangeBand) {240 var x = scale1, dx = x.rangeBand() / 2;241 scale0 = scale1 = function (d) {242 return x(d) + dx;243 };244 } else if (scale0.rangeBand) {245 scale0 = scale1;246 } else {247 tickExit.call(tickTransform, scale1);248 }249 tickEnter.call(tickTransform, scale0);250 tickUpdate.call(tickTransform, scale1);251 });252 }253 axis.scale = function (x) {254 if (!arguments.length) { return scale; }255 scale = x;256 return axis;257 };258 axis.orient = function (x) {259 if (!arguments.length) { return orient; }260 orient = x in {top: 1, right: 1, bottom: 1, left: 1} ? x + "" : "bottom";261 return axis;262 };263 axis.tickFormat = function (format) {264 if (!arguments.length) { return tickFormat; }265 tickFormat = format;266 return axis;267 };268 axis.tickCentered = function (isCentered) {269 if (!arguments.length) { return tickCentered; }270 tickCentered = isCentered;271 return axis;272 };273 axis.tickOffset = function () {274 return tickOffset;275 };276 axis.tickInterval = function () {277 var interval, length;278 if (params.isCategory) {279 interval = tickOffset * 2;280 }281 else {282 length = axis.g.select('path.domain').node().getTotalLength() - outerTickSize * 2;283 interval = length / axis.g.selectAll('line').size();284 }285 return interval === Infinity ? 0 : interval;286 };287 axis.ticks = function () {288 if (!arguments.length) { return tickArguments; }289 tickArguments = arguments;290 return axis;291 };292 axis.tickCulling = function (culling) {293 if (!arguments.length) { return tickCulling; }294 tickCulling = culling;295 return axis;296 };297 axis.tickValues = function (x) {298 if (typeof x === 'function') {299 tickValues = function () {300 return x(scale.domain());301 };302 }303 else {304 if (!arguments.length) { return tickValues; }305 tickValues = x;306 }307 return axis;308 };309 return axis;...
linear.js.uncompressed.js
Source:linear.js.uncompressed.js
1define("dojox/charting/scaler/linear", ["dojo/_base/lang", "./common"], 2 function(lang, common){3 var linear = lang.getObject("dojox.charting.scaler.linear", true);4 5 var deltaLimit = 3, // pixels6 getLabel = common.getNumericLabel;7 function findString(/*String*/ val, /*Array*/ text){8 val = val.toLowerCase();9 for(var i = text.length - 1; i >= 0; --i){10 if(val === text[i]){11 return true;12 }13 }14 return false;15 }16 17 var calcTicks = function(min, max, kwArgs, majorTick, minorTick, microTick, span){18 kwArgs = lang.delegate(kwArgs);19 if(!majorTick){20 if(kwArgs.fixUpper == "major"){ kwArgs.fixUpper = "minor"; }21 if(kwArgs.fixLower == "major"){ kwArgs.fixLower = "minor"; }22 }23 if(!minorTick){24 if(kwArgs.fixUpper == "minor"){ kwArgs.fixUpper = "micro"; }25 if(kwArgs.fixLower == "minor"){ kwArgs.fixLower = "micro"; }26 }27 if(!microTick){28 if(kwArgs.fixUpper == "micro"){ kwArgs.fixUpper = "none"; }29 if(kwArgs.fixLower == "micro"){ kwArgs.fixLower = "none"; }30 }31 var lowerBound = findString(kwArgs.fixLower, ["major"]) ?32 Math.floor(kwArgs.min / majorTick) * majorTick :33 findString(kwArgs.fixLower, ["minor"]) ?34 Math.floor(kwArgs.min / minorTick) * minorTick :35 findString(kwArgs.fixLower, ["micro"]) ?36 Math.floor(kwArgs.min / microTick) * microTick : kwArgs.min,37 upperBound = findString(kwArgs.fixUpper, ["major"]) ?38 Math.ceil(kwArgs.max / majorTick) * majorTick :39 findString(kwArgs.fixUpper, ["minor"]) ?40 Math.ceil(kwArgs.max / minorTick) * minorTick :41 findString(kwArgs.fixUpper, ["micro"]) ?42 Math.ceil(kwArgs.max / microTick) * microTick : kwArgs.max;43 44 if(kwArgs.useMin){ min = lowerBound; }45 if(kwArgs.useMax){ max = upperBound; }46 47 var majorStart = (!majorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major"])) ?48 min : Math.ceil(min / majorTick) * majorTick,49 minorStart = (!minorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor"])) ?50 min : Math.ceil(min / minorTick) * minorTick,51 microStart = (! microTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor", "micro"])) ?52 min : Math.ceil(min / microTick) * microTick,53 majorCount = !majorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major"]) ?54 Math.round((max - majorStart) / majorTick) :55 Math.floor((max - majorStart) / majorTick)) + 1,56 minorCount = !minorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor"]) ?57 Math.round((max - minorStart) / minorTick) :58 Math.floor((max - minorStart) / minorTick)) + 1,59 microCount = !microTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor", "micro"]) ?60 Math.round((max - microStart) / microTick) :61 Math.floor((max - microStart) / microTick)) + 1,62 minorPerMajor = minorTick ? Math.round(majorTick / minorTick) : 0,63 microPerMinor = microTick ? Math.round(minorTick / microTick) : 0,64 majorPrecision = majorTick ? Math.floor(Math.log(majorTick) / Math.LN10) : 0,65 minorPrecision = minorTick ? Math.floor(Math.log(minorTick) / Math.LN10) : 0,66 scale = span / (max - min);67 if(!isFinite(scale)){ scale = 1; }68 69 return {70 bounds: {71 lower: lowerBound,72 upper: upperBound,73 from: min,74 to: max,75 scale: scale,76 span: span77 },78 major: {79 tick: majorTick,80 start: majorStart,81 count: majorCount,82 prec: majorPrecision83 },84 minor: {85 tick: minorTick,86 start: minorStart,87 count: minorCount,88 prec: minorPrecision89 },90 micro: {91 tick: microTick,92 start: microStart,93 count: microCount,94 prec: 095 },96 minorPerMajor: minorPerMajor,97 microPerMinor: microPerMinor,98 scaler: linear99 };100 };101 102 return lang.mixin(linear, {103 buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs, /*Number?*/ delta, /*Number?*/ minorDelta){104 var h = {fixUpper: "none", fixLower: "none", natural: false};105 if(kwArgs){106 if("fixUpper" in kwArgs){ h.fixUpper = String(kwArgs.fixUpper); }107 if("fixLower" in kwArgs){ h.fixLower = String(kwArgs.fixLower); }108 if("natural" in kwArgs){ h.natural = Boolean(kwArgs.natural); }109 }110 minorDelta = !minorDelta || minorDelta < deltaLimit ? deltaLimit : minorDelta;111 112 // update bounds113 if("min" in kwArgs){ min = kwArgs.min; }114 if("max" in kwArgs){ max = kwArgs.max; }115 if(kwArgs.includeZero){116 if(min > 0){ min = 0; }117 if(max < 0){ max = 0; }118 }119 h.min = min;120 h.useMin = true;121 h.max = max;122 h.useMax = true;123 124 if("from" in kwArgs){125 min = kwArgs.from;126 h.useMin = false;127 }128 if("to" in kwArgs){129 max = kwArgs.to;130 h.useMax = false;131 }132 133 // check for erroneous condition134 if(max <= min){135 return calcTicks(min, max, h, 0, 0, 0, span); // Object136 }137 if(!delta){138 delta = max - min;139 }140 var mag = Math.floor(Math.log(delta) / Math.LN10),141 major = kwArgs && ("majorTickStep" in kwArgs) ? kwArgs.majorTickStep : Math.pow(10, mag),142 minor = 0, micro = 0, ticks;143 144 // calculate minor ticks145 if(kwArgs && ("minorTickStep" in kwArgs)){146 minor = kwArgs.minorTickStep;147 }else{148 do{149 minor = major / 10;150 if(!h.natural || minor > 0.9){151 ticks = calcTicks(min, max, h, major, minor, 0, span);152 if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }153 }154 minor = major / 5;155 if(!h.natural || minor > 0.9){156 ticks = calcTicks(min, max, h, major, minor, 0, span);157 if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }158 }159 minor = major / 2;160 if(!h.natural || minor > 0.9){161 ticks = calcTicks(min, max, h, major, minor, 0, span);162 if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }163 }164 return calcTicks(min, max, h, major, 0, 0, span); // Object165 }while(false);166 }167 168 // calculate micro ticks169 if(kwArgs && ("microTickStep" in kwArgs)){170 micro = kwArgs.microTickStep;171 ticks = calcTicks(min, max, h, major, minor, micro, span);172 }else{173 do{174 micro = minor / 10;175 if(!h.natural || micro > 0.9){176 ticks = calcTicks(min, max, h, major, minor, micro, span);177 if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }178 }179 micro = minor / 5;180 if(!h.natural || micro > 0.9){181 ticks = calcTicks(min, max, h, major, minor, micro, span);182 if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }183 }184 micro = minor / 2;185 if(!h.natural || micro > 0.9){186 ticks = calcTicks(min, max, h, major, minor, micro, span);187 if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }188 }189 micro = 0;190 }while(false);191 }192 193 return micro ? ticks : calcTicks(min, max, h, major, minor, 0, span); // Object194 },195 buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){196 var step, next, tick,197 nextMajor = scaler.major.start,198 nextMinor = scaler.minor.start,199 nextMicro = scaler.micro.start;200 if(kwArgs.microTicks && scaler.micro.tick){201 step = scaler.micro.tick, next = nextMicro;202 }else if(kwArgs.minorTicks && scaler.minor.tick){203 step = scaler.minor.tick, next = nextMinor;204 }else if(scaler.major.tick){205 step = scaler.major.tick, next = nextMajor;206 }else{207 // no ticks208 return null;209 }210 // make sure that we have finite bounds211 var revScale = 1 / scaler.bounds.scale;212 if(scaler.bounds.to <= scaler.bounds.from || isNaN(revScale) || !isFinite(revScale) ||213 step <= 0 || isNaN(step) || !isFinite(step)){214 // no ticks215 return null;216 }217 // loop over all ticks218 var majorTicks = [], minorTicks = [], microTicks = [];219 while(next <= scaler.bounds.to + revScale){220 if(Math.abs(nextMajor - next) < step / 2){221 // major tick222 tick = {value: nextMajor};223 if(kwArgs.majorLabels){224 tick.label = getLabel(nextMajor, scaler.major.prec, kwArgs);225 }226 majorTicks.push(tick);227 nextMajor += scaler.major.tick;228 nextMinor += scaler.minor.tick;229 nextMicro += scaler.micro.tick;230 }else if(Math.abs(nextMinor - next) < step / 2){231 // minor tick232 if(kwArgs.minorTicks){233 tick = {value: nextMinor};234 if(kwArgs.minorLabels && (scaler.minMinorStep <= scaler.minor.tick * scaler.bounds.scale)){235 tick.label = getLabel(nextMinor, scaler.minor.prec, kwArgs);236 }237 minorTicks.push(tick);238 }239 nextMinor += scaler.minor.tick;240 nextMicro += scaler.micro.tick;241 }else{242 // micro tick243 if(kwArgs.microTicks){244 microTicks.push({value: nextMicro});245 }246 nextMicro += scaler.micro.tick;247 }248 next += step;249 }250 return {major: majorTicks, minor: minorTicks, micro: microTicks}; // Object251 },252 getTransformerFromModel: function(/*Object*/ scaler){253 var offset = scaler.bounds.from, scale = scaler.bounds.scale;254 return function(x){ return (x - offset) * scale; }; // Function255 },256 getTransformerFromPlot: function(/*Object*/ scaler){257 var offset = scaler.bounds.from, scale = scaler.bounds.scale;258 return function(x){ return x / scale + offset; }; // Function259 }260 });...
linear.js
Source:linear.js
1define(["dojo/_base/lang", "./common"], 2 function(lang, common){3 var linear = lang.getObject("dojox.charting.scaler.linear", true);4 5 var deltaLimit = 3, // pixels6 getLabel = common.getNumericLabel;7 function findString(/*String*/ val, /*Array*/ text){8 val = val.toLowerCase();9 for(var i = text.length - 1; i >= 0; --i){10 if(val === text[i]){11 return true;12 }13 }14 return false;15 }16 17 var calcTicks = function(min, max, kwArgs, majorTick, minorTick, microTick, span){18 kwArgs = lang.delegate(kwArgs);19 if(!majorTick){20 if(kwArgs.fixUpper == "major"){ kwArgs.fixUpper = "minor"; }21 if(kwArgs.fixLower == "major"){ kwArgs.fixLower = "minor"; }22 }23 if(!minorTick){24 if(kwArgs.fixUpper == "minor"){ kwArgs.fixUpper = "micro"; }25 if(kwArgs.fixLower == "minor"){ kwArgs.fixLower = "micro"; }26 }27 if(!microTick){28 if(kwArgs.fixUpper == "micro"){ kwArgs.fixUpper = "none"; }29 if(kwArgs.fixLower == "micro"){ kwArgs.fixLower = "none"; }30 }31 var lowerBound = findString(kwArgs.fixLower, ["major"]) ?32 Math.floor(kwArgs.min / majorTick) * majorTick :33 findString(kwArgs.fixLower, ["minor"]) ?34 Math.floor(kwArgs.min / minorTick) * minorTick :35 findString(kwArgs.fixLower, ["micro"]) ?36 Math.floor(kwArgs.min / microTick) * microTick : kwArgs.min,37 upperBound = findString(kwArgs.fixUpper, ["major"]) ?38 Math.ceil(kwArgs.max / majorTick) * majorTick :39 findString(kwArgs.fixUpper, ["minor"]) ?40 Math.ceil(kwArgs.max / minorTick) * minorTick :41 findString(kwArgs.fixUpper, ["micro"]) ?42 Math.ceil(kwArgs.max / microTick) * microTick : kwArgs.max;43 44 if(kwArgs.useMin){ min = lowerBound; }45 if(kwArgs.useMax){ max = upperBound; }46 47 var majorStart = (!majorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major"])) ?48 min : Math.ceil(min / majorTick) * majorTick,49 minorStart = (!minorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor"])) ?50 min : Math.ceil(min / minorTick) * minorTick,51 microStart = (! microTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor", "micro"])) ?52 min : Math.ceil(min / microTick) * microTick,53 majorCount = !majorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major"]) ?54 Math.round((max - majorStart) / majorTick) :55 Math.floor((max - majorStart) / majorTick)) + 1,56 minorCount = !minorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor"]) ?57 Math.round((max - minorStart) / minorTick) :58 Math.floor((max - minorStart) / minorTick)) + 1,59 microCount = !microTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor", "micro"]) ?60 Math.round((max - microStart) / microTick) :61 Math.floor((max - microStart) / microTick)) + 1,62 minorPerMajor = minorTick ? Math.round(majorTick / minorTick) : 0,63 microPerMinor = microTick ? Math.round(minorTick / microTick) : 0,64 majorPrecision = majorTick ? Math.floor(Math.log(majorTick) / Math.LN10) : 0,65 minorPrecision = minorTick ? Math.floor(Math.log(minorTick) / Math.LN10) : 0,66 scale = span / (max - min);67 if(!isFinite(scale)){ scale = 1; }68 69 return {70 bounds: {71 lower: lowerBound,72 upper: upperBound,73 from: min,74 to: max,75 scale: scale,76 span: span77 },78 major: {79 tick: majorTick,80 start: majorStart,81 count: majorCount,82 prec: majorPrecision83 },84 minor: {85 tick: minorTick,86 start: minorStart,87 count: minorCount,88 prec: minorPrecision89 },90 micro: {91 tick: microTick,92 start: microStart,93 count: microCount,94 prec: 095 },96 minorPerMajor: minorPerMajor,97 microPerMinor: microPerMinor,98 scaler: linear99 };100 };101 102 return lang.mixin(linear, {103 buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs, /*Number?*/ delta, /*Number?*/ minorDelta){104 var h = {fixUpper: "none", fixLower: "none", natural: false};105 if(kwArgs){106 if("fixUpper" in kwArgs){ h.fixUpper = String(kwArgs.fixUpper); }107 if("fixLower" in kwArgs){ h.fixLower = String(kwArgs.fixLower); }108 if("natural" in kwArgs){ h.natural = Boolean(kwArgs.natural); }109 }110 minorDelta = !minorDelta || minorDelta < deltaLimit ? deltaLimit : minorDelta;111 112 // update bounds113 if("min" in kwArgs){ min = kwArgs.min; }114 if("max" in kwArgs){ max = kwArgs.max; }115 if(kwArgs.includeZero){116 if(min > 0){ min = 0; }117 if(max < 0){ max = 0; }118 }119 h.min = min;120 h.useMin = true;121 h.max = max;122 h.useMax = true;123 124 if("from" in kwArgs){125 min = kwArgs.from;126 h.useMin = false;127 }128 if("to" in kwArgs){129 max = kwArgs.to;130 h.useMax = false;131 }132 133 // check for erroneous condition134 if(max <= min){135 return calcTicks(min, max, h, 0, 0, 0, span); // Object136 }137 if(!delta){138 delta = max - min;139 }140 var mag = Math.floor(Math.log(delta) / Math.LN10),141 major = kwArgs && ("majorTickStep" in kwArgs) ? kwArgs.majorTickStep : Math.pow(10, mag),142 minor = 0, micro = 0, ticks;143 144 // calculate minor ticks145 if(kwArgs && ("minorTickStep" in kwArgs)){146 minor = kwArgs.minorTickStep;147 }else{148 do{149 minor = major / 10;150 if(!h.natural || minor > 0.9){151 ticks = calcTicks(min, max, h, major, minor, 0, span);152 if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }153 }154 minor = major / 5;155 if(!h.natural || minor > 0.9){156 ticks = calcTicks(min, max, h, major, minor, 0, span);157 if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }158 }159 minor = major / 2;160 if(!h.natural || minor > 0.9){161 ticks = calcTicks(min, max, h, major, minor, 0, span);162 if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }163 }164 return calcTicks(min, max, h, major, 0, 0, span); // Object165 }while(false);166 }167 168 // calculate micro ticks169 if(kwArgs && ("microTickStep" in kwArgs)){170 micro = kwArgs.microTickStep;171 ticks = calcTicks(min, max, h, major, minor, micro, span);172 }else{173 do{174 micro = minor / 10;175 if(!h.natural || micro > 0.9){176 ticks = calcTicks(min, max, h, major, minor, micro, span);177 if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }178 }179 micro = minor / 5;180 if(!h.natural || micro > 0.9){181 ticks = calcTicks(min, max, h, major, minor, micro, span);182 if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }183 }184 micro = minor / 2;185 if(!h.natural || micro > 0.9){186 ticks = calcTicks(min, max, h, major, minor, micro, span);187 if(ticks.bounds.scale * ticks.micro.tick > deltaLimit){ break; }188 }189 micro = 0;190 }while(false);191 }192 193 return micro ? ticks : calcTicks(min, max, h, major, minor, 0, span); // Object194 },195 buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){196 var step, next, tick,197 nextMajor = scaler.major.start,198 nextMinor = scaler.minor.start,199 nextMicro = scaler.micro.start;200 if(kwArgs.microTicks && scaler.micro.tick){201 step = scaler.micro.tick, next = nextMicro;202 }else if(kwArgs.minorTicks && scaler.minor.tick){203 step = scaler.minor.tick, next = nextMinor;204 }else if(scaler.major.tick){205 step = scaler.major.tick, next = nextMajor;206 }else{207 // no ticks208 return null;209 }210 // make sure that we have finite bounds211 var revScale = 1 / scaler.bounds.scale;212 if(scaler.bounds.to <= scaler.bounds.from || isNaN(revScale) || !isFinite(revScale) ||213 step <= 0 || isNaN(step) || !isFinite(step)){214 // no ticks215 return null;216 }217 // loop over all ticks218 var majorTicks = [], minorTicks = [], microTicks = [];219 while(next <= scaler.bounds.to + revScale){220 if(Math.abs(nextMajor - next) < step / 2){221 // major tick222 tick = {value: nextMajor};223 if(kwArgs.majorLabels){224 tick.label = getLabel(nextMajor, scaler.major.prec, kwArgs);225 }226 majorTicks.push(tick);227 nextMajor += scaler.major.tick;228 nextMinor += scaler.minor.tick;229 nextMicro += scaler.micro.tick;230 }else if(Math.abs(nextMinor - next) < step / 2){231 // minor tick232 if(kwArgs.minorTicks){233 tick = {value: nextMinor};234 if(kwArgs.minorLabels && (scaler.minMinorStep <= scaler.minor.tick * scaler.bounds.scale)){235 tick.label = getLabel(nextMinor, scaler.minor.prec, kwArgs);236 }237 minorTicks.push(tick);238 }239 nextMinor += scaler.minor.tick;240 nextMicro += scaler.micro.tick;241 }else{242 // micro tick243 if(kwArgs.microTicks){244 microTicks.push({value: nextMicro});245 }246 nextMicro += scaler.micro.tick;247 }248 next += step;249 }250 return {major: majorTicks, minor: minorTicks, micro: microTicks}; // Object251 },252 getTransformerFromModel: function(/*Object*/ scaler){253 var offset = scaler.bounds.from, scale = scaler.bounds.scale;254 return function(x){ return (x - offset) * scale; }; // Function255 },256 getTransformerFromPlot: function(/*Object*/ scaler){257 var offset = scaler.bounds.from, scale = scaler.bounds.scale;258 return function(x){ return x / scale + offset; }; // Function259 }260 });...
scaler.js
Source:scaler.js
1if(!dojo._hasResource["dojox.charting.scaler"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.2dojo._hasResource["dojox.charting.scaler"] = true;3dojo.provide("dojox.charting.scaler");4(function(){5 var deltaLimit = 3; // pixels6 7 var isText = function(val, text){8 val = val.toLowerCase();9 for(var i = 0; i < text.length; ++i){10 if(val == text[i]){ return true; }11 }12 return false;13 };14 15 var calcTicks = function(min, max, kwArgs, majorTick, minorTick, microTick, span){16 kwArgs = dojo.clone(kwArgs);17 if(!majorTick){18 if(kwArgs.fixUpper == "major"){ kwArgs.fixUpper = "minor"; }19 if(kwArgs.fixLower == "major"){ kwArgs.fixLower = "minor"; }20 }21 if(!minorTick){22 if(kwArgs.fixUpper == "minor"){ kwArgs.fixUpper = "micro"; }23 if(kwArgs.fixLower == "minor"){ kwArgs.fixLower = "micro"; }24 }25 if(!microTick){26 if(kwArgs.fixUpper == "micro"){ kwArgs.fixUpper = "none"; }27 if(kwArgs.fixLower == "micro"){ kwArgs.fixLower = "none"; }28 }29 var lowerBound = isText(kwArgs.fixLower, ["major"]) ? 30 Math.floor(min / majorTick) * majorTick :31 isText(kwArgs.fixLower, ["minor"]) ? 32 Math.floor(min / minorTick) * minorTick :33 isText(kwArgs.fixLower, ["micro"]) ?34 Math.floor(min / microTick) * unit : min,35 upperBound = isText(kwArgs.fixUpper, ["major"]) ? 36 Math.ceil(max / majorTick) * majorTick :37 isText(kwArgs.fixUpper, ["minor"]) ? 38 Math.ceil(max / minorTick) * minorTick :39 isText(kwArgs.fixUpper, ["unit"]) ?40 Math.ceil(max / unit) * unit : max,41 majorStart = (isText(kwArgs.fixLower, ["major"]) || !majorTick) ?42 lowerBound : Math.ceil(lowerBound / majorTick) * majorTick,43 minorStart = (isText(kwArgs.fixLower, ["major", "minor"]) || !minorTick) ?44 lowerBound : Math.ceil(lowerBound / minorTick) * minorTick,45 microStart = (isText(kwArgs.fixLower, ["major", "minor", "micro"]) || ! microTick) ?46 lowerBound : Math.ceil(lowerBound / microTick) * microTick,47 majorCount = !majorTick ? 0 : (isText(kwArgs.fixUpper, ["major"]) ?48 Math.round((upperBound - majorStart) / majorTick) :49 Math.floor((upperBound - majorStart) / majorTick)) + 1,50 minorCount = !minorTick ? 0 : (isText(kwArgs.fixUpper, ["major", "minor"]) ?51 Math.round((upperBound - minorStart) / minorTick) :52 Math.floor((upperBound - minorStart) / minorTick)) + 1,53 microCount = !microTick ? 0 : (isText(kwArgs.fixUpper, ["major", "minor", "micro"]) ?54 Math.round((upperBound - microStart) / microTick) :55 Math.floor((upperBound - microStart) / microTick)) + 1,56 minorPerMajor = minorTick ? Math.round(majorTick / minorTick) : 0,57 microPerMinor = microTick ? Math.round(minorTick / microTick) : 0,58 majorPrecision = majorTick ? Math.floor(Math.log(majorTick) / Math.LN10) : 0,59 minorPrecision = minorTick ? Math.floor(Math.log(minorTick) / Math.LN10) : 0,60 scale = span / (upperBound - lowerBound);61 if(!isFinite(scale)){ scale = 1; }62 return {63 bounds: {64 lower: lowerBound,65 upper: upperBound66 },67 major: {68 tick: majorTick,69 start: majorStart,70 count: majorCount,71 prec: majorPrecision72 },73 minor: {74 tick: minorTick,75 start: minorStart,76 count: minorCount,77 prec: minorPrecision78 },79 micro: {80 tick: microTick,81 start: microStart,82 count: microCount,83 prec: 084 },85 minorPerMajor: minorPerMajor,86 microPerMinor: microPerMinor,87 scale: scale88 };89 };90 dojox.charting.scaler = function(min, max, span, kwArgs){91 var h = {fixUpper: "none", fixLower: "none", natural: false};92 if(kwArgs){93 if("fixUpper" in kwArgs){ h.fixUpper = String(kwArgs.fixUpper); }94 if("fixLower" in kwArgs){ h.fixLower = String(kwArgs.fixLower); }95 if("natural" in kwArgs){ h.natural = Boolean(kwArgs.natural); }96 }97 98 if(max <= min){99 return calcTicks(min, max, h, 0, 0, 0, span); // Object100 }101 102 var mag = Math.floor(Math.log(max - min) / Math.LN10),103 major = kwArgs && ("majorTick" in kwArgs) ? kwArgs.majorTick : Math.pow(10, mag), 104 minor = 0, micro = 0, ticks;105 106 // calculate minor ticks107 if(kwArgs && ("minorTick" in kwArgs)){108 minor = kwArgs.minorTick;109 }else{110 do{111 minor = major / 10;112 if(!h.natural || minor > 0.9){113 ticks = calcTicks(min, max, h, major, minor, 0, span);114 if(ticks.scale * ticks.minor.tick > deltaLimit){ break; }115 }116 minor = major / 5;117 if(!h.natural || minor > 0.9){118 ticks = calcTicks(min, max, h, major, minor, 0, span);119 if(ticks.scale * ticks.minor.tick > deltaLimit){ break; }120 }121 minor = major / 2;122 if(!h.natural || minor > 0.9){123 ticks = calcTicks(min, max, h, major, minor, 0, span);124 if(ticks.scale * ticks.minor.tick > deltaLimit){ break; }125 }126 return calcTicks(min, max, h, major, 0, 0, span); // Object127 }while(false);128 }129 // calculate micro ticks130 if(kwArgs && ("microTick" in kwArgs)){131 micro = kwArgs.microTick;132 ticks = calcTicks(min, max, h, major, minor, micro, span);133 }else{134 do{135 micro = minor / 10;136 if(!h.natural || micro > 0.9){137 ticks = calcTicks(min, max, h, major, minor, micro, span);138 if(ticks.scale * ticks.micro.tick > deltaLimit){ break; }139 }140 micro = minor / 5;141 if(!h.natural || micro > 0.9){142 ticks = calcTicks(min, max, h, major, minor, micro, span);143 if(ticks.scale * ticks.micro.tick > deltaLimit){ break; }144 }145 micro = minor / 2;146 if(!h.natural || micro > 0.9){147 ticks = calcTicks(min, max, h, major, minor, micro, span);148 if(ticks.scale * ticks.micro.tick > deltaLimit){ break; }149 }150 micro = 0;151 }while(false);152 }153 return micro ? ticks : calcTicks(min, max, h, major, minor, 0, span); // Object154 };155})();...
Axis2D.js
Source:Axis2D.js
1//BEGIN COPYRIGHT2//*************************************************************************3//4// Licensed Materials - Property of IBM5// 5655-FLW6// (C) Copyright IBM Corporation 2008, 2009. All Rights Reserved.7// US Government Users Restricted Rights- Use, duplication or disclosure8// restricted by GSA ADP Schedule Contract with IBM Corp.9//10//*************************************************************************11//END COPYRIGHT12//**************************************13//14// Version: 1.3 09/08/06 00:05:0915//16//**************************************17dojo.provide("bpc.charting.Axis2D");18dojo.require("dojox.charting.axis2d.Default");19 var dc = dojox.charting,20 df = dojox.lang.functional,21 du = dojox.lang.utils,22 g = dojox.gfx,23 lin = dc.scaler.linear,24 labelGap = 4; // in pixels25 26 var eq = function(/* Number */ a, /* Number */ b){27 // summary: compare two FP numbers for equality28 return Math.abs(a - b) <= 1e-6 * (Math.abs(a) + Math.abs(b)); // Boolean29 };30 31 dojo.declare("bpc.charting.Axis2D", dojox.charting.axis2d.Default, {32 render: function(dim, offsets){33 if(!this.dirty){ return this; }34 // prepare variable35 var start, stop, axisVector, tickVector, labelOffset, labelAlign,36 ta = this.chart.theme.axis,37 taStroke = "stroke" in this.opt ? this.opt.stroke : ta.stroke,38 taMajorTick = "majorTick" in this.opt ? this.opt.majorTick : ta.majorTick,39 taMinorTick = "minorTick" in this.opt ? this.opt.minorTick : ta.minorTick,40 taMicroTick = "microTick" in this.opt ? this.opt.microTick : ta.minorTick,41 taFont = "font" in this.opt ? this.opt.font : ta.font,42 taFontColor = "fontColor" in this.opt ? this.opt.fontColor : ta.fontColor,43 tickSize = Math.max(taMajorTick.length, taMinorTick.length),44 size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0;45 if(this.vertical){46 start = {y: dim.height - offsets.b};47 stop = {y: offsets.t};48 axisVector = {x: 0, y: -1};49 if(this.opt.leftBottom){50 start.x = stop.x = offsets.l;51 tickVector = {x: -1, y: 0};52 labelAlign = "end";53 }else{54 start.x = stop.x = dim.width - offsets.r;55 tickVector = {x: 1, y: 0};56 labelAlign = "start";57 }58 labelOffset = {x: tickVector.x * (tickSize + labelGap), y: size * 0.4};59 }else{60 start = {x: offsets.l};61 stop = {x: dim.width - offsets.r};62 axisVector = {x: 1, y: 0};63 labelAlign = "middle";64 if(this.opt.leftBottom){65 start.y = stop.y = dim.height - offsets.b;66 tickVector = {x: 0, y: 1};67 labelOffset = {y: tickSize + labelGap + size};68 }else{69 start.y = stop.y = offsets.t;70 tickVector = {x: 0, y: -1};71 labelOffset = {y: -tickSize - labelGap};72 }73 labelOffset.x = 0;74 }75 // bug fix for rtl axis position 76 if (!dojo._isBodyLtr()){77 labelOffset.x = labelOffset.x - dim.width;78 }79 // render shapes80 this.cleanGroup();81 try{82 var s = this.group, c = this.scaler, t = this.ticks, canLabel,83 f = lin.getTransformerFromModel(this.scaler),84 forceHtmlLabels = dojox.gfx.renderer == "canvas",85 labelType = forceHtmlLabels || this.opt.htmlLabels && !dojo.isIE && !dojo.isOpera ? "html" : "gfx",86 dx = tickVector.x * taMajorTick.length,87 dy = tickVector.y * taMajorTick.length;88 s.createLine({x1: start.x, y1: start.y, x2: stop.x, y2: stop.y}).setStroke(taStroke);89 dojo.forEach(t.major, function(tick){90 var offset = f(tick.value), elem,91 x = start.x + axisVector.x * offset,92 y = start.y + axisVector.y * offset;93 s.createLine({94 x1: x, y1: y,95 x2: x + dx,96 y2: y + dy97 }).setStroke(taMajorTick);98 if(tick.label){99 elem = dc.axis2d.common.createText[labelType]100 (this.chart, s, x + labelOffset.x, y + labelOffset.y, labelAlign,101 tick.label, taFont, taFontColor);102 if(labelType == "html"){ this.htmlElements.push(elem); }103 }104 }, this);105 dx = tickVector.x * taMinorTick.length;106 dy = tickVector.y * taMinorTick.length;107 canLabel = c.minMinorStep <= c.minor.tick * c.bounds.scale;108 dojo.forEach(t.minor, function(tick){109 var offset = f(tick.value), elem,110 x = start.x + axisVector.x * offset,111 y = start.y + axisVector.y * offset;112 s.createLine({113 x1: x, y1: y,114 x2: x + dx,115 y2: y + dy116 }).setStroke(taMinorTick);117 if(canLabel && tick.label){118 elem = dc.axis2d.common.createText[labelType]119 (this.chart, s, x + labelOffset.x, y + labelOffset.y, labelAlign,120 tick.label, taFont, taFontColor);121 if(labelType == "html"){ this.htmlElements.push(elem); }122 }123 }, this);124 dx = tickVector.x * taMicroTick.length;125 dy = tickVector.y * taMicroTick.length;126 dojo.forEach(t.micro, function(tick){127 var offset = f(tick.value), elem,128 x = start.x + axisVector.x * offset,129 y = start.y + axisVector.y * offset;130 s.createLine({131 x1: x, y1: y,132 x2: x + dx,133 y2: y + dy134 }).setStroke(taMicroTick);135 }, this);136 }catch(e){137 // squelch138 }139 this.dirty = false;140 return this;141 }...
Using AI Code Generation
1var wpt = require('webpagetest');2var wpt = new WebPageTest('www.webpagetest.org');3var location = 'Dulles:Chrome';4var options = {5 videoParams: {6 }7};8wpt.runTest(url, options, function(err, data) {9 if (err) return console.log(err);10 console.log('Waiting for test results...');11 wpt.getTestResults(data.data.testId, function(err, data) {12 if (err) return console.log(err);13 console.log('Test completed!');14 console.log(data);15 });16});
Using AI Code Generation
1var wpt = require('webpagetest');2var api = new wpt('www.webpagetest.org');3 api.getTestResults(data.data.testId, function (err, data) {4 console.log(data);5 });6});7var wpt = require('webpagetest');8var api = new wpt('www.webpagetest.org');9 api.getTestResults(data.data.testId, function (err, data) {10 console.log(data);11 });12});13var wpt = require('webpagetest');14var api = new wpt('www.webpagetest.org');15 api.getTestResults(data.data.testId, function (err, data) {16 console.log(data);17 });18});
Using AI Code Generation
1var wpt = require('./wpt');2var wpt = new wpt('API_KEY');3 if (err) {4 console.log(err);5 } else {6 var testId = data.data.testId;7 wpt.tick(testId, function(err, data) {8 if (err) {9 console.log(err);10 } else {11 console.log(data);12 }13 });14 }15});16### getLocations(callback)17var wpt = require('./wpt');18var wpt = new wpt('API_KEY');19wpt.getLocations(function(err, data) {20 if (err) {21 console.log(err);22 } else {23 console.log(data);24 }25});26### getTesters(callback)27var wpt = require('./wpt');28var wpt = new wpt('API_KEY');29wpt.getTesters(function(err, data) {30 if (err) {31 console.log(err);32 } else {33 console.log(data);34 }35});36### getLocations(callback)37var wpt = require('./wpt');38var wpt = new wpt('API_KEY');39wpt.getLocations(function(err, data) {40 if (err) {41 console.log(err);42 } else {43 console.log(data);44 }45});46### getTesters(callback)47var wpt = require('./wpt');48var wpt = new wpt('API_KEY');49wpt.getTesters(function(err, data) {50 if (err) {51 console.log(err);52 } else {53 console.log(data);54 }55});56### getLocations(callback)57var wpt = require('./wpt');58var wpt = new wpt('API_KEY');59wpt.getLocations(function(err, data) {60 if (err) {61 console.log(err);62 } else {63 console.log(data);64 }65});
Using AI Code Generation
1var wpt = require('webpagetest');2var wpt = new WebPageTest('www.webpagetest.org', 'A.7c6a8d8f2d2a3a3d1b3f9b9e0f7a6a2b');3 videoParams: {4 }5}, function(err, data) {6 if (err) return console.error(err);7 wpt.getTestResults(data.data.testId, function(err, data) {8 if (err) return console.error(err);9 console.log(data);10 });11});
Using AI Code Generation
1var wpt = require('webpagetest');2var wpt = wpt('A.9c1d4b4a8f8f5e6c2a7e5a6b8d8b5a6');3var location = 'Dulles_MotoG:Chrome';4wpt.runTest(url, {location: location}, function(err, data) {5 if (err) return console.log(err);6 console.log(data);7 wpt.getTestResults(data.data.testId, function(err, data) {8 if (err) return console.log(err);9 console.log(data);10 });11});12var wpt = require('webpagetest');13var wpt = wpt('A.9c1d4b4a8f8f5e6c2a7e5a6b8d8b5a6');14var location = 'Dulles_MotoG:Chrome';15wpt.runTest(url, {location: location}, function(err, data) {16 if (err) return console.log(err);17 console.log(data);18 wpt.getTestResults(data.data.testId, function(err, data) {19 if (err) return console.log(err);20 console.log(data);21 });22});23var wpt = require('webpagetest');24var wpt = wpt('A.9c1d4b4a8f8f5e6c2a7e5a6b8d8b5a6');25var location = 'Dulles_MotoG:Chrome';26wpt.runTest(url, {location: location}, function(err, data) {27 if (err) return console.log(err);28 console.log(data);
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!