[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 Yahoo! Inc. All rights reserved. 4 Licensed under the BSD License. 5 http://yuilibrary.com/license/ 6 */ 7 8 YUI.add('charts-legend', function (Y, NAME) { 9 10 /** 11 * Adds legend functionality to charts. 12 * 13 * @module charts 14 * @submodule charts-legend 15 */ 16 var TOP = "top", 17 RIGHT = "right", 18 BOTTOM = "bottom", 19 LEFT = "left", 20 EXTERNAL = "external", 21 HORIZONTAL = "horizontal", 22 VERTICAL = "vertical", 23 WIDTH = "width", 24 HEIGHT = "height", 25 POSITION = "position", 26 _X = "x", 27 _Y = "y", 28 PX = "px", 29 PieChartLegend, 30 LEGEND = { 31 setter: function(val) 32 { 33 var legend = this.get("legend"); 34 if(legend) 35 { 36 legend.destroy(true); 37 } 38 if(val instanceof Y.ChartLegend) 39 { 40 legend = val; 41 legend.set("chart", this); 42 } 43 else 44 { 45 val.chart = this; 46 if(!val.hasOwnProperty("render")) 47 { 48 val.render = this.get("contentBox"); 49 val.includeInChartLayout = true; 50 } 51 legend = new Y.ChartLegend(val); 52 } 53 return legend; 54 } 55 }, 56 57 /** 58 * Contains methods for displaying items horizontally in a legend. 59 * 60 * @module charts 61 * @submodule charts-legend 62 * @class HorizontalLegendLayout 63 */ 64 HorizontalLegendLayout = { 65 /** 66 * Displays items horizontally in a legend. 67 * 68 * @method _positionLegendItems 69 * @param {Array} items Array of items to display in the legend. 70 * @param {Number} maxWidth The width of the largest item in the legend. 71 * @param {Number} maxHeight The height of the largest item in the legend. 72 * @param {Number} totalWidth The total width of all items in a legend. 73 * @param {Number} totalHeight The total height of all items in a legend. 74 * @param {Number} padding The left, top, right and bottom padding properties for the legend. 75 * @param {Number} horizontalGap The horizontal distance between items in a legend. 76 * @param {Number} verticalGap The vertical distance between items in a legend. 77 * @param {String} hAlign The horizontal alignment of the legend. 78 * @protected 79 */ 80 _positionLegendItems: function(items, maxWidth, maxHeight, totalWidth, totalHeight, padding, horizontalGap, verticalGap, hAlign) 81 { 82 var i = 0, 83 rowIterator = 0, 84 item, 85 node, 86 itemWidth, 87 itemHeight, 88 len, 89 width = this.get("width"), 90 rows, 91 rowsLen, 92 row, 93 totalWidthArray, 94 legendWidth, 95 topHeight = padding.top - verticalGap, 96 limit = width - (padding.left + padding.right), 97 left, 98 top, 99 right, 100 bottom; 101 HorizontalLegendLayout._setRowArrays(items, limit, horizontalGap); 102 rows = HorizontalLegendLayout.rowArray; 103 totalWidthArray = HorizontalLegendLayout.totalWidthArray; 104 rowsLen = rows.length; 105 for(; rowIterator < rowsLen; ++ rowIterator) 106 { 107 topHeight += verticalGap; 108 row = rows[rowIterator]; 109 len = row.length; 110 legendWidth = HorizontalLegendLayout.getStartPoint(width, totalWidthArray[rowIterator], hAlign, padding); 111 for(i = 0; i < len; ++i) 112 { 113 item = row[i]; 114 node = item.node; 115 itemWidth = item.width; 116 itemHeight = item.height; 117 item.x = legendWidth; 118 item.y = 0; 119 left = !isNaN(left) ? Math.min(left, legendWidth) : legendWidth; 120 top = !isNaN(top) ? Math.min(top, topHeight) : topHeight; 121 right = !isNaN(right) ? Math.max(legendWidth + itemWidth, right) : legendWidth + itemWidth; 122 bottom = !isNaN(bottom) ? Math.max(topHeight + itemHeight, bottom) : topHeight + itemHeight; 123 node.setStyle("left", legendWidth + PX); 124 node.setStyle("top", topHeight + PX); 125 legendWidth += itemWidth + horizontalGap; 126 } 127 topHeight += item.height; 128 } 129 this._contentRect = { 130 left: left, 131 top: top, 132 right: right, 133 bottom: bottom 134 }; 135 if(this.get("includeInChartLayout")) 136 { 137 this.set("height", topHeight + padding.bottom); 138 } 139 }, 140 141 /** 142 * Creates row and total width arrays used for displaying multiple rows of 143 * legend items based on the items, available width and horizontalGap for the legend. 144 * 145 * @method _setRowArrays 146 * @param {Array} items Array of legend items to display in a legend. 147 * @param {Number} limit Total available width for displaying items in a legend. 148 * @param {Number} horizontalGap Horizontal distance between items in a legend. 149 * @protected 150 */ 151 _setRowArrays: function(items, limit, horizontalGap) 152 { 153 var item = items[0], 154 rowArray = [[item]], 155 i = 1, 156 rowIterator = 0, 157 len = items.length, 158 totalWidth = item.width, 159 itemWidth, 160 totalWidthArray = [[totalWidth]]; 161 for(; i < len; ++i) 162 { 163 item = items[i]; 164 itemWidth = item.width; 165 if((totalWidth + horizontalGap + itemWidth) <= limit) 166 { 167 totalWidth += horizontalGap + itemWidth; 168 rowArray[rowIterator].push(item); 169 } 170 else 171 { 172 totalWidth = horizontalGap + itemWidth; 173 if(rowArray[rowIterator]) 174 { 175 rowIterator += 1; 176 } 177 rowArray[rowIterator] = [item]; 178 } 179 totalWidthArray[rowIterator] = totalWidth; 180 } 181 HorizontalLegendLayout.rowArray = rowArray; 182 HorizontalLegendLayout.totalWidthArray = totalWidthArray; 183 }, 184 185 /** 186 * Returns the starting x-coordinate for a row of legend items. 187 * 188 * @method getStartPoint 189 * @param {Number} w Width of the legend. 190 * @param {Number} totalWidth Total width of all labels in the row. 191 * @param {String} align Horizontal alignment of items for the legend. 192 * @param {Object} padding Object contain left, top, right and bottom padding properties. 193 * @return Number 194 * @protected 195 */ 196 getStartPoint: function(w, totalWidth, align, padding) 197 { 198 var startPoint; 199 switch(align) 200 { 201 case LEFT : 202 startPoint = padding.left; 203 break; 204 case "center" : 205 startPoint = (w - totalWidth) * 0.5; 206 break; 207 case RIGHT : 208 startPoint = w - totalWidth - padding.right; 209 break; 210 } 211 return startPoint; 212 } 213 }, 214 215 /** 216 * Contains methods for displaying items vertically in a legend. 217 * 218 * @module charts 219 * @submodule charts-legend 220 * @class VerticalLegendLayout 221 */ 222 VerticalLegendLayout = { 223 /** 224 * Displays items vertically in a legend. 225 * 226 * @method _positionLegendItems 227 * @param {Array} items Array of items to display in the legend. 228 * @param {Number} maxWidth The width of the largest item in the legend. 229 * @param {Number} maxHeight The height of the largest item in the legend. 230 * @param {Number} totalWidth The total width of all items in a legend. 231 * @param {Number} totalHeight The total height of all items in a legend. 232 * @param {Number} padding The left, top, right and bottom padding properties for the legend. 233 * @param {Number} horizontalGap The horizontal distance between items in a legend. 234 * @param {Number} verticalGap The vertical distance between items in a legend. 235 * @param {String} vAlign The vertical alignment of the legend. 236 * @protected 237 */ 238 _positionLegendItems: function(items, maxWidth, maxHeight, totalWidth, totalHeight, padding, horizontalGap, verticalGap, vAlign) 239 { 240 var i = 0, 241 columnIterator = 0, 242 item, 243 node, 244 itemHeight, 245 itemWidth, 246 len, 247 height = this.get("height"), 248 columns, 249 columnsLen, 250 column, 251 totalHeightArray, 252 legendHeight, 253 leftWidth = padding.left - horizontalGap, 254 legendWidth, 255 limit = height - (padding.top + padding.bottom), 256 left, 257 top, 258 right, 259 bottom; 260 VerticalLegendLayout._setColumnArrays(items, limit, verticalGap); 261 columns = VerticalLegendLayout.columnArray; 262 totalHeightArray = VerticalLegendLayout.totalHeightArray; 263 columnsLen = columns.length; 264 for(; columnIterator < columnsLen; ++ columnIterator) 265 { 266 leftWidth += horizontalGap; 267 column = columns[columnIterator]; 268 len = column.length; 269 legendHeight = VerticalLegendLayout.getStartPoint(height, totalHeightArray[columnIterator], vAlign, padding); 270 legendWidth = 0; 271 for(i = 0; i < len; ++i) 272 { 273 item = column[i]; 274 node = item.node; 275 itemHeight = item.height; 276 itemWidth = item.width; 277 item.y = legendHeight; 278 item.x = leftWidth; 279 left = !isNaN(left) ? Math.min(left, leftWidth) : leftWidth; 280 top = !isNaN(top) ? Math.min(top, legendHeight) : legendHeight; 281 right = !isNaN(right) ? Math.max(leftWidth + itemWidth, right) : leftWidth + itemWidth; 282 bottom = !isNaN(bottom) ? Math.max(legendHeight + itemHeight, bottom) : legendHeight + itemHeight; 283 node.setStyle("left", leftWidth + PX); 284 node.setStyle("top", legendHeight + PX); 285 legendHeight += itemHeight + verticalGap; 286 legendWidth = Math.max(legendWidth, item.width); 287 } 288 leftWidth += legendWidth; 289 } 290 this._contentRect = { 291 left: left, 292 top: top, 293 right: right, 294 bottom: bottom 295 }; 296 if(this.get("includeInChartLayout")) 297 { 298 this.set("width", leftWidth + padding.right); 299 } 300 }, 301 302 /** 303 * Creates column and total height arrays used for displaying multiple columns of 304 * legend items based on the items, available height and verticalGap for the legend. 305 * 306 * @method _setColumnArrays 307 * @param {Array} items Array of legend items to display in a legend. 308 * @param {Number} limit Total available height for displaying items in a legend. 309 * @param {Number} verticalGap Vertical distance between items in a legend. 310 * @protected 311 */ 312 _setColumnArrays: function(items, limit, verticalGap) 313 { 314 var item = items[0], 315 columnArray = [[item]], 316 i = 1, 317 columnIterator = 0, 318 len = items.length, 319 totalHeight = item.height, 320 itemHeight, 321 totalHeightArray = [[totalHeight]]; 322 for(; i < len; ++i) 323 { 324 item = items[i]; 325 itemHeight = item.height; 326 if((totalHeight + verticalGap + itemHeight) <= limit) 327 { 328 totalHeight += verticalGap + itemHeight; 329 columnArray[columnIterator].push(item); 330 } 331 else 332 { 333 totalHeight = verticalGap + itemHeight; 334 if(columnArray[columnIterator]) 335 { 336 columnIterator += 1; 337 } 338 columnArray[columnIterator] = [item]; 339 } 340 totalHeightArray[columnIterator] = totalHeight; 341 } 342 VerticalLegendLayout.columnArray = columnArray; 343 VerticalLegendLayout.totalHeightArray = totalHeightArray; 344 }, 345 346 /** 347 * Returns the starting y-coordinate for a column of legend items. 348 * 349 * @method getStartPoint 350 * @param {Number} h Height of the legend. 351 * @param {Number} totalHeight Total height of all labels in the column. 352 * @param {String} align Vertical alignment of items for the legend. 353 * @param {Object} padding Object contain left, top, right and bottom padding properties. 354 * @return Number 355 * @protected 356 */ 357 getStartPoint: function(h, totalHeight, align, padding) 358 { 359 var startPoint; 360 switch(align) 361 { 362 case TOP : 363 startPoint = padding.top; 364 break; 365 case "middle" : 366 startPoint = (h - totalHeight) * 0.5; 367 break; 368 case BOTTOM : 369 startPoint = h - totalHeight - padding.bottom; 370 break; 371 } 372 return startPoint; 373 } 374 }, 375 376 CartesianChartLegend = Y.Base.create("cartesianChartLegend", Y.CartesianChart, [], { 377 /** 378 * Redraws and position all the components of the chart instance. 379 * 380 * @method _redraw 381 * @private 382 */ 383 _redraw: function() 384 { 385 if(this._drawing) 386 { 387 this._callLater = true; 388 return; 389 } 390 this._drawing = true; 391 this._callLater = false; 392 var w = this.get("width"), 393 h = this.get("height"), 394 layoutBoxDimensions = this._getLayoutBoxDimensions(), 395 leftPaneWidth = layoutBoxDimensions.left, 396 rightPaneWidth = layoutBoxDimensions.right, 397 topPaneHeight = layoutBoxDimensions.top, 398 bottomPaneHeight = layoutBoxDimensions.bottom, 399 leftAxesCollection = this.get("leftAxesCollection"), 400 rightAxesCollection = this.get("rightAxesCollection"), 401 topAxesCollection = this.get("topAxesCollection"), 402 bottomAxesCollection = this.get("bottomAxesCollection"), 403 i = 0, 404 l, 405 axis, 406 graphOverflow = "visible", 407 graph = this.get("graph"), 408 topOverflow, 409 bottomOverflow, 410 leftOverflow, 411 rightOverflow, 412 graphWidth, 413 graphHeight, 414 graphX, 415 graphY, 416 allowContentOverflow = this.get("allowContentOverflow"), 417 diff, 418 rightAxesXCoords, 419 leftAxesXCoords, 420 topAxesYCoords, 421 bottomAxesYCoords, 422 legend = this.get("legend"), 423 graphRect = {}; 424 425 if(leftAxesCollection) 426 { 427 leftAxesXCoords = []; 428 l = leftAxesCollection.length; 429 for(i = l - 1; i > -1; --i) 430 { 431 leftAxesXCoords.unshift(leftPaneWidth); 432 leftPaneWidth += leftAxesCollection[i].get("width"); 433 } 434 } 435 if(rightAxesCollection) 436 { 437 rightAxesXCoords = []; 438 l = rightAxesCollection.length; 439 i = 0; 440 for(i = l - 1; i > -1; --i) 441 { 442 rightPaneWidth += rightAxesCollection[i].get("width"); 443 rightAxesXCoords.unshift(w - rightPaneWidth); 444 } 445 } 446 if(topAxesCollection) 447 { 448 topAxesYCoords = []; 449 l = topAxesCollection.length; 450 for(i = l - 1; i > -1; --i) 451 { 452 topAxesYCoords.unshift(topPaneHeight); 453 topPaneHeight += topAxesCollection[i].get("height"); 454 } 455 } 456 if(bottomAxesCollection) 457 { 458 bottomAxesYCoords = []; 459 l = bottomAxesCollection.length; 460 for(i = l - 1; i > -1; --i) 461 { 462 bottomPaneHeight += bottomAxesCollection[i].get("height"); 463 bottomAxesYCoords.unshift(h - bottomPaneHeight); 464 } 465 } 466 467 graphWidth = w - (leftPaneWidth + rightPaneWidth); 468 graphHeight = h - (bottomPaneHeight + topPaneHeight); 469 graphRect.left = leftPaneWidth; 470 graphRect.top = topPaneHeight; 471 graphRect.bottom = h - bottomPaneHeight; 472 graphRect.right = w - rightPaneWidth; 473 if(!allowContentOverflow) 474 { 475 topOverflow = this._getTopOverflow(leftAxesCollection, rightAxesCollection); 476 bottomOverflow = this._getBottomOverflow(leftAxesCollection, rightAxesCollection); 477 leftOverflow = this._getLeftOverflow(bottomAxesCollection, topAxesCollection); 478 rightOverflow = this._getRightOverflow(bottomAxesCollection, topAxesCollection); 479 480 diff = topOverflow - topPaneHeight; 481 if(diff > 0) 482 { 483 graphRect.top = topOverflow; 484 if(topAxesYCoords) 485 { 486 i = 0; 487 l = topAxesYCoords.length; 488 for(; i < l; ++i) 489 { 490 topAxesYCoords[i] += diff; 491 } 492 } 493 } 494 495 diff = bottomOverflow - bottomPaneHeight; 496 if(diff > 0) 497 { 498 graphRect.bottom = h - bottomOverflow; 499 if(bottomAxesYCoords) 500 { 501 i = 0; 502 l = bottomAxesYCoords.length; 503 for(; i < l; ++i) 504 { 505 bottomAxesYCoords[i] -= diff; 506 } 507 } 508 } 509 510 diff = leftOverflow - leftPaneWidth; 511 if(diff > 0) 512 { 513 graphRect.left = leftOverflow; 514 if(leftAxesXCoords) 515 { 516 i = 0; 517 l = leftAxesXCoords.length; 518 for(; i < l; ++i) 519 { 520 leftAxesXCoords[i] += diff; 521 } 522 } 523 } 524 525 diff = rightOverflow - rightPaneWidth; 526 if(diff > 0) 527 { 528 graphRect.right = w - rightOverflow; 529 if(rightAxesXCoords) 530 { 531 i = 0; 532 l = rightAxesXCoords.length; 533 for(; i < l; ++i) 534 { 535 rightAxesXCoords[i] -= diff; 536 } 537 } 538 } 539 } 540 graphWidth = graphRect.right - graphRect.left; 541 graphHeight = graphRect.bottom - graphRect.top; 542 graphX = graphRect.left; 543 graphY = graphRect.top; 544 if(legend) 545 { 546 if(legend.get("includeInChartLayout")) 547 { 548 switch(legend.get("position")) 549 { 550 case "left" : 551 legend.set("y", graphY); 552 legend.set("height", graphHeight); 553 break; 554 case "top" : 555 legend.set("x", graphX); 556 legend.set("width", graphWidth); 557 break; 558 case "bottom" : 559 legend.set("x", graphX); 560 legend.set("width", graphWidth); 561 break; 562 case "right" : 563 legend.set("y", graphY); 564 legend.set("height", graphHeight); 565 break; 566 } 567 } 568 } 569 if(topAxesCollection) 570 { 571 l = topAxesCollection.length; 572 i = 0; 573 for(; i < l; i++) 574 { 575 axis = topAxesCollection[i]; 576 if(axis.get("width") !== graphWidth) 577 { 578 axis.set("width", graphWidth); 579 } 580 axis.get("boundingBox").setStyle("left", graphX + PX); 581 axis.get("boundingBox").setStyle("top", topAxesYCoords[i] + PX); 582 } 583 if(axis._hasDataOverflow()) 584 { 585 graphOverflow = "hidden"; 586 } 587 } 588 if(bottomAxesCollection) 589 { 590 l = bottomAxesCollection.length; 591 i = 0; 592 for(; i < l; i++) 593 { 594 axis = bottomAxesCollection[i]; 595 if(axis.get("width") !== graphWidth) 596 { 597 axis.set("width", graphWidth); 598 } 599 axis.get("boundingBox").setStyle("left", graphX + PX); 600 axis.get("boundingBox").setStyle("top", bottomAxesYCoords[i] + PX); 601 } 602 if(axis._hasDataOverflow()) 603 { 604 graphOverflow = "hidden"; 605 } 606 } 607 if(leftAxesCollection) 608 { 609 l = leftAxesCollection.length; 610 i = 0; 611 for(; i < l; ++i) 612 { 613 axis = leftAxesCollection[i]; 614 axis.get("boundingBox").setStyle("top", graphY + PX); 615 axis.get("boundingBox").setStyle("left", leftAxesXCoords[i] + PX); 616 if(axis.get("height") !== graphHeight) 617 { 618 axis.set("height", graphHeight); 619 } 620 } 621 if(axis._hasDataOverflow()) 622 { 623 graphOverflow = "hidden"; 624 } 625 } 626 if(rightAxesCollection) 627 { 628 l = rightAxesCollection.length; 629 i = 0; 630 for(; i < l; ++i) 631 { 632 axis = rightAxesCollection[i]; 633 axis.get("boundingBox").setStyle("top", graphY + PX); 634 axis.get("boundingBox").setStyle("left", rightAxesXCoords[i] + PX); 635 if(axis.get("height") !== graphHeight) 636 { 637 axis.set("height", graphHeight); 638 } 639 } 640 if(axis._hasDataOverflow()) 641 { 642 graphOverflow = "hidden"; 643 } 644 } 645 this._drawing = false; 646 if(this._callLater) 647 { 648 this._redraw(); 649 return; 650 } 651 if(graph) 652 { 653 graph.get("boundingBox").setStyle("left", graphX + PX); 654 graph.get("boundingBox").setStyle("top", graphY + PX); 655 graph.set("width", graphWidth); 656 graph.set("height", graphHeight); 657 graph.get("boundingBox").setStyle("overflow", graphOverflow); 658 } 659 660 if(this._overlay) 661 { 662 this._overlay.setStyle("left", graphX + PX); 663 this._overlay.setStyle("top", graphY + PX); 664 this._overlay.setStyle("width", graphWidth + PX); 665 this._overlay.setStyle("height", graphHeight + PX); 666 } 667 }, 668 669 /** 670 * Positions the legend in a chart and returns the properties of the legend to be used in the 671 * chart's layout algorithm. 672 * 673 * @method _getLayoutDimensions 674 * @return {Object} The left, top, right and bottom values for the legend. 675 * @protected 676 */ 677 _getLayoutBoxDimensions: function() 678 { 679 var box = { 680 top: 0, 681 right: 0, 682 bottom: 0, 683 left: 0 684 }, 685 legend = this.get("legend"), 686 position, 687 direction, 688 dimension, 689 size, 690 w = this.get(WIDTH), 691 h = this.get(HEIGHT), 692 gap; 693 if(legend && legend.get("includeInChartLayout")) 694 { 695 gap = legend.get("styles").gap; 696 position = legend.get(POSITION); 697 if(position !== EXTERNAL) 698 { 699 direction = legend.get("direction"); 700 dimension = direction === HORIZONTAL ? HEIGHT : WIDTH; 701 size = legend.get(dimension); 702 box[position] = size + gap; 703 switch(position) 704 { 705 case TOP : 706 legend.set(_Y, 0); 707 break; 708 case BOTTOM : 709 legend.set(_Y, h - size); 710 break; 711 case RIGHT : 712 legend.set(_X, w - size); 713 break; 714 case LEFT: 715 legend.set(_X, 0); 716 break; 717 } 718 } 719 } 720 return box; 721 }, 722 723 /** 724 * Destructor implementation for the CartesianChart class. Calls destroy on all axes, series, legend (if available) and the Graph instance. 725 * Removes the tooltip and overlay HTML elements. 726 * 727 * @method destructor 728 * @protected 729 */ 730 destructor: function() 731 { 732 var legend = this.get("legend"); 733 if(legend) 734 { 735 legend.destroy(true); 736 } 737 } 738 }, { 739 ATTRS: { 740 legend: LEGEND 741 } 742 }); 743 744 Y.CartesianChart = CartesianChartLegend; 745 746 PieChartLegend = Y.Base.create("pieChartLegend", Y.PieChart, [], { 747 /** 748 * Redraws the chart instance. 749 * 750 * @method _redraw 751 * @private 752 */ 753 _redraw: function() 754 { 755 if(this._drawing) 756 { 757 this._callLater = true; 758 return; 759 } 760 this._drawing = true; 761 this._callLater = false; 762 var graph = this.get("graph"), 763 w = this.get("width"), 764 h = this.get("height"), 765 graphWidth, 766 graphHeight, 767 legend = this.get("legend"), 768 x = 0, 769 y = 0, 770 legendX = 0, 771 legendY = 0, 772 legendWidth, 773 legendHeight, 774 dimension, 775 gap, 776 position, 777 direction; 778 if(graph) 779 { 780 if(legend) 781 { 782 position = legend.get("position"); 783 direction = legend.get("direction"); 784 graphWidth = graph.get("width"); 785 graphHeight = graph.get("height"); 786 legendWidth = legend.get("width"); 787 legendHeight = legend.get("height"); 788 gap = legend.get("styles").gap; 789 790 if((direction === "vertical" && (graphWidth + legendWidth + gap !== w)) || 791 (direction === "horizontal" && (graphHeight + legendHeight + gap !== h))) 792 { 793 switch(legend.get("position")) 794 { 795 case LEFT : 796 dimension = Math.min(w - (legendWidth + gap), h); 797 legendHeight = h; 798 x = legendWidth + gap; 799 legend.set(HEIGHT, legendHeight); 800 break; 801 case TOP : 802 dimension = Math.min(h - (legendHeight + gap), w); 803 legendWidth = w; 804 y = legendHeight + gap; 805 legend.set(WIDTH, legendWidth); 806 break; 807 case RIGHT : 808 dimension = Math.min(w - (legendWidth + gap), h); 809 legendHeight = h; 810 legendX = dimension + gap; 811 legend.set(HEIGHT, legendHeight); 812 break; 813 case BOTTOM : 814 dimension = Math.min(h - (legendHeight + gap), w); 815 legendWidth = w; 816 legendY = dimension + gap; 817 legend.set(WIDTH, legendWidth); 818 break; 819 } 820 graph.set(WIDTH, dimension); 821 graph.set(HEIGHT, dimension); 822 } 823 else 824 { 825 switch(legend.get("position")) 826 { 827 case LEFT : 828 x = legendWidth + gap; 829 break; 830 case TOP : 831 y = legendHeight + gap; 832 break; 833 case RIGHT : 834 legendX = graphWidth + gap; 835 break; 836 case BOTTOM : 837 legendY = graphHeight + gap; 838 break; 839 } 840 } 841 } 842 else 843 { 844 graph.set(_X, 0); 845 graph.set(_Y, 0); 846 graph.set(WIDTH, w); 847 graph.set(HEIGHT, h); 848 } 849 } 850 this._drawing = false; 851 if(this._callLater) 852 { 853 this._redraw(); 854 return; 855 } 856 if(graph) 857 { 858 graph.set(_X, x); 859 graph.set(_Y, y); 860 } 861 if(legend) 862 { 863 legend.set(_X, legendX); 864 legend.set(_Y, legendY); 865 } 866 } 867 }, { 868 ATTRS: { 869 /** 870 * The legend for the chart. 871 * 872 * @attribute 873 * @type Legend 874 */ 875 legend: LEGEND 876 } 877 }); 878 Y.PieChart = PieChartLegend; 879 /** 880 * ChartLegend provides a legend for a chart. 881 * 882 * @class ChartLegend 883 * @module charts 884 * @submodule charts-legend 885 * @extends Widget 886 */ 887 Y.ChartLegend = Y.Base.create("chartlegend", Y.Widget, [Y.Renderer], { 888 /** 889 * Initializes the chart. 890 * 891 * @method initializer 892 * @private 893 */ 894 initializer: function() 895 { 896 this._items = []; 897 }, 898 899 /** 900 * @method renderUI 901 * @private 902 */ 903 renderUI: function() 904 { 905 var bb = this.get("boundingBox"), 906 cb = this.get("contentBox"), 907 styles = this.get("styles").background, 908 background = new Y.Rect({ 909 graphic: cb, 910 fill: styles.fill, 911 stroke: styles.border 912 }); 913 bb.setStyle("display", "block"); 914 bb.setStyle("position", "absolute"); 915 this.set("background", background); 916 }, 917 918 /** 919 * @method bindUI 920 * @private 921 */ 922 bindUI: function() 923 { 924 this.get("chart").after("seriesCollectionChange", Y.bind(this._updateHandler, this)); 925 this.get("chart").after("stylesChange", Y.bind(this._updateHandler, this)); 926 this.after("stylesChange", this._updateHandler); 927 this.after("positionChange", this._positionChangeHandler); 928 this.after("widthChange", this._handleSizeChange); 929 this.after("heightChange", this._handleSizeChange); 930 }, 931 932 /** 933 * @method syncUI 934 * @private 935 */ 936 syncUI: function() 937 { 938 var w = this.get("width"), 939 h = this.get("height"); 940 if(isFinite(w) && isFinite(h) && w > 0 && h > 0) 941 { 942 this._drawLegend(); 943 } 944 }, 945 946 /** 947 * Handles changes to legend. 948 * 949 * @method _updateHandler 950 * @param {Object} e Event object 951 * @private 952 */ 953 _updateHandler: function() 954 { 955 if(this.get("rendered")) 956 { 957 this._drawLegend(); 958 } 959 }, 960 961 /** 962 * Handles position changes. 963 * 964 * @method _positionChangeHandler 965 * @param {Object} e Event object 966 * @private 967 */ 968 _positionChangeHandler: function() 969 { 970 var chart = this.get("chart"), 971 parentNode = this._parentNode; 972 if(parentNode && ((chart && this.get("includeInChartLayout")))) 973 { 974 this.fire("legendRendered"); 975 } 976 else if(this.get("rendered")) 977 { 978 this._drawLegend(); 979 } 980 }, 981 982 /** 983 * Updates the legend when the size changes. 984 * 985 * @method _handleSizeChange 986 * @param {Object} e Event object. 987 * @private 988 */ 989 _handleSizeChange: function(e) 990 { 991 var attrName = e.attrName, 992 pos = this.get(POSITION), 993 vert = pos === LEFT || pos === RIGHT, 994 hor = pos === BOTTOM || pos === TOP; 995 if((hor && attrName === WIDTH) || (vert && attrName === HEIGHT)) 996 { 997 this._drawLegend(); 998 } 999 }, 1000 1001 /** 1002 * Draws the legend 1003 * 1004 * @method _drawLegend 1005 * @private 1006 */ 1007 _drawLegend: function() 1008 { 1009 if(this._drawing) 1010 { 1011 this._callLater = true; 1012 return; 1013 } 1014 this._drawing = true; 1015 this._callLater = false; 1016 if(this.get("includeInChartLayout")) 1017 { 1018 this.get("chart")._itemRenderQueue.unshift(this); 1019 } 1020 var chart = this.get("chart"), 1021 node = this.get("contentBox"), 1022 seriesCollection = chart.get("seriesCollection"), 1023 series, 1024 styles = this.get("styles"), 1025 padding = styles.padding, 1026 itemStyles = styles.item, 1027 seriesStyles, 1028 hSpacing = itemStyles.hSpacing, 1029 vSpacing = itemStyles.vSpacing, 1030 direction = this.get("direction"), 1031 align = direction === "vertical" ? styles.vAlign : styles.hAlign, 1032 marker = styles.marker, 1033 labelStyles = itemStyles.label, 1034 displayName, 1035 layout = this._layout[direction], 1036 i, 1037 len, 1038 isArray, 1039 legendShape, 1040 shape, 1041 shapeClass, 1042 item, 1043 fill, 1044 border, 1045 fillColors, 1046 borderColors, 1047 borderWeight, 1048 items = [], 1049 markerWidth = marker.width, 1050 markerHeight = marker.height, 1051 totalWidth = 0 - hSpacing, 1052 totalHeight = 0 - vSpacing, 1053 maxWidth = 0, 1054 maxHeight = 0, 1055 itemWidth, 1056 itemHeight; 1057 if(marker && marker.shape) 1058 { 1059 legendShape = marker.shape; 1060 } 1061 this._destroyLegendItems(); 1062 if(chart instanceof Y.PieChart) 1063 { 1064 series = seriesCollection[0]; 1065 displayName = series.get("categoryAxis").getDataByKey(series.get("categoryKey")); 1066 seriesStyles = series.get("styles").marker; 1067 fillColors = seriesStyles.fill.colors; 1068 borderColors = seriesStyles.border.colors; 1069 borderWeight = seriesStyles.border.weight; 1070 i = 0; 1071 len = displayName.length; 1072 shape = legendShape || Y.Circle; 1073 isArray = Y.Lang.isArray(shape); 1074 for(; i < len; ++i) 1075 { 1076 shape = isArray ? shape[i] : shape; 1077 fill = { 1078 color: fillColors[i] 1079 }; 1080 border = { 1081 colors: borderColors[i], 1082 weight: borderWeight 1083 }; 1084 displayName = chart.getSeriesItems(series, i).category.value; 1085 item = this._getLegendItem(node, this._getShapeClass(shape), fill, border, labelStyles, markerWidth, markerHeight, displayName); 1086 itemWidth = item.width; 1087 itemHeight = item.height; 1088 maxWidth = Math.max(maxWidth, itemWidth); 1089 maxHeight = Math.max(maxHeight, itemHeight); 1090 totalWidth += itemWidth + hSpacing; 1091 totalHeight += itemHeight + vSpacing; 1092 items.push(item); 1093 } 1094 } 1095 else 1096 { 1097 i = 0; 1098 len = seriesCollection.length; 1099 for(; i < len; ++i) 1100 { 1101 series = seriesCollection[i]; 1102 seriesStyles = this._getStylesBySeriesType(series, shape); 1103 if(!legendShape) 1104 { 1105 shape = seriesStyles.shape; 1106 if(!shape) 1107 { 1108 shape = Y.Circle; 1109 } 1110 } 1111 shapeClass = Y.Lang.isArray(shape) ? shape[i] : shape; 1112 item = this._getLegendItem( 1113 node, 1114 this._getShapeClass(shape), 1115 seriesStyles.fill, 1116 seriesStyles.border, 1117 labelStyles, 1118 markerWidth, 1119 markerHeight, 1120 series.get("valueDisplayName") 1121 ); 1122 itemWidth = item.width; 1123 itemHeight = item.height; 1124 maxWidth = Math.max(maxWidth, itemWidth); 1125 maxHeight = Math.max(maxHeight, itemHeight); 1126 totalWidth += itemWidth + hSpacing; 1127 totalHeight += itemHeight + vSpacing; 1128 items.push(item); 1129 } 1130 } 1131 this._drawing = false; 1132 if(this._callLater) 1133 { 1134 this._drawLegend(); 1135 } 1136 else 1137 { 1138 layout._positionLegendItems.apply( 1139 this, 1140 [items, maxWidth, maxHeight, totalWidth, totalHeight, padding, hSpacing, vSpacing, align] 1141 ); 1142 this._updateBackground(styles); 1143 this.fire("legendRendered"); 1144 } 1145 }, 1146 1147 /** 1148 * Updates the background for the legend. 1149 * 1150 * @method _updateBackground 1151 * @param {Object} styles Reference to the legend's styles attribute 1152 * @private 1153 */ 1154 _updateBackground: function(styles) 1155 { 1156 var backgroundStyles = styles.background, 1157 contentRect = this._contentRect, 1158 padding = styles.padding, 1159 x = contentRect.left - padding.left, 1160 y = contentRect.top - padding.top, 1161 w = contentRect.right - x + padding.right, 1162 h = contentRect.bottom - y + padding.bottom; 1163 this.get("background").set({ 1164 fill: backgroundStyles.fill, 1165 stroke: backgroundStyles.border, 1166 width: w, 1167 height: h, 1168 x: x, 1169 y: y 1170 }); 1171 }, 1172 1173 /** 1174 * Retrieves the marker styles based on the type of series. For series that contain a marker, the marker styles are returned. 1175 * 1176 * @method _getStylesBySeriesType 1177 * @param {CartesianSeries | PieSeries} The series in which the style properties will be received. 1178 * @return Object An object containing fill, border and shape information. 1179 * @private 1180 */ 1181 _getStylesBySeriesType: function(series) 1182 { 1183 var styles = series.get("styles"), 1184 color; 1185 if(series instanceof Y.LineSeries || series instanceof Y.StackedLineSeries) 1186 { 1187 styles = series.get("styles").line; 1188 color = styles.color || series._getDefaultColor(series.get("graphOrder"), "line"); 1189 return { 1190 border: { 1191 weight: 1, 1192 color: color 1193 }, 1194 fill: { 1195 color: color 1196 } 1197 }; 1198 } 1199 else if(series instanceof Y.AreaSeries || series instanceof Y.StackedAreaSeries) 1200 { 1201 styles = series.get("styles").area; 1202 color = styles.color || series._getDefaultColor(series.get("graphOrder"), "slice"); 1203 return { 1204 border: { 1205 weight: 1, 1206 color: color 1207 }, 1208 fill: { 1209 color: color 1210 } 1211 }; 1212 } 1213 else 1214 { 1215 styles = series.get("styles").marker; 1216 return { 1217 fill: styles.fill, 1218 1219 border: { 1220 weight: styles.border.weight, 1221 1222 color: styles.border.color, 1223 1224 shape: styles.shape 1225 }, 1226 shape: styles.shape 1227 }; 1228 } 1229 }, 1230 1231 /** 1232 * Returns a legend item consisting of the following properties: 1233 * <dl> 1234 * <dt>node</dt><dd>The `Node` containing the legend item elements.</dd> 1235 * <dt>shape</dt><dd>The `Shape` element for the legend item.</dd> 1236 * <dt>textNode</dt><dd>The `Node` containing the text></dd> 1237 * <dt>text</dt><dd></dd> 1238 * </dl> 1239 * 1240 * @method _getLegendItem 1241 * @param {Node} shapeProps Reference to the `node` attribute. 1242 * @param {String | Class} shapeClass The type of shape 1243 * @param {Object} fill Properties for the shape's fill 1244 * @param {Object} border Properties for the shape's border 1245 * @param {String} labelStyles String to be rendered as the legend's text 1246 * @param {Number} width Total width of the legend item 1247 * @param {Number} height Total height of the legend item 1248 * @param {String} text Text for the legendItem 1249 * @return Object 1250 * @private 1251 */ 1252 _getLegendItem: function(node, shapeClass, fill, border, labelStyles, w, h, text) 1253 { 1254 var containerNode = Y.Node.create("<div>"), 1255 textField = Y.Node.create("<span>"), 1256 shape, 1257 dimension, 1258 padding, 1259 left, 1260 item, 1261 ShapeClass = shapeClass; 1262 containerNode.setStyle(POSITION, "absolute"); 1263 textField.setStyle(POSITION, "absolute"); 1264 textField.setStyles(labelStyles); 1265 textField.set("text", text); 1266 containerNode.appendChild(textField); 1267 node.append(containerNode); 1268 dimension = textField.get("offsetHeight"); 1269 padding = dimension - h; 1270 left = w + padding + 2; 1271 textField.setStyle("left", left + PX); 1272 containerNode.setStyle("height", dimension + PX); 1273 containerNode.setStyle("width", (left + textField.get("offsetWidth")) + PX); 1274 shape = new ShapeClass({ 1275 fill: fill, 1276 stroke: border, 1277 width: w, 1278 height: h, 1279 x: padding * 0.5, 1280 y: padding * 0.5, 1281 w: w, 1282 h: h, 1283 graphic: containerNode 1284 }); 1285 textField.setStyle("left", dimension + PX); 1286 item = { 1287 node: containerNode, 1288 width: containerNode.get("offsetWidth"), 1289 height: containerNode.get("offsetHeight"), 1290 shape: shape, 1291 textNode: textField, 1292 text: text 1293 }; 1294 this._items.push(item); 1295 return item; 1296 }, 1297 1298 /** 1299 * Evaluates and returns correct class for drawing a shape. 1300 * 1301 * @method _getShapeClass 1302 * @return Shape 1303 * @private 1304 */ 1305 _getShapeClass: function() 1306 { 1307 var graphic = this.get("background").get("graphic"); 1308 return graphic._getShapeClass.apply(graphic, arguments); 1309 }, 1310 1311 /** 1312 * Returns the default hash for the `styles` attribute. 1313 * 1314 * @method _getDefaultStyles 1315 * @return Object 1316 * @protected 1317 */ 1318 _getDefaultStyles: function() 1319 { 1320 var styles = { 1321 padding: { 1322 top: 8, 1323 right: 8, 1324 bottom: 8, 1325 left: 9 1326 }, 1327 gap: 10, 1328 hAlign: "center", 1329 vAlign: "top", 1330 marker: this._getPlotDefaults(), 1331 item: { 1332 hSpacing: 10, 1333 vSpacing: 5, 1334 label: { 1335 color:"#808080", 1336 fontSize:"85%", 1337 whiteSpace: "nowrap" 1338 } 1339 }, 1340 background: { 1341 shape: "rect", 1342 fill:{ 1343 color:"#faf9f2" 1344 }, 1345 border: { 1346 color:"#dad8c9", 1347 weight: 1 1348 } 1349 } 1350 }; 1351 return styles; 1352 }, 1353 1354 /** 1355 * Gets the default values for series that use the utility. This method is used by 1356 * the class' `styles` attribute's getter to get build default values. 1357 * 1358 * @method _getPlotDefaults 1359 * @return Object 1360 * @protected 1361 */ 1362 _getPlotDefaults: function() 1363 { 1364 var defs = { 1365 width: 10, 1366 height: 10 1367 }; 1368 return defs; 1369 }, 1370 1371 /** 1372 * Destroys legend items. 1373 * 1374 * @method _destroyLegendItems 1375 * @private 1376 */ 1377 _destroyLegendItems: function() 1378 { 1379 var item; 1380 if(this._items) 1381 { 1382 while(this._items.length > 0) 1383 { 1384 item = this._items.shift(); 1385 item.shape.get("graphic").destroy(); 1386 item.node.empty(); 1387 item.node.destroy(true); 1388 item.node = null; 1389 item = null; 1390 } 1391 } 1392 this._items = []; 1393 }, 1394 1395 /** 1396 * Maps layout classes. 1397 * 1398 * @property _layout 1399 * @private 1400 */ 1401 _layout: { 1402 vertical: VerticalLegendLayout, 1403 horizontal: HorizontalLegendLayout 1404 }, 1405 1406 /** 1407 * Destructor implementation ChartLegend class. Removes all items and the Graphic instance from the widget. 1408 * 1409 * @method destructor 1410 * @protected 1411 */ 1412 destructor: function() 1413 { 1414 var background = this.get("background"), 1415 backgroundGraphic; 1416 this._destroyLegendItems(); 1417 if(background) 1418 { 1419 backgroundGraphic = background.get("graphic"); 1420 if(backgroundGraphic) 1421 { 1422 backgroundGraphic.destroy(); 1423 } 1424 else 1425 { 1426 background.destroy(); 1427 } 1428 } 1429 1430 } 1431 }, { 1432 ATTRS: { 1433 /** 1434 * Indicates whether the chart's contentBox is the parentNode for the legend. 1435 * 1436 * @attribute includeInChartLayout 1437 * @type Boolean 1438 * @private 1439 */ 1440 includeInChartLayout: { 1441 value: false 1442 }, 1443 1444 /** 1445 * Reference to the `Chart` instance. 1446 * 1447 * @attribute chart 1448 * @type Chart 1449 */ 1450 chart: { 1451 setter: function(val) 1452 { 1453 this.after("legendRendered", Y.bind(val._itemRendered, val)); 1454 return val; 1455 } 1456 }, 1457 1458 /** 1459 * Indicates the direction in relation of the legend's layout. The `direction` of the legend is determined by its 1460 * `position` value. 1461 * 1462 * @attribute direction 1463 * @type String 1464 */ 1465 direction: { 1466 value: "vertical" 1467 }, 1468 1469 /** 1470 * Indicates the position and direction of the legend. Possible values are `left`, `top`, `right` and `bottom`. 1471 * Values of `left` and `right` values have a `direction` of `vertical`. Values of `top` and `bottom` values have 1472 * a `direction` of `horizontal`. 1473 * 1474 * @attribute position 1475 * @type String 1476 */ 1477 position: { 1478 lazyAdd: false, 1479 1480 value: "right", 1481 1482 setter: function(val) 1483 { 1484 if(val === TOP || val === BOTTOM) 1485 { 1486 this.set("direction", HORIZONTAL); 1487 } 1488 else if(val === LEFT || val === RIGHT) 1489 { 1490 this.set("direction", VERTICAL); 1491 } 1492 return val; 1493 } 1494 }, 1495 1496 /** 1497 * The width of the legend. Depending on the implementation of the ChartLegend, this value is `readOnly`. 1498 * By default, the legend is included in the layout of the `Chart` that it references. Under this circumstance, 1499 * `width` is always `readOnly`. When the legend is rendered in its own dom element, the `readOnly` status is 1500 * determined by the direction of the legend. If the `position` is `left` or `right` or the `direction` is 1501 * `vertical`, width is `readOnly`. If the position is `top` or `bottom` or the `direction` is `horizontal`, 1502 * width can be explicitly set. If width is not explicitly set, the width will be determined by the width of the 1503 * legend's parent element. 1504 * 1505 * @attribute width 1506 * @type Number 1507 */ 1508 width: { 1509 getter: function() 1510 { 1511 var chart = this.get("chart"), 1512 parentNode = this._parentNode; 1513 if(parentNode) 1514 { 1515 if((chart && this.get("includeInChartLayout")) || this._width) 1516 { 1517 if(!this._width) 1518 { 1519 this._width = 0; 1520 } 1521 return this._width; 1522 } 1523 else 1524 { 1525 return parentNode.get("offsetWidth"); 1526 } 1527 } 1528 return ""; 1529 }, 1530 1531 setter: function(val) 1532 { 1533 this._width = val; 1534 return val; 1535 } 1536 }, 1537 1538 /** 1539 * The height of the legend. Depending on the implementation of the ChartLegend, this value is `readOnly`. 1540 * By default, the legend is included in the layout of the `Chart` that it references. Under this circumstance, 1541 * `height` is always `readOnly`. When the legend is rendered in its own dom element, the `readOnly` status is 1542 * determined by the direction of the legend. If the `position` is `top` or `bottom` or the `direction` is 1543 * `horizontal`, height is `readOnly`. If the position is `left` or `right` or the `direction` is `vertical`, 1544 * height can be explicitly set. If height is not explicitly set, the height will be determined by the width of the 1545 * legend's parent element. 1546 * 1547 * @attribute height 1548 * @type Number 1549 */ 1550 height: { 1551 valueFn: "_heightGetter", 1552 1553 getter: function() 1554 { 1555 var chart = this.get("chart"), 1556 parentNode = this._parentNode; 1557 if(parentNode) 1558 { 1559 if((chart && this.get("includeInChartLayout")) || this._height) 1560 { 1561 if(!this._height) 1562 { 1563 this._height = 0; 1564 } 1565 return this._height; 1566 } 1567 else 1568 { 1569 return parentNode.get("offsetHeight"); 1570 } 1571 } 1572 return ""; 1573 }, 1574 1575 setter: function(val) 1576 { 1577 this._height = val; 1578 return val; 1579 } 1580 }, 1581 1582 /** 1583 * Indicates the x position of legend. 1584 * 1585 * @attribute x 1586 * @type Number 1587 * @readOnly 1588 */ 1589 x: { 1590 lazyAdd: false, 1591 1592 value: 0, 1593 1594 setter: function(val) 1595 { 1596 var node = this.get("boundingBox"); 1597 if(node) 1598 { 1599 node.setStyle(LEFT, val + PX); 1600 } 1601 return val; 1602 } 1603 }, 1604 1605 /** 1606 * Indicates the y position of legend. 1607 * 1608 * @attribute y 1609 * @type Number 1610 * @readOnly 1611 */ 1612 y: { 1613 lazyAdd: false, 1614 1615 value: 0, 1616 1617 setter: function(val) 1618 { 1619 var node = this.get("boundingBox"); 1620 if(node) 1621 { 1622 node.setStyle(TOP, val + PX); 1623 } 1624 return val; 1625 } 1626 }, 1627 1628 /** 1629 * Array of items contained in the legend. Each item is an object containing the following properties: 1630 * 1631 * <dl> 1632 * <dt>node</dt><dd>Node containing text for the legend item.</dd> 1633 * <dt>marker</dt><dd>Shape for the legend item.</dd> 1634 * </dl> 1635 * 1636 * @attribute items 1637 * @type Array 1638 * @readOnly 1639 */ 1640 items: { 1641 getter: function() 1642 { 1643 return this._items; 1644 } 1645 }, 1646 1647 /** 1648 * Background for the legend. 1649 * 1650 * @attribute background 1651 * @type Rect 1652 */ 1653 background: {} 1654 1655 /** 1656 * Properties used to display and style the ChartLegend. This attribute is inherited from `Renderer`. 1657 * Below are the default values: 1658 * 1659 * <dl> 1660 * <dt>gap</dt><dd>Distance, in pixels, between the `ChartLegend` instance and the chart's content. When `ChartLegend` 1661 * is rendered within a `Chart` instance this value is applied.</dd> 1662 * <dt>hAlign</dt><dd>Defines the horizontal alignment of the `items` in a `ChartLegend` rendered in a horizontal direction. 1663 * This value is applied when the instance's `position` is set to top or bottom. This attribute can be set to left, center 1664 * or right. The default value is center.</dd> 1665 * <dt>vAlign</dt><dd>Defines the vertical alignment of the `items` in a `ChartLegend` rendered in vertical direction. This 1666 * value is applied when the instance's `position` is set to left or right. The attribute can be set to top, middle or 1667 * bottom. The default value is middle.</dd> 1668 * <dt>item</dt><dd>Set of style properties applied to the `items` of the `ChartLegend`. 1669 * <dl> 1670 * <dt>hSpacing</dt><dd>Horizontal distance, in pixels, between legend `items`.</dd> 1671 * <dt>vSpacing</dt><dd>Vertical distance, in pixels, between legend `items`.</dd> 1672 * <dt>label</dt><dd>Properties for the text of an `item`. 1673 * <dl> 1674 * <dt>color</dt><dd>Color of the text. The default values is "#808080".</dd> 1675 * <dt>fontSize</dt><dd>Font size for the text. The default value is "85%".</dd> 1676 * </dl> 1677 * </dd> 1678 * <dt>marker</dt><dd>Properties for the `item` markers. 1679 * <dl> 1680 * <dt>width</dt><dd>Specifies the width of the markers.</dd> 1681 * <dt>height</dt><dd>Specifies the height of the markers.</dd> 1682 * </dl> 1683 * </dd> 1684 * </dl> 1685 * </dd> 1686 * <dt>background</dt><dd>Properties for the `ChartLegend` background. 1687 * <dl> 1688 * <dt>fill</dt><dd>Properties for the background fill. 1689 * <dl> 1690 * <dt>color</dt><dd>Color for the fill. The default value is "#faf9f2".</dd> 1691 * </dl> 1692 * </dd> 1693 * <dt>border</dt><dd>Properties for the background border. 1694 * <dl> 1695 * <dt>color</dt><dd>Color for the border. The default value is "#dad8c9".</dd> 1696 * <dt>weight</dt><dd>Weight of the border. The default values is 1.</dd> 1697 * </dl> 1698 * </dd> 1699 * </dl> 1700 * </dd> 1701 * </dl> 1702 * 1703 * @attribute styles 1704 * @type Object 1705 */ 1706 } 1707 }); 1708 1709 1710 }, '3.17.2', {"requires": ["charts-base"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |