comparison js/boxplotsFlow.js @ 1:b5453d07f740 draft default tip

"planemo upload for repository https://github.com/ImmPortDB/immport-galaxy-tools/tree/master/flowtools/flow_overview commit 65373effef15809f3db0e5f9603ef808f4110aa3"
author azomics
date Wed, 29 Jul 2020 17:03:53 -0400
parents
children
comparison
equal deleted inserted replaced
0:8283ff163ba6 1:b5453d07f740
1 // Copyright (c) 2016 Northrop Grumman.
2 // All rights reserved.
3 var updateBPmfi = function(plotconfig){
4 plotconfig.selectedPopulations = [];
5 $(plotconfig.popSelectj).each(function() {
6 if (this.checked) {
7 plotconfig.selectedPopulations.push(parseInt(this.value));
8 }
9 });
10 // Update selected markers?
11 plotconfig.selectedMarkers = [];
12 $(plotconfig.mrkrSelectj).each(function() {
13 if (this.checked) {
14 plotconfig.selectedMarkers.push(parseInt(this.value));
15 }
16 });
17 // update plot
18 updateBoxplotMFI(plotconfig);
19 };
20
21 var displayPopulationLegend = function(plotconfig) {
22 $(plotconfig.table).empty();
23 plotconfig.allPopulations.map(function(value,index) {
24 $(plotconfig.table).append('<tr><td align="center">'
25 + '<input type="checkbox" checked class=' + plotconfig.popSelect
26 + ' value=' + value + '/></td><td title="' + newNames[value] + '">'
27 + newNames[value] + '</td><td><span style="background-color:'
28 + color_palette[0][value][0] + '">&nbsp;&nbsp;&nbsp;</span></td></tr>');
29 });
30
31 $(plotconfig.popSelectAll).click(function() {
32 var checkAll = $(plotconfig.popSelectAll).prop('checked');
33 if (checkAll) {
34 $(plotconfig.popSelectj).prop("checked", true);
35 } else {
36 $(plotconfig.popSelectj).prop("checked", false);
37 }
38 updateBPmfi(plotconfig);
39 });
40
41 $(plotconfig.popSelectj).click(function() {
42 if ($(plotconfig.popSelectj).length == $(plotconfig.popSelectCheck).length) {
43 $(plotconfig.popSelectAll).prop("checked",true);
44 } else {
45 $(plotconfig.popSelectAll).prop("checked",false);
46 }
47 updateBPmfi(plotconfig);
48 });
49
50 $(plotconfig.popSelectj).each(function() {
51 var selectedpopn = parseInt(this.value);
52 if ($.inArray(selectedpopn,plotconfig.selectedPopulations) > -1) {
53 this.checked = true;
54 } else {
55 this.checked = false;
56 }
57 });
58 };
59
60 var displayToolbar = function(plotconfig){
61 $(plotconfig.displaybutton).on("click",function() {
62 $(plotconfig.popSelectAll).prop("checked",true);
63 $(plotconfig.popSelectj).prop("checked", true);
64 $(plotconfig.mrkrSelectj).prop("checked", true);
65 $(plotconfig.mrkrSelectAll).prop("checked",true);
66 $(plotconfig.displayMFI).prop("checked", false);
67 $(plotconfig.displayvalues).prop("checked", false);
68 updateBPmfi(plotconfig);
69 });
70
71 $(plotconfig.toggledisplayj).on("click",function() {
72 var text = document.getElementById(plotconfig.toggledisplay).firstChild;
73 text.data = text.data == "View per marker" ? "View per population" : "View per marker";
74 plotconfig.view = plotconfig.view == "p" ? "m" : "p";
75 updateBPmfi(plotconfig);
76 });
77
78 $(plotconfig.displayMFI).on("click", function(){
79 updateBPmfi(plotconfig);
80 });
81
82 $(plotconfig.displayvalues).on("click", function(){
83 updateBPmfi(plotconfig);
84 });
85
86 displayPlot(plotconfig);
87 };
88
89 var displayPlot = function(plotconfig) {
90 var h = $(window).height() - 200,
91 nbPop = Object.keys(plotconfig.csdata.mfi[plotconfig.mrkrNames[0]]).length + 2;
92
93 $(plotconfig.plotdivj).empty();
94 $(plotconfig.plotdivj).height(h);
95
96 // Get Markers too
97 for (var i = 0, nbMarkers = plotconfig.mrkrNames.length; i < nbMarkers; i++){
98 plotconfig.allMarkers.push(i);
99 plotconfig.selectedMarkers.push(i);
100 }
101 for (var i = 2; i < nbPop; i++) {
102 plotconfig.allPopulations.push(i - 1);
103 plotconfig.selectedPopulations.push(i - 1);
104 }
105
106 $(window).on('resize',function() {
107 waitForFinalEvent(function() {
108 updateBoxplotMFI(plotconfig);
109 }, 500, "resizePlot");
110 });
111
112 displayPopulationLegend(plotconfig);
113 displayMarkerTable(plotconfig);
114 updateBoxplotMFI(plotconfig);
115 };
116
117 var displayMarkerTable = function(plotconfig){
118 var nbm = plotconfig.mrkrNames.length + 1;
119 $(plotconfig.mtable).empty();
120 plotconfig.allMarkers.map(function(v) {
121 $(plotconfig.mtable).append('<tr>'
122 + '<td><span style="background-color:rgba(0,0,0,' + (v + 1 )/ nbm + ')'
123 + '">&nbsp;&nbsp;&nbsp;</span></td>'
124 + '<td title="' + plotconfig.mrkrNames[v] + '">'
125 + plotconfig.mrkrNames[v] + '</td>'
126 + '<td align="center"><input type="checkbox" checked class='
127 + plotconfig.mrkrSelect + ' value=' + v + '/></td></tr>');
128 });
129
130 if (nbm > 5) {
131 $(plotconfig.mrkrSelectAll).prop('checked', false);
132 $(plotconfig.mrkrSelectAll).prop('disabled', true);
133 $('#markerWarning').show();
134 $(plotconfig.mrkrSelectj).each(function() {
135 var selectedMrkr = parseInt(this.value);
136 if (selectedMrkr > 4){
137 this.checked = false;
138 this.disabled = true;
139 } else {
140 this.checked = true;
141 }
142 });
143 }
144
145 $(plotconfig.mrkrSelectAll).click(function() {
146 var checkAll = $(plotconfig.mrkrSelectAll).prop('checked');
147 if (checkAll) {
148 $(plotconfig.mrkrSelectj).prop("checked", true);
149 } else {
150 $(plotconfig.mrkrSelectj).prop("checked", false);
151 }
152 updateBPmfi(plotconfig);
153 });
154
155 $(plotconfig.mrkrSelectj).click(function() {
156 if (nbm < 6){
157 if ($(plotconfig.mrkrSelectj).length == $(plotconfig.mrkrSelectCheck).length) {
158 $(plotconfig.mrkrSelectAll).prop("checked",true);
159 } else {
160 $(plotconfig.mrkrSelectAll).prop("checked",false);
161 }
162 } else {
163 var nbSelected = 0;
164 $(plotconfig.mrkrSelectj).each(function() {
165 if (this.checked) {nbSelected++}
166 });
167 if (nbSelected < 5) {
168 $(plotconfig.mrkrSelectj).prop('disabled', false);
169 } else {
170 $(plotconfig.mrkrSelectj).each(function() {
171 if (!this.checked) {
172 this.disabled = true;
173 }
174 });
175 }
176 }
177 updateBPmfi(plotconfig);
178 });
179 };
180
181 var updateBoxplotMFI = function(plotconfig){
182 var margin = {top: 30, right: 10, bottom: 50, left: 60},
183 h = 0,
184 w = 0,
185 width = 0,
186 height = 0,
187 labels = false, // show the text labels beside individual boxplots?
188 mfi_option = false,
189 checkLabels = $(plotconfig.displayvalues).prop("checked"),
190 checkMFI = $(plotconfig.displayMFI).prop("checked"),
191 dataToPlot = [],
192 tmp = [],
193 nbm = plotconfig.mrkrNames.length + 1,
194 maxRange = 0,
195 minRange = 0,
196 domainx = [],
197 domainx1 = [],
198 min = Infinity,
199 max = -Infinity;
200
201 $(plotconfig.plotdivj).empty();
202 h = $(window).height() - 200;
203 $(plotconfig.plotdivj).height(h);
204 w = $(plotconfig.plotdivj).width();
205 width = w - margin.left - margin.right;
206 height = h - margin.top - margin.bottom;
207
208 var svg = d3.select(plotconfig.plotdivj).append("svg")
209 .attr("width", width + margin.left + margin.right)
210 .attr("height", height + margin.top + margin.bottom)
211 .attr("class", "box")
212 .append("g")
213 .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
214
215 if (checkLabels) {
216 labels = true;
217 };
218 if (checkMFI) {
219 mfi_option = true;
220 };
221
222 /* Get the data in proper shape to feed to the boxplot function
223 want [Object, Object, ..., Object] where Object:
224 'population': pop
225 'Data' : [Object, Object, ..., Object] where Object:
226 'Marker' : marker name
227 'outliers' : outliers
228 */
229
230 if (plotconfig.view == 'p') {
231 plotconfig.selectedPopulations.forEach(function(p) {
232 tmpPlot = [];
233 plotconfig.selectedMarkers.forEach(function(m) {
234 var markernm = plotconfig.mrkrNames[m],
235 qtmp = [
236 +plotconfig.csdata.q1[markernm][p],
237 +plotconfig.csdata.q2[markernm][p],
238 +plotconfig.csdata.q3[markernm][p]
239 ],
240 wtmp = [
241 +plotconfig.csdata.lower[markernm][p],
242 +plotconfig.csdata.upper[markernm][p]
243 ];
244 tmp = [];
245 // Get min and max while we're here
246 plotconfig.csdata.outliers[markernm][p].forEach(function(outl) {
247 tmp.push(+outl);
248 if (+outl > max) {max = +outl};
249 if (+outl < min) {min = +outl};
250 });
251 if (+plotconfig.csdata.upper[markernm][p] > max) {
252 max = +plotconfig.csdata.upper[markernm][p];
253 }
254 if (+plotconfig.csdata.lower[markernm][p] < min) {
255 min = +plotconfig.csdata.lower[markernm][p];
256 }
257 tmpPlot.push({
258 marker: markernm,
259 outliers: tmp,
260 quartiles: qtmp,
261 whiskers: wtmp,
262 config: [m,p, nbm],
263 mfi: +plotconfig.csdata.mfi[markernm][p]
264 });
265 });
266 dataToPlot.push({population:p, popdata: tmpPlot});
267 });
268 } else {
269 plotconfig.selectedMarkers.forEach(function(m) {
270 var markernm = plotconfig.mrkrNames[m];
271 tmpPlot = [];
272 plotconfig.selectedPopulations.forEach(function(p) {
273 var qtmp = [
274 +plotconfig.csdata.q1[markernm][p],
275 +plotconfig.csdata.q2[markernm][p],
276 +plotconfig.csdata.q3[markernm][p]
277 ],
278 wtmp = [
279 +plotconfig.csdata.lower[markernm][p],
280 +plotconfig.csdata.upper[markernm][p]
281 ];
282 // Get min and max while we're here
283 tmp = [];
284 plotconfig.csdata.outliers[markernm][p].forEach(function(outl) {
285 tmp.push(+outl);
286 if (+outl > max) {max = +outl};
287 if (+outl < min) {min = +outl};
288 });
289 if (+plotconfig.csdata.upper[markernm][p] > max) {
290 max = +plotconfig.csdata.upper[markernm][p];
291 }
292 if (+plotconfig.csdata.lower[markernm][p] < min) {
293 min = +plotconfig.csdata.lower[markernm][p];
294 }
295 tmpPlot.push({
296 population:p,
297 outliers: tmp,
298 quartiles: qtmp,
299 whiskers: wtmp,
300 config: [m,p, nbm],
301 mfi: +plotconfig.csdata.mfi[markernm][p]
302 });
303 });
304 dataToPlot.push({marker: markernm, popdata: tmpPlot});
305 });
306 };
307 maxRange = max + 30;
308 minRange = min - 30;
309
310 if (plotconfig.view == 'p') {
311 domainx = plotconfig.selectedPopulations;
312 domainx1 = plotconfig.selectedMarkers.map(function(d){
313 return plotconfig.mrkrNames[d]
314 });
315 } else {
316 domainx1 = plotconfig.selectedPopulations;
317 domainx = plotconfig.selectedMarkers.map(function(d){
318 return plotconfig.mrkrNames[d]
319 });
320 }
321 // axes
322 var xScale = d3.scale.ordinal()
323 .domain(domainx)
324 .rangeRoundBands([0 , width], 0.2, 0.02);
325
326 var x1Scale = d3.scale.ordinal()
327 .domain(domainx1)
328 .rangeRoundBands([0, xScale.rangeBand()], 0.1);
329
330 var xAxis = d3.svg.axis()
331 .scale(xScale)
332 .orient("bottom");
333
334 // the y-axis
335 var yScale = d3.scale.linear()
336 .domain([minRange, maxRange])
337 .range([height + margin.top, 0 + margin.top]);
338
339 var yAxis = d3.svg.axis()
340 .scale(yScale)
341 .orient("left")
342 .tickFormat(d3.format("d"));
343
344 svg.append("g")
345 .attr("class", "x axisbp")
346 .attr("transform", "translate(0," + (height + margin.top) + ")")
347 .call(xAxis);
348
349 svg.append("g")
350 .attr("class", "y axisbp")
351 .call(yAxis)
352 .append("text")
353 .attr("class", "ylabel")
354 .attr("transform", "rotate(-90)")
355 .attr("y", 0 - margin.left)
356 .attr("x", 0 - (height / 2))
357 .attr("dy", "1em")
358 .style("text-anchor", "middle")
359 .text("MFI values");
360
361 var boxplot = d3.box()
362 .width(x1Scale.rangeBand())
363 .height(height + margin.top)
364 .domain([minRange, maxRange])
365 .showLabels(labels)
366 .showMFI(mfi_option);
367
368 if (plotconfig.view == 'p'){
369 var group = svg.selectAll(".groups")
370 .data(dataToPlot)
371 .enter().append("g")
372 .attr("class", "group")
373 .attr("transform", function(d) {
374 return "translate(" + xScale(d.population) + ",0)";
375 });
376
377 group.selectAll(".box")
378 .data(function(d) { return d.popdata; })
379 .enter().append("g")
380 .attr("transform", function(d) { return "translate(" + x1Scale(d.marker) + ",0)"; })
381 .call(boxplot);
382 } else {
383 var group = svg.selectAll(".groups")
384 .data(dataToPlot)
385 .enter().append("g")
386 .attr("class", "group")
387 .attr("transform", function(d) {
388 return "translate(" + xScale(d.marker) + ",0)";
389 });
390
391 group.selectAll(".box")
392 .data(function(d) { return d.popdata; })
393 .enter().append("g")
394 .attr("transform", function(d) { return "translate(" + x1Scale(d.population) + ",0)"; })
395 .call(boxplot);
396 }
397 };
398
399 (function() {
400 // Inspired by http://informationandvisualization.de/blog/box-plot
401 // Modified to fit our data structure.
402 d3.box = function() {
403 var width = 1,
404 height = 1,
405 duration = 0,
406 domain = null,
407 value = Number,
408 showLabels = true, // whether or not to show text labels
409 numBars = 4,
410 curBar = 1,
411 showMFI = true, // display MFI ?
412 tickFormat = null;
413 var margin = {top: 30, right: 10, bottom: 50, left: 60};
414
415 // For each small multiple…
416 function box(g) {
417 g.each(function(data, i) {
418 var d = data.outliers.sort(d3.ascending);
419 var g = d3.select(this),
420 n = d.length,
421 min = Infinity,
422 max = -Infinity;
423 if (n > 0){
424 min = d[0],
425 max = d[n - 1];
426 }
427 // Readjust min and max with upper and lower values
428 if (data.whiskers[0] < min) {min = data.whiskers[0]}
429 if (data.whiskers[1] > max) {max = data.whiskers[1]}
430 // Compute quartiles. Must return exactly 3 elements.
431 var quartileData = data.quartiles;
432 // Compute whiskers. Must return exactly 2 elements, or null.
433 var whiskerData = data.whiskers;
434 // Compute outliers. here all data in d is an outlier.
435 // We compute the outliers as indices, so that we can join across transitions!
436 var outlierIndices = d3.range(n);
437 var mfiData = data.mfi;
438 // this is the scale for ONE SET of values
439 // Compute the new x-scale.
440 var x1 = d3.scale.linear()
441 .domain(domain && domain.call(this, d, i) || [min, max])
442 .range([height , 0 + margin.top ]);
443 // Retrieve the old x-scale, if this is an update.
444 var x0 = this.__chart__ || d3.scale.linear()
445 .domain([0, Infinity])
446 .range(x1.range());
447
448 // Stash the new scale.
449 this.__chart__ = x1;
450 // Note: the box, median, and box tick elements are fixed in number,
451 // so we only have to handle enter and update. In contrast, the outliers
452 // and other elements are variable, so we need to exit them! Variable
453 // elements also fade in and out.
454 // Update center line: the vertical line spanning the whiskers.
455 var center = g.selectAll("line.center")
456 .data(whiskerData ? [whiskerData] : []);
457
458 //vertical line
459 center.enter().insert("line", "rect")
460 .attr("class", "center")
461 .attr("x1", width / 2)
462 .attr("y1", function(d) { return x0(d[0]); })
463 .attr("x2", width / 2)
464 .attr("y2", function(d) { return x0(d[1]); })
465 .style("opacity", 1e-6)
466 .style("stroke", function(d) { return color_palette[0][data.config[1]][3]; })
467 .transition()
468 .duration(duration)
469 .style("opacity", 1)
470 .attr("y1", function(d) { return x1(d[0]); })
471 .attr("y2", function(d) { return x1(d[1]); });
472
473 center.transition()
474 .duration(duration)
475 .style("opacity", 1)
476 .attr("y1", function(d) { return x1(d[0]); })
477 .attr("y2", function(d) { return x1(d[1]); });
478
479 center.exit().transition()
480 .duration(duration)
481 .style("opacity", 1e-6)
482 .attr("y1", function(d) { return x1(d[0]); })
483 .attr("y2", function(d) { return x1(d[1]); })
484 .remove();
485
486 // Update innerquartile box.
487 var box = g.selectAll("rect.box")
488 .data([quartileData]);
489
490 box.enter().append("rect")
491 .attr("class", "box")
492 .style("fill", function(d) {
493 var nbm = data.config[2],
494 pop = data.config[1],
495 mrkr = data.config[0];
496 var color = color_palette[0][pop][1] + (mrkr + 1 )/ nbm + ')';
497 return color })
498 .style("stroke", function(d) { return color_palette[0][data.config[1]][3]; })
499 .attr("x", 0)
500 .attr("y", function(d) { return x0(d[2]); })
501 .attr("width", width)
502 .attr("height", function(d) { return x0(d[0]) - x0(d[2]); })
503 .transition()
504 .duration(duration)
505 .attr("y", function(d) { return x1(d[2]); })
506 .attr("height", function(d) { return x1(d[0]) - x1(d[2]); });
507
508 box.transition()
509 .duration(duration)
510 .attr("y", function(d) { return x1(d[2]); })
511 .attr("height", function(d) { return x1(d[0]) - x1(d[2]); });
512
513 // Update median line.
514 var medianLine = g.selectAll("line.median")
515 .data([quartileData[1]]);
516
517 medianLine.enter().append("line")
518 .attr("class", "median")
519 .attr("x1", 0)
520 .attr("y1", x0)
521 .attr("x2", width)
522 .attr("y2", x0)
523 .style("stroke", function(d) { return color_palette[0][data.config[1]][3]; })
524 .transition()
525 .duration(duration)
526 .attr("y1", x1)
527 .attr("y2", x1);
528
529 medianLine.transition()
530 .duration(duration)
531 .attr("y1", x1)
532 .attr("y2", x1);
533
534 // Update MFI line.
535 var MFILine = g.selectAll("line.mfi")
536 .data([mfiData]);
537 if (showMFI == true) {
538 MFILine.enter().append("line")
539 .attr("class", "mfi")
540 .style("stroke", function(d){ return color_palette[0][data.config[1]][2]; })
541 .attr("x1", 0)
542 .attr("y1", x0)
543 .attr("x2", width)
544 .attr("y2", x0)
545 .transition()
546 .duration(duration)
547 .attr("y1", x1)
548 .attr("y2", x1);
549
550 MFILine.transition()
551 .duration(duration)
552 .attr("y1", x1)
553 .attr("y2", x1);
554 }
555
556 // Update whiskers.
557 var whisker = g.selectAll("line.whisker")
558 .data(whiskerData || []);
559
560 whisker.enter().insert("line", "circle, text")
561 .attr("class", "whisker")
562 .attr("x1", 0)
563 .attr("y1", x0)
564 .attr("x2", 0 + width)
565 .attr("y2", x0)
566 .style("opacity", 1e-6)
567 .style("stroke", function(d) { return color_palette[0][data.config[1]][3]; })
568 .transition()
569 .duration(duration)
570 .attr("y1", x1)
571 .attr("y2", x1)
572 .style("opacity", 1);
573
574 whisker.transition()
575 .duration(duration)
576 .attr("y1", x1)
577 .attr("y2", x1)
578 .style("opacity", 1);
579
580 whisker.exit().transition()
581 .duration(duration)
582 .attr("y1", x1)
583 .attr("y2", x1)
584 .style("opacity", 1e-6)
585 .remove();
586
587 // Update outliers.
588 var outlier = g.selectAll("circle.outlier")
589 .data(outlierIndices, Number);
590
591 outlier.enter().insert("circle", "text")
592 .attr("class", "outlier")
593 .attr("r", 3)
594 .attr("cx", function(d){
595 return Math.floor(Math.random() * width);
596 })
597 .attr("cy", function(i) { return x0(d[i]); })
598 .style("opacity", 1e-6)
599 .style("fill", function(d) {
600 var nbm = data.config[2],
601 pop = data.config[1],
602 mrkr = data.config[0];
603 var color = color_palette[0][pop][1] + (mrkr + 1 )/ nbm + ')';
604 return color; })
605 .style("stroke", function(d) { return color_palette[0][data.config[1]][3]; })
606 .transition()
607 .duration(duration)
608 .attr("cy", function(i) { return x1(d[i]); })
609 .style("opacity", 1);
610
611 outlier.transition()
612 .duration(duration)
613 .attr("cy", function(i) { return x1(d[i]); })
614 .style("opacity", 1);
615
616 outlier.exit().transition()
617 .duration(duration)
618 .attr("cy", function(i) { return x1(d[i]); })
619 .style("opacity", 1e-6)
620 .remove();
621
622 // Compute the tick format.
623 var format = tickFormat || x1.tickFormat(8);
624 // Update box ticks.
625 var boxTick = g.selectAll("text.box")
626 .data(quartileData);
627
628 if(showLabels == true) {
629 boxTick.enter().append("text")
630 .attr("class", "box")
631 .attr("dy", ".3em")
632 .attr("dx", function(d, i) { return i & 1 ? 6 : -6 })
633 .attr("x", function(d, i) { return i & 1 ? + width : 0 })
634 .attr("y", x0)
635 .attr("text-anchor", function(d, i) { return i & 1 ? "start" : "end"; })
636 .text(format)
637 .transition()
638 .duration(duration)
639 .attr("y", x1);
640 }
641
642 boxTick.transition()
643 .duration(duration)
644 .text(format)
645 .attr("y", x1);
646
647 // Update whisker ticks. These are handled separately from the box
648 // ticks because they may or may not exist, and we want don't want
649 // to join box ticks pre-transition with whisker ticks post-.
650 var whiskerTick = g.selectAll("text.whisker")
651 .data(whiskerData || []);
652 if(showLabels == true) {
653 whiskerTick.enter().append("text")
654 .attr("class", "whisker")
655 .attr("dy", ".3em")
656 .attr("dx", 6)
657 .attr("x", width)
658 .attr("y", x0)
659 .text(format)
660 .style("opacity", 1e-6)
661 .style("stroke", function(d) { return color_palette[0][data.config[1]][3]; })
662 .transition()
663 .duration(duration)
664 .attr("y", x1)
665 .style("opacity", 1);
666 }
667 whiskerTick.transition()
668 .duration(duration)
669 .text(format)
670 .attr("y", x1)
671 .style("opacity", 1);
672
673 whiskerTick.exit().transition()
674 .duration(duration)
675 .attr("y", x1)
676 .style("opacity", 1e-6)
677 .remove();
678 });
679 d3.timer.flush();
680 }
681
682 box.width = function(x) {
683 if (!arguments.length) return width;
684 width = x;
685 return box;
686 };
687 box.height = function(x) {
688 if (!arguments.length) return height;
689 height = x;
690 return box;
691 };
692 box.tickFormat = function(x) {
693 if (!arguments.length) return tickFormat;
694 tickFormat = x;
695 return box;
696 };
697 box.duration = function(x) {
698 if (!arguments.length) return duration;
699 duration = x;
700 return box;
701 };
702 box.domain = function(x) {
703 if (!arguments.length) return domain;
704 domain = x == null ? x : d3.functor(x);
705 return box;
706 };
707 box.value = function(x) {
708 if (!arguments.length) return value;
709 value = x;
710 return box;
711 };
712 box.showLabels = function(x) {
713 if (!arguments.length) return showLabels;
714 showLabels = x;
715 return box;
716 };
717 box.showMFI = function(x) {
718 if (!arguments.length) return showMFI;
719 showMFI = x;
720 return box;
721 };
722 return box;
723 };
724 })();