visualSolution.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. /**
  20. * @file Visual solution, for consistent option specification.
  21. */
  22. import * as zrUtil from 'zrender/src/core/util';
  23. import VisualMapping from './VisualMapping';
  24. var each = zrUtil.each;
  25. function hasKeys(obj) {
  26. if (obj) {
  27. for (var name in obj) {
  28. if (obj.hasOwnProperty(name)) {
  29. return true;
  30. }
  31. }
  32. }
  33. }
  34. /**
  35. * @param {Object} option
  36. * @param {Array.<string>} stateList
  37. * @param {Function} [supplementVisualOption]
  38. * @return {Object} visualMappings <state, <visualType, module:echarts/visual/VisualMapping>>
  39. */
  40. export function createVisualMappings(option, stateList, supplementVisualOption) {
  41. var visualMappings = {};
  42. each(stateList, function (state) {
  43. var mappings = visualMappings[state] = createMappings();
  44. each(option[state], function (visualData, visualType) {
  45. if (!VisualMapping.isValidType(visualType)) {
  46. return;
  47. }
  48. var mappingOption = {
  49. type: visualType,
  50. visual: visualData
  51. };
  52. supplementVisualOption && supplementVisualOption(mappingOption, state);
  53. mappings[visualType] = new VisualMapping(mappingOption);
  54. // Prepare a alpha for opacity, for some case that opacity
  55. // is not supported, such as rendering using gradient color.
  56. if (visualType === 'opacity') {
  57. mappingOption = zrUtil.clone(mappingOption);
  58. mappingOption.type = 'colorAlpha';
  59. mappings.__hidden.__alphaForOpacity = new VisualMapping(mappingOption);
  60. }
  61. });
  62. });
  63. return visualMappings;
  64. function createMappings() {
  65. var Creater = function () {};
  66. // Make sure hidden fields will not be visited by
  67. // object iteration (with hasOwnProperty checking).
  68. Creater.prototype.__hidden = Creater.prototype;
  69. var obj = new Creater();
  70. return obj;
  71. }
  72. }
  73. /**
  74. * @param {Object} thisOption
  75. * @param {Object} newOption
  76. * @param {Array.<string>} keys
  77. */
  78. export function replaceVisualOption(thisOption, newOption, keys) {
  79. // Visual attributes merge is not supported, otherwise it
  80. // brings overcomplicated merge logic. See #2853. So if
  81. // newOption has anyone of these keys, all of these keys
  82. // will be reset. Otherwise, all keys remain.
  83. var has;
  84. zrUtil.each(keys, function (key) {
  85. if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) {
  86. has = true;
  87. }
  88. });
  89. has && zrUtil.each(keys, function (key) {
  90. if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) {
  91. thisOption[key] = zrUtil.clone(newOption[key]);
  92. }
  93. else {
  94. delete thisOption[key];
  95. }
  96. });
  97. }
  98. /**
  99. * @param {Array.<string>} stateList
  100. * @param {Object} visualMappings <state, Object.<visualType, module:echarts/visual/VisualMapping>>
  101. * @param {module:echarts/data/List} list
  102. * @param {Function} getValueState param: valueOrIndex, return: state.
  103. * @param {object} [scope] Scope for getValueState
  104. * @param {string} [dimension] Concrete dimension, if used.
  105. */
  106. // ???! handle brush?
  107. export function applyVisual(stateList, visualMappings, data, getValueState, scope, dimension) {
  108. var visualTypesMap = {};
  109. zrUtil.each(stateList, function (state) {
  110. var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);
  111. visualTypesMap[state] = visualTypes;
  112. });
  113. var dataIndex;
  114. function getVisual(key) {
  115. return data.getItemVisual(dataIndex, key);
  116. }
  117. function setVisual(key, value) {
  118. data.setItemVisual(dataIndex, key, value);
  119. }
  120. if (dimension == null) {
  121. data.each(eachItem);
  122. }
  123. else {
  124. data.each([dimension], eachItem);
  125. }
  126. function eachItem(valueOrIndex, index) {
  127. dataIndex = dimension == null ? valueOrIndex : index;
  128. var rawDataItem = data.getRawDataItem(dataIndex);
  129. // Consider performance
  130. if (rawDataItem && rawDataItem.visualMap === false) {
  131. return;
  132. }
  133. var valueState = getValueState.call(scope, valueOrIndex);
  134. var mappings = visualMappings[valueState];
  135. var visualTypes = visualTypesMap[valueState];
  136. for (var i = 0, len = visualTypes.length; i < len; i++) {
  137. var type = visualTypes[i];
  138. mappings[type] && mappings[type].applyVisual(
  139. valueOrIndex, getVisual, setVisual
  140. );
  141. }
  142. }
  143. }
  144. /**
  145. * @param {module:echarts/data/List} data
  146. * @param {Array.<string>} stateList
  147. * @param {Object} visualMappings <state, Object.<visualType, module:echarts/visual/VisualMapping>>
  148. * @param {Function} getValueState param: valueOrIndex, return: state.
  149. * @param {number} [dim] dimension or dimension index.
  150. */
  151. export function incrementalApplyVisual(stateList, visualMappings, getValueState, dim) {
  152. var visualTypesMap = {};
  153. zrUtil.each(stateList, function (state) {
  154. var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]);
  155. visualTypesMap[state] = visualTypes;
  156. });
  157. function progress(params, data) {
  158. if (dim != null) {
  159. dim = data.getDimension(dim);
  160. }
  161. function getVisual(key) {
  162. return data.getItemVisual(dataIndex, key);
  163. }
  164. function setVisual(key, value) {
  165. data.setItemVisual(dataIndex, key, value);
  166. }
  167. var dataIndex;
  168. while ((dataIndex = params.next()) != null) {
  169. var rawDataItem = data.getRawDataItem(dataIndex);
  170. // Consider performance
  171. if (rawDataItem && rawDataItem.visualMap === false) {
  172. continue;
  173. }
  174. var value = dim != null
  175. ? data.get(dim, dataIndex, true)
  176. : dataIndex;
  177. var valueState = getValueState(value);
  178. var mappings = visualMappings[valueState];
  179. var visualTypes = visualTypesMap[valueState];
  180. for (var i = 0, len = visualTypes.length; i < len; i++) {
  181. var type = visualTypes[i];
  182. mappings[type] && mappings[type].applyVisual(value, getVisual, setVisual);
  183. }
  184. }
  185. }
  186. return {progress: progress};
  187. }