| import {getOutlineNode} from './docHelper'; | |
| const OPTION_EXAMPLE_LAYOUT = '_ec_option_example_layout'; | |
| export const optionExampleLayouts = ['auto', 'top', 'bottom', 'right']; | |
| export function updateOptionExampleLayout(layout) { | |
| if (layout === 'auto') { | |
| store.computedOptionExampleLayout = window.innerWidth < 1400 ? 'bottom' : 'right'; | |
| } | |
| else { | |
| store.computedOptionExampleLayout = layout; | |
| } | |
| store.optionExampleLayout = layout; | |
| window.localStorage && window.localStorage.setItem(OPTION_EXAMPLE_LAYOUT, layout); | |
| } | |
| function getInitialOptionExampleLayout() { | |
| const layout = {}; | |
| const savedLayout = window.localStorage && window.localStorage.getItem(OPTION_EXAMPLE_LAYOUT); | |
| if (!savedLayout || savedLayout === 'auto' || optionExampleLayouts.indexOf(savedLayout) < 0) { | |
| layout.mode = 'auto'; | |
| layout.computedMode = window.innerWidth < 1400 ? 'bottom' : 'right'; | |
| } | |
| else { | |
| layout.mode = layout.computedMode = savedLayout; | |
| } | |
| return layout; | |
| } | |
| const initialOptionExampleLayout = getInitialOptionExampleLayout(); | |
| export const store = { | |
| docType: '', | |
| // Current selected option | |
| currentPath: '', | |
| // Search content | |
| fuzzySearch: false, | |
| searchQuery: '', | |
| isMobile: false, | |
| locale: 'zh', | |
| showOptionExample: false, | |
| allOptionExamples: null, | |
| // Clear before setOption | |
| cleanMode: false, | |
| currentExampleName: '', | |
| currentExampleOption: '', | |
| // Can be `top`, `bottom`, `right`, `auto` | |
| optionExampleLayout: initialOptionExampleLayout.mode, | |
| // Can be `top`, `bottom`, `right` | |
| computedOptionExampleLayout: initialOptionExampleLayout.computedMode | |
| }; | |
| export function getPagePath() { | |
| if (store.isMobile) { | |
| // No hierarchy | |
| let parts = store.currentPath.split('.'); | |
| let node = getOutlineNode(store.currentPath); | |
| let isLeaf = node && (!node.children || !node.children.length); | |
| if (isLeaf && parts.length > 1) { // Is leaf | |
| parts.pop(); | |
| } | |
| return parts.join('.'); | |
| } | |
| else { | |
| return store.currentPath.split('.')[0]; | |
| } | |
| } | |
| export function isOptionDoc() { | |
| return store.docType === 'option' | |
| || store.docType === 'option-gl'; | |
| } | |
| const componentCanHost = ['markPoint', 'markLine', 'markArea', 'tooltip', 'axisPointer']; | |
| function makeDefaultOption(key) { | |
| if (key === 'markPoint') { | |
| return { | |
| data: [{ | |
| type: 'max' | |
| }] | |
| }; | |
| } | |
| else if (key === 'markLine') { | |
| return { | |
| data: [{ | |
| type: 'average' | |
| }] | |
| }; | |
| } | |
| else if (key === 'markArea') { | |
| return { | |
| data: [ [{ | |
| type: 'min' | |
| }, { | |
| type: 'max' | |
| }] ] | |
| }; | |
| } | |
| } | |
| export function changeOption(option, path, value) { | |
| function changeOptionRecursive(obj, pathParts, objKey, nodePath) { | |
| const itemStr = pathParts.shift(); | |
| nodePath = (nodePath ? (nodePath + '.') : '') + itemStr; | |
| if (objKey === 'data' && (typeof obj !== 'object' || Array.isArray(obj))) { | |
| // Convert number to object | |
| obj = { | |
| value: obj | |
| }; | |
| } | |
| // Clone a new object because the original one is freezed and cant be changed. | |
| obj = Object.assign({}, obj); | |
| if (!pathParts.length) { | |
| if (value === undefined) { | |
| delete obj[itemStr]; | |
| return obj; | |
| } | |
| else { | |
| obj[itemStr] = value; | |
| return obj; | |
| } | |
| } | |
| const subtypeItems = itemStr.split('-'); | |
| const key = subtypeItems[0]; | |
| const subtype = subtypeItems[1]; | |
| // TODO: If prop not exists and it should be an array. | |
| if (obj[key] == null) { | |
| const outlineNode = getOutlineNode(nodePath); | |
| obj[key] = makeDefaultOption(key) || | |
| ((outlineNode && outlineNode.isArray) ? [] : {}); | |
| } | |
| const prop = obj[key]; | |
| if (Array.isArray(prop)) { | |
| if (key === 'series') { // Only set all on series. | |
| obj[key] = prop.map(function (childObj, idx) { | |
| if (subtype && childObj.type !== subtype) { | |
| return childObj; | |
| } | |
| return changeOptionRecursive(childObj, pathParts.slice(), key, nodePath); | |
| }); | |
| } | |
| else { | |
| // Only change the first one. | |
| // TODO: Should be able to choose the index. | |
| obj[key] = prop.slice(); | |
| obj[key][0] = changeOptionRecursive(obj[key][0] || {}, pathParts.slice(), key, nodePath); | |
| } | |
| } | |
| else { | |
| if (subtype && prop.type !== subtype) { | |
| obj[key] = prop; | |
| } | |
| obj[key] = changeOptionRecursive(prop, pathParts.slice(), key, nodePath); | |
| } | |
| return obj; | |
| } | |
| // For the components can be hosted on other components, like axisPointer, markers. | |
| function findAndSetHostComponentRecursively(root, componentKey) { | |
| if (root[componentKey]) { | |
| return changeOptionRecursive(root, path.split('.'), '', ''); | |
| } | |
| if (Array.isArray(root)) { | |
| const newArr = []; | |
| for (let i = 0; i < root.length; i++) { | |
| newArr.push(findAndSetHostComponentRecursively(root[i], componentKey)); | |
| } | |
| return newArr; | |
| } | |
| else if (typeof root === 'object') { | |
| const newObj = {}; | |
| for (let key in root) { | |
| if (root.hasOwnProperty(key)) { | |
| newObj[key] = findAndSetHostComponentRecursively(root[key], componentKey); | |
| } | |
| } | |
| return newObj; | |
| } | |
| return root; | |
| } | |
| const componentKey = path.split('.')[0]; | |
| if (componentKey === 'timeline' && option.baseOption) { | |
| return Object.assign({}, option, { | |
| baseOption: changeOptionRecursive(option.baseOption, path.split('.'), '', '') | |
| }); | |
| } | |
| else if (componentCanHost.indexOf(componentKey) >= 0) { | |
| return findAndSetHostComponentRecursively(option, componentKey); | |
| } | |
| return changeOptionRecursive(option, path.split('.'), '', ''); | |
| } |