;(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['rave', 'rave-library', 'rave-utilities', 'rave-layouts', 'rave-legends'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('rave'), require('rave-library'), require('rave-utilities'), require('rave-layouts'), require('rave-legends'));
} else {
root.raveLibraryComposite = factory(root.rave, root.raveLibrary, root.raveUtilities, root.raveLayouts, root.raveLegends);
}
}(this, function(rave, raveLibrary, raveUtilities, raveLayouts, raveLegends) {
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o A component that renders the background to the chart. The {@link #this.type()} method returns "BackgroundComponent". A component that does the layout for a bundle chart. The {@link #this.type()} method returned "ChartLayoutComponent". Chart layout is controlled by the following properties: Manages one or more legend components for a bundle. The number of legends N is fixed and declared in the constructor, and legends are identified by an array index number between 0 and N-1. (For now we don't need a dynamic collection, especially since we're generating the chart structure statically and each legend gets its own <g&;gt; node. If a chart sometimes needs one legend and sometimes two, it will create two nodes and construct the manager for two legends.) The manager has the following properties: Each legend has the following properties: The general pattern of use is to create the LegendsManager in the view's constructor or setup method, allocating the maximum number of legends that will ever be needed. The chart structure will have corresponding <g> nodes, and in the view's draw method all the legend selectors are set to the corresponding group. The legend palettes, titles, and formatters will usually be set next, making sure to set the palettes of any unused legends to null, and {@link #this.anyVisible()} used to find if any rectangles need to be drawn so the overall chart may be laid out. The rectangle, orientation, and transition information can then be set and {@link #this.draw()} called. The visible legends (those with palettes) divide the rectangle equally along the orientation. For example if there are three legends in horizontal orientation and two are visible, they will split the rectangle vertically in half. Legends are drawn left-to-right for horizontal orientation, and top-to-bottom for vertical orientation, in index order. If a transition is requested and the duration is non-negative, a transition is created from the legend's selector; otherwise the selector is used. However, in order to give a somewhat better appearance, a transition is not used if the legend was not visible (no shapes rendered) the last time it was drawn. Managers the axes and gridlines for a bundle. The manager handles rectangular axes, where the axes are drawn to the top, bottom, left, and/or right of a central chart. The manager does not do the layout of axes or the setup of scales. Bundle views will normally create an instance in the setup method, then set properties in their draw method and call {@link #this.draw()} to render all the axes and gridlines (including setting the transforms and clip paths on the groups). The manager has four axes and four gridlines, identified by the logical roles X1, X2, Y1, Y2. These corresponding to the constants in the {@link (com.ibm.rave.bundles.component.AxisComponent) AxisComponent} API. The X roles are the independent axes and the Y roles are the dependent axes. The manager will create an instance of the {@link (com.ibm.rave.bundles.components.AxisComponentImpl) AxisComponentImpl} or {@link (com.ibm.rave.bundles.components.GridComponentImpl) GridComponentImpl} for each role as it is required. The manager has four group (<g>) selectors for axes and four for gridlines, identified by their geometric positions top, bottom, left, and right. In bundles the group structure is created when the bundle first runs, so these selectors can in theory be set just once. Note that the axes and grids are identified logically, while the groups are identified geometrically. By default X1 is the bottom group, X2 the top, Y1 the left, and Y2 the right. This association is controlled by properties which transpose and/or flip the assignments. This is in part a RAVE/D3 requirement, since the core Axis examines the shapes in the group to generate transitions. The group selectors should be ordinary selectors. If a transition is requested and the transition duration is non-negative, the manager creates transitions from the selectors. However in order to give a somewhat better appearance, the manager keeps track of whether shapes were drawn into the group on the previous execution, and a transition is not used if the group was not used. The manager has the following overall properties: The manager has the following per-role (X1, X2, Y1, Y2) properties: The manager has the following per-position (bottom, top, left, right) properties: An {@link (com.ibm.rave.bundles.components.AxisComponentImpl) AxisComponentImpl} and {@link (com.ibm.rave.bundles.components.GridComponentImpl) GridComponentImpl} can be obtained for each role. These instances are created on demand, usually when a view requests the instance, but also if the manager is drawing and detects that the instance is needed. Once created the instance will be used by the manager thereafter. Views should use these instances to configure the appearance properties of the axes and grids. All other properties (such as scale, bounds, orient, role, and pre-execution callback) are set by the AxesManager. Views can set these properties but the manager's {@link #this.draw()} method will change the settings. Values for some of these properties (e.g. scale and bounds) are set in the manager by the view, and the others are found automatically by the manager. Layout Properties
*/
var com_ibm_rave_bundles_component_ChartLayoutComponent = rave['internal']['Declare'].implement(
//padding : function() {},
//topPadding : function() {},
//leftPadding : function() {},
//bottomPadding : function() {},
//rightPadding : function() {},
//legendChartAlign : function() {},
//legendPosition : function() {},
//legendChartGap : function() {},
//legendPosition : function(position) {},
//topPadding : function(value) {},
//leftPadding : function(value) {},
//bottomPadding : function(value) {},
//rightPadding : function(value) {},
/**
* Sets the padding around the outside of the chart/legend.
* @param (Object) value a string containing up to 4 CSS sizes for left, top, right, bottom padding (eg. "padding-left:10px;padding-top:10%"). Null is treated as 0.
* @return (com.ibm.rave.bundles.component.ChartLayoutComponent) This object
*/
//padding : function(value) {},
/**
* Sets all chart paddings. Null values are treated as 0.
* @param (Object) top New top padding
* @param (Object) left New left padding
* @param (Object) bottom New bottom padding
* @param (Object) right New right padding
* @return (com.ibm.rave.bundles.component.ChartLayoutComponent) This object
* @deprecated Please use {@link #this.padding(Object)} and {@link #this.legendChartGap(Object)}
*/
//chartPadding : function(top, left, bottom, right) {},
/**
* Sets whether the legend should align with the chart "body".
* @param (boolean) legendChartAlign the boolean state
* @return (com.ibm.rave.bundles.component.ChartLayoutComponent) This object
*/
//legendChartAlign : function(legendChartAlign) {},
/**
* Set the space for the gap between chart and legend
* @param (Object) value the gap distance (css length)
* @return (com.ibm.rave.bundles.component.ChartLayoutComponent) This object
*/
//legendChartGap : function(value) {},
/**
* Set the size information for the legend. Null value is treated as no visible legend.
* @param (com.ibm.rave.bundles.component.ChartLayoutSizable) sizable An object that implements the ChartLayoutSizable interface
* @return (com.ibm.rave.bundles.component.ChartLayoutComponent) This object
*/
//legendSize : function(sizable) {},
/**
* Reset list of axis sizables to 0
* @return (com.ibm.rave.bundles.component.ChartLayoutComponent) This object
*/
//removeAxisSizables : function() {},
/**
* Add an axis to be considered in layout operation.
* @param (com.ibm.rave.bundles.component.ChartLayoutSizable) sizable An object that implements the ChartLayoutSizable interface
* @return (com.ibm.rave.bundles.component.ChartLayoutComponent) This object
*/
//addAxisSizable : function(sizable) {}
);
/**
* The string returned by {@link #this.type()} is "ChartLayoutComponent".
*/
/** @expose */
com_ibm_rave_bundles_component_ChartLayoutComponent.COMPONENT_TYPE = "ChartLayoutComponent";
// $source: com/ibm/rave/bundles/components/LegendsManager
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/bundles/components/LegendComponentImpl (runtime) // new, orientationOf
/**
*
Properties
Components
To associate multiple data slots with an axis role, see {@link #this.setDataSlot(, Array)} .
* @param (int) role An axis role, one of {@link this.AxesManager#0} , {@link this.AxesManager#1} , {@link this.AxesManager#2} , {@link this.AxesManager#3} .
* @param (rave['library']['internal']['DataSlotEntry']) slot DataSlotEntry to be associated with the axis role.
*/
setDataSlot$0 : function(role, slot) {
this.setDataSlot$1(role, [slot]);
return this;
},
/**
* Set a list of data slot entries that will be associated with the specified axis role.
* @param (int) role An axis role, one of {@link this.AxesManager#0} , {@link this.AxesManager#1} , {@link this.AxesManager#2} , {@link this.AxesManager#3} .
* @param (Array) slots List of DataSlotEntry to be associated with the axis role.
*/
setDataSlot$1 : function(role, slots) {
if (role < 4 && role >= 0) {
this._dataSlotEntries[role].length = 0;
if (slots) {
for (var __i_enFor0 = 0, __exp_enFor0 = slots, __len_enFor0 = __exp_enFor0.length;
__i_enFor0 < __len_enFor0; ++__i_enFor0) {
var slot = __exp_enFor0[__i_enFor0];
this._dataSlotEntries[role].push(slot);
}
}
}
return this;
},
/**
*
A component that renders an axis (RAVE core Axis) with an optional title in an XY axis chart. The {@link #this.type()} method returns "AxisComponent".
The {@link #this.role()} method is used to identify the axis. Most charts with axes will use only the {@link #"ROLE_X1"} and {@link #"ROLE_Y1"} roles. The composite bundle also uses {@link #"ROLE_Y2"} . {@link #"ROLE_X2"} is not currently used by any chart.
The axis component uses a RAVE capability axis, available with {@link #this.axis()} . When used with a pre-execution callback, the axis is only valid for the duration of the callback (do not use the reference outside the callback). Properties of the capability axis may be set by the pre-execution callback, but note that many properties are set by the AxisComponent after the callback. To change those properties, use the methods of this class to change the AxisComponent, which will then set the capability axis properties.
*/ var com_ibm_rave_bundles_component_AxisComponent = rave['internal']['Declare'].implement( /** * @return (String) The role of the axis in the chart */ //role : function() {}, /** * @return (rave['internal']['Axis']) The capability Axis used by this AxisComponent */ //axis : function() {}, /** * The tickFormat is applied to the values of the ticks to create the string that is displayed. * @param (rave['internal']['ValueFunction']) tickFormat The new tickFormat * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //tickFormat : function(tickFormat) {}, /** * Get the tickFormat function used by this component. May be null. * @return (rave['internal']['ValueFunction']) Format function, or null */ //tickFormat : function() {}, /** * Set the indicator to be used for truncated text ex: indicator set to "..." , results in helloworld - > hello... * @param (String) indicator the string to be placed to indicated truncated text * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //textTruncateIndicator : function(indicator) {}, /** * Whether to display the axis title. * @param (boolean) displayAxisTitle true to display the axis title, false otherwise * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //displayAxisTitle : function(displayAxisTitle) {}, /** * Whether to display the axis line. * @param (boolean) displayAxisLine true to display the axis line, false otherwise * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //displayAxisLine : function(displayAxisLine) {}, /** * Whether to display the axis tick marks. * @param (boolean) displayTicks true to display the axis ticks, false otherwise * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //displayTicks : function(displayTicks) {}, /** * Whether to display the axis labels, as set by the show axis labels property * @param (boolean) displayTickLabels true to display the axis tick labels, false otherwise * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //displayTickLabels : function(displayTickLabels) {}, /** * Whether to display the axis labels, as set by the hide pan-zoom labels property * @param (boolean) showPanZoomTickLabels true to display the axis tick labels, false otherwise * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //showPanZoomTickLabels : function(showPanZoomTickLabels) {}, /** * @param (String) axisTitle The new axisTitle * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //axisTitle : function(axisTitle) {}, /** * The color used to draw the axis line and ticks. This is equivalent to calling both {@link #this.lineColor(String)} and {@link #this.tickColor(String)} . * @param (String) axisColor The new line and tick color * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //axisColor : function(axisColor) {}, /** * The color used to draw the axis line. * @param (String) lineColor The new lineColor * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //lineColor : function(lineColor) {}, /** * The color used to draw the axis ticks. * @param (String) tickColor The new tickColor * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //tickColor : function(tickColor) {}, /** * The color used to draw the axis labels. * @param (String) labelColor The new labelColor * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //labelColor : function(labelColor) {}, /** * The style for the axis labels. * @param (String) fontStyle CSS string of font properties * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //labelStyle : function(fontStyle) {}, /** * The style for the axis labels. * @param (String) fill The color used to draw the labels * @param (String) fontSize CSS font size * @param (String) fontFamily CSS font-families list * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //labelStyle : function(fill, fontSize, fontFamily) {}, /** * The color used to draw the axis title. * @param (String) titleColor The new titleColor * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //titleColor : function(titleColor) {}, /** * The style for the axis title. * @param (String) fontStyle CSS string of font properties * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //titleStyle : function(fontStyle) {}, /** * The style for the axis title. * @param (String) fill The color used to draw the title * @param (String) fontSize CSS font size * @param (String) fontFamily CSS font-families list * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ //titleStyle : function(fill, fontSize, fontFamily) {} ); /** * The string returned by {@link #this.type()} is "AxisComponent". */ /** @expose */ com_ibm_rave_bundles_component_AxisComponent.COMPONENT_TYPE = "AxisComponent"; /** * Returned by {@link #this.role()} for the first independent axis. */ /** @expose */ com_ibm_rave_bundles_component_AxisComponent.ROLE_X1 = "ROLE_X1"; /** * Returned by {@link #this.role()} for the first dependent axis. */ /** @expose */ com_ibm_rave_bundles_component_AxisComponent.ROLE_Y1 = "ROLE_Y1"; /** * Returned by {@link #this.role()} for the second independent axis. */ /** @expose */ com_ibm_rave_bundles_component_AxisComponent.ROLE_X2 = "ROLE_X2"; /** * Returned by {@link #this.role()} for the second dependent axis. */ /** @expose */ com_ibm_rave_bundles_component_AxisComponent.ROLE_Y2 = "ROLE_Y2"; // $source: com/ibm/rave/bundles/utilities/TextCrossfader /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** *Utility class for setting up a cross-fade of a single text node. This could be extended to a multiple-node selection (e.g. using value functions to return the text strings for each node in the selection), but that is not yet needed in the bundles. However use this with care, since if the transition does select multiple texts, they will all change to the new text string.
Any other text properties that are changing, for example the color or position, can be set up in the transition either before or after calling the utility method.
*/ var com_ibm_rave_bundles_utilities_TextCrossfader = rave['internal']['Declare']({ }); /** *Perform a text cross fade for a single text node. The selection holds that node. If it is not a transition, the new text is set; otherwise the cross-fade transition is done using tweeners on the "text" and "fill-opacity" attributes.
The "text" attribute tweener uses the oldText before transition time 0.5, and the new text thereafter. (Note this assumes that the old text is in fact the node's text; if not, the displayed text will change to the "old" text when the transition begins, then to the new text halfway through the transition.)
The text is optionally faded out and back in, disappearing completely at time 0.5, by setting the "fill-opacity" style attribute. The fading is controlled by the delay argument, which is clamped to the range [0.0, 0.5]. If the clamped delay is 0.5, or if the text does not actually change, no crossfade is used. Otherwise the opacity is full for transition times less than the delay or greater than 1-delay, fading to 0.0 at time 0.5. For example if the delay is 0.2, the opacity will be full from transition time 0.0 to 0.2, fade out linearly to 0 at time 0.5, fade in linearly to full at time 0.8, and be full from time 0.8 to 1.0.
The old and new texts and the full opacity are all passed as arguments, because it is generally not safe to try to find the values when the method runs. In particular, if we run this method while a transition (such as a previous cross-fade) is already in progress, we may pick up an intermediate fill-opacity value, perhaps even 0.0, and set the text opacity to that value! * @param (rave['internal']['Selection']) selection Selection containing the single text node, may be a transition * @param (String) oldText Old value of the text string, may be null * @param (String) newText New value of the text string, may be null * @param (Object) fillOpacity Fill opacity, may be null (in which case 1.0 is assumed) * @param (double) delay Number between 0 and 0.5 controlling the timing of the fade * @return (rave['internal']['Selection']) The selection, modified by the new text and fill-opacity */ /** @expose */ com_ibm_rave_bundles_utilities_TextCrossfader.textCrossFade = function(selection, oldText, newText, fillOpacity, delay) { if (!(selection.isTransition())) { return selection.text(newText); } var _t = (selection).tween("text", function(data, index, groupIndex) { return function(t) { this.rave_setText(t < 0.5 ? oldText : newText); }; }); var t0 = Math.max(0.0, Math.min(0.5, delay)); if (t0 == 0.5 || (oldText == null && newText == null) || (oldText != null && oldText == newText)) { return selection; } var opacity = fillOpacity == null ? 1.0 : + (fillOpacity); var tf = 1.0 / (0.5 - t0); return _t.tween("fill-opacity", function(data, index, groupIndex) { return function(t) { if (t <= t0 || t >= (1.0 - t0)) { this.rave_setStyle("fill-opacity", fillOpacity); } else { this.rave_setStyle("fill-opacity", opacity * Math.abs(t - 0.5) * tf); } }; }); }; // $source: com/ibm/rave/bundles/utilities/BundleLabelDropper /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED var com_ibm_rave_bundles_utilities_BundleLabelDropper = rave['internal']['Declare']({ //_dropOverlap : null, labelCount : 0, _$functionClassMethod : function() { var _$self = function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { _$self.drop(args[0], ((args[1]))); return null; } }; return _$self; }, /** @expose */ constructor : function() { this._dropOverlap = (rave.capabilities.extension("position")).drop().remove(false); this._dropOverlap.setOverlapGap(4.0); }, /** * Drop the overlapping labels or reset the overlap. * @param (rave['internal']['Selection']) labels The selector for the labels * @param (boolean) removeOverlap true to remove the overlapping labels, false to reset */ /** @expose */ drop : function(labels, removeOverlap) { if (!(labels.isTransition())) { this.applyLabelDrop(labels, removeOverlap); } else { var steps = [0, 25, 75]; var self = this; (labels).tween("__pointLabelDrop__", function(data, index, groupIndex) { if (index == 0) { return function(t) { var currentStep = Math.floor(t * 100); if (steps.length > 0 && currentStep < 100 && currentStep >= steps[0]) { steps.splice(0, 1); self.applyLabelDrop(labels, removeOverlap); } }; } return null; }); this.labelCount = 0; (labels).each(function(data, index, groupIndex) { ++self.labelCount; }).each("end", function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { if (--self.labelCount == 0) { self.applyLabelDrop(labels, removeOverlap); } return null; } }); } }, applyLabelDrop : function(labels, removeOverlap) { if (removeOverlap) { labels.call(this._dropOverlap); } else { this._dropOverlap.reset(labels); } }, /** @expose */ configureForDataLabels : function(rect) { if (rect) { var ex = [[rect.x, rect.y], [rect.x + rect.width, rect.y + rect.height]]; this._dropOverlap.extent(ex); } this._dropOverlap.noClipping(); } }); /** * Drop overlap extension */ //com_ibm_rave_bundles_utilities_BundleLabelDropper.POSITION_EXTENSION = "position"; /** * space between labels during overlap testing */ com_ibm_rave_bundles_utilities_BundleLabelDropper.OVERLAP_GAP = 4; // $source: com/ibm/rave/bundles/components/StyleStructs /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** * Struct classes to hold style properties. */ var com_ibm_rave_bundles_components_StyleStructs = rave['internal']['Declare']({ }); /** * Filled shape style properties. */ com_ibm_rave_bundles_components_StyleStructs.ShapeStyle = function() { this._fill = null; this._stroke = null; this._strokeWidth = null; }; /** * Line style properties. */ com_ibm_rave_bundles_components_StyleStructs.LineStyle = function() { this._stroke = null; this._strokeWidth = null; this._dashArray = null; }; // $source: com/ibm/rave/bundles/component/GridComponent /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** *
A component that renders gridlines in an XY axis chart. The {@link #this.type()} method returns "GridComponent".
The {@link #this.role()} method is used to identify the grid. The return values are defined in {@link (com.ibm.rave.bundles.component.AxisComponent) AxisComponent} : {@link this.AxisComponent#"ROLE_X1"} , {@link this.AxisComponent#"ROLE_Y1"} , and so on.
*/ var com_ibm_rave_bundles_component_GridComponent = rave['internal']['Declare'].implement( /** * @return (String) The role of the grid in the chart */ //role : function() {}, /** * Whether to display the gridlines. * @param (boolean) displayGridlines The new displayGridlines * @return (com.ibm.rave.bundles.component.GridComponent) This component */ //displayGridlines : function(displayGridlines) {}, /** * Set the line styling. Equivalent to calling {@link #this.gridlineColor(String)} and {@link #this.dashArray(String)} . * @param (String) stroke The stroke color * @param (String) dashArray The stroke-dasharray * @return (com.ibm.rave.bundles.component.GridComponent) This component */ //gridlineStyle : function(stroke, dashArray) {}, /** * The color used to draw the gridlines. * @param (String) gridlineColor The new stroke color * @return (com.ibm.rave.bundles.component.GridComponent) This component */ //gridlineColor : function(gridlineColor) {}, /** * The dashing used to draw the gridlines. The argument is a string, giving a comma-separated list of numbers as used with the SVG "stroke-dasharray" style. * @param (String) dashArray The new dash array * @return (com.ibm.rave.bundles.component.GridComponent) This component */ //dashArray : function(dashArray) {} ); /** * The string returned by {@link #this.type()} is "GridComponent". */ /** @expose */ com_ibm_rave_bundles_component_GridComponent.COMPONENT_TYPE = "GridComponent"; // $source: com/ibm/rave/bundles/components/IntervalDataUtilities /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** * A structure for holding interval data (IntervalData}, and utilities for building an array of the data from the tabular data and accessors objects. The array has one entry per entry in the tabular data, and the array entries are in the same order as the datum rows for joining by selectors. */ var com_ibm_rave_bundles_components_IntervalDataUtilities = rave['internal']['Declare']({ }); /** *Create intervals for a simple bar chart. The intervals come directly from the data, with the independent interval the independent value (for both ends) and the dependent interval 0.0 to the dependent value. The group and label are copied from the datum. The callout independent is the independent value, and the callout dependent is the dependent value (the bar extent).
If the xScale is non-null and returns null for an independent (X) value, the data is skipped.
* @param (Array) data Data array * @param (rave['internal']['SingleValueFunction']) x X accessor, should not be null * @param (rave['internal']['SingleValueFunction']) xScale Function to check if the X value is valid * @param (rave['internal']['SingleValueFunction']) y Y accessor, should not be null * @param (rave['internal']['SingleValueFunction']) color Color accessor, may be null * @param (rave['internal']['SingleValueFunction']) label Label accessor, may be null * @return (Array) Array of intervals for the data */ /** @expose */ com_ibm_rave_bundles_components_IntervalDataUtilities.simpleBars = function(data, x, xScale, y, yStart, color, label) { var result = []; if (!data || data.length == 0 || !x || !y) { return result; } data.forEach(function(d, ix, list) { var xv = x(d); if (xv != null && (!xScale || xScale(xv) != null)) { var yv = y(d); var yvStart = !yStart ? 0 : yStart(d); if (yv != null && yvStart != null) { var r = new com_ibm_rave_bundles_components_IntervalDataUtilities.IntervalData(); r.key = ix; r.ind1 = xv; r.ind2 = r.ind1; r.cind = r.ind1; r.dep1 = yvStart; r.dep2 = yv; r.cdep = r.dep2; r.color = color ? color(d) : null; r.label = label ? label(d) : null; r.value = r.dep2; r._originalData = d; r.valueAsPercentOfCategory = 100; result.push(r); } } return null; }); var sum = 0; for (var i = 0; i < result.length; ++i) { var iData = result[i]; var value = + (iData.value); sum += Math.abs(value); } if (sum != 0) { for (var i = 0; i < result.length; ++i) { var iData = result[i]; var value = + (iData.value); iData.valueAsPercentOfColor = value / sum * 100; } } return result; }; /** * Create intervals for bars in a clustered chart. This is similar to the simple bars, except the independent values are an array of accessors. * @param (Array) data Data array * @param (Array) x Independent accessor array, should not be null and no entries should be null * @param (Array) xScale Array of possibly-null functions to check if X values are in domain; array should not be null, and should be same length as x * @param (rave['internal']['SingleValueFunction']) y Dependent accessor, should not be null * @param (rave['internal']['SingleValueFunction']) color Color accessor, may be null * @param (rave['internal']['SingleValueFunction']) label Label accessor, may be null * @return (Array) Array of intervals for the data */ /** @expose */ com_ibm_rave_bundles_components_IntervalDataUtilities.clusteredBars = function(data, x, xScale, y, yStart, color, label) { var result = []; if (!data || data.length == 0 || !x || x.length == 0 || !y) { return result; } var len = x.length; var categories = {}; var colors = {}; data.forEach(function(d, ix, list) { var OK = true; var ind = []; for (var i = 0; i < len; ++i) { var xv = x[i](d); if (xv == null || (xScale[i] && xScale[i](xv) == null)) { OK = false; break; } ind.push(xv); if (i == 0) { if (!(categories.hasOwnProperty(xv))) { categories[""+(xv)] = 1; } } else if (!(colors.hasOwnProperty(xv))) { colors[""+(xv)] = 1; } } var dep = y(d); var depStart = !yStart ? 0 : yStart(d); if (OK && dep != null && depStart != null) { var r = new com_ibm_rave_bundles_components_IntervalDataUtilities.IntervalData(); r.key = ix; r.ind1 = ind; r.ind2 = ind; r.cind = ind; r.dep1 = depStart; r.dep2 = dep; r.cdep = r.dep2; r.color = color ? color(d) : null; r.label = label ? label(d) : null; r.value = r.dep2; r._originalData = d; result.push(r); } return null; }); for (var __i_enFor0 = 0, __exp_enFor0 = Object.keys(categories), __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var o = __exp_enFor0[__i_enFor0]; var s = ""+(o); var sum = 0; for (var i = 0; i < result.length; ++i) { var iData = result[i]; if (s == (iData.ind1)[0]) { var value = + (iData.value); sum += Math.abs(value); } } if (sum == 0) { continue; } for (var i = 0; i < result.length; ++i) { var iData = result[i]; if (s == (iData.ind1)[0]) { var value = + (iData.value); iData.valueAsPercentOfCategory = value / sum * 100; } } } for (var __i_enFor1 = 0, __exp_enFor1 = Object.keys(colors), __len_enFor1 = __exp_enFor1.length; __i_enFor1 < __len_enFor1; ++__i_enFor1) { var o = __exp_enFor1[__i_enFor1]; var s = ""+(o); var sum = 0; for (var i = 0; i < result.length; ++i) { var iData = result[i]; if (s == iData.color) { var value = + (iData.value); sum += Math.abs(value); } } if (sum == 0) { continue; } for (var i = 0; i < result.length; ++i) { var iData = result[i]; if (s == iData.color) { var value = + (iData.value); iData.valueAsPercentOfColor = value / sum * 100; } } } return result; }; /** * Create intervals for an stacked bar chart. The data is formed into stacks by the unique values of the independent data. The independent interval is the independent value (for both ends), and the dependent interval is from the stacking with the extent equal to the dependent value. The callout independent is the independent value, and the callout dependent is the dependent value (the bar extent). If percent is true, the bars are rescaled so the total height of each stack is 1.0. If xScale is non-null and returns null for an x value, that bar is skipped. * @param (Array) data Data array * @param (rave['internal']['SingleValueFunction']) x Independent accessor, should not be null * @param (rave['internal']['SingleValueFunction']) xScale Possibly-null function to check if X values are in domain * @param (rave['internal']['SingleValueFunction']) y Dependent accessor, should not be null * @param (rave['internal']['SingleValueFunction']) color Color accessor, may be null * @param (rave['internal']['SingleValueFunction']) label Label accessor, may be null * @param (boolean) percent If true, create percent bars * @return (Array) Array of intervals for the data */ /** @expose */ com_ibm_rave_bundles_components_IntervalDataUtilities.stackedBars = function(data, x, xScale, y, color, label, percent) { var result = []; if (!data || data.length == 0 || !x || !y) { return result; } var stacks = {}; var categories = {}; var colors = {}; data.forEach(function(d, ix, list) { var xv = x(d); if (xv != null && (!xScale || xScale(xv) != null)) { var yv = y(d); if (yv != null) { var stack = stacks[xv]; if (!stack) { stack = new com_ibm_rave_bundles_components_IntervalDataUtilities.Stack(); stacks[xv] = stack; } var dVal = + (yv); if (!percent) { var r = new com_ibm_rave_bundles_components_IntervalDataUtilities.IntervalData(); r.key = ix; r.ind1 = xv; r.ind2 = xv; r.cind = xv; var sum = dVal < 0.0 ? stack.negativeSum : stack.positiveSum; r.dep1 = sum; r.dep2 = sum + dVal; r.cdep = r.dep2; r.color = color ? color(d) : null; r.label = label ? label(d) : null; r.value = dVal; r._originalData = d; result.push(r); } if (dVal < 0.0) { stack.negativeSum += dVal; } else { stack.positiveCount++; stack.positiveSum += dVal; } if (!(categories.hasOwnProperty(xv))) { categories[""+(xv)] = 1; } if (color) { var o = color(d); if ((o != null) && !(colors.hasOwnProperty(o))) { colors[""+(o)] = 1; } } } } return null; }); if (percent) { data.forEach(function(d, ix, list) { var xv = x(d); if (xv != null && (!xScale || xScale(xv) != null)) { var yv = y(d); if (yv != null) { var stack = stacks[xv]; var dVal = + (yv); var percent; if (dVal < 0.0) { percent = -100.0 * dVal / stack.negativeSum; } else if (stack.positiveSum > 0) { percent = 100.0 * dVal / stack.positiveSum; } else { percent = 100.0 / stack.positiveCount; } var r = new com_ibm_rave_bundles_components_IntervalDataUtilities.IntervalData(); r.key = ix; r.ind1 = xv; r.ind2 = xv; r.cind = xv; var sum = dVal < 0.0 ? stack.negativePercent : stack.positivePercent; r.dep1 = sum; r.dep2 = sum + percent; r.cdep = r.dep2; r.color = color ? color(d) : null; r.label = label ? label(d) : null; r.value = dVal; r.valueAsPercentOfCategory = percent; r._originalData = d; result.push(r); if (dVal < 0.0) { stack.negativePercent += percent; } else { stack.positivePercent += percent; } } } return null; }); } else { for (var __i_enFor0 = 0, __exp_enFor0 = Object.keys(categories), __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var o = __exp_enFor0[__i_enFor0]; var s = ""+(o); var sum = 0; for (var i = 0; i < result.length; ++i) { var iData = result[i]; if (s == iData.ind1) { var value = + (iData.value); sum += Math.abs(value); } } if (sum == 0) { continue; } for (var i = 0; i < result.length; ++i) { var iData = result[i]; if (s == iData.ind1) { var value = + (iData.value); iData.valueAsPercentOfCategory = value / sum * 100; } } } } for (var __i_enFor1 = 0, __exp_enFor1 = Object.keys(colors), __len_enFor1 = __exp_enFor1.length; __i_enFor1 < __len_enFor1; ++__i_enFor1) { var o = __exp_enFor1[__i_enFor1]; var s = ""+(o); var sum = 0; for (var i = 0; i < result.length; ++i) { var iData = result[i]; if (s == iData.color) { var value = + (iData.value); sum += Math.abs(value); } } if (sum == 0) { continue; } for (var i = 0; i < result.length; ++i) { var iData = result[i]; if (s == iData.color) { var value = + (iData.value); iData.valueAsPercentOfColor = value / sum * 100; } } } return result; }; /** * Structure class holding interval information. */ com_ibm_rave_bundles_components_IntervalDataUtilities.IntervalData = rave['internal']['Declare']({ /** * Key value; for now this is the data index */ /** @expose */ key : null, /** * First independent value */ /** @expose */ ind1 : null, /** * Second independent value (in all current uses, same as ind1) */ /** @expose */ ind2 : null, /** * First dependent value */ /** @expose */ dep1 : null, /** * Second dependent value */ /** @expose */ dep2 : null, /** * The data value that the interval represents. Not the pixel value. Used in stacked chart */ /** @expose */ value : null, /** * Color value */ /** @expose */ color : null, /** * Label value */ /** @expose */ label : null, /** * Callout independent value (in all current uses, same as ind1) */ /** @expose */ cind : null, /** * Callout dependent value (dependent extent) */ /** @expose */ cdep : null, /** @expose */ _originalData : null, /** * The data value (in percentage) for specific category */ /** @expose */ valueAsPercentOfCategory : NaN, /** * The data value (in percentage) across all categories */ /** @expose */ valueAsPercentOfColor : NaN, /** @expose */ originalData : function() { return this._originalData; }, /** @expose */ originalDataList : function() { var list = []; list.push(this._originalData); return list; } }); com_ibm_rave_bundles_components_IntervalDataUtilities.Stack = function() { this.positiveCount = 0; this.positiveSum = 0; this.negativeSum = 0; this.positivePercent = 0; this.negativePercent = 0; }; /** * Accessor for the callout dependent value */ /** @expose */ com_ibm_rave_bundles_components_IntervalDataUtilities.CALLOUT_DEPENDENT_ACCESSOR = function(data) { return (data).cdep; }; /** * Accessor for the callout independent value */ /** @expose */ com_ibm_rave_bundles_components_IntervalDataUtilities.CALLOUT_INDEPENDENT_ACCESSOR = function(data) { return (data).cind; }; /** * Accessor for the data value */ /** @expose */ com_ibm_rave_bundles_components_IntervalDataUtilities.VALUE_ACCESSOR = function(data) { return (data).value; }; /** * Accessor for data value as percent of category */ /** @expose */ com_ibm_rave_bundles_components_IntervalDataUtilities.PERCENT_OF_CATEGORY_ACCESSOR = function(data) { var percent = (data).valueAsPercentOfCategory; return isNaN(percent) ? "" : percent.toFixed(1) + "%"; }; /** * Accessor for data value as percent of color (series) */ /** @expose */ com_ibm_rave_bundles_components_IntervalDataUtilities.PERCENT_OF_COLOR_ACCESSOR = function(data) { var percent = (data).valueAsPercentOfColor; return isNaN(percent) ? "" : percent.toFixed(1) + "%"; }; // $source: com/ibm/rave/bundles/data/PointDataUtilities /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** * Utility class for building arrays of point datum objects from tabular data. */ var com_ibm_rave_bundles_data_PointDataUtilities = rave['internal']['Declare']({ }); /** *Filter the input data list-array and return a list-array of PointData objects in the same order. If the data is null, an empty list is returned. Any null object in the data is skipped.
If an accessor is null, the X or Y value in the returned PointData objects is always null. If the accessor is non-null, points for which the accessor returns null are not included in the result; if the scale is also non-null, points for which the scale applied to the value returns null are not included in the result.
The returned PointDatum objects have the X accessor and Y accessor values (so may be null), and the original datum set to the object from the data.
* @param (Array) data Input data, list of arbitrary objects * @param (rave['internal']['SingleValueFunction']) xAccessor X accessor function, may be null * @param (rave['internal']['SingleValueFunction']) xScale Scale to test if the X value should be included, may be null * @param (rave['internal']['SingleValueFunction']) yAccessor Y accessor function, may be null * @param (rave['internal']['SingleValueFunction']) yScale Scale to test if the Y value should be included, may be null * @return (Array) List of PointData objects */ /** @expose */ com_ibm_rave_bundles_data_PointDataUtilities.buildPoints = function(data, xAccessor, xScale, yAccessor, yScale) { var result = []; if (data) { for (var __i_enFor0 = 0, __exp_enFor0 = data, __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var o = __exp_enFor0[__i_enFor0]; if (o != null) { var xv = null; if (xAccessor) { xv = xAccessor(o); if (xv == null || (xScale && xScale(xv) == null)) { continue; } } var yv = null; if (yAccessor) { yv = yAccessor(o); if (yv == null || (yScale && yScale(yv) == null)) { continue; } } var datum = new com_ibm_rave_bundles_data_PointDataUtilities.PointDatum(); datum._x = xv; datum._y = yv; datum._originalData = o; result.push(datum); } } } return result; }; /** * Datum object representing a point with X and Y values. Either X or Y may be null, depending on how the point is used, for example in a scatterplot. */ com_ibm_rave_bundles_data_PointDataUtilities.PointDatum = rave['internal']['Declare']({ /** * The X value */ /** @expose */ _x : null, /** * The Y value */ /** @expose */ _y : null, /** * The data value (in percentage) that the point represents */ /** @expose */ _yAsPercentOfCategory : null, /** * The data value (in percentage) that the point represents */ /** @expose */ _yAsPercentOfColor : null, /** * The original data */ /** @expose */ _originalData : null, /** @expose */ originalData : function() { return this._originalData; }, /** @expose */ originalDataList : function() { var list = []; list.push(this._originalData); return list; } }); /** * Accessor returning the _x property of a PointDatum. */ /** @expose */ com_ibm_rave_bundles_data_PointDataUtilities.X_ACCESSOR = function(d) { return (d)._x; }; /** * Accessor returning the _y property of a PointDatum. */ /** @expose */ com_ibm_rave_bundles_data_PointDataUtilities.Y_ACCESSOR = function(d) { return (d)._y; }; /** * Accessor returning the _yAsPercentOfCategory property of a PointDatum. */ /** @expose */ com_ibm_rave_bundles_data_PointDataUtilities.PERCENT_OF_CATEGORY_ACCESSOR = function(d) { var percent = + ((d)._yAsPercentOfCategory); return isNaN(percent) ? "" : percent.toFixed(1) + "%"; }; /** * Accessor returning the _yAsPercentOfColor property of a PointDatum. */ /** @expose */ com_ibm_rave_bundles_data_PointDataUtilities.PERCENT_OF_COLOR_ACCESSOR = function(d) { var percent = + ((d)._yAsPercentOfColor); return isNaN(percent) ? "" : percent.toFixed(1) + "%"; }; // $source: com/ibm/rave/bundles/utilities/ColorUtil /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED var com_ibm_rave_bundles_utilities_ColorUtil = rave['internal']['Declare']({ }); /** * It is used to get a foreground color which has atleast a 4.5 contrast ratio with the background color. * @param (Object) bg bakground color * @param (Object) fg foreground color * @return (Object) a color ( darker/ligher/same fg color ) which contrast with background. */ com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor$0 = function(bg, fg) { var contrastRatio = com_ibm_rave_bundles_utilities_ColorUtil.getContrastRatio(bg, fg); if (contrastRatio < 4.5) { var bgHSL = rave.hsl(bg); var fgHSL = rave.hsl(fg); var brightness = 0.33 * (rave.rgb(bg).getR() / 255.0) + 0.5 * (rave.rgb(bg).getG() / 255.0) + 0.16 * (rave.rgb(bg).getB() / 255.0); if (brightness > 0.5) { if (bgHSL.getL() > 0.5) { return rave.hsl(fgHSL.getH(), fgHSL.getS(), Math.min(fgHSL.getL(), bgHSL.getL() - 0.4)); } else { return rave.hsl(fgHSL.getH(), fgHSL.getS(), Math.min(fgHSL.getL(), 0.1)); } } else { if (bgHSL.getL() < 0.5) { return rave.hsl(fgHSL.getH(), fgHSL.getS(), Math.max(fgHSL.getL(), bgHSL.getL() + 0.4)); } else { return rave.hsl(fgHSL.getH(), fgHSL.getS(), Math.max(fgHSL.getL(), 0.9)); } } } return fg; }; com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor$1 = function(labelColor) { var labelRGB = rave.rgb(labelColor); return labelRGB.contrastShift(21); }; /** @expose */ com_ibm_rave_bundles_utilities_ColorUtil.getContrastRatio = function(colorA, colorB) { var foregroundLuminance = rave.rgb(colorA).getLuminance(); var backgroundLuminance = rave.rgb(colorB).getLuminance(); var contrastRatio = (foregroundLuminance >= backgroundLuminance) ? (foregroundLuminance + 0.05) / (backgroundLuminance + 0.05) : (backgroundLuminance + 0.05) / (foregroundLuminance + 0.05); return contrastRatio; }; /** @expose */ com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor = function(a0, a1) { var args = arguments; if (args.length == 1) { return com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor$1(a0); } return com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor$0(a0, a1); }; // $source: com/ibm/rave/bundles/component/IntervalComponent /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** *A component that renders interval elements (rectangles based on data, showing an extent in both X and Y dimensions, as in a bar chart). The {@link #this.type()} method returns "IntervalComponent".
*/ var com_ibm_rave_bundles_component_IntervalComponent = rave['internal']['Declare'].implement( /** * Turn labels on or off. If labels are on but there is no label data, empty text nodes will be created. * @param (boolean) itemLabel Whether to use labels * @return (com.ibm.rave.bundles.component.IntervalComponent) This object */ //itemLabel : function(itemLabel) {}, /** * @param (boolean) _itemOverlap Whether to show/hide overlap labels * @return (com.ibm.rave.bundles.component.IntervalComponent) This object */ //itemOverlap : function(_itemOverlap) {}, /** * Sets function that will specify position of item label for given chart element. * @param (rave['internal']['ValueFunction']) labelPosition Function to be used to determine label position * @return (com.ibm.rave.bundles.component.IntervalComponent) This object */ //itemLabelPosition : function(labelPosition) {}, /** * Set the border width, which is also the stroke width. * @param (String) width * @return (com.ibm.rave.bundles.component.IntervalComponent) This object */ //borderWidth : function(width) {}, /** * Set the border color. * @param (String) borderColor * @return (com.ibm.rave.bundles.component.IntervalComponent) This object */ //borderColor : function(borderColor) {}, /** * Set the classname of the labellayer * @param (String) string * @return (com.ibm.rave.bundles.component.IntervalComponent) This object */ //labelLayerClassName : function(string) {}, /** * Set the classname of the elementlayer * @param (String) string * @return (com.ibm.rave.bundles.component.IntervalComponent) This object */ //elementLayerClassName : function(string) {}, /** * @param bounds The bounds of the chart area. */ //bounds : function(chartRect) {} ); /** * The string returned by {@link #this.type()} is "IntervalComponent". */ /** @expose */ com_ibm_rave_bundles_component_IntervalComponent.COMPONENT_TYPE = "IntervalComponent"; // $source: com/ibm/rave/bundles/utilities/LabelStyleUtil /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/FilterComponentImpl (runtime) // new //@import com/ibm/rave/bundles/utilities/ColorUtil (runtime) // getContrastColor, getContrastRatio /** * This class can be used to apply styles on labels. Eg: when we need to overrule the given label style properties. */ var com_ibm_rave_bundles_utilities_LabelStyleUtil = rave['internal']['Declare']({ //_labelFontStyle : null, //_contrastLabelColorfilter : null, //_sameLabelColorfilter : null, /** * eg: apply contrast label color with background. apply different font size for each level label. apply a contrast shadow for a label. */ //_labelFillColor : null, //_labelFontSize : null, _labelShadow : false, _$functionClassMethod : function() { var _$self = function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { if (_$self._labelFontStyle) { for (var __i_enFor0 = 0, __exp_enFor0 = Object.keys(_$self._labelFontStyle), __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var stylenName = __exp_enFor0[__i_enFor0]; if ((stylenName == "fill" || stylenName == "color" && _$self._labelFillColor) || (stylenName == "font-size" && _$self._labelFontSize) || (stylenName == "text-shadow" && _$self._labelShadow == true)) { continue; } this.style(stylenName, _$self._labelFontStyle[stylenName]); } } if (_$self._labelFillColor) { this.style("fill", _$self._labelFillColor); } if (_$self._labelFontSize) { this.style("font-size", _$self._labelFontSize); } var labels = this.selectAll("*"); if (labels.length == 0) { labels = this; } if (_$self._labelShadow) { var self = _$self; var defaultLabelFill = _$self.getDefaultLabelColor(_$self._labelFontStyle); _$self._contrastLabelColorfilter = new com_ibm_rave_bundles_components_FilterComponentImpl("contrast_label_drop_shadow"); _$self._contrastLabelColorfilter.setDropshadow("1px", "1px", "0px", rave.rgb(com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor(defaultLabelFill))); _$self._sameLabelColorfilter = new com_ibm_rave_bundles_components_FilterComponentImpl("same_label_drop_shadow"); _$self._sameLabelColorfilter.setDropshadow("1px", "1px", "0px", rave.rgb(defaultLabelFill)); var owner = this.node().rave_getOwner(); rave.select(owner).select("defs").call(_$self._contrastLabelColorfilter); rave.select(owner).select("defs").call(_$self._sameLabelColorfilter); this.each(function(data, index, groupIndex) { if (self._labelFillColor) { var contrastRatio = com_ibm_rave_bundles_utilities_ColorUtil.getContrastRatio(rave.rgb(self._labelFillColor.call(this, data, index, groupIndex)), defaultLabelFill); if (contrastRatio < 4.5) { this.setAttribute("filter", "url(#" + self._contrastLabelColorfilter.getId() + ")"); } else { this.setAttribute("filter", "url(#" + self._sameLabelColorfilter.getId() + ")"); } } else { this.setAttribute("filter", "url(#" + self._contrastLabelColorfilter.getId() + ")"); } }); labels.each(function(data, index, groupIndex) { if (self._labelFillColor) { this.rave_setProperty("_rave_drop_shadow", "1px 1px 0px " + com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor(self._labelFillColor.call(this, data, index, groupIndex)).toString()); } else { this.rave_setProperty("_rave_drop_shadow", "1px 1px 0px " + com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor(defaultLabelFill).toString()); } }); } else { labels.each(function(data, index, groupIndex) { this.rave_setProperty("_rave_drop_shadow", null); }); this.attr("filter", null); } return null; } }; return _$self; }, /** @expose */ labelFont : function(labelFontStyle) { this._labelFontStyle = labelFontStyle; return this; }, /** @expose */ labelFillColor : function(_labelFillColor) { this._labelFillColor = _labelFillColor; return this; }, /** @expose */ labelFontSize : function(_labelFontSize) { this._labelFontSize = _labelFontSize; return this; }, /** @expose */ labelShadow : function(labelShadow) { this._labelShadow = labelShadow; return this; }, /** @expose */ getDefaultLabelColor : function(_labelStyle) { if (!_labelStyle) { return "#000000"; } var defaultFillColor; if (_labelStyle) { defaultFillColor = _labelStyle["fill"]; if (defaultFillColor == null) { defaultFillColor = _labelStyle["color"]; } } if (defaultFillColor == null) { defaultFillColor = "#000000"; } return defaultFillColor.toString(); } }); // $source: com/ibm/rave/bundles/component/LabelCollisionComponent /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** */ var com_ibm_rave_bundles_component_LabelCollisionComponent = rave['internal']['Declare'].implement( ); /** * The string returned by {@link #this.type()} is "LabelCollisionComponent". */ /** @expose */ com_ibm_rave_bundles_component_LabelCollisionComponent.COMPONENT_TYPE = "LabelCollisionComponent"; // $source: com/ibm/rave/bundles/utilities/PathUtils /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED var com_ibm_rave_bundles_utilities_PathUtils = rave['internal']['Declare']({ }); /** * Transition a path element selection with a fade-out-fade-in effect. In many cases, transitioning between two unrelated path strings will result in an undesirable morphing effect. This method allows the path to first fade out (to opacity 0), update the path string without morphing, then fade back in. * @param (rave['internal']['Selection']) selection A selection (either Selector or Transition) containing "path" elements. * @param (rave['internal']['ValueFunction']) pathFunction The path string generator function, e.g. Rave.svg.line(). */ /** @expose */ com_ibm_rave_bundles_utilities_PathUtils.fadeOutIn = function(selection, pathFunction) { if (selection.isTransition()) { var transition = selection; transition.ease("linear").styleTween("opacity", function(data, index, value) { var path = rave.select(this); if (!(this.rave_hasProperty("__rave_originalOpacity__"))) { this.rave_setProperty("__rave_originalOpacity__", path.style("opacity")); } var styleOpacity = this.rave_getProperty("__rave_originalOpacity__"); var opacity = styleOpacity != null ? parseFloat(""+(styleOpacity)) : 1.0; var mid1 = 0.45, mid2 = 0.55; var s = rave.scale.linear().domain([0.0, mid1, mid2, 1.0]).range([opacity, 0.0, 0.0, opacity]); var setPath = []; setPath[0] = false; return function(t) { if (t > mid1 && !setPath[0]) { path.attr("d", pathFunction); setPath[0] = true; } return + (s.call(null, t, 0, 0)); }; }); transition.each("end", function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { this.rave_removeProperty("__rave_originalOpacity__"); return null; } }); } else { selection.attr("d", pathFunction); } }; //com_ibm_rave_bundles_utilities_PathUtils.OPACITY = "opacity"; //com_ibm_rave_bundles_utilities_PathUtils.ORIGINAL_OPACITY = "__rave_originalOpacity__"; //com_ibm_rave_bundles_utilities_PathUtils.PATH_DATA = "d"; //com_ibm_rave_bundles_utilities_PathUtils.EASE_LINEAR = "linear"; // $source: com/ibm/rave/bundles/component/LineComponent /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** *A component that renders line elements (polylines, each with a series of points in X and Y dimensions, as in a line chart). The {@link #this.type()} method returns "LineComponent".
*/ var com_ibm_rave_bundles_component_LineComponent = rave['internal']['Declare'].implement( /** * The interpolation modes are from the RAVE core line path generator, for example "linear", "cardinal". * @param (String) interpolate The interpolation mode * @return (com.ibm.rave.bundles.component.LineComponent) This component */ //interpolate : function(interpolate) {} ); /** * The string returned by {@link #this.type()} is "LineComponent". */ /** @expose */ com_ibm_rave_bundles_component_LineComponent.COMPONENT_TYPE = "LineComponent"; // $source: com/ibm/rave/bundles/data/LineDataUtilities /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/data/PointDataUtilities (runtime) // new /** *Utility class for working with line and area features, as used in the line, area, and composite bundles. A line or area is represented by a LineDatum, which has a group (line ID) and a points array. The points are two-element arrays as used in the RAVE core line and area path generators.
The buildLines method takes tabular data and accessors as used in all three bundles' data models, where the table is of point data with X, Y, and group slots. Points with null X are ignored; other points are formed into lines using the group values. Note that line points may have null Y values; this causes a gap in the line or area. Points are added in data order.
The other static methods work with an array of LineDatum as returned by buildLines:
Points are returned as an array of PointDatum so may be used in components exactly as the points returned by PointDataUtilities.
*/ var com_ibm_rave_bundles_data_LineDataUtilities = rave['internal']['Declare']({ }); /** *Process tabular data as used in the tabular data models of the line, area, and composite bundles, returning an array-list of LineData objects. Each row of data in the table is a single point with X, Y, and optional group values. The group accessor returns strings, as in all three bundles. The points are grouped by the accessor values (null is treated as a distinct value) and each group forms a LineData. If the group accessor is null, all points are in one group.
If the xScale is non-null and returns null for an X value, the point is ignored.
The LineData group value is the unique group value (possibly null). The LineData points are the [X,Y] coordinates as an ArrayEx, suitable for use with the line and area path generators. The points in each line are in row (input array) order. This wil be the single place where we need to fix the sorting problem, defect 23553.
* @param (Array) data Array of data objects * @param (rave['internal']['SingleValueFunction']) xAccessor Non-null X accessor function * @param (rave['internal']['SingleValueFunction']) xScale Value function used to check if X value is in domain * @param (rave['internal']['SingleValueFunction']) yAccessor Non-null Y accessor function * @param (rave['internal']['SingleValueFunction']) groupAccessor Possibly-null group accessor function * @return (Array) Non-null but possibly empty array of LineData items, one per distinct group value */ /** @expose */ com_ibm_rave_bundles_data_LineDataUtilities.buildLines = function(data, xAccessor, xScale, yAccessor, groupAccessor) { var result = []; if (!data || data.length == 0) { return result; } var categories = {}; var noGroup; var lines = {}; for (var __i_enFor0 = 0, __exp_enFor0 = data, __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var datum = __exp_enFor0[__i_enFor0]; if (datum == null) { continue; } var xValue = xAccessor(datum); if (xValue != null && (!xScale || xScale(xValue) != null)) { if (!(categories.hasOwnProperty(xValue))) { categories[""+(xValue)] = 1; } var group = groupAccessor ? (groupAccessor(datum)) : null; var line; if (group == null) { if (!noGroup) { noGroup = new com_ibm_rave_bundles_data_LineDataUtilities.LineDatum(null); result.push(noGroup); } line = noGroup; } else { line = lines[group]; if (!line) { line = new com_ibm_rave_bundles_data_LineDataUtilities.LineDatum(group); lines[group] = line; result.push(line); } } line.addPoint(datum, xValue, yAccessor(datum)); } } for (var __i_enFor1 = 0, __exp_enFor1 = Object.keys(categories), __len_enFor1 = __exp_enFor1.length; __i_enFor1 < __len_enFor1; ++__i_enFor1) { var o = __exp_enFor1[__i_enFor1]; var s = ""+(o); var sum = 0; for (var i = 0; i < result.length; ++i) { var lineDatum = result[i]; for (var j = 0; j < lineDatum._pointData.length; ++j) { var pointDatum = lineDatum._pointData[j]; if (s == pointDatum._x) { pointDatum._yAsPercentOfCategory = NaN; var value = + (pointDatum._y); sum += Math.abs(value); } } } if (sum == 0) { continue; } for (var i = 0; i < result.length; ++i) { var lineDatum = result[i]; for (var j = 0; j < lineDatum._pointData.length; ++j) { var pointDatum = lineDatum._pointData[j]; if (s == pointDatum._x) { var value = + (pointDatum._y); pointDatum._yAsPercentOfCategory = value / sum * 100; } } } } for (var i = 0; i < result.length; ++i) { var sum = 0; var lineDatum = result[i]; for (var j = 0; j < lineDatum._pointData.length; ++j) { var pointDatum = lineDatum._pointData[j]; pointDatum._yAsPercentOfColor = NaN; var value = + (pointDatum._y); sum += Math.abs(value); } if (sum != 0) { for (var j = 0; j < lineDatum._pointData.length; ++j) { var pointDatum = lineDatum._pointData[j]; var value = + (pointDatum._y); pointDatum._yAsPercentOfColor = value / sum * 100; } } } return result; }; com_ibm_rave_bundles_data_LineDataUtilities.get = function(val, data) { for (var i = 0; i < data.length; ++i) { var entry = data[i]; if (entry.key===val) { return entry; } } return null; }; /** @expose */ com_ibm_rave_bundles_data_LineDataUtilities.buildLinesForStacking = function(data, xAccessor, yAccessor, groupAccessor) { if (!data || data.length == 0) { return []; } var keyToOriginalValue = {}; var stacks = []; var nest = rave.nest(); nest.key(function(d) { var keyValue = xAccessor(d); var strKeyValue = (keyValue); keyToOriginalValue[strKeyValue] = keyValue; return strKeyValue; }); nest.key(function(d) { var stack = groupAccessor(d).toString(); if (!(stacks.indexOf(stack)> -1)) { stacks.push(stack); } return stack; }); var result = nest.entries(data); var missingValue = new Number(0); var stackData = stacks.map(function(name, index, array) { var line = new com_ibm_rave_bundles_data_LineDataUtilities.LineDatum(array[index].valueOf()); result.forEach(function(currentValue, index, array) { var values = currentValue.values; var currentElement = com_ibm_rave_bundles_data_LineDataUtilities.get(line.group, values); var datum = null; var yValue = null; if (!currentElement) { yValue = missingValue; } else { datum = (currentElement.values)[0]; yValue = yAccessor(datum); if (yValue == null) { yValue = missingValue; } } line.addPoint(datum, keyToOriginalValue[currentValue.key], yValue); return null; }); return line; }); return stackData; }; /** *Sort an array of LineData by the X-coordinate. The CoordinateScale must be initialized with the domain of the line data, and its range must be set. The points of each line are sorted in increasing order of the scaled X-value.
For efficiency this method assumes the lines are as created by buildLines, so each point is non-null, and has two values of which the first is non-null.
* @param (Array) lines A non-null array of LineDatum objects, such as produced by buildLines * @param (rave['library']['internal']['CoordinateScaleImpl']) scale A non-null scale */ /** @expose */ com_ibm_rave_bundles_data_LineDataUtilities.sortLines = function(lines, scale) { var comp = function(a, b) { var av = scale.center(a._x); if (av == null) { return 1; } var bv = scale.center(b._x); if (bv == null) { return -1; } var v = av - bv; return v < 0 ? -1 : v > 0 ? 1 : 0; }; for (var __i_enFor0 = 0, __exp_enFor0 = lines, __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var line = __exp_enFor0[__i_enFor0]; line.sort(comp); } }; /** * Get one PointDatum object for every point in the lines, omitting any points where the X or Y value is null. The returned array may be empty. * @param (Array) lines A non-null array of LineDatum objects, such as produced by buildLines * @return (Array) Array of PointDatum for points where X and Y are both non-null */ /** @expose */ com_ibm_rave_bundles_data_LineDataUtilities.getLineWithPoints = function(lines) { var result = []; for (var __i_enFor0 = 0, __exp_enFor0 = lines, __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var line = __exp_enFor0[__i_enFor0]; line.getLineWithPoints(result); } return result; }; /** * Get one PointDatum object for every point in the lines that meets the "null-point-null" criterion: The point has non-null X and Y, and the points before/after it have null Y. * @param (Array) lines A non-null array of LineDatum objects, such as produced by buildLines * @return (Array) Array of PointDatum for points meeting the null-point-null criterion */ /** @expose */ com_ibm_rave_bundles_data_LineDataUtilities.getNPNPoints = function(lines) { var result = []; for (var __i_enFor0 = 0, __exp_enFor0 = lines, __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var line = __exp_enFor0[__i_enFor0]; line.getNPNPoints(result); } return result; }; /** *Representation of a line. Assumes that the line will be built from data objects representing points, and grouped into lines by a group key. Contains:
Group key, for the line identifier. May be null.
Array of PointDatum objects. This is used when sorting the point data.
Array of points for line or area generator. Each point is a two-element [x,y] array in the unscaled data space.
Original data. This is an array of objects from the original point data.
*/ com_ibm_rave_bundles_data_LineDataUtilities.LineDatum = rave['internal']['Declare']({ /** * Group key, may be null */ /** @expose */ group : null, /** * Array of line-generator points in data space, non-null but may be empty */ /** @expose */ points : null, /** * Array of point datum objects, non-null but may be empty. */ //_pointData : null, /** * Original data, non-null but may be empty. */ //_originalData : null, /** * Construct. * @param (String) group The line's group. */ constructor : function(group) { this.group = group; this.points = []; this._pointData = []; this._originalData = []; }, /** @expose */ originalData : function() { return this._originalData; }, /** @expose */ originalDataList : function() { return this._originalData; }, /** * Add a point to the line. * @param (Object) originalData Original data for this point * @param (Object) x X value, must not be null * @param (Object) y Y value, may be null (for line/non-stacking area charts with gaps for null Y) */ addPoint : function(originalData, x, y) { var point = new com_ibm_rave_bundles_data_PointDataUtilities.PointDatum(); point._x = x; point._y = y; point._originalData = originalData; this.points.push([x, y]); this._pointData.push(point); this._originalData.push(originalData); }, /** * Sort the points by X value (data values) using the comparator, which must compare the X values of two PointDatum objects. The PointDatum array is sorted first, then the line generator and original data arrays are sorted to match. * @param (rave['internal']['Comparator']) comp Comparator that takes PointDatum arguments and sorts by X value */ sort : function(comp) { this._pointData.sort(comp); var N = this._pointData.length; for (var i = 0; i < N; ++i) { var d = this._pointData[i]; var p = this.points[i]; p[0] = d._x; p[1] = d._y; this._originalData[i] = d._originalData; } }, /** * Add all PointDatum objects where X and Y are non-null to the array. For efficiency this assumes the X values are non-null. * @param (Array) result Array collecting points */ getLineWithPoints : function(result) { for (var __i_enFor0 = 0, __exp_enFor0 = this._pointData, __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var point = __exp_enFor0[__i_enFor0]; if (point._y != null) { result.push(point); } } }, /** * Add all PointDatum objects that meet the "null-point-null" criterion to the array. For efficiency this assumes the X values are non-null. * @param (Array) result Array collecting points */ getNPNPoints : function(result) { var N = this._pointData.length; var lastY; for (var i = 0; i < N; ++i) { var point = this._pointData[i]; if (point._y != null) { var nextY = (i < N - 1) ? this._pointData[i + 1]._y : null; if (lastY == null && nextY == null) { result.push(point); } } lastY = point._y; } } }); /** * A value function that takes a LineData as argument and returns the group. */ /** @expose */ com_ibm_rave_bundles_data_LineDataUtilities.GROUP_ACCESSOR = function(d) { return (d).group; }; /** * A value function that takes a LineData as argument and returns theoints. */ /** @expose */ com_ibm_rave_bundles_data_LineDataUtilities.POINTS_ACCESSOR = function(d) { return (d).points; }; // $source: com/ibm/rave/bundles/component/PointComponent /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** *A component that renders point elements (glyphs based on data, showing a point with X and Y dimensions, as in a scatterplot chart). The {@link #this.type()} method returns "PointComponent".
*/ var com_ibm_rave_bundles_component_PointComponent = rave['internal']['Declare'].implement( /** * The default size used for a point, when no size scale is used or when the size data for the element is null. * @param (double) defaultSize The new defaultSize * @return (com.ibm.rave.bundles.component.PointComponent) This component */ //defaultSize : function(defaultSize) {}, /** * Turn labels on or off. If labels are on but there is no label data, empty text nodes will be created. * @param (boolean) itemLabel Whether to use labels * @return (com.ibm.rave.bundles.component.PointComponent) This component */ //itemLabel : function(itemLabel) {}, /** * Whether to drop overlapping labels. * @param (boolean) itemOverlap The new itemOverlap * @return (com.ibm.rave.bundles.component.PointComponent) This component */ //itemOverlap : function(itemOverlap) {}, /** * The symbol to be used for the points. * @param (String) symbol The new symbol * @return (com.ibm.rave.bundles.component.PointComponent) This component */ //symbol : function(symbol) {}, /** * Set the width of border * @param (String) borderWidth CSS value * @return (com.ibm.rave.bundles.component.PointComponent) This component */ //borderWidth : function(borderWidth) {}, /** * Set the color of border * @param (String) borderColor * @return (com.ibm.rave.bundles.component.PointComponent) This component */ //borderColor : function(borderColor) {}, /** * Set the classname of the labellayer * @param string * @return (com.ibm.rave.bundles.component.PointComponent) This object */ //labelLayerClassName : function(className) {}, /** * Set the classname of the elementlayer * @param string * @return (com.ibm.rave.bundles.component.PointComponent) This object */ //elementLayerClassName : function(className) {}, /** * Sets function that will specify position of item label for given chart element. * @param (rave['internal']['ValueFunction']) labelPosition Function to be used to determine label position * @return (com.ibm.rave.bundles.component.PointComponent) This object */ //itemLabelPosition : function(labelPosition) {} ); /** * The string returned by {@link #this.type()} is "PointComponent". */ /** @expose */ com_ibm_rave_bundles_component_PointComponent.COMPONENT_TYPE = "PointComponent"; // $source: com/ibm/rave/bundles/components/AlignAxisTicksComponent /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** * This is a utility class with one public method, alignAxisScales, which takes the Linear Coordinate Scales of two axes and aligns them so that their ticks and their zero positions align, producing one set of grid lines for both. This works only for Linear Coordinate Scales. */ var com_ibm_rave_bundles_components_AlignAxisTicksComponent = rave['internal']['Declare']({ }); /** * To align the axes so that the grid lines coincide, we ensure that both scales will be subdivided into the same or a multiple of the number of ticks by the LinearScale tick maker. This means that we may have to increase the upper range of at least one of the scales. To ensure that the alignment is not thrown of be a large remainder at one of the scales, we always set the scales to nice if they have not already been set. * @param (rave['library']['internal']['CoordinateScaleImpl']) scale1 the scale for the first axis * @param (rave['library']['internal']['CoordinateScaleImpl']) scale2 the scale for the second axis */ /** @expose */ com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignAxisScales = function(scale1, scale2) { if (scale1.isLinear() && scale2.isLinear()) { com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignScaleZero(scale1, scale2); var count1 = com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignScale(scale1, null); var count2 = com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignScale(scale2, null); if (count1 > count2) { com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignScale(scale2, count1); } else if (count1 < count2) { com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignScale(scale1, count2); } } }; /** * This method takes two scales and expands them in the negative and positive direction so that their zero tick will align on both sides. There are a number of possible scenarios for this, each comprised of one of a and one of b below: a1. scale 1 has a negative and a positive a2. scale 1 has no negative but a positive a3. scale 1 has a negative and no positive a4. scale 1 has no extent b1. scale 2 has a negative and a positive b2. scale 2 has no negative but a positive b3. scale 2 has a negative and no positive b4. scale 2 has no extent All are covered in the method. * @param (rave['library']['internal']['CoordinateScaleImpl']) scale1 the scale for the first axis * @param (rave['library']['internal']['CoordinateScaleImpl']) scale2 the scale for the second axis */ /** @expose */ com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignScaleZero = function(scale1, scale2) { var extent1 = rave['internal']['AbstractScale'].scaleExtent(scale1.scale().domain()); var extent2 = rave['internal']['AbstractScale'].scaleExtent(scale2.scale().domain()); var min1 = + (extent1[0]); var min2 = + (extent2[0]); if (min1 >= 0.0 && min2 >= 0.0) { return; } var max1 = + (extent1[1]); var max2 = + (extent2[1]); if (max1 <= 0.0 && max2 <= 0.0) { return; } var ratio1 = 0; var ratio2 = 0; if (min1 < 0.0) { ratio1 = max1 / Math.abs(min1); if (min2 < 0.0) { ratio2 = max2 / Math.abs(min2); if (ratio1 > ratio2) { extent2[1] = Math.abs(min2) * ratio1; } if (ratio2 > ratio1) { extent1[1] = Math.abs(min1) * ratio2; } } else { if (ratio1 > 0.0) { extent2[0] = -max2 / ratio1; } else { ratio1 = Math.abs(min1) / max2; ratio1 = ratio1 > 4.0 ? 4.0 : ratio1; ratio1 = ratio1 < 0.25 ? 0.25 : ratio1; extent1[1] = -min1 / ratio1; extent2[0] = -max2 * ratio1; } } } else if (min2 < 0.0) { if (max2 > 0) { ratio2 = max2 / Math.abs(min2); extent1[0] = -max1 / ratio2; } else { ratio2 = Math.abs(min2) / max1; ratio2 = ratio2 > 4.0 ? 4.0 : ratio2; ratio2 = ratio2 < 0.25 ? 0.25 : ratio2; extent2[1] = -min2 / ratio2; extent1[0] = -max1 * ratio2; } } var exList = []; exList.splice(0, 0, extent2[0]); exList.splice(1, 0, extent2[1]); scale2.scale().domain(exList); exList.length = 0; exList.splice(0, 0, extent1[0]); exList.splice(1, 0, extent1[1]); scale1.scale().domain(exList); }; /** * Mainly copied from LinearScale, this calculates the number of ticks that will be created, and can be used, if tickCount is not null, to increase the domain of the shorter axis to make the ticks match the other axis. * @param (rave['library']['internal']['CoordinateScaleImpl']) coordScale the original scale * @param (Number) tickCount the tickCount we wish to expand the scale to * @return (double) the number of ticks of the scale */ /** @expose */ com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignScale = function(coordScale, tickCount) { var m = 10; var extent = rave['internal']['AbstractScale'].scaleExtent(coordScale.scale().domain()); var span = + (extent[1]) - + (extent[0]); var step = Math.pow(10, Math.floor(Math.log(span / m) / Math.log(10))); var err = m / span * step; if (err <= 0.15) { step *= 10; } else if (err <= 0.35) { step *= 5; } else if (err <= 0.75) { step *= 2; } var min = + (extent[0]); var max = + (extent[1]); var numSteps = (max - min) / step; if (tickCount != null && numSteps < tickCount) { var negSteps = 0.0; if (min < 0.0) { negSteps = Math.abs(min) / step; } var posSteps = max / step; negSteps = negSteps * tickCount / numSteps; posSteps = posSteps * tickCount / numSteps; var exList = []; exList.splice(0, 0, -negSteps * step); exList.splice(1, 0, posSteps * step); coordScale.scale().domain(exList); numSteps = tickCount; } return numSteps; }; com_ibm_rave_bundles_components_AlignAxisTicksComponent.LINEAR_DEFAULT_TICKS = 10; // $source: com/ibm/rave/bundles/components/ComponentConfiguration /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED /** * Utility class that does configuration for components, optionally drawing them into selections. Some of the configuration information is taken from a bundle context, and uses standard property IDs as defined in the shared property files and {@link (rave['library']['internal']['CommonPropertyIDs']) CommonPropertyIDs} . If a bundle does not use define the expected properties, an error will occur. In this documentation the property ID is referred to by the CommonPropertyIDs constant, for example property LEGEND_DISPLAY means the property with the ID {@link this.CommonPropertyIDs#"legend.display"} . */ var com_ibm_rave_bundles_components_ComponentConfiguration = rave['internal']['Declare']({ //constructor : function() {} }); /** *Do "standard" configuration of a Zoom and optionally run it on a selection. If the provided Zoom is null a new one is created. Component properties are set as follows:
Note that it is not possible to remove a scale from an existing zoom, since the core Zoom does not allow null scales in the x() and y() methods. To do that, first disable any existing zoom (with Selector#on("zoom",null)) then call this method with a null Zoom.
The scales are ordered x, y, x2, y2 in the parameters and in the p and s arrays, since most charts will only have the x and y scales.
* @param (rave['internal']['Selection']) chart Selection on which to run the zoom, may be null * @param (rave['internal']['Zoom']) zoom The Zoom; if null one is created and returned * @param (rave['library']['internal']['CoordinateScaleImpl']) xScale X dimension scale, may be null * @param (rave['library']['internal']['CoordinateScaleImpl']) yScale Y dimension scale, may be null * @param (rave['library']['internal']['CoordinateScaleImpl']) x2Scale X2 dimension scale, may be null * @param (rave['library']['internal']['CoordinateScaleImpl']) y2Scale Y2 dimension scale, may be null * @param (Array) scaleExtent Scale extent, may be null; if null the range 0.2 to 5.0 is used * @param (rave['internal']['RectStruct']) chartRect The rectangle of the chart * @param (double[]) p the zoom translate position (x, y, x2, y2) * @param (double[]) s the zoom scale (x, y, x2, y2) * @param (String) zoomOps The zoom operation (x|y|x2|y2|all) * @param (rave['internal']['RunFunction']) callback Callback on each zoom event, must not be null * @return (rave['internal']['Zoom']) The zoom */ /** @expose */ com_ibm_rave_bundles_components_ComponentConfiguration.configureZoom = function(chart, zoom, xScale, yScale, x2Scale, y2Scale, scaleExtent, chartRect, p, s, zoomOps, callback) { var z = zoom ? zoom : rave.behavior.zoom(); var z1 = (x2Scale || y2Scale) && zoomOps == "all" ? rave.behavior.zoom() : null; var dummyScale = (rave.scale.linear()); z.x(dummyScale); z.y(dummyScale); if (xScale && zoomOps == "x") { z.x(xScale.scale()); z.scale(s[0]); z.translate([p[0], 0]); } if (yScale && zoomOps == "y") { z.y(yScale.scale()); z.scale(s[1]); z.translate([0, p[1]]); } if (x2Scale && zoomOps == "x2") { z.x(x2Scale.scale()); z.scale(s[2]); z.translate([p[2], 0]); } if (y2Scale && zoomOps == "y2") { z.y(y2Scale.scale()); z.scale(s[3]); z.translate([0, p[3]]); } if (zoomOps == "all") { if (xScale) { z.x(xScale.scale()); } if (yScale) { z.y(yScale.scale()); } z.scale(1); z.translate([0, 0]); if (z1) { if (x2Scale) { z1.x(x2Scale.scale()); } if (y2Scale) { z1.y(y2Scale.scale()); } z1.scale(1); z1.translate([0, 0]); } } z.scaleExtent(scaleExtent ? scaleExtent : [1, Infinity]).on("zoom.default", function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { var event = args[3]; var scale = event.scale; var translate = event.translate; var scaledX = chartRect.x * (scale - 1); var scaledXExtent = (chartRect.width * (1 - scale)) - scaledX; translate[0] = Math.min(-scaledX, Math.max(scaledXExtent, translate[0])); var scaledY = chartRect.y * (scale - 1); var scaledYExtent = (chartRect.height * (1 - scale)) - scaledY; translate[1] = Math.min(-scaledY, Math.max(scaledYExtent, translate[1])); z.translate([translate[0], translate[1]]); if (z1) { z1.translate([translate[0], translate[1]]); z1.scale(scale); } if (zoomOps == "x") { p[0] = translate[0]; s[0] = scale; } else if (zoomOps == "y") { p[1] = translate[1]; s[1] = scale; } else if (zoomOps == "x2") { p[2] = translate[0]; s[2] = scale; } else if (zoomOps == "y2") { p[3] = translate[1]; s[3] = scale; } else if (zoomOps == "all") { p[0] = translate[0]; p[1] = translate[1]; p[2] = translate[0]; p[3] = translate[1]; s[0] = scale; s[1] = scale; s[2] = scale; s[3] = scale; } return callback.apply(this, args); } }); return z; }; // $source: com/ibm/rave/bundles/internal/nativeImpl/BundleModule /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2015 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // Must be the first import // @import ./BundleModuleHeader // expose DataFormatter to the global variable rave //rave["library"]["CustomFormatter"]=com_ibm_rave_library_framework_CustomFormatter; // $source: com/ibm/rave/bundles/compositeBundle/CompositeBundle /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/library/Library (static) // Library //@import com/ibm/rave/bundles/RaveBundle (loadtime) // superclass //@import com/ibm/rave/bundles/compositeBundle/CompositeView (runtime) // new var com_ibm_rave_bundles_compositeBundle_CompositeBundle = rave['internal']['Declare'](com_ibm_rave_bundles_RaveBundle, { /** @expose */ getName : function() { return com_ibm_rave_bundles_compositeBundle_CompositeBundle.BUNDLE_NAME; }, /** @expose */ createView : function(ctx) { return new com_ibm_rave_bundles_compositeBundle_CompositeView(ctx); } //constructor : function() {} }); /** * Register the bundle factory with the library. The bundle will not be made available if this method is not called. */ /** @expose */ com_ibm_rave_bundles_compositeBundle_CompositeBundle.init = function() { if (!(com_ibm_rave_library_Library.bundle.isRegistered(com_ibm_rave_bundles_compositeBundle_CompositeBundle.BUNDLE_NAME))) { var bundle; com_ibm_rave_library_Library.bundle.extension(com_ibm_rave_bundles_compositeBundle_CompositeBundle.BUNDLE_NAME, function() { if (!bundle) { bundle = new com_ibm_rave_bundles_compositeBundle_CompositeBundle(); bundle.loadResources(); require("./vizlibrary-composite.css"); } return bundle; }); } return com_ibm_rave_bundles_compositeBundle_CompositeBundle.BUNDLE_NAME; }; com_ibm_rave_bundles_compositeBundle_CompositeBundle.BUNDLE_NAME = "compositeBundle"; // Auto initialization com_ibm_rave_bundles_compositeBundle_CompositeBundle.init(); if (!com_ibm_rave_library_Library.bundle[com_ibm_rave_bundles_compositeBundle_CompositeBundle.BUNDLE_NAME]) { com_ibm_rave_library_Library.bundle[com_ibm_rave_bundles_compositeBundle_CompositeBundle.BUNDLE_NAME] = function() { if (!bundle) { bundle = new com_ibm_rave_bundles_compositeBundle_CompositeBundle(); bundle.loadResources(); require("./vizlibrary-composite.css"); } return bundle; }; } else { console.log("Could not register extension: CompositeBundle"); } // $source: com/ibm/rave/bundles/views/AbstractColumnView /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/views/BundleView (loadtime) // superclass //@import com/ibm/rave/bundles/components/IntervalComponentImpl (runtime) // new //@import com/ibm/rave/bundles/components/IntervalDataUtilities (runtime) // IntervalDataUtilities, simpleBars, clusteredBars, stackedBars //@import com/ibm/rave/library/Library (runtime) // logError //@import com/ibm/rave/bundles/utilities/FontPropertyParser (runtime) // parseCSSFont /** * An abstract Column view implementation that contains code common to 'column'-like charts. For instance a composite (column/line) chart will also use this functionality. */ var com_ibm_rave_bundles_views_AbstractColumnView = rave['internal']['Declare'](com_ibm_rave_bundles_views_BundleView, { /** @expose */ datasetId : null, /** * Interval component, created in setup */ /** @expose */ _intervalComponent : null, /** @expose */ constructor : function(context) { this.datasetId = "data"; }, /** @expose */ setup : function() { com_ibm_rave_bundles_views_BundleView.prototype.setup.call(this); this._intervalComponent = new com_ibm_rave_bundles_components_IntervalComponentImpl(); this._intervalComponent.keyAccessor(function(data) { return (data).key; }).independent1Accessor(function(data) { return (data).ind1; }).independent2Accessor(function(data) { return (data).ind2; }).dependent1Accessor(function(data) { return (data).dep1; }).dependent2Accessor(function(data) { return (data).dep2; }).valueAccessor(com_ibm_rave_bundles_components_IntervalDataUtilities.VALUE_ACCESSOR); }, /** @expose */ dataValid : function() { if (!(this.dataModel.validate())) { return false; } var dataHandling = this.getStringProperty("data.handling"); var dataSet = this.dataModel.dataset(this.datasetId); var yAccessor = dataSet.slot("y").entry(); var yStart = dataSet.slot("yStart"); var yStartAccessor = yStart ? yStart.entry() : null; if (dataHandling == "Stacked" || dataHandling == "Stacked100") { if (yStartAccessor || yAccessor.type() == "date") { com_ibm_rave_library_Library.logError(408, "Column chart isn't stackable when ystart is defined or y is date"); return false; } } if (yStartAccessor && !(yStartAccessor.type() == yAccessor.type())) { com_ibm_rave_library_Library.logError(409, "y and ystart slot must have the same data type in Column data"); return false; } return true; }, /** * Convert data model into array of IntervalData structures, based on the group handling. See {@link (com.ibm.rave.bundles.components.IntervalDataUtilities) IntervalDataUtilities} . * @return (Array) Array of intervals */ /** @expose */ makeData : function(dataModel, _data) { if (!_data || _data.length == 0) { return []; } var dataSet = dataModel.dataset(this.datasetId); var xAccessor = dataSet.slot("x").entry(); var yAccessor = dataSet.slot("y").entry(); var colorAccessor = dataSet.slot("color").entry(); var labelAccessor = dataSet.slot("label").entry(); var yStart = dataSet.slot("yStart"); var yStartAccessor = yStart ? yStart.entry() : null; var dataHandling = this.getStringProperty("data.handling"); if ("Clustered" == dataHandling && colorAccessor) { return com_ibm_rave_bundles_components_IntervalDataUtilities.clusteredBars(_data, [xAccessor, colorAccessor], [rave['library']['internal']['AbstractView'].domainCheckerOf(_data, xAccessor), rave['library']['internal']['AbstractView'].domainCheckerOf(_data, colorAccessor)], yAccessor, yStartAccessor, colorAccessor, labelAccessor); } if ("Stacked" == dataHandling) { return com_ibm_rave_bundles_components_IntervalDataUtilities.stackedBars(_data, xAccessor, rave['library']['internal']['AbstractView'].domainCheckerOf(_data, xAccessor), yAccessor, colorAccessor, labelAccessor, false); } if ("Stacked100" == dataHandling) { return com_ibm_rave_bundles_components_IntervalDataUtilities.stackedBars(_data, xAccessor, rave['library']['internal']['AbstractView'].domainCheckerOf(_data, xAccessor), yAccessor, colorAccessor, labelAccessor, true); } return com_ibm_rave_bundles_components_IntervalDataUtilities.simpleBars(_data, xAccessor, rave['library']['internal']['AbstractView'].domainCheckerOf(_data, xAccessor), yAccessor, yStartAccessor, colorAccessor, labelAccessor); }, /** @expose */ configureDataLabels : function(dataSet, colorDataSlotEntry) { if (!(this.isShowDataLabels())) { this._intervalComponent.itemLabel(false); this._intervalComponent.itemLabelPosition(null); this._intervalComponent.labelFont(null); this._intervalComponent.labelAccessor(null); this._intervalComponent.labelFormatter(null); return; } var dataHandling = this.getStringProperty("data.handling"); var isStacked = (colorDataSlotEntry) && ("Stacked" == dataHandling || "Stacked100" == dataHandling); var dataLabelPosition = function(data, index, groupIndex) { if (isStacked) { return 1; } else { var iData = data; var value = + (iData.value); return (value >= 0) ? 0 : 2; } }; var labelAccessor = this.getlDataLabelAccessor(dataSet, "label", true); var labelEntry = this.getEntryForDataLabelFormatter(dataSet, "label", "y"); this._intervalComponent.itemLabel(true); this._intervalComponent.itemOverlap(true); this._intervalComponent.itemLabelPosition(dataLabelPosition); var labelFontStyle = com_ibm_rave_bundles_utilities_FontPropertyParser.parseCSSFont(this.getStringProperty("labelstyle.font")); if (!isStacked) { labelFontStyle = this.getBackgroundConstrastLabelStyle(); } this._intervalComponent.labelFont(labelFontStyle); this._intervalComponent.labelAccessor(labelAccessor); this._intervalComponent.labelContrast(this.getBooleanProperty("contrast.label.color")); this._intervalComponent.labelFormatter(this.context.getCustomFormatterForElementLabels(labelEntry, (dataSet.slot("label").entry()) ? "ROLE_NONE" : "ROLE_Y1")); this._intervalComponent.labelContrast(this.getBooleanProperty("contrast.label.color")); this._intervalComponent.labelShadow(this.getBooleanProperty("label.shadow")); } }); /** @expose */ com_ibm_rave_bundles_views_AbstractColumnView.DATAMODEL_TABULAR = "tabular"; /** @expose */ com_ibm_rave_bundles_views_AbstractColumnView.DATASET_DATA = "data"; /** @expose */ com_ibm_rave_bundles_views_AbstractColumnView.DATASLOT_X = "x"; /** @expose */ com_ibm_rave_bundles_views_AbstractColumnView.DATASLOT_Y = "y"; /** @expose */ com_ibm_rave_bundles_views_AbstractColumnView.DATASLOT_Y_START = "yStart"; /** @expose */ com_ibm_rave_bundles_views_AbstractColumnView.DATASLOT_COLOR = "color"; /** @expose */ com_ibm_rave_bundles_views_AbstractColumnView.DATASLOT_LABEL = "label"; // $source: com/ibm/rave/bundles/compositeBundle/CompositeView /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2018 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/views/AbstractColumnView (loadtime) // superclass //@import com/ibm/rave/bundles/components/LabelCollisionComponentImpl (runtime) // new //@import com/ibm/rave/bundles/components/LineComponentImpl (runtime) // new //@import com/ibm/rave/bundles/data/LineDataUtilities (runtime) // getNPNPoints, buildLines, sortLines, LineDataUtilities, getLineWithPoints //@import com/ibm/rave/bundles/components/PointComponentImpl (runtime) // new //@import com/ibm/rave/bundles/data/PointDataUtilities (runtime) // PointDataUtilities //@import com/ibm/rave/bundles/components/AxesManager (runtime) // percentFormat //@import com/ibm/rave/bundles/components/AlignAxisTicksComponent (runtime) // alignAxisScales //@import com/ibm/rave/bundles/components/ComponentConfiguration (runtime) // configureZoom //@import com/ibm/rave/library/Library (runtime) // logError /** *A composite view with a column and line chart. The two are plotted on the same independent (X) axis, and have separate dependent (Y) axes.
*/ var com_ibm_rave_bundles_compositeBundle_CompositeView = rave['internal']['Declare'](com_ibm_rave_bundles_views_AbstractColumnView, { /** * Line component, created in setup */ //_lineComponent : null, /** * Point component, created when first needed */ //_pointComponent : null, /** * Column data */ //_intervalData : null, /** * Line data */ //_lineData : null, /** * Point data; the line points which have non-null X and Y */ //_pointData : null, /** * Null-point data; the line points which have non-null X and Y, and are flanked by points with null Y */ //_pointNPNData : null, //_independentScale : null, //_intervalDependentScale : null, //_lineDependentScale : null, //zoomendedTimer : null, /** * color accessor for the column portion of the composite bundle */ //_columnColorAccessor : null, //indepScale : null, //intervalScale : null, //lineScale : null, /** * Label collision component, created in setup */ /** @expose */ _labelCollisionComponent : null, _transpose : false, /** * When true, don't start a new timer */ _pendingLabelTimer : false, /** * Counts the number of label collision timers to kill */ _cancelLabelTimers : 0, /** @expose */ constructor : function(context) { this.datasetId = "column"; this._columnColorAccessor = function(data) { return (data).color; }; }, /** @expose */ getLegendCount : function() { return 2; }, /** @expose */ isAxesManagerRequired : function() { return true; }, /** @expose */ setup : function() { com_ibm_rave_bundles_views_AbstractColumnView.prototype.setup.call(this); this._pendingLabelTimer = false; this._cancelLabelTimers = 0; this._labelCollisionComponent = new com_ibm_rave_bundles_components_LabelCollisionComponentImpl(); rave['library']['internal']['BundleUtils'].setupDefaultActions(this.context, ".chart ." + "element-shape", null); this._lineComponent = new com_ibm_rave_bundles_components_LineComponentImpl(); this._lineComponent.pointsAccessor(function(data) { return (data).points; }).groupAccessor(com_ibm_rave_bundles_data_LineDataUtilities.GROUP_ACCESSOR); this._pointComponent = new com_ibm_rave_bundles_components_PointComponentImpl(); this._pointComponent.independentAccessor(com_ibm_rave_bundles_data_PointDataUtilities.X_ACCESSOR).dependentAccessor(com_ibm_rave_bundles_data_PointDataUtilities.Y_ACCESSOR); }, /** @expose */ draw : function() { if (this.isUpdateNothing()) { return; } this.preDraw("g.vizlibrary-composite"); this.dataModel = this.context.dataModel(); if (this.dataModel.getDescriptor().id() == com_ibm_rave_bundles_compositeBundle_CompositeView.DATAMODEL_SIMPLE) { this.datasetId = "composite"; } else { this.datasetId = "column"; } if (!(this.validateDataModel("g.element-group", "g.grid", "g.axis"))) { return; } this.setActionsWithBorder(); this.stopLabelCollisions(); var columnDataSet; var lineDataSet; if (this.dataModel.getDescriptor().id() == com_ibm_rave_bundles_compositeBundle_CompositeView.DATAMODEL_SIMPLE) { columnDataSet = this.dataModel.dataset("composite"); lineDataSet = this.dataModel.dataset("composite"); } else { columnDataSet = this.dataModel.dataset(this.datasetId); lineDataSet = this.dataModel.dataset("line"); } if (!(this.compatibleDomains(columnDataSet, lineDataSet))) { this._chart.selectAll("g.element-group").selectAll("*").remove(); this._chart.selectAll("g.element-label-group").selectAll("*").remove(); this._chart.selectAll("g.grid").selectAll("*").remove(); this._chart.selectAll("g.axis").selectAll("*").remove(); this._legends.visible(false).draw(); } var effect = this.getStringProperty("effect.name"); var duration = this.getEffectDuration(effect); this._transpose = this.getBooleanProperty("transpose"); var columnData = (columnDataSet.data()); var lineModelData = (lineDataSet.data()); var useLineLegend = this.getBooleanProperty("legend.line.display"); var useColumnLegend = this.getBooleanProperty("legend.column.display"); var legendPosition = this.getLegendPosition(); var columnXDataSlotEntry = columnDataSet.slot("x").entry(); var columnYDataSlotEntry = columnDataSet.slot("y").entry(); var columnColorDataSlotEntry = columnDataSet.slot("color").entry(); if (!columnColorDataSlotEntry && columnYDataSlotEntry) { columnDataSet.slot("color").overrideLabel(columnYDataSlotEntry.label()); } var lineXDataSlotEntry = lineDataSet.slot("x").entry(); var lineYDataSlotEntry; var lineColorDataSlotEntry; var lineYSlotName = "y"; var lineColorSlotName = "color"; if (this.dataModel.getDescriptor().id() == com_ibm_rave_bundles_compositeBundle_CompositeView.DATAMODEL_SIMPLE) { lineYSlotName += "Line"; lineColorSlotName += "Line"; } lineYDataSlotEntry = lineDataSet.slot(lineYSlotName).entry(); lineColorDataSlotEntry = lineDataSet.slot(lineColorSlotName).entry(); if (!lineColorDataSlotEntry && lineYDataSlotEntry) { lineDataSet.slot(lineColorSlotName).overrideLabel(lineYDataSlotEntry.label()); } if (this.updateType == 0) { this._intervalData = this.makeData(this.dataModel, columnData); this._lineData = com_ibm_rave_bundles_data_LineDataUtilities.buildLines(lineModelData, rave['library']['internal']['AbstractView'].accessorOf(lineXDataSlotEntry), rave['library']['internal']['AbstractView'].domainCheckerOf(lineModelData, lineXDataSlotEntry), rave['library']['internal']['AbstractView'].accessorOf(lineYDataSlotEntry), rave['library']['internal']['AbstractView'].accessorOf(lineColorDataSlotEntry)); this.context.actions.action("deselectAll")(this.context.node.selectAll("." + "element-shape")); } var columnColorPalette = this.getPalette("color.palette.column"); columnColorPalette.setData(columnDataSet, "color"); columnColorPalette.setAccessor(this._columnColorAccessor); columnColorPalette.setNullColor(this.getStringProperty("color.null")); var swap = this.getBooleanProperty("swapLineColumn"); var lineColorPalette = this.getPalette("color.palette.line"); lineColorPalette.setData(lineDataSet, lineColorSlotName); lineColorPalette.setAccessor(com_ibm_rave_bundles_data_LineDataUtilities.GROUP_ACCESSOR); var drawLineOrPoints = this.getStringProperty("lineWithPoints.display"); var drawPoints = ("line_points" == drawLineOrPoints || "points" == drawLineOrPoints); var drawLine = ("line_points" == drawLineOrPoints || "line" == drawLineOrPoints); this.configureLegends(effect, duration, useLineLegend, useColumnLegend, legendPosition, columnColorDataSlotEntry, lineColorDataSlotEntry, columnColorPalette, lineColorPalette, drawPoints); this.doLayout(columnDataSet, lineDataSet, duration, lineModelData, columnXDataSlotEntry, columnYDataSlotEntry, lineXDataSlotEntry, lineYDataSlotEntry, swap); if (this.updateType == 0 && this._independentScale && this.getBooleanProperty("sortX")) { com_ibm_rave_bundles_data_LineDataUtilities.sortLines(this._lineData, this._independentScale); } if (this.updateType == 0) { this._pointData = com_ibm_rave_bundles_data_LineDataUtilities.getLineWithPoints(this._lineData); this._pointNPNData = com_ibm_rave_bundles_data_LineDataUtilities.getNPNPoints(this._lineData); } var elementRect = this._layoutComponent.elementRect(); this._clip.clipRect(elementRect).applyTo(this._chart.select(".content1")).call(this.context.node.select("defs")); this._clip.clipRect(elementRect).applyTo(this._chart.select(".content2")).call(this.context.node.select("defs")); this._chart.select("rect.background.elements").attr("x", elementRect.x).attr("y", elementRect.y).attr("width", elementRect.width).attr("height", elementRect.height); this._legends.rectangle(this._layoutComponent.legendRect()); this.setBackgroundProperties(elementRect, duration); this.configureDataLabels(columnDataSet, columnColorDataSlotEntry); this.drawLinesAndPoints(columnDataSet, lineDataSet, effect, duration, lineColorDataSlotEntry, lineColorSlotName, columnColorPalette, lineColorPalette, drawPoints, drawLine, elementRect); this.drawAxes(duration, columnXDataSlotEntry, columnYDataSlotEntry, lineYDataSlotEntry); this._legends.draw(); this.zoom(swap, elementRect); this.runLabelCollisions(this._chart, elementRect, duration, this.delayFunction(duration, this._independentScale)); this.resetUpdate(); this._chart.selectAll(".element-shape").classed("bundle-shape", true); this._chart.selectAll(".legendShape").classed("bundle-shape", true); }, drawAxes : function(duration, columnXDataSlotEntry, columnYDataSlotEntry, lineYDataSlotEntry) { var stacked100 = "Stacked100" == this.getStringProperty("data.handling"); var subDomainDivisionColumn = columnYDataSlotEntry.subDomainDivision(); var scaleDivisionColumn = subDomainDivisionColumn == null ? null : + (subDomainDivisionColumn); var subDomainDivisionLine = lineYDataSlotEntry.subDomainDivision(); var scaleDivisionLine = subDomainDivisionLine == null ? null : + (subDomainDivisionLine); this._axes.visible(true).duration(duration).useDefaultSelectors().useDefaultX1Properties(true).useDefaultY1Properties(true).useDefaultY2Properties(true).scaleTickMagnitude(2, scaleDivisionColumn).scaleTickMagnitude(3, scaleDivisionLine).setTickFormatterList(0, [columnXDataSlotEntry, columnYDataSlotEntry], "none", null).setTickFormatterList(2, [columnYDataSlotEntry], stacked100 ? "percent" : "none", stacked100 ? com_ibm_rave_bundles_components_AxesManager.percentFormat(0) : null).setTickFormatter(3, lineYDataSlotEntry); this._axes.draw(); }, doLayout : function(columnDataSet, lineDataSet, duration, lineModelData, columnXDataSlotEntry, columnYDataSlotEntry, lineXDataSlotEntry, lineYDataSlotEntry, swap) { var legendPosition; if (this.updateType <= 1) { this._independentScale = this.makeIndependentScale(columnDataSet, lineDataSet); this._intervalDependentScale = this.makeIntervalDependentScale(columnDataSet.slot("y").entry(), this._intervalData); this._lineDependentScale = rave['library']['internal']['ScaleManager'].makeCoordinateScale(lineModelData, lineYDataSlotEntry); var subDomainDivisionColumn = columnYDataSlotEntry.subDomainDivision(); var scaleDivisionColumn = subDomainDivisionColumn == null ? null : + (subDomainDivisionColumn); var subDomainDivisionLine = lineYDataSlotEntry.subDomainDivision(); var scaleDivisionLine = subDomainDivisionLine == null ? null : + (subDomainDivisionLine); this._axes.visible(true).duration(duration).transpose(this._transpose).swapY(swap ^ this._transpose).scale(0, this._independentScale).scale(2, this._intervalDependentScale).scale(3, this._lineDependentScale).scaleTickMagnitude(2, scaleDivisionColumn).scaleTickMagnitude(3, scaleDivisionLine).setDataSlot(0, [columnXDataSlotEntry, lineXDataSlotEntry]).setDataSlot(2, columnYDataSlotEntry).setDataSlot(3, lineYDataSlotEntry).useDefaultSelectors().useDefaultX1Properties(true).useDefaultY1Properties(true).useDefaultY2Properties(true); this.prepareLayoutComponent(); this.prepareLayoutSizables(this._layoutComponent, false, true, true, true, this._legends.anyVisible()); legendPosition = this._layoutComponent.legendPosition(); var isLegendLeftOrRight = "left" == legendPosition || "right" == legendPosition; if (isLegendLeftOrRight) { this._legends.preLayout(this._layoutComponent, false); this._axes.preLayout(this._layoutComponent, false, 0.1, 0.05, 0, 0.1, 0.0, 0); } else { this._axes.preLayout(this._layoutComponent, true, 0.1, 0.05, 0, 0.1, 0.0, 0); this._legends.preLayout(this._layoutComponent, true); } this._layoutComponent.layout(); this._legends.position(legendPosition); this._axes.useBoundsFromLayout(this._layoutComponent).setIndependentScaleRanges(0.1, 0.05, 0).setDependentScaleRanges(0.1, 0.0, 0); if (this._independentScale) { var csize = this.getCSSSizeToPixelNumber("column.size"); this._independentScale.setWidth(csize); this._independentScale.applyWidth(this.getBooleanProperty("column.applysize")); this._independentScale.expandZeroExtent(false); this._independentScale.expandPixels(csize / 2.0 + 1.0, false); if (this.getBooleanProperty("axis.x.scale.nice")) { this._independentScale.nice(); } if (this.getBooleanProperty("axis.x.scale.includeZero")) { this._independentScale.includeZero(); } this.indepScale = this._independentScale.scale().copy(); } var intervalDomainmax = 0.0; if (this._intervalDependentScale) { intervalDomainmax = + (this._intervalDependentScale.scale().domain()[1]); if (this.getBooleanProperty("axis.y.scale.includeZero")) { this._intervalDependentScale.includeZero(); } this._intervalDependentScale.expandZeroExtent(true); if (this.getBooleanProperty("axis.y.scale.nice")) { this._intervalDependentScale.nice(scaleDivisionColumn); } } var lineDomainmax = 0.0; if (this._lineDependentScale) { lineDomainmax = + (this._lineDependentScale.scale().domain()[1]); if (this.getBooleanProperty("axis.y2.scale.includeZero")) { this._lineDependentScale.includeZero(); } this._lineDependentScale.expandZeroExtent(true); if (this.getBooleanProperty("axis.y2.scale.nice")) { this._lineDependentScale.nice(scaleDivisionLine); } } var isLineOnly = "line" == this.getStringProperty("lineWithPoints.display"); var linePadding = isLineOnly ? 2.0 : Math.max(2.0, 2 + Math.sqrt(this.getCSSSizeToPixelNumber("lineWithPoints.size"))); var intervalPadding = 2.0; if (this.getBooleanProperty("data.label.display")) { if (this._lineDependentScale) { var lineNiceScaleDomain = this._lineDependentScale.scale().domain(); var lineRange = this._lineDependentScale.scale().range(); var pixelPerUnit = Math.abs(+ (lineRange[1]) - + (lineRange[0])) / Math.abs(+ (lineNiceScaleDomain[1]) - + (lineNiceScaleDomain[0])); linePadding = 20 - (Math.abs(+ (lineNiceScaleDomain[1]) - lineDomainmax) * pixelPerUnit); } var columnColorDataSlotEntry = columnDataSet.slot("color").entry(); var dataHandling = this.getStringProperty("data.handling"); var isStacked = (columnColorDataSlotEntry) && ("Stacked" == dataHandling || "Stacked100" == dataHandling); if (this._intervalDependentScale && !isStacked) { var intervalNiceScaleDomain = this._intervalDependentScale.scale().domain(); var intervalRange = this._intervalDependentScale.scale().range(); var dependentScaleLengthPx = Math.abs(+ (intervalRange[1]) - + (intervalRange[0])); var intervalPixelPerUnit = dependentScaleLengthPx / Math.abs(+ (intervalNiceScaleDomain[1]) - + (intervalNiceScaleDomain[0])); var paddingNeeded = 20; if (this._transpose && (""+(intervalDomainmax)).length * 12 < dependentScaleLengthPx / 4) { paddingNeeded = (""+(intervalDomainmax)).length * 12; } intervalPadding = paddingNeeded - Math.abs(+ (intervalNiceScaleDomain[1]) - intervalDomainmax) * intervalPixelPerUnit; } } if (this._intervalDependentScale && this._lineDependentScale && this.getBooleanProperty("alignAxes")) { com_ibm_rave_bundles_components_AlignAxisTicksComponent.alignAxisScales(this._intervalDependentScale, this._lineDependentScale); } if (this.isSameDomain() || this.getBooleanProperty("alignAxes")) { this._intervalDependentScale.expandPixels(Math.max(linePadding, intervalPadding), true); this._lineDependentScale.expandPixels(Math.max(linePadding, intervalPadding), true); } else { if (this._intervalDependentScale) { this._intervalDependentScale.expandPixels(intervalPadding, true); } if (this._lineDependentScale) { this._lineDependentScale.expandPixels(linePadding, true); } } if (this._intervalDependentScale) { this.intervalScale = this._intervalDependentScale.scale().copy(); } if (this._lineDependentScale) { this.lineScale = this._lineDependentScale.scale().copy(); } this.resetZoom(); } }, isSameDomain : function() { if ((!this._intervalDependentScale) || (!this._lineDependentScale)) { return false; } var y1Domain = this._intervalDependentScale.scale().domain(); var y1Min = Math.floor(+ (y1Domain[0])); var y1Max = Math.ceil(+ (y1Domain[1])); var y2Domain = this._lineDependentScale.scale().domain(); var y2Min = Math.floor(+ (y2Domain[0])); var y2Max = Math.ceil(+ (y2Domain[1])); var minDifferent = (y1Min < y2Min) || (y1Min > y2Min); var maxDifferent = (y1Max < y2Max) || (y1Max > y2Max); return (minDifferent || maxDifferent) ? false : true; }, zoom : function(swap, elementRect) { if (this.updateType <= 2) { var ops = this.getStringProperty("zoom"); if (this._independentScale && (ops == "all" || ops == "x")) { (this._independentScale.scale()).domain(this.indepScale.domain()); } if (this._intervalDependentScale && (ops == "all" || ops == "y")) { (this._intervalDependentScale.scale()).domain(this.intervalScale.domain()); } if (this._lineDependentScale && (ops == "all" || ops == "y2")) { (this._lineDependentScale.scale()).domain(this.lineScale.domain()); } var xScale = this._transpose ? (swap ? this._lineDependentScale : this._intervalDependentScale) : this._independentScale; var x2Scale = this._transpose ? (swap ? this._intervalDependentScale : this._lineDependentScale) : null; var yScale = this._transpose ? this._independentScale : (swap ? this._lineDependentScale : this._intervalDependentScale); var y2Scale = this._transpose ? null : this._lineDependentScale; var self = this; var zoom = this.context.actions.action("zoom").get("zoom"); com_ibm_rave_bundles_components_ComponentConfiguration.configureZoom(this._chart, zoom, xScale, yScale, x2Scale, y2Scale, null, elementRect, this._zoomP, this._zoomS, this.convertZoomOps(swap), function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { self._chart.selectAll("g.element-column").call(self._intervalComponent); self._chart.selectAll("g.element-line").call(self._lineComponent); if (self._pointComponent) { self._chart.selectAll("g.element-point").call(self._pointComponent); } self._axes.redraw(true); self._chart.call(self._labelCollisionComponent); return self._chart; } }); zoom.on("zoomend.hideLabels", function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { if (self._axes.hideAnyPanZoom()) { if (self.zoomendedTimer != null) { clearTimeout(self.zoomendedTimer); } self.zoomendedTimer = setTimeout(function() { self.zoomendedTimer = null; self._axes.redraw(false); self._chart.call(self._labelCollisionComponent); }, 300); } return null; } }); } }, drawLinesAndPoints : function(columnDataSet, lineDataSet, effect, duration, lineColorDataSlotEntry, lineColorSlotName, columnColorPalette, lineColorPalette, drawPoints, drawLine, elementRect) { this._intervalComponent.data(this._intervalData).key(rave['library']['internal']['AbstractView'].originalDatumAccessor(rave['library']['internal']['AbstractView'].accessorOf(columnDataSet.slot("key").entry()))).independentScale(this._independentScale).dependentScale(this._intervalDependentScale).transpose(this._transpose).colorPalette(columnColorPalette).delay(this.delayFunction(duration, this._independentScale)).setPreExecute(this.context.getPreExecute()).borderWidth(this.context.convertCSSSizeToPixels(this.context.getPropertyValue("column.borderWidth"))).borderColor((this.context.getPropertyValue("column.borderColor"))).bounds(this._layoutComponent.elementRect()); this._chart.selectAll("g.element-column").transition("transition").duration(duration).call(this._intervalComponent); var lineKeyDataSlotEntry = lineDataSet.slot("key").entry(); if (drawLine) { this._lineComponent.data(this._lineData); } else { this._lineComponent.data(null); } var showMissingAsGap = this.getBooleanProperty("lineWithPoints.showMissingAsGap"); this._lineComponent.key(rave['library']['internal']['AbstractView'].originalDatumAccessor(rave['library']['internal']['AbstractView'].accessorOf(lineKeyDataSlotEntry))).independentScale(this._independentScale).dependentScale(this._lineDependentScale).transpose(this._transpose).colorPalette(lineColorPalette).effect(effect).showMissingAsGap(showMissingAsGap).setPreExecute(this.context.getPreExecute()).interpolate(this.getStringProperty("lineWithPoints.interpolate")); this._chart.selectAll("g.element-line").transition("transition").duration(duration).call(this._lineComponent); if (drawPoints || this.isShowDataLabels()) { this._pointComponent.data(this._pointData); } else { this._pointComponent.data(showMissingAsGap ? this._pointNPNData : null); } this.configureLineDataLabels(lineDataSet); var pointsColorPalette = this.getPalette("color.palette.line"); pointsColorPalette.setData(lineDataSet, lineColorSlotName); pointsColorPalette.setAccessor(rave['library']['internal']['AbstractView'].originalDatumAccessor(rave['library']['internal']['AbstractView'].accessorOf(lineColorDataSlotEntry))); this._pointComponent.key(rave['library']['internal']['AbstractView'].originalDatumAccessor(rave['library']['internal']['AbstractView'].accessorOf(lineKeyDataSlotEntry))).bounds(elementRect).independentScale(this._independentScale).dependentScale(this._lineDependentScale).colorPalette(pointsColorPalette).labelContrast(this.getBooleanProperty("contrast.label.color")).labelShadow(this.getBooleanProperty("label.shadow")).transpose(this._transpose).effect(effect).setPreExecute(this.context.getPreExecute()).defaultSize(this.getCSSSizeToPixelNumber("lineWithPoints.size")).symbol(drawPoints ? this.getStringProperty("lineWithPoints.symbol") : null).itemOverlap(false); this._chart.selectAll("g.element-point").transition("transition").duration(duration).call(this._pointComponent); }, configureLegends : function(effect, duration, useLineLegend, useColumnLegend, legendPosition, columnColorDataSlotEntry, lineColorDataSlotEntry, columnColorPalette, lineColorPalette, drawPoints) { var lineTitleString = (this.context.getPropertyValue("legend.line.titlestyle.font")); if (lineTitleString != null) { this._legends.titleFont(0, lineTitleString); } var lineEntryString = (this.context.getPropertyValue("legend.line.entrystyle.font")); if (lineEntryString != null) { this._legends.entryFont(0, lineEntryString); } var columnTitleString = (this.context.getPropertyValue("legend.column.titlestyle.font")); if (columnTitleString != null) { this._legends.titleFont(1, columnTitleString); } var columnEntryString = (this.context.getPropertyValue("legend.column.entrystyle.font")); if (columnEntryString != null) { this._legends.entryFont(1, columnEntryString); } this._legends.position(legendPosition).transition(!("none" == effect), duration).setPreExecute(this.context.getPreExecute()).visible(0, useLineLegend).selector(0, this.context.node.selectAll("g.legend.line")).palette(0, lineColorPalette).shape(0, drawPoints ? this.getStringProperty("lineWithPoints.symbol") : "compositeViewLegendLineSymbol").title(0, this.context.getDataSlotLabel("legend.line.title", lineColorDataSlotEntry)).titleFill(0, (this.context.getPropertyValue("legend.line.titlestyle.fill"))).titleFontSize(0, (this.context.getPropertyValue("legend.line.titlestyle.fontsize"))).titleFontFamily(0, (this.context.getPropertyValue("legend.line.titlestyle.fontfamily"))).setDataSlot(0, lineColorDataSlotEntry).visible(1, useColumnLegend).selector(1, this.context.node.selectAll("g.legend.column")).palette(1, columnColorPalette).shape(1, "square").title(1, this.context.getDataSlotLabel("legend.column.title", columnColorDataSlotEntry)).titleFill(1, (this.context.getPropertyValue("legend.column.titlestyle.fill"))).titleFontSize(1, (this.context.getPropertyValue("legend.column.titlestyle.fontsize"))).titleFontFamily(1, (this.context.getPropertyValue("legend.column.titlestyle.fontfamily"))).setDataSlot(1, columnColorDataSlotEntry); }, /** * Check if the X accessors of the two data sets have the same type, and if not report an error and return false. The model has already been validated, so the accessors are non-null. * @param dataModel Data model to be checked * @return (boolean) True if X accessors are the same type, false otherwise */ compatibleDomains : function(columnDataSet, lineDataSet) { var columnDataSlotEntry = columnDataSet.slot("x").entry(); var lineDataSlotEntry = lineDataSet.slot("x").entry(); if (columnDataSlotEntry && lineDataSlotEntry && !(columnDataSlotEntry.type() == lineDataSlotEntry.type())) { com_ibm_rave_library_Library.logError(101, "The column bundle X accessors must be the same type"); return false; } return true; }, /** * Create the independent scale. This combines the X domains from the column and line data sets. The X accessors are known to be of the same type. TODO: Domain classes, with a merge function. * @return (rave['library']['internal']['CoordinateScaleImpl']) Coordinate scale for the independent values */ makeIndependentScale : function(columnDataSet, lineDataSet) { var columnData = (columnDataSet.data()); var lineData = (lineDataSet.data()); var columnXAccessor = columnDataSet.slot("x").entry(); var lineXAccessor = lineDataSet.slot("x").entry(); if (!columnXAccessor || !lineXAccessor) { return null; } var columnScale = rave['library']['internal']['ScaleManager'].makeCoordinateScale(columnData, columnXAccessor); var lineScale = rave['library']['internal']['ScaleManager'].makeCoordinateScale(lineData, lineXAccessor); var isClustered = "Clustered" == this.getStringProperty("data.handling"); if (isClustered || "string" == columnXAccessor.type()) { var intervalDomain = (rave['library']['internal']['ScaleManager'].ordinalDomain(columnData, columnXAccessor)); var lineDomain = (rave['library']['internal']['ScaleManager'].ordinalDomain(lineData, lineXAccessor)); var uniqueValues = []; var originalDomainMap = rave['internal']['ES6Map'].create(); if (intervalDomain) { for (var __i_enFor0 = 0, __exp_enFor0 = intervalDomain, __len_enFor0 = __exp_enFor0.length; __i_enFor0 < __len_enFor0; ++__i_enFor0) { var v = __exp_enFor0[__i_enFor0]; if (v != null) { var datum = originalDomainMap.get(v); if (!datum) { uniqueValues.push(v); datum = originalDomainMap.set(v, new rave['library']['internal']['OrdinalCoordinateScaleDatum'](v)); } } } } if (lineDomain) { for (var __i_enFor1 = 0, __exp_enFor1 = lineDomain, __len_enFor1 = __exp_enFor1.length; __i_enFor1 < __len_enFor1; ++__i_enFor1) { var v = __exp_enFor1[__i_enFor1]; if (v != null) { var datum = originalDomainMap.get(v); if (!datum) { uniqueValues.push(v); datum = originalDomainMap.set(v, new rave['library']['internal']['OrdinalCoordinateScaleDatum'](v)); } } } } for (var __i_enFor2 = 0, __exp_enFor2 = columnData, __len_enFor2 = __exp_enFor2.length; __i_enFor2 < __len_enFor2; ++__i_enFor2) { var o = __exp_enFor2[__i_enFor2]; var key = columnXAccessor(o); var datum = originalDomainMap.get(key); if (datum) { datum.push(o); } } for (var __i_enFor3 = 0, __exp_enFor3 = lineData, __len_enFor3 = __exp_enFor3.length; __i_enFor3 < __len_enFor3; ++__i_enFor3) { var o = __exp_enFor3[__i_enFor3]; var key = lineXAccessor(o); var datum = originalDomainMap.get(key); if (datum) { datum.push(o); } } var originalDomain = []; for (var __i_enFor4 = 0, __exp_enFor4 = uniqueValues, __len_enFor4 = __exp_enFor4.length; __i_enFor4 < __len_enFor4; ++__i_enFor4) { var d = __exp_enFor4[__i_enFor4]; originalDomain.push(originalDomainMap.get(d)); } if (isClustered) { var colorAccessor = columnDataSet.slot("color").entry(); var domains = []; domains.push(uniqueValues); domains.push(rave['library']['internal']['ScaleManager'].ordinalDomain(columnData, colorAccessor)); columnScale = rave['library']['internal']['ClusteredCoordinateScale'].create(domains, originalDomain); } else { columnScale = rave['library']['internal']['OrdinalCoordinateScale'].create(uniqueValues, originalDomain); } } else { var intervalDomain = columnScale.scale().domain(); var lineDomain = lineScale.scale().domain(); if (intervalDomain.length == 0 && !lineDomain) { return null; } var domain; if (intervalDomain.length == 0 && lineDomain) { domain = (lineDomain); } else if (!lineDomain && intervalDomain.length > 0) { domain = (intervalDomain); } else { domain = [rave.min([intervalDomain[0], lineDomain[0]]), rave.max([intervalDomain[1], lineDomain[1]])]; } var type = lineXAccessor.type(); if ("numeric" == type) { columnScale = rave['library']['internal']['LinearCoordinateScale'].create(domain); } else { columnScale = rave['library']['internal']['TimeCoordinateScale'].create(domain); } } if (columnScale) { columnScale.originalDomainLabelAccessor(function(data, index, groupIndex) { var key = (data).key(); return ""+(key); }); } return columnScale; }, /** * Create the dependent scale from the data values. The scale range includes all dep1 and dep2 values in the array. It also includes 0 and is padded by 2 pixels to avoid clipping. * @param (Array) data Data array * @return (rave['library']['internal']['CoordinateScaleImpl']) Coordinate scale for the range of values */ makeIntervalDependentScale : function(columnYDataSlotEntry, data) { var domain = columnYDataSlotEntry.domain(); if (domain) { return rave['library']['internal']['LinearCoordinateScale'].create(domain); } var omax = rave.max(data, function(data, ix, gix) { var dep1 = + (((data).dep1)); var dep2 = + (((data).dep2)); return dep1 != 0 ? Math.max(dep1, dep2) : dep2; }); if (omax == null) { return null; } var omin = rave.min(data, function(data, ix, gix) { var dep1 = + (((data).dep1)); var dep2 = + (((data).dep2)); return dep1 != 0 ? Math.min(dep1, dep2) : dep2; }); var scale = rave['library']['internal']['LinearCoordinateScale'].create([omin, omax]); return scale; }, /** @expose */ getCoordinateScale : function(role) { if ("ROLE_X1" == role) { return this._independentScale; } if ("ROLE_Y1" == role) { return this._intervalDependentScale; } if ("ROLE_Y2" == role) { return this._lineDependentScale; } return null; }, /** * Corrects the zoom operation for transpose and switch. This adjusts the operation so that no matter the setting for transpose and switch, the original axis corresponding to the setting will be the one that is zoomed, not the axis currently occupying that position. * @param (boolean) swap true if we are swapping the dependent axes * @return (String) the proper zoom code */ convertZoomOps : function(swap) { var zoom = this.getStringProperty("zoom"); if (this._transpose) { if ("x" == zoom) { zoom = "y"; } else if ("y" == zoom) { if (swap) { zoom = "x2"; } else { zoom = "x"; } } else if ("y2" == zoom) { if (swap) { zoom = "x"; } else { zoom = "x2"; } } } return zoom; }, /** * When the delay option is true, the transition of a bar is delayed by a fraction of the duration based on the bar's ordinal scale value. * @param (int) duration * @param (rave['library']['internal']['CoordinateScaleImpl']) independentScale * @return (rave['internal']['ValueFunction']) */ delayFunction : function(duration, independentScale) { if (duration > 0 && independentScale && this.getBooleanProperty("effect.delay")) { var range = independentScale.scale().range(); if (range && range.length > 1) { var rmin = (+ (range[0])); var rmax = (+ (range[range.length - 1])); if (rmin != rmax) { var scaling = duration / (rmax - rmin); return function(data, index, groupIndex) { return (+ (independentScale.center((data).ind1)) - rmin) * scaling; }; } } } return null; }, /** @expose */ requireUpdate : function(property) { if (property == "axis.y2.title.text" && !(this.getBooleanProperty("axis.y2.title.display"))) { return 4; } if (property == "legend.title.column" && !(this.isShowLegend())) { return 4; } if (property == "legend.title.line" && !(this.isShowLegend())) { return 4; } if (property == "swapLineColumn") { return 1; } return rave['library']['internal']['AbstractView'].prototype.requireUpdate.call(this, property); }, /** * Set up all actions, taking into account the settings for the border width and color. */ /** @expose */ setActionsWithBorder : function() { var self = this; var borderWidth = this.context.convertCSSSizeToPixels(this.context.getPropertyValue("column.borderWidth")); var v = this.getProperty("column.borderColor"); var borderColor = v == null ? null : ""+(v); var style = {}; style["stroke-width"] = borderWidth; style["stroke"] = borderColor; var highlightAction = this.context.actions.action("highlight"); var unhighlightAction = this.context.actions.action("unhighlight"); var deselectAllAction = this.context.actions.action("deselectAll"); var lineHighlightEventListener = function(data, index, groupIndex, event) { if (this.rave_getParentNode().rave_containsClass("element-line") && this.rave_containsClass("element-shape")) { rave.select(this).style("stroke-width", 4); } else { highlightAction(rave.select(this)); } }; highlightAction.setBindFn(rave['library']['internal']['BundleUtils'].bindOrUnbindActionFunctionCreater(this.context, ".element-point .element-shape, .element-line .element-shape, .element-column .element-shape", ["mouseenter.default"], lineHighlightEventListener)); var unhighlightEventListener = function(data, index, groupIndex, event) { if (this.rave_getParentNode().rave_containsClass("element-line") && this.rave_containsClass("element-shape")) { rave.select(this).style("stroke-width", 2); } else if (this.rave_getParentNode().rave_containsClass("element-point") && this.rave_containsClass("element-shape")) { rave.select(this).style("stroke-width", 0); } else if (this.rave_getParentNode().rave_getParentNode().rave_containsClass("element-column") && this.rave_containsClass("element-shape")) { highlightAction(rave.select(this), style); } }; unhighlightAction.setBindFn(rave['library']['internal']['BundleUtils'].bindOrUnbindActionFunctionCreater(this.context, ".element-point .element-shape, .element-line .element-shape, .element-column .element-shape", ["mouseout.default"], unhighlightEventListener)); var deselectAllEventListener = function(data, index, groupIndex, event) { self.context.node.selectAll(".element-point .element-shape").style("stroke-width", 0).style("opacity", 1).property("selected", null); self.context.node.selectAll(".element-line .element-shape").style("stroke-width", 2).style("opacity", 1).property("selected", null); self.context.node.selectAll(".element-column .element-shape").style(style).style("opacity", 1).property("selected", null); }; deselectAllAction.setBindFn(rave['library']['internal']['BundleUtils'].bindOrUnbindActionFunctionCreater(this.context, ".background", ["click.default", "touchstart.default"], deselectAllEventListener)); }, /** @expose */ configureLineDataLabels : function(dataSet) { if (!(this.isShowDataLabels())) { this._pointComponent.itemLabel(false); this._pointComponent.itemLabelPosition(null); this._pointComponent.labelFont(null); this._pointComponent.labelAccessor(null); this._pointComponent.labelFormatter(null); return; } var self = this; var dataLabelPosition = function(data, index, groupIndex) { var currentData = data; var prevData = (index == 0) ? null : self._pointData[index - 1]; var nextData = (index == self._pointData.length - 1) ? null : self._pointData[index + 1]; if (!prevData || !nextData) { return 0; } var angleWithPreviousPoint = Math.atan2(self._lineDependentScale.center(prevData._y) - self._lineDependentScale.center(currentData._y), self._independentScale.center(prevData._x) - self._independentScale.center(currentData._x)); var angleWithNextPoint = Math.atan2(self._lineDependentScale.center(nextData._y) - self._lineDependentScale.center(currentData._y), self._independentScale.center(nextData._x) - self._independentScale.center(currentData._x)); if (angleWithNextPoint <= 0 && angleWithPreviousPoint <= 0) { return 2; } if ((angleWithNextPoint >= 0 && angleWithPreviousPoint >= 0) || ((180 - Math.abs(angleWithPreviousPoint * (180 / Math.PI)) < 30) && Math.abs(angleWithNextPoint * (180 / Math.PI)) < 30)) { return 0; } if (180 - Math.abs(angleWithPreviousPoint * (180 / Math.PI)) > 30) { return 3; } return 4; }; var labelAccessor = this.getlDataLabelAccessor(dataSet, "label", false); var labelEntry = this.getEntryForDataLabelFormatter(dataSet, "label", "y"); this._pointComponent.itemLabel(true); this._pointComponent.labelFont(this.getBackgroundConstrastLabelStyle()); this._pointComponent.labelFormatter(this.context.getCustomFormatterForElementLabels(labelEntry, (dataSet.slot("label").entry()) ? "ROLE_NONE" : "ROLE_Y2")); this._pointComponent.labelAccessor(labelAccessor); this._pointComponent.itemLabelPosition(dataLabelPosition); }, /** * Start a Rave timer with a delay of half the transition duration and a start time of the current time plus the duration. If there are no staggered transitions, (that is, no delay function) this should trigger the label collisions to begin as soon as the ordinary transitions end, after the duration. If there are staggered transitions, we have to wait double the transition time. In this way the label collisions will never fire until all the transitions are complete, and the labels will have settled into their target positions and be ready for collision resolution. Note that this delay will occur even when there are no visible transitions--there is no way to tell whether we are doing a full redraw, or a minor property update. * @param (rave['internal']['Selector']) chart the entire chart * @param (rave['internal']['RectStruct']) chartRect the center rectangle for the chart area, without axes or legends * @param (Object) delayFunction if null, there are no staggered transitions */ /** @expose */ runLabelCollisions : function(chart, chartRect, duration, delayFunction) { if (!(this.isShowDataLabels())) { return; } var self = this; var staggeredTransitions = delayFunction == null ? false : true; this._pendingLabelTimer = true; var labelCollideCallback = function(elapsed) { if (self._cancelLabelTimers > 0) { self._cancelLabelTimers--; return true; } self._labelCollisionComponent.bounds(chartRect).numberOfSweeps(1000).labelResolution("Drop Labels"); chart.call(self._labelCollisionComponent); self._pendingLabelTimer = false; return true; }; if (staggeredTransitions) { rave.timer(labelCollideCallback, duration * 2.0); } else { rave.timer(labelCollideCallback, duration); } }, /** * If at least one label collision request is pending we stop the label collision component, and shut down the label collision timer event. */ /** @expose */ stopLabelCollisions : function() { this._labelCollisionComponent.labelResolution("none"); if (this._pendingLabelTimer) { this._cancelLabelTimers++; } }, /** @expose */ getGroupStructure : function() { return ["defs", "g.vizlibrary vizlibrary-composite", "(", "rect.background chart", "g.chart", "(", "rect.background elements", "g.gridlines", "(", "g.grid left", "g.grid right", "g.grid top", "g.grid bottom", ")", "g.content1", "(", "g.element-column", "(", "g.element-group", "g.element-label-group", ")", ")", "g.axes", "(", "g.axes-layout", "g.axisTransform left", "g.axisTransform right", "g.axisTransform top", "g.axisTransform bottom", ")", "g.content2", "(", "g.elements2", "(", "g.element-group element-line", "g.element-point", "(", "g.element-group", "g.element-label-group", ")", ")", ")", "g.axis-callout", ")", "g.legends", "(", "g.legends-layout", "g.legend line", "g.legend column", ")", ")"]; } }); com_ibm_rave_bundles_compositeBundle_CompositeView.SCALE_PADDING = 2.0; //com_ibm_rave_bundles_compositeBundle_CompositeView.DATASET_COLUMNDATA = "column"; //com_ibm_rave_bundles_compositeBundle_CompositeView.DATASET_LINEDATA = "line"; //com_ibm_rave_bundles_compositeBundle_CompositeView.DATASLOT_GROUP = "color"; //com_ibm_rave_bundles_compositeBundle_CompositeView.DATASLOT_KEY = "key"; /** * CSS class for shapes inside an element. */ //com_ibm_rave_bundles_compositeBundle_CompositeView.ELEMENT_SHAPE_CLASSES = "element-shape"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LINE_WITH_POINTS_SYMBOL = "lineWithPoints.symbol"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LINE_OR_POINTS_DISPLAY = "lineWithPoints.display"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LINE_DISPLAY = "line"; //com_ibm_rave_bundles_compositeBundle_CompositeView.POINTS_DISPLAY = "points"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LINE_WITH_POINTS_DISPLAY = "line_points"; //com_ibm_rave_bundles_compositeBundle_CompositeView.COLUMN_BORDER_WIDTH = "column.border.width"; //com_ibm_rave_bundles_compositeBundle_CompositeView.COLUMN_BORDER_COLOR = "column.border.color"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LINE_WITH_POINTS_SIZE = "lineWithPoints.size"; //com_ibm_rave_bundles_compositeBundle_CompositeView.COLOR_PALLETTE_COLUMN = "color.palette.column"; //com_ibm_rave_bundles_compositeBundle_CompositeView.COLOR_PALLETTE_LINE = "color.palette.line"; //com_ibm_rave_bundles_compositeBundle_CompositeView.AXIS_LINE_COLUMN_SWAP = "swapLineColumn"; /** @expose */ com_ibm_rave_bundles_compositeBundle_CompositeView.GRID_ALIGN_DEPENDENT_AXES = "alignAxes"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LINE_INTERPOLATE_PROPERTY = "lineWithPoints.interpolate"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LINE_MISSING_AS_GAP_PROPERTY = "lineWithPoints.showMissingAsGap"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_LINE_DISPLAY = "legend.line.display"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_LINE_TITLE = "legend.line.title"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_LINE_TITLESTYLE_FONT = "legend.line.titlestyle.font"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_LINE_ENTRYSTYLE_FONT = "legend.line.entrystyle.font"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_LINE_TITLESTYLE_FILL = "legend.line.titlestyle.fill"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_LINE_TITLESTYLE_FONTSIZE = "legend.line.titlestyle.fontsize"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_LINE_TITLESTYLE_FONTFAMILY = "legend.line.titlestyle.fontfamily"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_COLUMN_DISPLAY = "legend.column.display"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_COLUMN_TITLE = "legend.column.title"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_COLUMN_TITLESTYLE_FONT = "legend.column.titlestyle.font"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_COLUMN_ENTRYSTYLE_FONT = "legend.column.entrystyle.font"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_COLUMN_TITLESTYLE_FILL = "legend.column.titlestyle.fill"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_COLUMN_TITLESTYLE_FONTSIZE = "legend.column.titlestyle.fontsize"; //com_ibm_rave_bundles_compositeBundle_CompositeView.LEGEND_COLUMN_TITLESTYLE_FONTFAMILY = "legend.column.titlestyle.fontfamily"; com_ibm_rave_bundles_compositeBundle_CompositeView.DATASET_COMPOSITE = "composite"; com_ibm_rave_bundles_compositeBundle_CompositeView.DATAMODEL_SIMPLE = "simple"; // $source: com/ibm/rave/bundles/components/BackgroundComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/BundleComponentImpl (loadtime) // superclass //@import com/ibm/rave/bundles/component/BackgroundComponent (runtime) // BackgroundComponent /** *Component to set the background color of a bundle. The component properties are:
The component assumes that the selector on which it is executed is a "rect" shape which lies below the chart. If the size property is non-null, it sets the geometry of this rectangle to be the given size, with upper-left corner at 0,0. If the size is null, the rectangle is not resized.
The rectangle fill is set to the backgroundColor property. If the property is null, white (#FFFFFF) is used. TODO. Should we set it to null, so the CSS style can also be used to set the background?
*/ var com_ibm_rave_bundles_components_BackgroundComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_BundleComponentImpl, { //_backgroundColor : null, //_rect : null, /** @expose */ constructor : function() { this._rect = new rave['internal']['RectStruct'](0, 0, 0, 0); }, /** @expose */ execute : function(g) { this.preExecute(); g.style("fill", this._backgroundColor != null ? this._backgroundColor : "#FFFFFF").style("fill-opacity", 1.0); g.attr("x", this._rect.x).attr("y", this._rect.y).attr("width", this._rect.width).attr("height", this._rect.height); }, /** @expose */ type : function() { return com_ibm_rave_bundles_component_BackgroundComponent.COMPONENT_TYPE; }, backgroundColor$0 : function() { return this._backgroundColor; }, backgroundColor$1 : function(backgroundColor) { this._backgroundColor = backgroundColor; return this; }, /** * @param (rave['library']['internal']['ContextSize']) size New value of size property * @return (com.ibm.rave.bundles.components.BackgroundComponentImpl) This component */ /** @expose */ size : function(size) { this._rect.x = 0; this._rect.y = 0; this._rect.width = size.w; this._rect.height = size.h; return this; }, /** @expose */ rect : function(rect) { var r = new rave['internal']['RectStruct'](rect.x, rect.y, rect.width, rect.height); this._rect = r; return this; }, /** @expose */ backgroundColor : function(a0) { var args = arguments; if (args.length == 0) { return this.backgroundColor$0(); } return this.backgroundColor$1(a0); } }); // $source: com/ibm/rave/bundles/components/ChartLayoutComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/BundleComponentImpl (loadtime) // superclass //@import com/ibm/rave/bundles/component/ChartLayoutComponent (runtime) // ChartLayoutComponent /** *Implementation of the chart layout component API. General sequence in a bundle view:
_clip.clipRect(new RectStruct(50, 50, 200, 200)) // Set the clipping rectangle .applyTo(chart.select(".content")) // Apply the clip-path attribute to a graphical element. This can be called repeatedly on different selections. .applyTo(chart.select(".otherContent")) .run(context.node.select("defs")); // ClipPathComponent creates a clipPath element within the provided node. This component should be executed on a single "defs" node, however there is no restriction.*/ var com_ibm_rave_bundles_components_ClipPathComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_BundleComponentImpl, { //_id : null, //_clipRect : null, constructor : function(id) { this._clipRect = new rave['internal']['RectStruct'](0, 0, 100, 100); /** * Initializes the component. The provided id will be used as the "id" attribute for the clipPath element created by this component. Recall that an "id" in an SVG/HTML document must be unique across the entire document. If you create multiple clipPath elements with the same id, then all elements referencing one of these clip paths will not be resolved as you expected. * @param (String) id String ID that is unique across the document. */ { this._id = id; } }, /** @expose */ type : function() { return "ClipPathComponent"; }, /** * Set the rectangular clipping area. Make the _clipRect one pixel larger than requested to avoid the cut-off at bounds. TODO: why?!? * @param (rave['internal']['RectStruct']) rect The rectangular bounds of the clipping area. * @return (com.ibm.rave.bundles.components.ClipPathComponentImpl) This ClipPathComponent. */ /** @expose */ clipRect : function(rect) { this._clipRect = new rave['internal']['RectStruct'](rect.x - 1, rect.y - 1, rect.width + 2, rect.height + 2); return this; }, /** * Set the clip-path attribute on the provided selection. * @return (com.ibm.rave.bundles.components.ClipPathComponentImpl) This ClipPathComponent. */ /** @expose */ applyTo : function(s) { s.attr("clip-path", "url(" + this.url() + ")"); return this; }, /** * Retrieve the id assigned to this clip path. */ /** @expose */ id : function() { return this._id; }, /** * Retrieve the URL that can be used to reference this clip path. */ /** @expose */ url : function() { return "#" + this._id; }, /** @expose */ execute : function(g) { var clipPath = g.selectAll("#" + this._id).data([0]); clipPath.enter().append("clipPath").attr("id", this._id).append("rect"); rave.transition(clipPath.select("rect")).attr("x", this._clipRect.x).attr("y", this._clipRect.y).attr("width", this._clipRect.width).attr("height", this._clipRect.height); } }); // $source: com/ibm/rave/bundles/components/LegendComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/BundleComponentImpl (loadtime) // superclass //@import com/ibm/rave/bundles/utilities/FontPropertyParser (runtime) // parseCSSFont /** *
A component to draw a legend, using a RAVE capability swatch legend. In JavaScript the RAVE legend and layout extensions must be loaded. The legend puts its shapes into the selector passed to its execute method, so that selector should choose a group node.
Most of the component properties are passed directly to the RAVE legend. The properties are:
visible: If true, the legend is drawn; otherwise it is cleared (all shapes are removed from the legend). The default is true.
size: A Dim with the size of the legend in the chart coordinate system. If null or zero-sized, the legend is cleared. This is passed to the swatch legend.
colorScale: A scale (OrdinalScale) used as the RAVE legend scale. If null, the legend is cleared. The legend currently only supports a single ordinal color scale.
orient: The RAVE legend orient, either "horizontal" or "vertical". The default is "vertical".
swatchSize: The RAVE legend size. Note that this is in square pixels. The default is 20*20.
shape: The RAVE legend shape. The default is "square".
title: The RAVE legend title. The default is null.
titleFill: The legend title color. The default is null.
titleFontSize: The legend title font size. The default is null.
titleFontFamily: The legend title font family. The default is null.
borderColor: The RAVE legend borderColor. The default is "black".
labelFormat: The RAVE legend labelFormat. The default is null.
*/ var com_ibm_rave_bundles_components_LegendComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_BundleComponentImpl, { /** * Legend size property */ //_size : null, /** * Color scale */ //_colorPalette : null, /** * Orient, "horizontal" or "vertical" */ //_orient : null, /** * Swatch size function */ //_swatchSizeFunc : null, /** * Scale */ //_scale : null, /** * Swatch symbol */ //_shape : null, /** * Legend title */ //_title : null, /** * Legend title styling */ //_titleStyle : null, /** * Legend entry styling */ //_entryStyle : null, /** * Custom formatter */ //_labelFormat : null, /** * The swatch legend, created on demand */ //_swatchLegend : null, /** * The continuous legend, created on demand */ //_continuousLegend : null, /** * The legend type, either "SwatchLegend" or "ContinuousLegend" */ //_legendType : null, /** * Is the legend visible */ _visible : false, /** * Swatch size in square pixels */ _swatchSize : 0, /** * Constructor; sets bound and, colorScale to null, all other properties to their default values. */ /** @expose */ constructor : function() { this._visible = true; this._size = null; this._colorPalette = null; this._orient = "horizontal"; this._swatchSize = 16.0 * 16.0; this._swatchSizeFunc = null; this._scale = null; this._shape = "square"; this._title = null; this._titleStyle = {}; this._entryStyle = {}; this._labelFormat = null; this._swatchLegend = null; this._continuousLegend = null; this._legendType = null; }, /** @expose */ type : function() { return "LegendComponent"; }, /** @expose */ execute : function(g) { if (this._colorPalette) { if ("continuous" == this._colorPalette.getType()) { if (!this._continuousLegend) { this._continuousLegend = (rave.capabilities.extension("legend")).continuous(); } this._legendType = "ContinuousLegend"; } else { if (!this._swatchLegend) { this._swatchLegend = (rave.capabilities.extension("legend")).swatch(); } this._legendType = "SwatchLegend"; } } else if (this._swatchSizeFunc) { if (!this._swatchLegend) { this._swatchLegend = (rave.capabilities.extension("legend")).swatch(); } this._legendType = "SwatchLegend"; } else { this._legendType = null; } this.preExecute(); if (!this._visible || (!this._colorPalette && !this._swatchSizeFunc) || !this._size || this._size[0] <= 0 || this._size[1] <= 0) { g.selectAll("*").remove(); return; } var fontChecker = rave.capabilities.extension("fontchecker"); if (this._colorPalette && "continuous" == this._colorPalette.getType()) { this._continuousLegend.shapeRectSize("horizontal" == this._orient ? [-1.0, 16.0] : [16.0, -1.0]).size(this._size).scale(this._colorPalette.getScale()).orient(this._orient).title(this._title).titleFill(this._titleStyle["fill"]).titleFontSize(this._titleStyle["font-size"]).titleFontFamily(this._titleStyle["font-Family"]).titleAlignment("start").labelFormat(this._labelFormat); var legend = g.call(this._continuousLegend); if (this._entryStyle) { legend.selectAll(".legendLabel").style(this._entryStyle); } if (this._titleStyle) { legend.selectAll(".legendTitle").style(this._titleStyle); } if (fontChecker) { legend.selectAll(".legendLabel").call(fontChecker); legend.selectAll(".legendTitle").call(fontChecker); } } else { var insets = {}; insets["bottom"] = 5; var swatchSize = this._swatchSize; var scale = null; var labelFormatter = this._labelFormat; if (this._swatchSizeFunc && this._scale) { swatchSize = this._swatchSizeFunc; scale = this._scale; } if (this._colorPalette) { scale = this._colorPalette.getScale(); var originalDomain = this._colorPalette.originalDomain(); if (originalDomain) { scale.domain(originalDomain); var f = this._colorPalette.originalDomainLabelAccessor(); if (this._labelFormat) { var self = this; labelFormatter = function(data, index, groupIndex) { return self._labelFormat.call(this, f.call(this, data, index, groupIndex), index, groupIndex); }; } else { labelFormatter = f; } } } this._swatchLegend.labelPadding(8).size(this._size).scale(scale).orient(this._orient).swatchSize(swatchSize).shape(this._shape).title(this._title).titleFill(this._titleStyle["fill"]).titleFontSize(this._titleStyle["font-size"]).titleFontFamily(this._titleStyle["font-family"]).titleAlignment("start").labelFormat(labelFormatter).titleInsets(insets); var legend = g.call(this._swatchLegend); if (this._entryStyle) { legend.selectAll(".legendLabel").style(this._entryStyle); } if (this._titleStyle) { legend.selectAll(".legendTitle").style(this._titleStyle); } if (fontChecker) { legend.selectAll(".legendLabel").call(fontChecker); legend.selectAll(".legendTitle").call(fontChecker); } } }, /** @expose */ legend : function() { if ("ContinuousLegend" == this._legendType) { return this._continuousLegend; } if ("SwatchLegend" == this._legendType) { return this._swatchLegend; } return null; }, /** @expose */ legendType : function() { return this._legendType; }, /** * Set the visible property. * @param (boolean) visible New visible * @return (com.ibm.rave.bundles.components.LegendComponentImpl) This object */ /** @expose */ visible : function(visible) { this._visible = visible; return this; }, /** * see if the legend is visible * @return (boolean) if its visible */ /** @expose */ isVisible : function() { return this._visible; }, /** * Set the size property. * @param (Array) size New size * @return (com.ibm.rave.bundles.components.LegendComponentImpl) This object */ /** @expose */ size : function(size) { this._size = size; return this; }, /** * Set the color scale property. * @param (rave['library']['internal']['Palette']) colorPalette New color scale * @return (com.ibm.rave.bundles.components.LegendComponentImpl) This object */ /** @expose */ colorPalette : function(colorPalette) { this._colorPalette = colorPalette; return this; }, /** * Set the orient property. If the argument is not "horizontal" or "vertical", it is ignored and the orient property is not changed. * @param (String) orient New orient * @return (com.ibm.rave.bundles.components.LegendComponentImpl) This object */ /** @expose */ orient : function(orient) { if ("horizontal" == orient || "vertical" == orient) { this._orient = orient; } return this; }, /** * Set the orient property from a legend position. If the argument is "top" or "bottom", the orient is set to "horizontal". Otherwise it is set to "vertical". * @param (String) position Legend position * @return (com.ibm.rave.bundles.components.LegendComponentImpl) This object */ /** @expose */ position : function(position) { return this.orient(com_ibm_rave_bundles_components_LegendComponentImpl.orientationOf(position)); }, swatchSize$0 : function(swatchSize) { if (swatchSize >= 0.0 && swatchSize != null) { this._swatchSize = swatchSize; } return this; }, /** @expose */ scale : function(scale) { this._scale = scale; return this; }, swatchSize$1 : function(swatchSize) { if (swatchSize) { this._swatchSizeFunc = swatchSize; } return this; }, /** @expose */ shape : function(shape) { this._shape = shape; return this; }, /** @expose */ title : function(title) { this._title = (title != null && title.length > 0) ? title : null; return this; }, /** @expose */ titleFill : function(titleFill) { this._titleStyle["fill"] = titleFill; return this; }, /** @expose */ titleFontSize : function(titleFontSize) { this._titleStyle["font-size"] = titleFontSize; return this; }, /** @expose */ titleFontFamily : function(titleFontFamily) { this._titleStyle["font-family"] = titleFontFamily; return this; }, /** @expose */ labelFormat : function(labelFormat) { this._labelFormat = labelFormat; return this; }, /** @expose */ titleFont : function(titleFontStyle) { this._titleStyle = com_ibm_rave_bundles_utilities_FontPropertyParser.parseCSSFont(titleFontStyle); return this; }, /** @expose */ entryFont : function(entryFontStyle) { this._entryStyle = com_ibm_rave_bundles_utilities_FontPropertyParser.parseCSSFont(entryFontStyle); return this; }, /** @expose */ getSpaceUsed : function() { if (this._colorPalette && "continuous" == this._colorPalette.getType()) { return this._continuousLegend.getUsedSize() + 2; } else { return this._swatchLegend.getUsedSize() + 2; } }, /** @expose */ swatchSize : function(a0) { var args = arguments; if (args.length == 1 && typeof a0 === "function") { return this.swatchSize$1(a0); } return this.swatchSize$0(a0); } }); /** * Get the orient for a position. "top" and "bottom" return "horizontal", anything else ("left", "right", or unknown/null) is "vertical". * @param (String) position A position * @return (String) "horizontal" or "vertical" */ /** @expose */ com_ibm_rave_bundles_components_LegendComponentImpl.orientationOf = function(position) { if ("top" == position || "bottom" == position) { return "horizontal"; } return "vertical"; }; //com_ibm_rave_bundles_components_LegendComponentImpl.HORIZONTAL = "horizontal"; //com_ibm_rave_bundles_components_LegendComponentImpl.VERTICAL = "vertical"; com_ibm_rave_bundles_components_LegendComponentImpl.BAR_THINKNESS = 16; com_ibm_rave_bundles_components_LegendComponentImpl.SWATCH_SIZE = 16; /** @expose */ com_ibm_rave_bundles_components_LegendComponentImpl.TOP = "top"; /** @expose */ com_ibm_rave_bundles_components_LegendComponentImpl.BOTTOM = "bottom"; /** @expose */ com_ibm_rave_bundles_components_LegendComponentImpl.LEFT = "left"; /** @expose */ com_ibm_rave_bundles_components_LegendComponentImpl.RIGHT = "right"; /** @expose */ com_ibm_rave_bundles_components_LegendComponentImpl.ADJUSTABLE = -1; // $source: com/ibm/rave/bundles/components/AxisComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2018 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/BundleComponentImpl (loadtime) // superclass //@import com/ibm/rave/bundles/component/AxisComponent (runtime) // AxisComponent //@import com/ibm/rave/bundles/utilities/TextCrossfader (runtime) // textCrossFade //@import com/ibm/rave/bundles/utilities/FontPropertyParser (runtime) // parseCSSFont //@import com/ibm/rave/bundles/utilities/BundleLabelDropper (runtime) // new /** *Component to draw an axis and title. The component is drawn into a Selector group, and the user of the component must translate the group to the axis position and set up the axis scale for the correct number of pixels.
The component uses a RAVE core Axis for drawing the axis. Most component properties are passed to the axis. The component properties are:
scale: The axis scale. This must be set up with the domain and range (pixels) of the axis. If null the axis does not render, and removes all axis shapes from the selector. Default null.
orient: The axis orient, "top", "bottom", "left", or "right". Default "bottom".
bounds: The bounding box for the axis, used to position the title and to wrap/truncate axis labels. If null the title is placed 50 pixels from the axis line and text is not wrapped.
tickFormat: A value function passed to the axis to format tick labels. Default null, meaning the RAVE default formatting is used.
displayAxisTitle: Whether to display the axis title. Default true.
axisTitle: The title to display on the axis. It is centered on the axis range, and the size property is used to find the distance from the axis. Default null.
axisColor: A color-string for the axis line. If null, no color is applied and the CSS defaults are used. Default null.
tickColor: A color-string for the axis ticks. If null, no color is applied and the CSS defaults are used. Default null.
labelColor: A color-string for the axis tick labels. If null, no color is applied and the CSS defaults are used. Default null.
titleColor: A color-string for the axis title. If null, no color is applied and the CSS defaults are used. Default null.
displayAxisLine: Whether to display the axis line. Default true.
displayAxisTicks: Whether to display the axis ticks. Default true.
displayAxisTickLabels: Whether to display the axis tick labels. Default true.
*/ var com_ibm_rave_bundles_components_AxisComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_BundleComponentImpl, { /** * Axis - created on demand */ //_axis : null, /** * Role, from the AxisComponent API */ //_role : null, /** * CoordinateScale */ //_scale : null, /** * Orient, always one of the four legal values */ //_orient : null, /** * Size */ //_bounds : null, //_elementRect : null, /** * The title text; default null (nothing visible) */ /** @expose */ _axisTitle : null, /** * The title style; defaults null (use the CSS styling) */ /** @expose */ _titleStyle : null, /** * Axis line color; default null (use the CSS styling) */ /** @expose */ _lineColor : null, /** * Axis tick color; default null (use the CSS styling) */ /** @expose */ _tickColor : null, /** * Axis tick label style; defaults null (use the CSS styling) */ /** @expose */ _labelStyle : null, //_staggerRotate45Nodes : null, //_staggerFirstNode : null, //_staggerLastNode : null, /** * Axis tick label formatting */ //_tickFormat : null, //_dropOverlap : null, /** * Used to get the extension to enable axis label wrapping */ //_textFlow : null, /** * Used to check the fonts on each label to make sure all characters are covered */ //_fontChecker : null, /** * Run function that applies the properties to the axis line */ //_axisLineProperties : null, /** * Run function that applies the properties to the axis ticks */ //_axisTickProperties : null, /** * Run function that applies the properties to the axis tick labels */ //_axisTickLabelProperties : null, /** * Run function that hides or displays the axis tick labels */ //_displayHideLabels : null, /** * Run function that hides or displays the axis tick labels */ //_panZoomLabels : null, /** * The tick handler registered with the axis; will get called during axis transition */ //_tickHandler : null, //_textTruncationIndicator : null, /** * Used when dealing with numeric scale on the vertical axis and the numbers don't fit */ //_simplifiedTickFormat : null, //_tickMagnitude : null, /** * Whether to display the axis title; default true */ /** @expose */ _displayAxisTitle : false, /** * Whether to display the axis line; default true */ /** @expose */ _displayAxisLine : false, /** * Whether to display the axis ticks; default true */ /** @expose */ _displayTicks : false, /** * Whether to display the axis tick labels (conditional on show labels property); default true */ /** @expose */ _displayTickLabels : false, /** * Whether to display the axis tick labels (conditional on pan-zoom hide property); default true */ /** @expose */ _showPanZoomTickLabels : false, /** * Whether to rotate the axis tick labels; default false */ _rotateLabels : false, _staggerCellWidth : 0, _staggerAlignFirstAtStart : false, _staggerAlignLastAtEnd : false, _layoutTimerId : 0, _layoutTitleSize : 0, _layoutLabelSize : 0, _layoutLabelHeight : 0, _layoutAverageDigitWidth : 0, _layoutSpillOver : 0, /** * Whether to hide overlapping labels; default true */ /** @expose */ _hideOverlappingLabels : false, /** * When true, don't start a new timer */ _pendingLabelTimer : false, /** * The padding in px between tick axis line and tick label, and also between tick label and title. Default 16px. */ _padding : 0, /** * After calling the component, this is true if shapes were rendered, false if they were cleared. */ _renderedShapes : false, _layoutMode : -1, _allowAutoAxisLayoutToChangeOrientaiton : true, _lastAutomaticAxisLayoutOrientation : -1, _allowStagger : false, _allowRotate45 : false, _allowRotate90 : false, constructor : function() { { var self = this; this._axisLineProperties = function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { var line = this.selectAll("path.domain"); if (self._lineColor != null) { line.style("stroke", self._lineColor); } if (self._displayAxisLine) { line.attr("visibility", null); } else { line.attr("visibility", "hidden"); } return null; } }; this._axisTickProperties = function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { var tickLines = this.selectAll("line"); if (self._displayTicks) { tickLines.attr("visibility", null); } else { tickLines.attr("visibility", "hidden"); } if (self._lineColor != null) { tickLines.style("stroke", self._tickColor); } return null; } }; this._axisTickLabelProperties = function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { var labels = this.selectAll("text"); labels.each(self._displayHideLabels); labels.each(self._panZoomLabels); labels.style(self._labelStyle); self._axis.ticksHandler(null); return null; } }; this._displayHideLabels = function(obj, group, index) { if (self._displayTickLabels) { if (this.rave_hasProperty("__tickLabelHidden__")) { this.rave_removeProperty("__tickLabelHidden__"); var count = ~~ (this.rave_getProperty("__hiddenCount__")); if (count <= 1) { this.rave_removeProperty("__hiddenCount__"); this.removeAttribute("visibility"); } else { this.rave_setProperty("__hiddenCount__", count - 1); } } } else { if (!(this.rave_hasProperty("__tickLabelHidden__"))) { this.setAttribute("visibility", "hidden"); this.rave_setProperty("__tickLabelHidden__", "hidden"); var count = ~~ (this.rave_getProperty("__hiddenCount__")); this.rave_setProperty("__hiddenCount__", count + 1); } } }; this._panZoomLabels = function(obj, group, index) { if (self._showPanZoomTickLabels) { if (this.rave_hasProperty("__panZoomHidden__")) { this.rave_removeProperty("__panZoomHidden__"); var count = ~~ (this.rave_getProperty("__hiddenCount__")); if (count <= 1) { this.rave_removeProperty("__hiddenCount__"); this.removeAttribute("visibility"); } else { this.rave_setProperty("__hiddenCount__", count - 1); } } } else { if (!(this.rave_hasProperty("__panZoomHidden__"))) { this.setAttribute("visibility", "hidden"); this.rave_setProperty("__panZoomHidden__", "hidden"); var count = ~~ (this.rave_getProperty("__hiddenCount__")); this.rave_setProperty("__hiddenCount__", count + 1); } } }; } this._tickHandler = new com_ibm_rave_bundles_components_AxisComponentImpl.AxisTickHandler(this._axisTickLabelProperties, this._axisTickProperties); /** * Initialize properties to defaults */ { this._axis = null; this._role = null; this._scale = null; this._orient = "bottom"; this._bounds = null; this._displayAxisTitle = true; this._axisTitle = null; this._titleStyle = {}; this._displayAxisLine = true; this._lineColor = null; this._displayTicks = true; this._tickColor = null; this._displayTickLabels = true; this._labelStyle = {}; this._rotateLabels = false; this._hideOverlappingLabels = true; this._dropOverlap = new com_ibm_rave_bundles_utilities_BundleLabelDropper(); this._tickFormat = null; this._showPanZoomTickLabels = true; this._pendingLabelTimer = false; this._padding = 16; this._textFlow = rave.capabilities.extension("textflow"); this._fontChecker = rave.capabilities.extension("fontchecker"); this._renderedShapes = false; } }, /** @expose */ type : function() { return com_ibm_rave_bundles_component_AxisComponent.COMPONENT_TYPE; }, /** @expose */ role : function() { return this._role; }, /** @expose */ execute : function(g) { this.preExecute(); if (!this._scale) { g.selectAll("*").remove(); this._renderedShapes = false; return; } this._renderedShapes = true; if (this._scale.isOrdinal() || this._scale.isClustered()) { this._hideOverlappingLabels = false; this._rotateLabels = true; } else { this._hideOverlappingLabels = true; this._rotateLabels = true; } this.drawTitle(g); this.drawAxis(g); this.handleAxisText(g); this.drawTitle(g); }, /** * This is one place where all the calls that affect the axis text happen in case of allowAutomaticAxisLayout the new behavior applies here * @param (rave['internal']['Selector']) g */ handleAxisText : function(g) { this.stopLabelDroppingUpdate(); var duration = 0, delay = 0; var g2 = rave.transition(g); if (g2.isTransition()) { var t2 = (g2); duration = t2.duration(); delay = t2.delay(); } var axisSelector = g.selectAll("g.axis"); var labels = axisSelector.selectAll("g.tick").filter(rave['library']['internal']['BundleUtils'].notExit).selectAll("text"); var fontChecker = rave.capabilities.extension("fontchecker"); labels.style(this._labelStyle); if (fontChecker) { labels.call(fontChecker); } var mode = this._allowAutoAxisLayoutToChangeOrientaiton ? this.determineWhichAutoMode(g) : this._lastAutomaticAxisLayoutOrientation; this.configureStaggerData(g, mode); this.handleLabelsRotationAndPosition(g, labels, mode); this.hashingNumericScales(labels, this.labelExtent(g), mode); if (duration == 0) { this.doLabelWrapping(g, mode); this.handleLabelsRotationAndPosition(g, labels, mode); } this._lastAutomaticAxisLayoutOrientation = mode; if (!(this._scale.isOrdinal()) && !(this._scale.isClustered())) { var isHorizontal = this._orient == "bottom" || this._orient == "top"; var tick = axisSelector.append("g").classed("tick", true); var tickText = tick.append("text"); if (labels.size() == 0) { var singleValue = this._scale.scale().domain()[0]; var formatter = this._tickFormat; if (!formatter) { var tickFunc = this._scale.scale().tickFormat; if (tickFunc) { formatter = tickFunc.apply(tickFunc, [singleValue]); } } var node = tickText[0][0]; var stringValue = formatter ? formatter.call(node, singleValue, 0, 0) : ""+(singleValue); tickText.text(stringValue); var dim = node.getBBox(); this._layoutLabelSize = isHorizontal ? dim.height : dim.width; if (!isHorizontal || mode != 0) { tickText.text(".0"); this._layoutLabelSize += node.getBBox().width; } } if (!isHorizontal || mode != 0) { tickText.text(".0"); var node = tickText[0][0]; var dim = node.getBBox(); this._layoutAverageDigitWidth = dim.width; } tick.remove(); } if (this._hideOverlappingLabels && duration > 0) { this.updateLabelDropping(labels, duration, delay); } if (duration > 0) { this.doLabelWrappingAfterAnimation(g, labels, mode, duration, delay); } if (!this._displayTickLabels) { this._layoutLabelSize = 0; this._layoutAverageDigitWidth = 0; } }, /** * Rotates the text and shifts it to compensate for the rotation Needs to be called twice once before wrapping in order to have text in correct position for wrap then after to know the correct height of wrapped text in order to shift it correct TODO: find a better way to do this * @param (rave['internal']['Selector']) g selector * @param (rave['internal']['Selector']) labels labels selector * @param (int) mode one of HORIZONTAL, STAGGER, ROTATE90 */ handleLabelsRotationAndPosition : function(g, labels, mode) { if (mode == 2 || mode == 1) { if (this._orient == "bottom") { this.rotateLabels(g, labels, "end", mode); } else if (this._orient == "top") { this.rotateLabels(g, labels, "start", mode); } else { this.rotateLabels(g, labels, "middle", mode); } } else { if (this._orient == "bottom" || this._orient == "top") { this.rotateLabels(g, labels, "middle", mode); } else if (this._orient == "right") { this.rotateLabels(g, labels, "start", mode); } else { this.rotateLabels(g, labels, "end", mode); } } }, /** *Numeric scales cannot be truncated or wrapped, if a number doesn't fit the allowed space the number should be hashed
ex: 12345 -> #####
This method should be called before {@link #this.doLabelWrapping(rave['internal']['Selector'])} , truncation must be set to off in case of numeric scale
* @param (rave['internal']['Selector']) labels */ hashingNumericScales : function(labels, extent, mode) { if (!labels || !extent) { return; } if (!(this._scale.isOrdinal()) && !(this._scale.isClustered())) { var isHorizontal = this._orient == "bottom" || this._orient == "top"; var tickSpace = mode == 1 ? extent[1] : extent[0]; this._textTruncationIndicator = ""; this._layoutLabelSize = 0; for (var i = 0; i < labels.size(); ++i) { var node = labels[i][0]; var dim = node.getBBox(); var width = dim.width; var height = dim.height; var size = !isHorizontal || mode == 1 ? width : height; if (size > this._layoutLabelSize) { this._layoutLabelSize = size; } if (width >= tickSpace) { if (this._simplifiedTickFormat) { var newText = this._simplifiedTickFormat.call(null, node.rave_getData(), 0, 0); if (newText != null) { node.rave_setText(newText); } if (node.getBBox().width >= tickSpace) { node.rave_setText(this.stringOfSize(node.rave_getText().length, "#")); } } else { node.rave_setText(this.stringOfSize(node.rave_getText().length, "#")); } } } } }, /** * @param (int) size The desired size of the string * @param (String) ch The character to be repeated in the string * @return (String) A string of the specified size containing repetition of the specified character */ stringOfSize : function(size, ch) { var returnString = ""; for (var i = 0; i < size; ++i) { returnString += ch; } return returnString; }, configureStaggerData : function(g, mode) { if (mode == 3 || mode == 2) { var horizontalDimensions = this.labelExtent(g); var cellWidth = horizontalDimensions[0]; var axisSelector = g.selectAll("g.axis"); var labels = axisSelector.selectAll("text"); var domain = this._scale.scale().domain(); var originalDataLabelAccessor = (this._scale).originalDomainLabelAccessor(); this._staggerRotate45Nodes = []; this._staggerFirstNode = null; this._staggerLastNode = null; for (var i = 0; i < labels.size(); ++i) { var node = labels[0][i]; if (this.isValid(node.rave_getData())) { var domainIndex = -1; if (mode == 3) { var domainLabel = !this._tickFormat ? node.rave_getText() : originalDataLabelAccessor.call(node, node.rave_getData(), 0, 0); for (var index = 0; index < domain.length; ++index) { if (domain[index].toString() == domainLabel) { domainIndex = index; break; } } } this._staggerRotate45Nodes.push(new com_ibm_rave_bundles_components_AxisComponentImpl.NodeIndex(node, domainIndex)); if (domainIndex == 0) { this._staggerFirstNode = node; } if (domainIndex == domain.length - 1) { this._staggerLastNode = node; } } } this._staggerCellWidth = cellWidth * 2; this._staggerAlignFirstAtStart = this._staggerFirstNode ? this._staggerFirstNode.getBBox().width > cellWidth : false; this._staggerAlignLastAtEnd = this._staggerLastNode ? this._staggerLastNode.getBBox().width > cellWidth : false; } }, getStaggerIndex : function(node) { for (var index = 0; index < this._staggerRotate45Nodes.length; ++index) { if (this._staggerRotate45Nodes[index].contains(node)) { var domainIndex = this._staggerRotate45Nodes[index].getIndex(); return domainIndex == -1 ? 0 : domainIndex; } } return -1; }, getStaggerCount : function() { var domain = this._scale.scale().domain(); return domain.length; }, /** *The method is responsible for determining which mode to be used with the label positioning if {@link com_ibm_rave_bundles_components_AxisComponentImpl._allowAutomaticLayout} flag is enabled
* @param (rave['internal']['Selector']) g */ determineWhichAutoMode : function(g) { var isHorizontal = this._orient == "bottom" || this._orient == "top"; var axisSelector = g.selectAll("g.axis"); var labels = axisSelector.selectAll("text"); var dim = this.labelExtent(g); var cellWidth = dim[0]; var cellWidth90 = dim[1]; var layoutLabelHeight = 0; var layoutLabelWidth = 0; var horizontalScore = 0; var staggerScore = 0; var rotate45Score = 0; var rotate90Score = 0; var validNodes = []; for (var i = 0; i < labels.size(); ++i) { var node = labels[0][i]; if (this.isValid(node.rave_getData())) { validNodes.push(node); } } var labelCount = validNodes.length; if (!(this._scale.isOrdinal()) && !(this._scale.isClustered())) { var mode = 0; if (isHorizontal) { mode = this._layoutMode == 1 ? 1 : 0; var tick = axisSelector.append("g").classed("tick", true); var tickText = tick.append("text"); tickText.style(this._labelStyle); tickText.text(",0"); var node = tickText[0][0]; var zeroWidth = node.getBBox().width; tick.remove(); var widestLabel = 0; for (var i = 0; i < labelCount; ++i) { node = validNodes[i]; var nodeRect = node.getBBox(); if (nodeRect.width > widestLabel) { widestLabel = nodeRect.width; } if (nodeRect.height > this._layoutLabelHeight) { this._layoutLabelHeight = nodeRect.height; } } widestLabel += zeroWidth; this._layoutSpillOver = mode == 1 ? this._layoutLabelHeight / 2 : widestLabel / 2 + 2; } else { for (var i = 0; i < labelCount; ++i) { var node = validNodes[i]; var nodeRect = node.getBBox(); if (nodeRect.height > this._layoutLabelHeight) { this._layoutLabelHeight = nodeRect.height; } } this._layoutSpillOver = this._layoutLabelHeight / 2; } return mode; } var originalDataLabelAccessor = (this._scale).originalDomainLabelAccessor(); var staggerStringsWontMatch = this._tickFormat && !originalDataLabelAccessor; var calcStagger = ((this._allowStagger && this._layoutMode == -1) || this._layoutMode == 3) && !staggerStringsWontMatch; var calcRotate45 = (this._allowRotate45 && this._layoutMode == -1) || this._layoutMode == 2; var calcRotate90 = (this._allowRotate90 && this._layoutMode == -1) || this._layoutMode == 1; var spaceFor45Label = 0; for (var i = 0; i < labelCount; ++i) { var node = validNodes[i]; var nodeRect = node.getBBox(); layoutLabelHeight = nodeRect.height; var labelWidth = nodeRect.width; if (labelWidth > layoutLabelWidth) { layoutLabelWidth = labelWidth; } horizontalScore += (labelWidth <= cellWidth ? 1 : cellWidth / labelWidth); if (isHorizontal) { if (calcStagger) { var spaceForLabel = cellWidth * 2; if (i == 0 && i == labelCount - 1) { spaceForLabel *= 0.5; } else if (i == 0 || i == labelCount - 1) { spaceForLabel *= 0.75; } staggerScore += (labelWidth <= spaceForLabel ? 1 : spaceForLabel / labelWidth); } if (calcRotate45) { if (spaceFor45Label == 0) { spaceFor45Label = cellWidth90 / 0.7071 - layoutLabelHeight; } var space = this.calculate45DegreeSpace(node, spaceFor45Label); rotate45Score += (labelWidth <= space ? 1 : space / labelWidth); } if (calcRotate90) { rotate90Score += (labelWidth <= cellWidth90 ? 1 : cellWidth90 / labelWidth); } } } var mode = 0; if (this._layoutMode == -1) { if (isHorizontal && this._allowStagger) { horizontalScore *= 1.1; staggerScore *= 1.1; } if ((staggerScore > horizontalScore) && (staggerScore >= rotate45Score) && (staggerScore >= rotate90Score)) { mode = 3; } else if ((rotate45Score > horizontalScore) && (rotate45Score >= rotate90Score)) { mode = 2; } else if (rotate90Score > horizontalScore) { mode = 1; } } else { if ((this._layoutMode == 3 && staggerStringsWontMatch) || !isHorizontal) { mode = 0; } else { mode = this._layoutMode; } } if (isHorizontal) { switch (mode) { case 3: this._layoutLabelSize = layoutLabelHeight * 2; break; case 2: this._layoutLabelSize = (layoutLabelWidth + layoutLabelHeight) * 0.7071; break; case 1: this._layoutLabelSize = layoutLabelWidth; break; case 0: default: this._layoutLabelSize = layoutLabelHeight; break; } } else { this._layoutLabelSize = layoutLabelWidth; } this._layoutLabelHeight = layoutLabelHeight; return mode; }, calculate45DegreeSpace : function(node, maxWidth) { var width = maxWidth; var tfm = node.rave_getParentNode().getAttribute("transform"); if (tfm != null) { var tfmString = tfm.toString(); var indexOfTrans = tfmString.indexOf("translate("); if (indexOfTrans != -1) { indexOfTrans += 10; var indexOfComma = tfmString.indexOf(",", indexOfTrans); if (indexOfComma != -1) { var xAmount = tfmString.substring(indexOfTrans, indexOfComma); var xLabelPos = + (xAmount); var width45Degrees = node.getBBox().width; var xLabelWidth = width45Degrees * 0.7071; var isBottom = this._orient == "bottom"; if (isBottom) { xLabelPos -= node.getBBox().height / 4; if (xLabelPos - xLabelWidth < this._bounds.x) { xLabelWidth = xLabelPos - this._bounds.x; width = xLabelWidth / 0.7071; } } else { if (xLabelPos + xLabelWidth > this._bounds.x + this._bounds.width) { xLabelWidth = (this._bounds.x + this._bounds.width) - xLabelPos; width = xLabelWidth / 0.7071; } } if (width > maxWidth) { width = maxWidth; } } } } return width; }, /** * @param (rave['internal']['Selector']) labels selector with all labels to be rotated * @param (rave['internal']['Selector']) g The parent selector of labels * @param (String) textAnchor The position of the anchor * @param alignmentMode One of HORIZONTAL, STAGGER, ROTATE45, ROTATE90 */ rotateLabels : function(g, labels, textAnchor, mode) { if (this._rotateLabels) { var self = this; var positioning = function(data, index, groupIndex) { var x = 0; var y = 0; var rotation_cy = 0; var isBottom = self._orient == "bottom"; if (mode == 3) { var cellIndex = self.getStaggerIndex(this); if (cellIndex != -1) { if (cellIndex % 2 == 1) { var staggerDirection = isBottom ? 1 : -1; y += (self._layoutLabelHeight * staggerDirection); } if (cellIndex == 0 && self._staggerAlignFirstAtStart) { x -= self._staggerCellWidth / 4; } else if (cellIndex == self.getStaggerCount() - 1 && self._staggerAlignLastAtEnd) { x += self._staggerCellWidth / 4; } } } else if (mode == 2) { if (isBottom) { x -= self._layoutLabelHeight; } else { x += self._layoutLabelHeight / 2; } } else if (mode == 1) { if (isBottom) { x -= (this.getBBox().height / 2 + self._layoutLabelHeight / 4); rotation_cy = ~~(self._padding / 4 + self._axis.tickSize()); } else { x -= (this.getBBox().height / 2 - self._layoutLabelHeight); rotation_cy = ~~-(self._padding / 4 + self._axis.tickSize()); } } var rotationDegrees = mode == 1 ? -90 : mode == 2 ? -45 : 0; return "translate(" + x + "," + y + ") rotate(" + rotationDegrees + ",0," + rotation_cy + ")"; }; labels.attr("transform", positioning).style("text-anchor", textAnchor); if (mode == 3) { if (this._staggerAlignFirstAtStart) { this._staggerFirstNode.rave_setStyle("text-anchor", "start"); } if (this._staggerAlignLastAtEnd) { this._staggerLastNode.rave_setStyle("text-anchor", "end"); } } } }, /** @expose */ axis : function() { return this._axis; }, /** * Draw the axis. The scale is non-null. * @param (rave['internal']['Selector']) g Selector group into which the axis is drawn. */ drawAxis : function(g) { var axisSelector = g.selectAll("g.axis").data([0]); axisSelector.enter().append("g").classed("axis", true).classed(this._orient, true); if (!this._axis) { this._axis = new rave['internal']['Axis'](); } if (this._hideOverlappingLabels) { this._textFlow.valignment("top").dropTextOnFail(false); } this._axis.ticksHandler(this._tickHandler); this._axis.orient(this._orient); this._axis.tickFormat(this._tickFormat); this._axis.tickPadding(10.0); if (this._scale.isOrdinal() || this._scale.isClustered()) { var labelHeight = 20.0; var isHorizontal = this._orient == "bottom" || this._orient == "top"; if (isHorizontal) { labelHeight /= 0.7071; } var range = this._scale.scale().rangeExtent(); var extent = + (range[1]) - + (range[0]); this._axis.ticks(extent / labelHeight); } else { if (this._tickMagnitude == null) { this._axis.ticks(10.0); } else { this._axis.ticks.apply(this._axis, [10.0, this._scale.scale().getTickFormat(), this._tickMagnitude]); } } var s = this._scale.scale(); if (this._scale.originalDomain()) { var sOrdinal = s.copy(); sOrdinal.domain(this._scale.originalDomain()); s = sOrdinal; var self = this; var originalDataLabelAccessor = (self._scale).originalDomainLabelAccessor(); var tickFormatter; if (originalDataLabelAccessor) { if (this._tickFormat) { tickFormatter = function(data, index, groupIndex) { return self._tickFormat.call(this, originalDataLabelAccessor.call(this, data, index, groupIndex), index, groupIndex); }; } else { tickFormatter = originalDataLabelAccessor; } } else { tickFormatter = this._tickFormat; } this._axis.tickFormat(tickFormatter); } this._axis.scale(s); axisSelector.call(this._axis); var g2 = rave.transition(axisSelector); if (!(g2.isTransition())) { axisSelector.selectAll("text").call(this._dropOverlap, this._hideOverlappingLabels); } axisSelector.selectAll("path.domain").classed("axis-line", true); axisSelector.selectAll("g.tick line").classed("axis-tick", true); if (this._fontChecker) { axisSelector.selectAll("g.tick text").classed("axis-label", true).call(this._fontChecker); } else { axisSelector.selectAll("g.tick text").classed("axis-label", true); } axisSelector.call(this._axisLineProperties); }, /** * Draw the axis title. * @param (rave['internal']['Selector']) g Selector group into which the title is drawn. */ drawTitle : function(g) { if (!this._displayAxisTitle || this._axisTitle == null || this._axisTitle.trim().length == 0 || !this._bounds) { g.selectAll("text.axis-title." + this._orient).remove(); return; } var x = 0; var y = 0; var dy = ""; var transform; if ("top" == this._orient) { x = this._elementRect.x + this._elementRect.width / 2; y = -this._bounds.height + this._padding / 4; dy = "0.75em"; } else if ("bottom" == this._orient) { x = this._elementRect.x + this._elementRect.width / 2; y = this._bounds.height - this._padding / 4; dy = "-0.25em"; } else if ("left" == this._orient) { x = -this._elementRect.y - this._elementRect.height / 2; y = -this._bounds.width + this._padding / 4; dy = "0.75em"; transform = "rotate(-90)"; } else { x = this._elementRect.y + this._elementRect.height / 2; y = -this._bounds.width + this._padding / 4; dy = "0.75em"; transform = "rotate(90)"; } var fillOpacity; { var tmp = g.append("text").attr("class", "axis-title " + this._orient); fillOpacity = tmp.style("fill-opacity"); tmp.remove(); } var label = g.selectAll("text.axis-title." + this._orient); if (label.size() == 0) { label.data([0]).enter().append("text").attr("class", "axis-title " + this._orient).style("text-anchor", "middle").attr("x", x).attr("y", y).attr("transform", transform).attr("dy", dy).style(this._titleStyle).text(this._axisTitle); if (this._fontChecker) { g.selectAll("text.axis-title." + this._orient).call(this._fontChecker); } } com_ibm_rave_bundles_utilities_TextCrossfader.textCrossFade(rave.transition(label), label.text(), this._axisTitle, fillOpacity, 0.25).style("text-anchor", "middle").attr("x", x).attr("y", y).attr("transform", transform).attr("dy", dy).style(this._titleStyle); }, getUnZoomedScale : function(scale) { var s = scale.copy(); if (s.getZoomTransform()) { s.getZoomTransform()(1, 0); } return s; }, isValid : function(data) { var s = this.getUnZoomedScale(this._axis.scale()); var v = + (s.call(null, data, 0, 0)); var range = this._axis.scale().range(); if (this._axis.scale().range().indexOf(v)> -1) { return true; } if (range[0] < v && v < range[1]) { return true; } if (range[0] > v && v > range[1]) { return true; } return false; }, /** * Apply label wrapping if requested. * @param (rave['internal']['Selector']) g * @param (int) mode One of HORIZONTAL, STAGGER, ROTATE45, ROTATE90 */ doLabelWrapping : function(g, mode) { if (this._displayTickLabels) { this._textFlow.valignment("top"); if (!this._hideOverlappingLabels) { this._textFlow.dropTextOnFail(true); } var d = this.labelExtent(g); if (!d || d[0] < 0 || d[1] < 0) { return; } var w = ~~ (d[0]); var h = ~~ (d[1]); if (mode == 2) { w = ~~(d[1] / 0.7071 - this._layoutLabelHeight); h = ~~(this._layoutLabelHeight / 0.7071); } else if (mode == 1) { var tmp = w; w = h; h = tmp; } var allowWrap = mode == 1; if (this._scale.isOrdinal() || this._scale.isClustered()) { var hActual = ~~ (this._layoutLabelHeight * 1.2); if (hActual > h) { h = hActual; } var isHorizontal = this._orient == "bottom" || this._orient == "top"; if (mode == 0 && !isHorizontal) { allowWrap = true; } } var self = this; var cellWidth = w; var cellHeight = h; this._textFlow.wrap(allowWrap).truncate(true).textTruncateIndicator(this._textTruncationIndicator != null ? this._textTruncationIndicator : "...").spacing(1.2).extent(function(data, index, groupIndex) { var width = cellWidth; var height = cellHeight; if (mode == 2) { var cellIndex = self.getStaggerIndex(this); if (cellIndex != -1) { width = ~~self.calculate45DegreeSpace(this, cellWidth); } } else if (mode == 3) { var cellIndex = self.getStaggerIndex(this); if (cellIndex != -1) { if (cellIndex == 0 && cellIndex == self.getStaggerCount() - 1) { width = cellWidth; } else if (cellIndex == 0 || cellIndex == self.getStaggerCount() - 1) { width = cellWidth * 3 / 2; } else { width = cellWidth * 2; } height = cellHeight / 2; } } return [width, height]; }); g.selectAll("g.tick > text").call(this._textFlow); } }, /** *Get the extent of the axis label bounds. If the axis bounds are non-null they are used as the axis bounds; otherwise the scale range and AXIS_LABEL_EXTENT_CONSTANT are used as the bounds.
If the axis scale has range bands, the label bounds are the size of the range bands in the dimension parallel to the axis and the size of the axis bounds in the other dimension. Otherwise the label bounds are the axis bounds.
If a title with non-empty text was created, the label bounds are reduced by the title font height in the dimension perpendicular to the axis (since the title is always placed at the edge of the bounds).
* @param (rave['internal']['Selector']) g Selector group for axis * @return (Array) The extent of the axis label bounds */ /** @expose */ labelExtent : function(g) { var isHorizontal = this._orient == "bottom" || this._orient == "top"; var w = this._bounds.width; var h = this._bounds.height; if (this._scale.scale().rangeBand) { var rangeBandValue = + (this._scale.scale().rangeBand()); if (isHorizontal) { w = rangeBandValue; } else { h = rangeBandValue; } } this.calcTitleExtent(g); if (isHorizontal) { h -= this._axis.tickSize(); h -= this._padding / 2; if (this._layoutTitleSize != 0) { h -= this._layoutTitleSize; h -= this._padding / 2; } } else { w -= this._axis.tickSize(); w -= this._padding / 2; if (this._layoutTitleSize != 0) { w -= this._layoutTitleSize; w -= this._padding / 2; } } return [w, h]; }, calcTitleExtent : function(g) { this._layoutTitleSize = 0; var title = g.selectAll("text.axis-title"); if (title.size() > 0) { var textHeight = title[0][0].getBBox().height; this._layoutTitleSize = textHeight; } }, /** * Set the role to one of the constants ROLE_X1 etc. defined in AxisComponent. * @param (String) role The new role * @return (com.ibm.rave.bundles.components.AxisComponentImpl) This object */ /** @expose */ setRole : function(role) { this._role = role; return this; }, /** * Set the ticks interval on the scale based on the magnitude. tickMagnitude represents power of 10. null value gives the default scale ticks. * @param (Number) tickMagnitude * @return (com.ibm.rave.bundles.component.AxisComponent) this */ /** @expose */ scaleTickMagnitude : function(tickMagnitude) { this._tickMagnitude = tickMagnitude; return this; }, /** * @param (rave['library']['internal']['CoordinateScaleImpl']) scale The new scale */ /** @expose */ scale : function(scale) { this._scale = scale ? scale : null; return this; }, /** * Only legal values are accepted, otherwise the orient is unchanged. * @param (String) orient The new orient */ orient$0 : function(orient) { if ("left" == orient || "bottom" == orient || "right" == orient || "top" == orient) { this._orient = orient; if (this._role == null) { if ("left" == orient) { this._role = "ROLE_Y1"; } else if ("bottom" == orient) { this._role = "ROLE_X1"; } else if ("right" == orient) { this._role = "ROLE_Y2"; } else { this._role = "ROLE_X2"; } } } return this; }, /** * Returns the current orientation string return The current orient */ orient$1 : function() { return this._orient; }, /** * @param (rave['internal']['RectStruct']) bounds The new bounds */ /** @expose */ bounds : function(bounds) { this._bounds = bounds; return this; }, /** @expose */ elementRect : function(elementRect) { this._elementRect = elementRect; return this; }, tickFormat$0 : function(tickFormat) { this._tickFormat = tickFormat; return this; }, tickFormat$1 : function() { return this._tickFormat; }, simplifiedTickFormat$0 : function(tickFormat) { this._simplifiedTickFormat = tickFormat; return this; }, simplifiedTickFormat$1 : function() { return this._simplifiedTickFormat; }, /** @expose */ displayAxisTitle : function(displayAxisTitle) { this._displayAxisTitle = displayAxisTitle; return this; }, /** @expose */ displayAxisLine : function(displayAxisLine) { this._displayAxisLine = displayAxisLine; return this; }, /** @expose */ displayTicks : function(displayTicks) { this._displayTicks = displayTicks; return this; }, /** @expose */ displayTickLabels : function(displayTickLabels) { this._displayTickLabels = displayTickLabels; return this; }, /** @expose */ allowAutomaticAxisLayoutToChangeOrientation : function(state) { this._allowAutoAxisLayoutToChangeOrientaiton = state; return this; }, /** @expose */ isAllowAutomaticAxisLayoutToChangeOrientation : function() { return this._allowAutoAxisLayoutToChangeOrientaiton; }, /** @expose */ showPanZoomTickLabels : function(showPanZoomTickLabels) { this._showPanZoomTickLabels = showPanZoomTickLabels; return this; }, /** @expose */ axisTitle : function(axisTitle) { this._axisTitle = axisTitle; return this; }, /** @expose */ axisColor : function(axisColor) { this._lineColor = axisColor; this._tickColor = axisColor; return this; }, /** @expose */ lineColor : function(lineColor) { this._lineColor = lineColor; return this; }, /** @expose */ tickColor : function(tickColor) { this._tickColor = tickColor; return this; }, /** @expose */ labelColor : function(labelColor) { this._labelStyle["fill"] = labelColor; return this; }, labelStyle$0 : function(fill, fontSize, fontFamily) { this._labelStyle["fill"] = fill; this._labelStyle["font-size"] = fontSize; this._labelStyle["font-family"] = fontFamily; return this; }, /** @expose */ titleColor : function(titleColor) { this._titleStyle["fill"] = titleColor; return this; }, titleStyle$0 : function(fill, fontSize, fontFamily) { this._titleStyle["fill"] = fill; this._titleStyle["font-size"] = fontSize; this._titleStyle["font-family"] = fontFamily; return this; }, /** * @param (int) padding The new padding */ /** @expose */ padding : function(padding) { this._padding = padding; return this; }, /** * @param mode LayoutMode for axis, one of: null (numeric axis), automatic, horizontal, stagger, rotate45, rotate90 */ /** @expose */ layoutMode : function(layoutMode) { this._layoutMode = -1; if (layoutMode != null) { if (layoutMode == "horizontal") { this._layoutMode = 0; } else if (layoutMode == "stagger") { this._layoutMode = 3; } else if (layoutMode == "rotate45") { this._layoutMode = 2; } else if (layoutMode == "rotate90") { this._layoutMode = 1; } } return this; }, /** * @param (boolean) allow Enable Stagger to be considered in the automatic layout algorithm */ /** @expose */ allowStagger : function(allow) { this._allowStagger = allow; return this; }, /** * @param (boolean) allow Enable Rotate 45 to be considered in the automatic layout algorithm */ /** @expose */ allowRotate45 : function(allow) { this._allowRotate45 = allow; return this; }, /** * @param (boolean) allow Enable Rotate 90 to be considered in the automatic layout algorithm */ /** @expose */ allowRotate90 : function(allow) { this._allowRotate90 = allow; return this; }, /** * @return (boolean) True if on the last call the axis rendered shapes, false otherwise */ renderedShapes : function() { return this._renderedShapes; }, labelStyle$1 : function(fontStyle) { this._labelStyle = com_ibm_rave_bundles_utilities_FontPropertyParser.parseCSSFont(fontStyle); return this; }, titleStyle$1 : function(fontStyle) { this._titleStyle = com_ibm_rave_bundles_utilities_FontPropertyParser.parseCSSFont(fontStyle); return this; }, /** * Determines whether the axis is swapped. * @return (boolean) True if axis is swapped */ isAxisSwapped : function() { return (((this._role == "ROLE_Y1" || this._role == "ROLE_Y2") && (this._orient == "top" || this._orient == "bottom")) || ((this._role == "ROLE_X1" || this._role == "ROLE_X2") && (this._orient == "right" || this._orient == "left"))); }, /** *Set the indicator to be used for truncated text
ex: indicator set to "..." , results in helloworld - > hello...
If the indicator is not set the default indicator "..." is used
* @param (String) indicator the string to be placed to indicated truncated text * @return (com.ibm.rave.bundles.component.AxisComponent) This component */ /** @expose */ textTruncateIndicator : function(indicator) { this._textTruncationIndicator = indicator; return this; }, /** * If at least one label collision request is pending we stop the label collision component, and shut down the label collision timer event. */ stopLabelDroppingUpdate : function() { this._pendingLabelTimer = false; }, /** * Start Rave timers with a delay of half the transition duration and the full transition duration. This will fire the label dropping at the halfway mark and at the end. * @param (rave['internal']['Selector']) labels the selection of valid labels for the end of the transition * @param (double) duration of the transition. If 0, we don't do anything. * @param (double) delay of the transition. Added to the duration to delay the updates. */ updateLabelDropping : function(labels, duration, delay) { var self = this; var start = delay + duration; var labelCollideCallback = function(elapsed) { if (!self._pendingLabelTimer) { return true; } labels.call(self._dropOverlap, self._hideOverlappingLabels); if (elapsed >= start) { self._pendingLabelTimer = false; return true; } return false; }; if (duration > 0) { this._pendingLabelTimer = true; rave.timer(labelCollideCallback, start); } }, doLabelWrappingAfterAnimation : function(g, labels, mode, duration, delay) { this._layoutTimerId++; var timerId = this._layoutTimerId; var self = this; var wrapCallback = function(elapsed) { if (self._layoutTimerId == timerId) { self.doLabelWrapping(g, mode); self.handleLabelsRotationAndPosition(g, labels, mode); } return true; }; rave.timer(wrapCallback, delay + duration); }, /** @expose */ preLayout : function() { this._layoutTitleSize = 0; this._layoutLabelSize = 0; this._layoutLabelHeight = 0; this._layoutAverageDigitWidth = 0; this._layoutSpillOver = 0; }, /** @expose */ getSizableType : function() { return this._scale.isOrdinal() || this._scale.isClustered() ? 1 : 0; }, /** @expose */ getSizableOrientation : function() { return this._orient; }, /** @expose */ getPreferredSize : function() { var layoutPaddingSize = 0; if (this._axis) { layoutPaddingSize = this._axis.tickSize(); if (this._layoutLabelSize != 0) { layoutPaddingSize += this._padding / 2; } if (this._layoutTitleSize != 0) { layoutPaddingSize += this._padding / 2; } } return this._layoutLabelSize + this._layoutAverageDigitWidth + this._layoutTitleSize + layoutPaddingSize + 2; }, /** @expose */ getSpillOverSize : function() { return this._layoutSpillOver; }, /** @expose */ orient : function(a0) { var args = arguments; if (args.length == 0) { return this.orient$1(); } return this.orient$0(a0); }, /** @expose */ tickFormat : function(a0) { var args = arguments; if (args.length == 0) { return this.tickFormat$1(); } return this.tickFormat$0(a0); }, /** @expose */ simplifiedTickFormat : function(a0) { var args = arguments; if (args.length == 0) { return this.simplifiedTickFormat$1(); } return this.simplifiedTickFormat$0(a0); }, /** @expose */ labelStyle : function(a0, a1, a2) { var args = arguments; if (args.length == 1) { return this.labelStyle$1(a0); } return this.labelStyle$0(a0, a1, a2); }, /** @expose */ titleStyle : function(a0, a1, a2) { var args = arguments; if (args.length == 1) { return this.titleStyle$1(a0); } return this.titleStyle$0(a0, a1, a2); } }); /** * Given the bounds for the axis and the orientation, return the [x,y] translation for the group containing the axis. These are the usual settings for d3 (RAVE core) axes, where the axis range (pixels) is in the global coordinates, then the axis is moved perpendicular to that to place it next to the chart. * @param (rave['internal']['RectStruct']) bounds Rectangle of the axis bounds * @param (String) orient Orient, "top", "bottom", "left", "right"; if not valid, "bottom" used * @return (double[]) Translation [x,y] */ /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.getTranslation = function(bounds, orient) { if ("left" == orient) { return [bounds.x + bounds.width, 0.0]; } if ("right" == orient) { return [bounds.x, 0.0]; } if ("top" == orient) { return [0.0, bounds.y + bounds.height]; } return [0.0, bounds.y]; }; com_ibm_rave_bundles_components_AxisComponentImpl.NodeIndex = rave['internal']['Declare']({ //_node : null, _domainIndex : 0, /** @expose */ constructor : function(node, domainIndex) { this._node = node; this._domainIndex = domainIndex; }, /** @expose */ contains : function(node) { return node == this._node; }, /** @expose */ getIndex : function() { return this._domainIndex; } }); /** * Tick Handler for the axis. This will get called as the core axis is transitioned. */ com_ibm_rave_bundles_components_AxisComponentImpl.AxisTickHandler = rave['internal']['Declare'](rave['internal']['AbstractTickHandler'], { //_label : null, //_tick : null, _$functionClassMethod : function() { var _$self = function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { _$self.handle(args[0]); return null; } }; return _$self; }, constructor : function(label, tick) { this._label = label; this._tick = tick; }, /** @expose */ handle : function(ticks) { ticks.call(this._tick); ticks.call(this._label); } }); //com_ibm_rave_bundles_components_AxisComponentImpl.VISIBILITY = "visibility"; //com_ibm_rave_bundles_components_AxisComponentImpl.HIDDEN = "hidden"; /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.LABEL_HIDDEN_FLAG = "__tickLabelHidden__"; /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.PANZOOM_HIDDEN_FLAG = "__panZoomHidden__"; /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.HIDDEN_COUNT = "__hiddenCount__"; /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.PREFERRED_SPACE_PER_TICK = 20; /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.PREFERRED_TICK_COUNT = 10; /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.TICK_PADDING = 10; //com_ibm_rave_bundles_components_AxisComponentImpl.HORIZONTAL_WEIGHT = 1.1; com_ibm_rave_bundles_components_AxisComponentImpl.HORIZONTAL = 0; com_ibm_rave_bundles_components_AxisComponentImpl.ROTATE90 = 1; com_ibm_rave_bundles_components_AxisComponentImpl.ROTATE45 = 2; com_ibm_rave_bundles_components_AxisComponentImpl.STAGGER = 3; /** * Constant used for text flow spacing */ com_ibm_rave_bundles_components_AxisComponentImpl.TEXTFLOW_SPACING = 1.2; /** * Bottom axis orientation string. */ /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.BOTTOM_ORIENTATION = "bottom"; /** * Top axis orientation string. */ /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.TOP_ORIENTATION = "top"; /** * Left axis orientation string. */ /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.LEFT_ORIENTATION = "left"; /** * Right axis orientation string. */ /** @expose */ com_ibm_rave_bundles_components_AxisComponentImpl.RIGHT_ORIENTATION = "right"; com_ibm_rave_bundles_components_AxisComponentImpl.AUTOMODE = -1; // $source: com/ibm/rave/bundles/components/GridComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/BundleComponentImpl (loadtime) // superclass //@import com/ibm/rave/bundles/components/StyleStructs (runtime) // new //@import com/ibm/rave/bundles/component/GridComponent (runtime) // GridComponent /** *Component to draw gridlines for an axis. The component is drawn into a Selector group, and the user of the component must translate the group to the axis position. Gridlines are created using the axis, setting the tick size to the dimension of the gridline space. For correct behavior the gridline component should be called after the axis has been called.
The properties are:
axis: The axis to use. If null, no gridlines are drawn. Default null.
orient: The axis orientation, one of "top", "bottom", "left", "right". Default "bottom".
bounds: A rectangle bounding the gridline area, used to find the line length. If null, no gridlines are drawn. Default null.
displayGridlines: Whether to draw the gridlines. Default false.
gridlineColor: A color-string for the grid lines. If null, no color is applied and the CSS defaults are used. Default null.
*/ var com_ibm_rave_bundles_components_GridComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_BundleComponentImpl, { /** * The axis property */ //_axis : null, /** * Role, from the AxisComponent API */ //_role : null, /** * The orientation */ //_orient : null, /** * The bounds */ //_bounds : null, /** * Style of gridlines */ //_gridlineStyle : null, /** * Whether to display gridlines */ _displayGridlines : false, /** * After calling the component, this is true if shapes were rendered, false if they were cleared. */ _renderedShapes : false, /** * Construct, with all properties the defaults. */ /** @expose */ constructor : function() { this._axis = null; this._role = null; this._orient = "bottom"; this._bounds = null; this._displayGridlines = true; this._gridlineStyle = new com_ibm_rave_bundles_components_StyleStructs.LineStyle(); this._renderedShapes = false; }, /** @expose */ type : function() { return com_ibm_rave_bundles_component_GridComponent.COMPONENT_TYPE; }, /** @expose */ role : function() { return this._role; }, /** @expose */ execute : function(g) { this.preExecute(); if (!this._displayGridlines || !this._axis || !this._bounds) { g.selectAll("*").remove(); this._renderedShapes = false; return; } this._renderedShapes = true; var size = ("bottom" == this._orient || "top" == this._orient) ? this._bounds.height : this._bounds.width; var ticksHandler = this._axis.ticksHandler(); var tickSize = this._axis.tickSize(); var outerTickSize = this._axis.outerTickSize(); var tickFormat = this._axis.tickFormat(); var ax = this._axis.tickSize(-size, 0).tickFormat("").ticksHandler(null); g.call(ax); this._axis.tickSize(tickSize, outerTickSize).tickFormat(tickFormat).ticksHandler(ticksHandler); g.selectAll("g.tick line").classed("grid-tick", true); g.selectAll(".grid-tick").style("stroke", this._gridlineStyle._stroke).style("stroke-dasharray", (this._gridlineStyle._dashArray)); g.selectAll("path.domain").remove(); }, /** * @param (rave['internal']['Axis']) axis The new axis */ /** @expose */ axis : function(axis) { this._axis = axis; return this; }, /** * Set the role to one of the constants ROLE_X1 etc. defined in AxisComponent. * @param (String) role The new role * @return (com.ibm.rave.bundles.components.GridComponentImpl) This object */ /** @expose */ setRole : function(role) { this._role = role; return this; }, /** * Only legal values are accepted, otherwise the orient is unchanged. * @param (String) orient The new orient */ orient$0 : function(orient) { if ("left" == orient || "right" == orient || "bottom" == orient || "top" == orient) { this._orient = orient; } return this; }, /** * @param (rave['internal']['RectStruct']) bounds The new bounds */ /** @expose */ bounds : function(bounds) { this._bounds = bounds; return this; }, displayGridlines$0 : function(displayGridlines) { this._displayGridlines = displayGridlines; return this; }, /** @expose */ gridlineStyle : function(gridlineColor, dashArray) { this.gridlineColor(gridlineColor); this.dashArray(dashArray); return this; }, gridlineColor$0 : function(gridlineColor) { this._gridlineStyle._stroke = (gridlineColor != null && gridlineColor.length > 0) ? gridlineColor : null; return this; }, dashArray$0 : function(dashArray) { this._gridlineStyle._dashArray = (dashArray != null && dashArray.length > 0) ? dashArray : null; return this; }, /** * @return (String) The orientation of the gridline. */ orient$1 : function() { return this._orient; }, displayGridlines$1 : function() { return this._displayGridlines; }, gridlineColor$1 : function() { return this._gridlineStyle._stroke; }, dashArray$1 : function() { return this._gridlineStyle._dashArray; }, /** * @return (boolean) True if on the last call the axis rendered shapes, false otherwise */ renderedShapes : function() { return this._renderedShapes; }, /** @expose */ orient : function(a0) { var args = arguments; if (args.length == 0) { return this.orient$1(); } return this.orient$0(a0); }, /** @expose */ displayGridlines : function(a0) { var args = arguments; if (args.length == 0) { return this.displayGridlines$1(); } return this.displayGridlines$0(a0); }, /** @expose */ gridlineColor : function(a0) { var args = arguments; if (args.length == 0) { return this.gridlineColor$1(); } return this.gridlineColor$0(a0); }, /** @expose */ dashArray : function(a0) { var args = arguments; if (args.length == 0) { return this.dashArray$1(); } return this.dashArray$0(a0); } }); // $source: com/ibm/rave/bundles/components/KeyedBundleComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/BundleComponentImpl (loadtime) // superclass /** * This type of component generates scene nodes based on a provided data set. Accordingly, any component deriving from this class can (and should) make use of this class's key function. Typically this key function will be passed to the second argument of {@link this.Selector#this.data(, rave['internal']['ValueFunction'])} method in Rave Core, when joining data to scene nodes. For more information on how key functions are used, see the documentation for {@link this.Selector#this.data(, rave['internal']['ValueFunction'])} in Rave Core. * @param < (com.ibm.rave.bundles.components.KeyedBundleComponentImpl) T > Any class that extends this component type must have a self reference in order to support method chaining of the {@link this.KeyedBundleComponentImpl#this.key(rave['internal']['SingleValueFunction'])} method. For example:public class MyComponent extends DataBasedBundleComponent*/ var com_ibm_rave_bundles_components_KeyedBundleComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_BundleComponentImpl, { //keyFunction : null, /** * Set the key function this component should use when joining data to scene nodes. * @param (rave['internal']['SingleValueFunction']) keyFunction This function will be passed each datum individually and must return a unique value (a key). * @return (com.ibm.rave.bundles.components.KeyedBundleComponentImpl) This. */ /** @expose */ key : function(keyFunction) { this.keyFunction = keyFunction; return this; }, /** * Returns a {@link (rave['internal']['ValueFunction']) ValueFunction} that wraps the provided key function. */ /** @expose */ getKey : function() { if (!this.keyFunction) { return null; } var self = this; return function(datum, index, groupIndex) { return self.keyFunction(datum); }; } }); // $source: com/ibm/rave/bundles/components/IntervalComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/KeyedBundleComponentImpl (loadtime) // superclass //@import com/ibm/rave/bundles/utilities/BundleLabelDropper (runtime) // new //@import com/ibm/rave/bundles/component/IntervalComponent (runtime) // IntervalComponent //@import com/ibm/rave/bundles/utilities/ColorUtil (runtime) // getContrastColor //@import com/ibm/rave/bundles/utilities/LabelStyleUtil (runtime) // new /** *{ ... ... MyComponent c = new MyComponent(); c.someSetter(arg) .key(keyFunction) // returns the MyComponent instance, rather than a DataBasedBundleComponent instance. .otherSetter(arg2);
A component to draw interval charts. The component puts its shapes into the selector passed to its execute method. Intervals are rectangular regions bounded by ranges in the dependent and independent dimensions.
The data array passed to the component has one entry per interval to be drawn. Each entry has six properties. Accessors are used to get these properties from the object, and scales to convert them to a graphical property. If a property is not defined (either no accessor or no scale), a default value is used for the property. The six properties are:
Intervals in general do not distinguish between the dependent and independent variables, although in bar charts they do. The names are used here for compatibility with other two-axis plots such as the line and point.
The component properties are:
data: An array with one entry per point. If null, no points are drawn.
independent1Accessor: A value function applied to a data object to get the independent1 value. If null, the interval is not drawn. The default is null.
independent2Accessor:A value function applied to a data object to get the independent2 value. If null, the interval is not drawn. The default is null.
independentScale: A scale applied to the independent values to get the pixel coordinate for drawing the line. If null, the midpoint of the coordinate range is used. The default is null.
dependentAccessor1: A value function applied to a data object to get the dependent1 value. If null, the interval is not drawn. The default is null.
dependentAccessor2: A value function applied to a data object to get the dependent2 value. If null, the interval is not drawn. The default is null.
dependentScale: A scale applied to the dependent value to get the pixel coordinate for drawing the line. If null, the midpoint of the coordinate range is used. The default is null.
colorAccessor: A value function applied to a data object to get the color value. If null, the point is drawn in the primary color. The default is null.
colorPalette: A palette applied to the color value to get a color value for drawing the point. If null or if it returns null, the point is drawn in the primary color.
labelAccessor: A value function applied to a data object to get the label. If null, the point is not labeled. The default is null.
labelFormatter: A value function applied to the data label (as returned by the labelAccessor) to get the formatted text string used in the chart. If null, the data label is coerced to a string and used as the formatted text string. The default is null. The method is not called when the data label is null.
valueAccessor: A value function applied to a data object to get the data value that the interval represents. If null, the interval is not drawn.
transpose: A boolean. If false the independent data is shown on the X axis and the dependent data on the Y; if true they are swapped. Default false.
primaryColor: The color used to fill the interval when the interval has no color value or there is no color scale. If null, the point is drawn but not colored, and the CSS style will be used.
itemLabel: A boolean. If true and if the label accessor is defined, the label is shown on each item. Default true.
itemLabelPosition: A value function applied to a data object to get the item label position. If null, the label is centered.
*/ var com_ibm_rave_bundles_components_IntervalComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_KeyedBundleComponentImpl, { /** * Data */ //_data : null, /** * Accessor for key variable */ //_keyAccessor : null, /** * Accessor for independent1 variable */ //_independent1Accessor : null, /** * Accessor for independent2 variable */ //_independent2Accessor : null, /** * Independent variable scale */ //_independentScale : null, /** * Accessor for dependent1 variable */ //_dependent1Accessor : null, /** * Accessor for dependent2 variable */ //_dependent2Accessor : null, /** * Dependent scale */ //_dependentScale : null, /** * Color scale */ //_colorPalette : null, /** * Accessor for label role */ //_labelAccessor : null, /** * Accessor for data values */ //_valueAccessor : null, /** * Label formatter, may be null */ //_labelFormatter : null, //_dropOverlap : null, /** * Show label */ //_itemLabelPosition : null, /** * border width */ //_borderWidth : null, //_borderColor : null, /** * Effect */ //_specialTransition : null, //_delay : null, //_labelFontStyle : null, //_bounds : null, //_labelStyleUtil : null, /** * Transpose */ _transpose : false, /** * Show label */ _itemLabel : false, /** * Drop overlapping labels */ _itemOverlap : true, _labelLayerClass : ".element-label-group", _elementLayerClass : ".element-group", _labelContrast : false, _labelShadow : false, constructor : function() { this._dropOverlap = new com_ibm_rave_bundles_utilities_BundleLabelDropper(); this._delay = function(data, index, groupIndex) { return 0; }; this._labelFontStyle = {}; { this._labelStyleUtil = new com_ibm_rave_bundles_utilities_LabelStyleUtil(); } }, /** @expose */ type : function() { return com_ibm_rave_bundles_component_IntervalComponent.COMPONENT_TYPE; }, /** @expose */ execute : function(g) { this.preExecute(); var elementGroupSelector = g.selectAll(this._elementLayerClass); var elementLabelGroupSelector = g.selectAll(this._labelLayerClass); if (g.classed(this._elementLayerClass) || elementGroupSelector.size() == 0 || elementLabelGroupSelector.size() == 0) { elementGroupSelector = g; elementLabelGroupSelector = g; } if (!this._data || !this._independent1Accessor || !this._independent2Accessor || !this._independentScale || !this._dependent1Accessor || !this._dependent2Accessor || !this._dependentScale) { elementGroupSelector.selectAll("*").remove(); elementLabelGroupSelector.selectAll("*").remove(); return; } var self = this; var labelText = !this._labelFormatter ? function(data, index, groupIndex) { if (Math.max(+ (self._dependentScale.upper(self._dependent1Accessor(data))), + (self._dependentScale.upper(self._dependent2Accessor(data)))) - Math.min(+ (self._dependentScale.lower(self._dependent1Accessor(data))), + (self._dependentScale.lower(self._dependent2Accessor(data)))) < 0.001) { return null; } return self._labelAccessor(data); } : function(data, index, groupIndex) { var v = self._labelAccessor(data); return v == null ? null : self._labelFormatter.call(this, v, index, groupIndex); }; var keyFunction = !this._keyAccessor ? null : function(datum, ix, gix) { return self._keyAccessor(datum); }; var labelsOn = this._itemLabel && this._labelAccessor; if (!labelsOn) { g.selectAll("text.element-label").remove(); } var elementSelector = elementGroupSelector.selectAll(".element").data(this._data, this.getKey() ? this.getKey() : keyFunction); elementSelector.exit().remove(); var elementEnter = elementSelector.enter().append("g").attr("class", "element"); elementEnter.append("rect").attr("class", "element-shape").attr("x", this._specialTransition == null ? this.rectangleCoord$0(true, true, true) : this.rectangleCoord$0(true, false, true)).attr("width", this._specialTransition == null ? this.rectangleSize(true, true, true) : this.rectangleSize(true, false, true)).attr("y", this.rectangleCoord$0(false, true, true)).attr("height", 0).style("fill", this._colorPalette); if (labelsOn) { var elementLabelSelector = elementLabelGroupSelector.selectAll(".element-label").data(this._data, this.getKey() ? this.getKey() : keyFunction); elementLabelSelector.exit().remove(); elementLabelSelector.enter().append("text").attr("class", "element-label"); this.addLabels(elementLabelSelector).text(labelText); } var shapes = elementSelector.select(".element-shape"); var t = rave.transition(shapes); if (t != shapes && this._delay) { (t).delay(this._delay); } t.style("fill", this._colorPalette); this.updateBorder(t, this._borderWidth, this._borderColor); var fontChecker = rave.capabilities.extension("fontchecker"); if (this._specialTransition == null) { t.attr("x", this.rectangleCoord$0(true, false, false)).attr("width", this.rectangleSize(true, false, false)).attr("y", this.rectangleCoord$0(false, false, false)).attr("height", this.rectangleSize(false, false, false)); } else if (this.isXYanimation()) { t.attr("y", this.rectangleCoord$0(false, false, false)).attr("height", this.rectangleSize(false, false, false)).transition().attr("x", this.rectangleCoord$0(true, false, false)).attr("width", this.rectangleSize(true, false, false)); } else { t.attr("x", this.rectangleCoord$0(true, false, false)).attr("width", this.rectangleSize(true, false, false)).transition().attr("y", this.rectangleCoord$0(false, false, false)).attr("height", this.rectangleSize(false, false, false)); } if (this._renderCallback) { t.call(this._renderCallback, "elements"); } if (labelsOn) { var labels = g.selectAll(".element-label"); var t2 = rave.transition(labels); if (fontChecker) { labels.call(fontChecker); } if (t2 != labels && this._delay) { (t2).delay(this._delay); } t2.attr("x", this.getXPosition()).attr("dx", this.getXOffset()).attr("y", this.getYPosition()).attr("dy", this.getYOffset()).style("text-anchor", this.getAnchor()); var labelColor = this.getDefaultLabelColor(this._labelFontStyle); this._labelStyleUtil.labelFont(this._labelFontStyle).labelFillColor(this._labelContrast ? this.getLabelFill() : function(data, index, groupIndex) { return labelColor; }).labelShadow(this._labelShadow); labels.call(this._labelStyleUtil); t2.text(labelText); this._dropOverlap.configureForDataLabels(this._bounds); t2.call(this._dropOverlap, this._itemOverlap); } }, /** * Add a <text g=element-label"> to each node in the selection s, setting the text properties to the usual defaults. * @param (rave['internal']['Selector']) s Selector * @return (rave['internal']['Selector']) Selector for the added labels */ addLabels : function(s) { return s.selectAll("element-label").attr("x", this.rectangleCenter(true, true, true)).attr("y", this.rectangleCenter(false, true, true)).attr("dy", ".3em").style("text-anchor", "middle"); }, getAnchor : function() { var self = this; return function(data, index, groupIndex) { if (!self._transpose || (!self._itemLabelPosition)) { return "middle"; } var labelPosition = self._itemLabelPosition.call(this, data, index, groupIndex); if (0 == labelPosition) { return "start"; } else if (1 == labelPosition) { return "middle"; } else { return "end"; } }; }, getLabelFill : function() { var self = this; var labelColor = this.getDefaultLabelColor(this._labelFontStyle); return function(data, index, groupIndex) { if (!self._itemLabelPosition) { return com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor(self._colorPalette.call(this, data, index, groupIndex), labelColor).toString(); } var labelPosition = self._itemLabelPosition.call(this, data, index, groupIndex); if (1 == labelPosition) { return com_ibm_rave_bundles_utilities_ColorUtil.getContrastColor(self._colorPalette.call(this, data, index, groupIndex), labelColor).toString(); } return labelColor; }; }, getXOffset : function() { var self = this; return function(data, index, groupIndex) { if (!self._transpose || (!self._itemLabelPosition)) { return "0em"; } var labelPosition = self._itemLabelPosition.call(this, data, index, groupIndex); if (0 == labelPosition) { return ".3em"; } else if (1 == labelPosition) { return "0em"; } else { return "-.3em"; } }; }, getYOffset : function() { var self = this; return function(data, index, groupIndex) { if (self._transpose || (!self._itemLabelPosition)) { return ".3em"; } var labelPosition = self._itemLabelPosition.call(this, data, index, groupIndex); if (0 == labelPosition) { return "-.3em"; } else if (1 == labelPosition) { return ".3em"; } else { return "1.1em"; } }; }, getXPosition : function() { var self = this; return function(data, index, groupIndex) { if (!self._transpose || (!self._itemLabelPosition)) { return self.rectangleCenter(true, false, false).call(this, data, index, groupIndex); } var labelPosition = self._itemLabelPosition.call(this, data, index, groupIndex); if (0 == labelPosition) { return self.rectangleCoord$1(true, false, false, true).call(this, data, index, groupIndex); } else if (1 == labelPosition) { return self.rectangleCenter(true, false, false).call(this, data, index, groupIndex); } else { return self.rectangleCoord$1(true, false, false, false).call(this, data, index, groupIndex); } }; }, getYPosition : function() { var self = this; return function(data, index, groupIndex) { if (self._transpose || (!self._itemLabelPosition)) { return self.rectangleCenter(false, false, false).call(this, data, index, groupIndex); } var labelPosition = self._itemLabelPosition.call(this, data, index, groupIndex); if (0 == labelPosition) { return self.rectangleCoord$1(false, false, false, false).call(this, data, index, groupIndex); } else if (1 == labelPosition) { return self.rectangleCenter(false, false, false).call(this, data, index, groupIndex); } else { return self.rectangleCoord$1(false, false, false, true).call(this, data, index, groupIndex); } }; }, /** * Return a value function that gives the "x" or "y" coordinate of a rectangle. * @param (boolean) xdim Whether "x" (true) or "y" (false) is requested * @param (boolean) fromBase If true and the scale is non-ordinal, the function returns the coordinate for value 0.0 * @param (boolean) enter Whether the coordinate is for an enter transition * @return (rave['internal']['ValueFunction']) Value function for that coordinate */ rectangleCoord$0 : function(xdim, fromBase, enter) { return this.rectangleCoord$1(xdim, fromBase, enter, false); }, rectangleCoord$1 : function(xdim, fromBase, enter, useMax) { var useDependent = xdim == this._transpose; var scale = useDependent ? this._dependentScale : this._independentScale; if (fromBase && useDependent && this._dependentScale.isLinear()) { var value = scale.lower(0.0); return function(data, index, groupIndex) { return value; }; } var a1 = useDependent ? this._dependent1Accessor : this._independent1Accessor; var a2 = useDependent ? this._dependent2Accessor : this._independent2Accessor; if (enter && this.isCTShandling()) { return function(data, index, groupIndex) { return scale.center(a1(data)); }; } return function(data, index, groupIndex) { if (useMax) { return Math.max(+ (scale.upper(a1(data))), + (scale.upper(a2(data)))); } else { return Math.min(+ (scale.lower(a1(data))), + (scale.lower(a2(data)))); } }; }, /** * Return a value function that gives the "height" or "width" coordinate of a rectangle. * @param (boolean) xdim Whether "width" (true) or "height" (false) is requested * @param (boolean) fromBase If true and the scale is non-ordinal, the function returns 0.001 * @param (boolean) enter Whether the size is for an enter transition * @return (rave['internal']['ValueFunction']) Value function for that coordinate */ rectangleSize : function(xdim, fromBase, enter) { var useDependent = xdim == this._transpose; var scale = useDependent ? this._dependentScale : this._independentScale; if ((fromBase && useDependent && this._dependentScale.isLinear()) || (enter && this.isCTShandling())) { return function(data, index, groupIndex) { return 0.001; }; } var a1 = useDependent ? this._dependent1Accessor : this._independent1Accessor; var a2 = useDependent ? this._dependent2Accessor : this._independent2Accessor; return function(data, index, groupIndex) { return Math.max(0.001, Math.max(+ (scale.upper(a1(data))), + (scale.upper(a2(data)))) - Math.min(+ (scale.lower(a1(data))), + (scale.lower(a2(data))))); }; }, /** * @return (boolean) Whether the XY animation (shift X, then Y) should be used */ isXYanimation : function() { return "XY_CTS" == this._specialTransition || "XY_STC" == this._specialTransition; }, /** * @return (boolean) Whether the data handling changed from clustered to stacked */ isCTShandling : function() { return "XY_CTS" == this._specialTransition || "YX_CTS" == this._specialTransition; }, /** * Return a value function that gives the x or y center coordinate of a rectangle. * @param (boolean) xdim Whether the x (true) or y (false) is requested * @param (boolean) fromBase If true and the scale is non-ordinal, the function returns the scaled 0.0 * @param (boolean) enter Whether the center is for an enter transition * @return (rave['internal']['ValueFunction']) Value function for that coordinate */ rectangleCenter : function(xdim, fromBase, enter) { var useDependent = xdim == this._transpose; var scale = useDependent ? this._dependentScale : this._independentScale; if (fromBase && useDependent && this._dependentScale.isLinear()) { var value = scale.lower(0.0); return function(data, index, groupIndex) { return value; }; } var a1 = useDependent ? this._dependent1Accessor : this._independent1Accessor; var a2 = useDependent ? this._dependent2Accessor : this._independent2Accessor; if (enter && this.isCTShandling()) { return function(data, index, groupIndex) { return + (scale.center(a1(data))); }; } return function(data, index, groupIndex) { var val = (Math.max(+ (scale.upper(a1(data))), + (scale.upper(a2(data)))) + Math.min(+ (scale.lower(a1(data))), + (scale.lower(a2(data))))) / 2.0; if (isNaN(val)) { val = 0; } return val; }; }, /** * @param (java.lang.Object[]) data The new data */ /** @expose */ data : function(data) { this._data = data; return this; }, /** * @param (rave['internal']['SingleValueFunction']) keyAccessor The new key accessor */ /** @expose */ keyAccessor : function(keyAccessor) { this._keyAccessor = keyAccessor; return this; }, /** * @param (rave['internal']['SingleValueFunction']) independent1Accessor The new independent1 accessor */ /** @expose */ independent1Accessor : function(independent1Accessor) { this._independent1Accessor = independent1Accessor; return this; }, /** * @param (rave['internal']['SingleValueFunction']) independent2Accessor The new independent1 accessor */ /** @expose */ independent2Accessor : function(independent2Accessor) { this._independent2Accessor = independent2Accessor; return this; }, /** * @param (rave['library']['internal']['CoordinateScaleImpl']) independentScale The new independent scale */ /** @expose */ independentScale : function(independentScale) { this._independentScale = independentScale; return this; }, /** * @param (rave['internal']['SingleValueFunction']) dependent1Accessor The new dependent1 accessor */ /** @expose */ dependent1Accessor : function(dependent1Accessor) { this._dependent1Accessor = dependent1Accessor; return this; }, /** * @param (rave['internal']['SingleValueFunction']) dependent2Accessor The new dependent2 accessor */ /** @expose */ dependent2Accessor : function(dependent2Accessor) { this._dependent2Accessor = dependent2Accessor; return this; }, /** * @param (rave['library']['internal']['CoordinateScaleImpl']) dependentScale The new dependent scale */ /** @expose */ dependentScale : function(dependentScale) { this._dependentScale = dependentScale; return this; }, /** * @param (rave['library']['internal']['Palette']) colorPalette The new colorPalette */ /** @expose */ colorPalette : function(colorPalette) { this._colorPalette = colorPalette; return this; }, /** * @param (rave['internal']['SingleValueFunction']) labelAccessor The new labelAccessor */ /** @expose */ labelAccessor : function(labelAccessor) { this._labelAccessor = labelAccessor; return this; }, /** * @param (rave['internal']['ValueFunction']) labelFormatter The new labelFormatter */ /** @expose */ labelFormatter : function(labelFormatter) { this._labelFormatter = labelFormatter; return this; }, /** * @param (boolean) transpose The new transpose */ /** @expose */ transpose : function(transpose) { this._transpose = transpose; return this; }, /** * @param (boolean) itemLabel The new itemLabel */ /** @expose */ itemLabel : function(itemLabel) { this._itemLabel = itemLabel; return this; }, /** * @param (rave['internal']['ValueFunction']) labelPosition Function to be used to determine label position */ /** @expose */ itemLabelPosition : function(labelPosition) { this._itemLabelPosition = labelPosition; return this; }, /** * @param itemOverlap drop or show overlap labels */ /** @expose */ itemOverlap : function(_itemOverlap) { this._itemOverlap = _itemOverlap; return this; }, /** @expose */ valueAccessor : function(valueAccessor) { this._valueAccessor = valueAccessor; return this; }, /** * Set the special transition used for clustered-to-stacked. Allowed values are:A component to handle label collisions, either by dropping labels or moving them. This requires that:
The component calls the LabelPositioning utility in capabilities.
*/ var com_ibm_rave_bundles_components_LabelCollisionComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_BundleComponentImpl, { /** * Handle label collisions method, move overlapping labels vs drop overlapping */ //_handleLabelCollisions : null, //_labelPositioning : null, /** * Rectangle for the drawing bounds */ //_bounds : null, /** * Handle label collisions method, move overlapping labels vs drop overlapping */ _labelClass : ".element-label", /** * Number of sweeps performed by the labelPositioning call */ _numberOfSweeps : 1000, /** @expose */ execute : function(chart) { var labels = chart.selectAll(this._labelClass); if (this._handleLabelCollisions == "Move Labels") { this.resolveLabelCollisions(labels); } else if (this._handleLabelCollisions == "Drop Labels") { this.dropLabels(labels); } else { this.resetLabels(labels); } }, /** @expose */ type : function() { return com_ibm_rave_bundles_component_LabelCollisionComponent.COMPONENT_TYPE; }, resetLabels : function(labels) { var position = rave.capabilities.extension("position"); position.drop().reset(labels); }, dropLabels : function(labels) { var position = rave.capabilities.extension("position"); var drop = position.drop(); if (this._bounds) { var ex = [[this._bounds.x, this._bounds.y], [this._bounds.x + this._bounds.width, this._bounds.y + this._bounds.height]]; drop.extent(ex); } drop.remove(false); drop.noClipping(); drop.dropOverlap(labels); }, /** * @param (rave['internal']['Selector']) labels */ resolveLabelCollisions : function(labels) { var self = this; var labelBoxes = []; var anchorPoints = []; labels.each(function(data, index, groupIndex) { var labelBox = {}; labelBox["x"] = + (this.getAttribute("x")); labelBox["y"] = + (this.getAttribute("y")); labelBox["width"] = + (this.getBBox().width); labelBox["height"] = + (this.getBBox().height); labelBoxes.push(labelBox); var anchorPoint = {}; anchorPoint["x"] = labelBox["x"]; anchorPoint["y"] = labelBox["y"]; anchorPoint["r"] = 5; anchorPoints.push(anchorPoint); }); labels.data(labelBoxes); var position = rave.capabilities.extension("position"); var repositionLabels = function(args) { if (args !== null || arguments.length > 1){ args = Array.prototype.slice.call(arguments, 0); } { if (self._handleLabelCollisions == "Move Labels") { labels.transition().duration(110).attr("x", function(data, index, groupIndex) { return (data)["x"]; }).attr("y", function(data, index, groupIndex) { return (data)["y"]; }); } return this; } }; this._labelPositioning = position.place().label(labelBoxes); this._labelPositioning.anchor(anchorPoints).width(this._bounds.width).height(this._bounds.height).numberOfSweeps(this._numberOfSweeps).start().on("tick", repositionLabels); }, /** * @param (String) className - the class name for labels. If not set, the default is ".element-label" return this */ /** @expose */ labelClassName : function(className) { this._labelClass = className; return this; }, /** * @param (String) resolve - if true, we resolve label collisions return this */ /** @expose */ labelResolution : function(resolve) { this._handleLabelCollisions = resolve; if (this._labelPositioning && this._handleLabelCollisions != null) { this._labelPositioning.stop(); } return this; }, /** * @param (rave['internal']['RectStruct']) bounds The new bounds */ /** @expose */ bounds : function(bounds) { this._bounds = bounds; return this; }, /** * @param (int) numberOfSweeps The number of sweeps performed by the labelPositioning code */ /** @expose */ numberOfSweeps : function(numberOfSweeps) { this._numberOfSweeps = numberOfSweeps; return this; } }); /** @expose */ com_ibm_rave_bundles_components_LabelCollisionComponentImpl.MOVE_LABELS = "Move Labels"; /** @expose */ com_ibm_rave_bundles_components_LabelCollisionComponentImpl.DROP_LABELS = "Drop Labels"; /** @expose */ com_ibm_rave_bundles_components_LabelCollisionComponentImpl.NONE = "none"; // $source: com/ibm/rave/bundles/components/AbstractPathComponent /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/KeyedBundleComponentImpl (loadtime) // superclass //@import com/ibm/rave/bundles/utilities/PathUtils (runtime) // fadeOutIn /** * Base class for Line and Area components, both of which create similar path-based elements. */ var com_ibm_rave_bundles_components_AbstractPathComponent = rave['internal']['Declare'](com_ibm_rave_bundles_components_KeyedBundleComponentImpl, { /** * Interpolation Mode (Smoothness of the line) */ /** @expose */ _interpolateMode : null, /** * Keep track of the previous Interpolation Mode */ /** @expose */ _previousInterpolateMode : null, constructor : function() { this._interpolateMode = rave['internal']['SVGLine'].r2_svg_lineLinear.getKey(); this._previousInterpolateMode = this._interpolateMode; }, /** @expose */ updatePath : function(updateSelection, pathFunction) { if (this._interpolateMode != null && !(this._interpolateMode == this._previousInterpolateMode)) { com_ibm_rave_bundles_utilities_PathUtils.fadeOutIn(updateSelection, pathFunction); } else { updateSelection.attr("d", pathFunction); } this._previousInterpolateMode = this._interpolateMode; } }); // $source: com/ibm/rave/bundles/components/LineComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/AbstractPathComponent (loadtime) // superclass //@import com/ibm/rave/bundles/component/LineComponent (runtime) // LineComponent /** *A component to draw line charts. The component puts its shapes into the selector passed to its execute method.
The data array passed to the component has one entry per line to be drawn. Each entry has two properties. Accessors are used to get these properties from the object. Their roles are:
The component properties are:
data: An array with one entry per line, structured as described above. If null, no lines are drawn.
pointsAccessor: A value function applied to an entry in the data array, returning the value of the points role (the array of points). If null, no lines are drawn. The default implementation assumes the entry is an object (OMap) and gets and gets the "points" property of the object.
colorAccessor: A value function applied to an entry in the data array, returning the value for the color role. If null, the line is drawn but not colored. The default implementation assumes the entry is an object (OMap) and gets the "color" property of the object.
independentAccessor: A value function applied to a point object to get the independent value. If null, no lines are drawn. The default implementation assumes each point is an array and returns the first object (as in the default line generator).
independentScale: A scale applied to the independent value of the point to get the pixel coordinate for drawing the line. If null, no lines are drawn. The default is null.
dependentAccessor: A value function applied to a point object to get the dependent value. If null, no lines are drawn. The default implementation assumes each point is an array and returns the second object (as in the default line generator).
dependentScale: A scale applied to the dependent value of the point to get the pixel coordinate for drawing the line. If null, no lines are drawn. The default is null.
colorScale: A scale applied to the value in the color role to get a color value for drawing the line. If null or if it returns null, the line is drawn in the primary color.
primaryColor: The color used to draw the line when the line has no color or there is no color scale. If null, the line is drawn but not colored, and the CSS style will be used.
transpose: A boolean. If false the categorical data is shown on the X axis and the linear data on the Y; if true they are swapped. Default false.
effect: A string. If non-null, requests an entrance effect. The only supported entrance effect is "fromBase", where the line grows up from the dependent axis zero; any other value is treated as null. This property is cleared to null on each render, for convenience in setting up zooming. Default null.
*/ var com_ibm_rave_bundles_components_LineComponentImpl = rave['internal']['Declare'](com_ibm_rave_bundles_components_AbstractPathComponent, { /** * Data */ //_data : null, /** * Accessor for points role */ //_pointsAccessor : null, /** * Accessor for color role */ //_groupAccessor : null, /** * Accessor for independent variable from a point */ //_independentAccessor : null, /** * Independent variable scale */ //_independentScale : null, /** * Accessor for dependent variable from a point */ //_dependentAccessor : null, /** * Dependent scale */ //_dependentScale : null, /** * Color scale */ //_colorPalette : null, /** * Effect, only "fromBase" supported */ //_effect : null, /** * Accessor for checking to see if Y value is null */ //_definedAccessor : null, /** * Transpose */ _transpose : false, /** * Show gaps for missing data */ _showMissingAsGap : false, /** * Initialize all properties to default values. */ /** @expose */ constructor : function() { this._data = null; this._interpolateMode = null; this._pointsAccessor = function(data) { return (data)["points"]; }; this._groupAccessor = null; this._independentAccessor = function(data) { return (data)[0]; }; this._independentScale = null; this._dependentAccessor = function(data) { return (data)[1]; }; var self = this; this._definedAccessor = function(data) { return (self._dependentAccessor(data) != null) && (self._independentAccessor(data) != null); }; this._dependentScale = null; this._colorPalette = null; this._transpose = false; this._effect = null; this._showMissingAsGap = true; }, /** @expose */ type : function() { return com_ibm_rave_bundles_component_LineComponent.COMPONENT_TYPE; }, /** @expose */ execute : function(g) { this.preExecute(); if (!this._data || !this._pointsAccessor || !this._independentAccessor || !this._independentScale || !this._dependentAccessor || !this._dependentScale) { g.selectAll("*").remove(); return; } var self = this; var independent = function(data, index, groupIndex) { return self._independentScale.center(self._independentAccessor(data)); }; var dependent = function(data, index, groupIndex) { return self._dependentScale.center(self._dependentAccessor(data)); }; var definedAccessorY = function(data, index, groupIndex) { return (self._definedAccessor(data)); }; var line = rave.svg.line().x(this._transpose ? dependent : independent).y(this._transpose ? independent : dependent).showMissingAsGap(this._showMissingAsGap); var lineFunction = function(d, index, groupIndex) { return line.call(this, self._pointsAccessor(d), index, groupIndex); }; line.defined(definedAccessorY); line.interpolate(this._interpolateMode); var lines = g.selectAll("path.element-shape").data(this._data, this._groupAccessor ? function(data, index, groupIndex) { return self._groupAccessor(data); } : null); lines.exit().remove(); var enter = lines.enter(); if (enter.size() > 0) { enter = enter.append("path").attr("class", "element-shape").style("stroke", this._colorPalette); if ("fromBase" == this._effect) { var dependentZero = function(data, index, groupIndex) { return self._dependentScale.center(0.0); }; var zeroLine = rave.svg.line().x(this._transpose ? dependentZero : independent).y(this._transpose ? independent : dependentZero); zeroLine.defined(definedAccessorY); enter.attr("d", function(d, index, groupIndex) { return zeroLine.call(this, self._pointsAccessor(d), index, groupIndex); }); } else { enter.attr("d", lineFunction); } } var linesUpdate = rave.transition(lines).style("stroke", this._colorPalette); this.updatePath(linesUpdate, lineFunction); this._effect = null; }, /** * @param (java.lang.Object[]) data The new data */ /** @expose */ data : function(data) { this._data = data; return this; }, /** * @param (rave['internal']['SingleValueFunction']) pointsAccessor The new pointsAccessor */ /** @expose */ pointsAccessor : function(pointsAccessor) { this._pointsAccessor = pointsAccessor; return this; }, /** * @param (rave['internal']['SingleValueFunction']) groupAccessor The new groupAccessor */ /** @expose */ groupAccessor : function(groupAccessor) { this._groupAccessor = groupAccessor; return this; }, /** * @param (rave['internal']['SingleValueFunction']) independentAccessor The new independent accessor */ /** @expose */ independentAccessor : function(independentAccessor) { this._independentAccessor = independentAccessor; return this; }, /** * @param (rave['library']['internal']['CoordinateScaleImpl']) independentScale The new independent scale */ /** @expose */ independentScale : function(independentScale) { this._independentScale = independentScale; return this; }, /** * @param (rave['internal']['SingleValueFunction']) dependentAccessor The new dependent accessor */ /** @expose */ dependentAccessor : function(dependentAccessor) { this._dependentAccessor = dependentAccessor; return this; }, /** * @param (rave['internal']['SingleValueFunction']) definedAccessor The new defined accessor */ /** @expose */ definedAccessor : function(definedAccessor) { this._definedAccessor = definedAccessor; return this; }, /** * @param (rave['library']['internal']['CoordinateScaleImpl']) dependentScale The new dependent scale */ /** @expose */ dependentScale : function(dependentScale) { this._dependentScale = dependentScale; return this; }, /** * @param (rave['library']['internal']['Palette']) colorPalette The new color palette */ /** @expose */ colorPalette : function(colorPalette) { this._colorPalette = colorPalette ? colorPalette : null; return this; }, /** * @param (boolean) transpose The new transpose */ /** @expose */ transpose : function(transpose) { this._transpose = transpose; return this; }, /** * @param (String) effect The new effect */ /** @expose */ effect : function(effect) { this._effect = effect; return this; }, /** * Configure whether lines generated should show a gap (line break) if a value is missing * @param (boolean) state true (default) for a gap, false for a line across missing values */ /** @expose */ showMissingAsGap : function(state) { this._showMissingAsGap = state; return this; }, /** * @param (String) mode sets the interpolation mode that makes the line of the area chart smooth or jagged. */ /** @expose */ interpolate : function(mode) { this._interpolateMode = mode; return this; } }); // $source: com/ibm/rave/bundles/components/PointComponentImpl /************************************************************************ ** IBM Confidential ** ** IBM Business Analytics: Rapidly Adaptive Visualization Engine ** ** (C) Copyright IBM Corp. 2017 ** ** The source code for this program is not published or otherwise divested of its trade secrets, ** irrespective of what has been deposited with the U.S. Copyright Office. ************************************************************************/ // GENERATED //@import com/ibm/rave/bundles/components/KeyedBundleComponentImpl (loadtime) // superclass //@import com/ibm/rave/bundles/component/PointComponent (runtime) // PointComponent //@import com/ibm/rave/bundles/utilities/PathUtils (runtime) // fadeOutIn //@import com/ibm/rave/bundles/utilities/ColorUtil (runtime) // getContrastColor //@import com/ibm/rave/bundles/utilities/BundleLabelDropper (runtime) // new //@import com/ibm/rave/bundles/utilities/LabelStyleUtil (runtime) // new /** *A component to draw point charts. The component puts its shapes into the selector passed to its execute method.
The data array passed to the component has one entry per point to be drawn. Each entry has five properties. Accessors are used to get these properties from the object, and scales to convert them to a graphical property. If a property is not defined (either no accessor or no scale), a default value is used for the property. The five properties are:
Scatterplots in general do not distinguish between the dependent and independent variables. The names are used here for compatibility with other two-axis plots such as the line and column.
The component properties are:
data: An array with one entry per point. If null, no points are drawn.
independentAccessor: A value function applied to a data object to get the independent value. If null, the midpoint of the coordinate range is used. The default is null.
independentScale: A scale applied to the independent value to get the pixel coordinate for drawing the line. If null, the midpoint of the coordinate range is used. The default is null.
dependentAccessor: A value function applied to a data object to get the dependent value. If null, the midpoint of the coordinate range is used. The default is null.
dependentScale: A scale applied to the dependent value to get the pixel coordinate for drawing the line. If null, the midpoint of the coordinate range is used. The default is null.
colorAccessor: A value function applied to a data object to get the color value. If null, the point is drawn in the primary color. The default is null.
colorPalette: A palette applied to the color value to get a color value for drawing the point. If null or if it returns null, the point is drawn in the primary color.
sizeAccessor: A value function applied to a data object to get the size value used for the point size. If null, the point is drawn with the default size. The default is null.
sizeScale: A scale applied to the size value to get the size for drawing for drawing the line. If null or if it returns null, the point is drawn with the default size. The default is null.
labelAccessor: A value function applied to a data object to get the label. If null, the point is not labeled. The default is null.
labelFormatter: A value function applied to the data label (as returned by the labelAccessor) to get the formatted text string used in the chart. If null, the data label is coerced to a string and used as the formatted text string. The default is null. The method is not called when the data label is null.
bounds: The bounding rectangle of the component, used to find the midpoints of the coordinates when the independent or dependent variables are not defined. If either of those variables is not defined and the bounds is null, no points are drawn. The default is null.
transpose: A boolean. If false the independent data is shown on the X axis and the dependent data on the Y; if true they are swapped. Default false.
primaryColor: The color used to draw the point when the point has no color value or there is no color scale. If null, the point is drawn but not colored, and the CSS style will be used.
symbol: The symbol used to draw the shape, which must be one of the RAVE/D3 symbol generator names or "rectangle". If null, the point is drawn as a circle.
defaultSize: The size used to draw the point when the point has no size value or there is no size scale. The default is 100 and the value cannot be set to less than 0. Note that this uses the RAVE/D3 convention, where the size is in square pixels.
itemLabel: A boolean. If true and if the label accessor is defined, the label is shown on each item. Default true.
itemOverlap: A boolean. If true, overlapping labels are removed. Default is true.
effect: A string. Requests an entrance effect; if null or not a supported effect, no entrance effect is used. Default null. The supported effects are: