/**
* Copyright (c) 2014, Oracle and/or its affiliates.
* All rights reserved.
*/
/**
* @ojcomponent oj.ojTreemap
* @augments oj.dvtBaseComponent
* @since 0.7
*
* @classdesc
* <h3 id="treemapOverview-section">
* JET Treemap Component
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#treemapOverview-section"></a>
* </h3>
*
* <p>Treemap component for JET. Treemaps are used to display hierarchical data across two dimensions, represented by
* the size and color of the treemap nodes. Treemaps are generally preferred over sunbursts when emphasizing the data
* for the leaf nodes.</p>
*
* {@ojinclude "name":"warning"}
*
* <pre class="prettyprint">
* <code>
* <div data-bind="ojComponent: {
* component: 'ojTreemap',
* nodes: [{value: 100, color: "#FFFF00", label: "Total Sales",
* nodes: [{value: 75, color: "#00FF00", label: "Candy"},
* {value: 20, color: "#FFFF00", label: "Fruit"},
* {value: 15, color: "#FF0000", label: "Vegetables"}]}]
* }"/>
* </code>
* </pre>
*
* {@ojinclude "name":"a11yKeyboard"}
*
* <h3 id="touch-section">
* Touch End User Information
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#touch-section"></a>
* </h3>
*
* {@ojinclude "name":"touchDoc"}
*
* <h3 id="keyboard-section">
* Gesture End User Information
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#keyboard-section"></a>
* </h3>
*
* {@ojinclude "name":"keyboardDoc"}
*
* <h3 id="perf-section">
* Performance
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#perf-section"></a>
* </h3>
*
* <h4>Animation</h4>
* <p>Animation should only be enabled for visualizations of small to medium data sets. Alternate visualizations should
* be considered if identifying data changes is important, since all nodes will generally move and resize on any data
* change.
* </p>
*
* <h4>Data Set Size</h4>
* <p>As a rule of thumb, it's recommended that applications only set usable data densities on this component.
* Applications can enable progressive reveal of data through drilling or aggregate small nodes to reduce the
* displayed data set size.
* </p>
*
* <h4>Style Attributes</h4>
* <p>Use the highest level options property available. For example, consider using attributes on
* <code class="prettyprint">nodeDefaults</code>, instead of attributes on the individual nodes. The component can
* take advantage of these higher level attributes to apply the style properties on containers, saving expensive DOM
* calls.
* </p>
*
* {@ojinclude "name":"rtl"}
*
* @desc Creates a JET Treemap.
* @example <caption>Initialize the Treemap with no options specified:</caption>
* $(".selector").ojTreemap();
*
* @example <caption>Initialize the Treemap with some options:</caption>
* $(".selector").ojTreemap({nodes: [{value: 75, color: "#00FF00", label: "Candy"}, {value: 20, color: "#FFFF00", label: "Fruit"}, {value: 15, color: "#FF0000", label: "Vegetables"}]});
*
* @example <caption>Initialize the Treemap via the JET <code class="prettyprint">ojComponent</code> binding:</caption>
* <div data-bind="ojComponent: {component: 'ojTreemap'}">
*/
oj.__registerWidget('oj.ojTreemap', $['oj']['dvtBaseComponent'],
{
widgetEventPrefix: "oj",
options: {
/**
* Fired whenever a supported component option changes, whether due to user interaction or programmatic
* intervention. If the new value is the same as the previous value, no event will be fired.
*
* @property {Object} data event payload
* @property {string} data.option the name of the option that changed, i.e. "value"
* @property {Object} data.previousValue an Object holding the previous value of the option
* @property {Object} data.value an Object holding the current value of the option
* @property {Object} ui.optionMetadata information about the option that is changing
* @property {string} ui.optionMetadata.writeback <code class="prettyprint">"shouldWrite"</code> or
* <code class="prettyprint">"shouldNotWrite"</code>. For use by the JET writeback mechanism.
*
* @example <caption>Initialize the component with the <code class="prettyprint">optionChange</code> callback:</caption>
* $(".selector").ojTreemap({
* 'optionChange': function (event, data) {}
* });
*
* @example <caption>Bind an event listener to the <code class="prettyprint">ojoptionchange</code> event:</caption>
* $(".selector").on({
* 'ojoptionchange': function (event, data) {
* window.console.log("option changing is: " + data['option']);
* };
* });
*
* @expose
* @event
* @memberof oj.ojTreemap
* @instance
*/
optionChange: null
},
//** @inheritdoc */
_CreateDvtComponent: function(context, callback, callbackObj) {
return dvt.DvtTreemap.newInstance(context, callback, callbackObj);
},
//** @inheritdoc */
_ConvertLocatorToSubId : function(locator) {
var subId = locator['subId'];
// Convert the supported locators
if(subId == 'oj-treemap-node') {
// node[index0][index1]...[indexN]
subId = 'node' + this._GetStringFromIndexPath(locator['indexPath']);
}
else if(subId == 'oj-treemap-tooltip') {
subId = 'tooltip';
}
// Return the converted result or the original subId if a supported locator wasn't recognized. We will remove
// support for the old subId syntax in 1.2.0.
return subId;
},
//** @inheritdoc */
_ConvertSubIdToLocator : function(subId) {
var locator = {};
if(subId.indexOf('node') == 0) {
// node[index0][index1]...[indexN]
locator['subId'] = 'oj-treemap-node';
locator['indexPath'] = this._GetIndexPath(subId);
}
else if(subId == 'tooltip') {
locator['subId'] = 'oj-treemap-tooltip';
}
return locator;
},
//** @inheritdoc */
_GetComponentStyleClasses: function() {
var styleClasses = this._super();
styleClasses.push('oj-treemap');
return styleClasses;
},
//** @inheritdoc */
_GetChildStyleClasses: function() {
var styleClasses = this._super();
styleClasses['oj-treemap-isolate-icon'] = {'path': '_resources/isolate', 'property': 'CSS_URL'};
styleClasses['oj-treemap-isolate-icon oj-hover'] = {'path': '_resources/isolateOver', 'property': 'CSS_URL'};
styleClasses['oj-treemap-isolate-icon oj-active'] = {'path': '_resources/isolateDown', 'property': 'CSS_URL'};
styleClasses['oj-treemap-restore-icon'] = {'path': '_resources/restore', 'property': 'CSS_URL'};
styleClasses['oj-treemap-restore-icon oj-hover'] = {'path': '_resources/restoreOver', 'property': 'CSS_URL'};
styleClasses['oj-treemap-restore-icon oj-active'] = {'path': '_resources/restoreDown', 'property': 'CSS_URL'};
styleClasses['oj-treemap-attribute-type-text'] = {'path': 'styleDefaults/_attributeTypeTextStyle', 'property': 'CSS_TEXT_PROPERTIES'};
styleClasses['oj-treemap-attribute-value-text'] = {'path': 'styleDefaults/_attributeValueTextStyle', 'property': 'CSS_TEXT_PROPERTIES'};
// TODO HZHANG add this once drilling is supported
// styleClasses['oj-treemapCurrentText '] = {'path' : '', 'property' : 'CSS_TEXT_PROPERTIES'};
styleClasses['oj-treemap-node'] = {'path': 'nodeDefaults/labelStyle', 'property': 'CSS_TEXT_PROPERTIES'};
styleClasses['oj-treemap-node oj-hover'] = {'path': 'nodeDefaults/hoverColor', 'property': 'border-top-color'};
styleClasses['oj-treemap-node oj-selected'] = [
{'path': 'nodeDefaults/selectedOuterColor', 'property': 'border-top-color'},
{'path': 'nodeDefaults/selectedInnerColor', 'property': 'border-bottom-color'}
];
styleClasses['oj-treemap-node-header'] = [
{'path': 'nodeDefaults/header/backgroundColor', 'property': 'background-color'},
{'path': 'nodeDefaults/header/borderColor', 'property': 'border-top-color'},
{'path': 'nodeDefaults/header/labelStyle', 'property': 'CSS_TEXT_PROPERTIES'}
];
styleClasses['oj-treemap-node-header oj-hover'] = [
{'path': 'nodeDefaults/header/hoverBackgroundColor', 'property': 'background-color'},
{'path': 'nodeDefaults/header/hoverOuterColor', 'property': 'border-top-color'},
{'path': 'nodeDefaults/header/hoverInnerColor', 'property': 'border-bottom-color'}
];
styleClasses['oj-treemap-node-header oj-selected'] = [
{'path': 'nodeDefaults/header/selectedBackgroundColor', 'property': 'background-color'},
{'path': 'nodeDefaults/header/selectedOuterColor', 'property': 'border-top-color'},
{'path': 'nodeDefaults/header/selectedInnerColor', 'property': 'border-bottom-color'}
];
return styleClasses;
},
//** @inheritdoc */
_GetEventTypes : function() {
return ['optionChange'];
},
//** @inheritdoc */
_GetTranslationMap: function() {
// The translations are stored on the options object.
var translations = this.options['translations'];
// Safe to modify super's map because function guarentees a new map is returned
var ret = this._super();
ret['DvtTreemapBundle.COLOR'] = translations['labelColor'];
ret['DvtTreemapBundle.ISOLATE'] = translations['tooltipIsolate'];
ret['DvtTreemapBundle.RESTORE'] = translations['tooltipRestore'];
ret['DvtTreemapBundle.SIZE'] = translations['labelSize'];
ret['DvtUtilBundle.TREEMAP'] = translations['componentName'];
return ret;
},
//** @inheritdoc */
_HandleEvent: function(event) {
var type = event && event.getType ? event.getType() : null, isolatedNodes, isolatedNode, isolateType;
if (type === dvt.DvtSelectionEvent.TYPE) {
// update the options selection state
this._UserOptionChange('selection', event.getSelection());
}
else if (type === dvt.DvtTreemapIsolateEvent.TYPE) {
// Keep track of all isolated nodes
isolatedNodes = this.options._isolatedNodes;
if (!isolatedNodes) {
this.options._isolatedNodes = [];
isolatedNodes = this.options._isolatedNodes;
}
// If event has id, it's an isolate. If null id, then restore.
isolatedNode = event.getId();
if (isolatedNode) {
isolateType = "on";
isolatedNodes.push(isolatedNode);
this._UserOptionChange('isolatedNode', isolatedNode);
}
else {
isolateType = "off";
isolatedNode = isolatedNodes.pop();
this._UserOptionChange('isolatedNode', (isolatedNodes.length > 0) ? isolatedNodes[isolatedNodes.length] : null);
}
}
else {
this._super(event);
}
},
/**
* Returns an object with the following properties for automation testing verification of the node with
* the specified subid path.
*
* @param {Array} subIdPath The array of indices in the subId for the desired node
* @property {string} color
* @property {string} label
* @property {boolean} selected
* @property {number} size
* @property {string} tooltip
* @property {Function} getColor <b>Deprecated</b>: Use <code class="prettyprint">color</code> instead.
* @property {Function} getLabel <b>Deprecated</b>: Use <code class="prettyprint">label</code> instead.
* @property {Function} getSize <b>Deprecated</b>: Use <code class="prettyprint">size</code> instead.
* @property {Function} getTooltip <b>Deprecated</b>: Use <code class="prettyprint">tooltip</code> instead.
* @property {Function} isSelected <b>Deprecated</b>: Use <code class="prettyprint">selected</code> instead.
* @return {Object|null} An object containing properties for the node, or null if none exists.
* @expose
* @instance
* @memberof oj.ojTreemap
*/
getNode: function(subIdPath) {
var ret = this._component.getAutomation().getNode(subIdPath);
// Bug 20884377: Provide backwards compatibility for getters until 1.2.0.
this._AddAutomationGetters(ret);
return ret;
},
/**
* {@ojinclude "name":"nodeContextDoc"}
* @param {!Element} node - {@ojinclude "name":"nodeContextParam"}
* @returns {Object|null} {@ojinclude "name":"nodeContextReturn"}
*
* @example {@ojinclude "name":"nodeContextExample"}
*
* @expose
* @instance
* @memberof oj.ojTreemap
*/
getContextByNode: function(node)
{
// context objects are documented with @ojnodecontext
var context = this.getSubIdByNode(node);
if (context && context['subId'] !== 'oj-treemap-tooltip')
return context;
return null;
}
});
Source: src/main/javascript/oracle/oj/ojtreemap/ojtreemap.js
Oracle® JavaScript Extension Toolkit (JET)
1.1.2
E65298-01