| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| */ | |
| import { createChart, getGraphicElements, getECModel } from '../../../core/utHelper'; | |
| // import { imageURI } from './setOptionImageURI'; | |
| import { EChartsType } from '../../../../../src/echarts'; | |
| import Element from 'zrender/src/Element'; | |
| import { EChartsOption } from '../../../../../src/export/option'; | |
| import { | |
| GraphicComponentOption, | |
| GraphicComponentImageOption | |
| } from '../../../../../src/component/graphic/GraphicModel'; | |
| import Group from 'zrender/src/graphic/Group'; | |
| import { Dictionary } from 'zrender/src/core/types'; | |
| // eslint-disable-next-line max-len | |
| const imageURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANwAAADcCAYAAAAbWs+BAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gIUARQAHY8+4wAAApBJREFUeNrt3cFqAjEUhlEjvv8rXzciiiBGk/He5JxdN2U649dY+KmnEwAAAAAv2uMXEeGOwERntwAEB4IDBAeCAwQHggPBAYIDwQGCA8GB4ADBgeAAwYHgAMGB4EBwgOCgpkuKq2it/r8Li2hbvGKqP6s/PycnHHv9YvSWEgQHCA4EBwgOBAeCAwQHggMEByXM+QRUE6D3suwuPafDn5MTDg50KXnVPSdxa54y/oYDwQGCA8EBggPBAYIDwYHggBE+X5rY3Y3Tey97Nn2eU+rnlGfaZa6Ft5SA4EBwgOBAcCA4QHAgOEBwIDjgZu60y1xrDPtIJxwgOBAcIDgQHAgOEBwIDhAcCA4EBwgOBAcIDgQHCA4EB4IDBAeCAwQHggPBAYIDwQGCA8GB4ADBgeAAwYHgAMGB4GADcz9y2McIgxMOBAeCAwQHggMEB4IDwQGCA8EBggPBATdP6+KIGPRdW7i1LCFi6ALfCQfeUoLgAMGB4ADBgeBAcIDgQHCA4CCdOVvK7quwveQgg7eRTjjwlhIQHAgOBAcIDgQHCA4EB4IDBAfl5dhSdl+17SX3F22rdLlOOBAcCA4QHAgOEBwIDgQHCA4EBwgO0qm5pez6Ce0uSym2jXTCgeAAwYHgQHCA4EBwgOBAcCA4QHBQ3vpbyu47Yns51OLbSCccCA4QHAgOBAcIDgQHCA4EB4ID5jDt+vkObjgFM9dywoHgAMGB4EBwgOBAcIDgQHAgOEBwsA5bysPveMLtpW2kEw4EBwgOBAcIDgQHggMEB4IDBAeCg33ZUqZ/Ql9sL20jnXCA4EBwIDhAcCA4QHAgOBAcIDgQHNOZai3DlhKccCA4QHAgOEBwIDgQHCA4AAAAAGA1VyxaWIohrgXFAAAAAElFTkSuQmCC'; | |
| // function loadImage(onload: (img: HTMLImageElement) => void) { | |
| // const img = new window.Image(); | |
| // img.onload = function () { | |
| // onload(img); | |
| // }; | |
| // img.src = imageURI; | |
| // } | |
| // FIXME: TMEP use rect, would have used image. | |
| // node-canvas will throw error when using data URI to zrender directly. | |
| // Havn't dig it out why yet. | |
| function tmpConvertImageOption(opt: GraphicComponentImageOption): object { | |
| const outOpt = opt as Dictionary<unknown>; | |
| outOpt.type = 'rect'; | |
| const style = opt.style || {}; | |
| delete style.image; | |
| outOpt.shape = { | |
| x: style.x || 0, | |
| y: style.y || 0, | |
| width: style.width || 0, | |
| height: style.height || 0 | |
| }; | |
| return outOpt; | |
| } | |
| describe('graphic_setOption', function () { | |
| const NUMBER_PRECISION = 6; | |
| function propHasAll(els: Element[], propsObjList: object[]) { | |
| for (let i = 0; i < propsObjList.length; i++) { | |
| propHas(els[i], propsObjList[i]); | |
| } | |
| } | |
| function propHas(target: object, propsObj: object): void { | |
| if (target == null || propsObj == null) { | |
| expect(false).toEqual(true); | |
| } | |
| expect(typeof target === 'object' && typeof propsObj === 'object').toEqual(true); | |
| // propsObj can be array | |
| if (propsObj instanceof Array) { | |
| expect(target instanceof Array).toEqual(true); | |
| for (let i = 0; i < propsObj.length; i++) { | |
| each((target as Element[])[i], propsObj[i], i); | |
| } | |
| } | |
| else { | |
| for (const name in propsObj) { | |
| if (propsObj.hasOwnProperty(name)) { | |
| each((target as any)[name], (propsObj as any)[name], name); | |
| } | |
| } | |
| } | |
| function each(targetVal: unknown, propVal: unknown, keyInfo: string | number): void { | |
| // console.log(targetVal, propVal, keyInfo); | |
| if (propVal == null) { | |
| expect(targetVal == null).toEqual(true); | |
| } | |
| // object or array | |
| else if (typeof propVal === 'object') { | |
| propHas(targetVal as object, propVal); | |
| } | |
| else if (typeof propVal === 'number') { | |
| expect(typeof targetVal).toEqual('number'); | |
| expect((targetVal as number).toFixed(NUMBER_PRECISION)).toEqual(propVal.toFixed(NUMBER_PRECISION)); | |
| } | |
| else { | |
| expect(targetVal).toStrictEqual(propVal); | |
| } | |
| } | |
| } | |
| let chart: EChartsType; | |
| beforeEach(function () { | |
| chart = createChart(); | |
| }); | |
| afterEach(function () { | |
| chart.dispose(); | |
| }); | |
| describe('option', function () { | |
| it('optionFlatten', function () { | |
| chart.setOption({ | |
| graphic: [ | |
| tmpConvertImageOption({ | |
| id: 'uriimg', | |
| type: 'image', | |
| name: 'nameuriimg', | |
| originX: 20, | |
| originY: 20, | |
| left: 10, | |
| top: 10, | |
| style: { | |
| image: imageURI, | |
| width: 80, | |
| height: 80, | |
| opacity: 0.5 | |
| } | |
| }), | |
| { | |
| type: 'group', | |
| id: 'gr', | |
| width: 230, | |
| height: 110, | |
| x: 70, | |
| y: 90, | |
| children: [ | |
| { | |
| type: 'rect', | |
| name: 'rectxx', | |
| shape: { | |
| width: 230, | |
| height: 80 | |
| }, | |
| style: { | |
| stroke: 'red', | |
| fill: 'transparent', | |
| lineWidth: 2 | |
| }, | |
| z: 100 | |
| }, | |
| { | |
| id: 'grouptext', | |
| type: 'text', | |
| bottom: 0, | |
| right: 0, | |
| rotation: 0.5, | |
| style: { | |
| text: 'aaa' | |
| }, | |
| z: 100 | |
| } | |
| ] | |
| }, | |
| { | |
| type: 'text', | |
| bottom: 0, | |
| left: 'center', | |
| style: { | |
| text: 'bbb' | |
| }, | |
| z: 100 | |
| } | |
| ] | |
| }); | |
| // Set option using getOption | |
| const option = chart.getOption(); | |
| const graphicOptionList = option.graphic as GraphicComponentOption[]; | |
| expect(graphicOptionList.length === 1).toEqual(true); | |
| const optionElements = graphicOptionList[0].elements; | |
| expect(optionElements && optionElements.length === 5).toEqual(true); | |
| expect(optionElements[0].id === 'uriimg' && optionElements[0].parentId == null).toEqual(true); | |
| expect(optionElements[1].id === 'gr' && optionElements[1].parentId == null).toEqual(true); | |
| expect(optionElements[2].name === 'rectxx' && optionElements[2].parentId === 'gr').toEqual(true); | |
| expect((optionElements[3] as any).style.text === 'aaa' && optionElements[3].parentId === 'gr') | |
| .toEqual(true); | |
| expect((optionElements[4] as any).style.text === 'bbb' && optionElements[4].parentId == null) | |
| .toEqual(true); | |
| }); | |
| it('groupSetOptionGetOption', function () { | |
| chart.setOption({ | |
| graphic: [ | |
| tmpConvertImageOption({ | |
| id: 'uriimg', | |
| type: 'image', | |
| name: 'nameuriimg', | |
| originX: 20, | |
| originY: 20, | |
| left: 10, | |
| top: 10, | |
| style: { | |
| image: imageURI, | |
| width: 80, | |
| height: 80, | |
| opacity: 0.5 | |
| } | |
| }), | |
| { | |
| type: 'group', | |
| id: 'gr', | |
| width: 230, | |
| height: 110, | |
| x: 70, | |
| y: 90, | |
| children: [ | |
| { | |
| type: 'rect', | |
| name: 'rectxx', | |
| shape: { | |
| width: 230, | |
| height: 80 | |
| }, | |
| style: { | |
| stroke: 'red', | |
| fill: 'transparent', | |
| lineWidth: 2 | |
| }, | |
| z: 100 | |
| }, | |
| { | |
| id: 'grouptext', | |
| type: 'text', | |
| bottom: 0, | |
| right: 0, | |
| rotation: 0.5, | |
| style: { | |
| text: 'aaa' | |
| }, | |
| z: 100 | |
| } | |
| ] | |
| }, | |
| { | |
| type: 'text', | |
| bottom: 0, | |
| left: 'center', | |
| style: { | |
| text: 'bbb' | |
| }, | |
| z: 100 | |
| } | |
| ] | |
| }); | |
| checkExistsAndRelations(); | |
| // Set option using getOption | |
| chart.setOption(chart.getOption()); | |
| // Check again, should be the same as before. | |
| checkExistsAndRelations(); | |
| function checkExistsAndRelations() { | |
| const els = getGraphicElements(chart, 'graphic'); | |
| expect(els.length === 6).toEqual(true); | |
| expect(els[0].type === 'group').toEqual(true); | |
| expect(els[1].name === 'nameuriimg').toEqual(true); | |
| expect(els[2].type === 'group').toEqual(true); | |
| const groupEls = getGraphicElements(els[2] as Group, 'graphic'); | |
| expect(groupEls.length === 2).toEqual(true); | |
| expect(groupEls[0] === els[3]).toEqual(true); | |
| expect(groupEls[1] === els[4]).toEqual(true); | |
| expect(els[3].name === 'rectxx').toEqual(true); | |
| expect((els[4] as any).style.text === 'aaa').toEqual(true); | |
| expect((els[5] as any).style.text === 'bbb').toEqual(true); | |
| } | |
| }); | |
| it('onlyOneGraphicComponentAvailable', function () { | |
| chart.setOption({ | |
| graphic: [ | |
| { | |
| elements: [ | |
| { | |
| type: 'circle', | |
| shape: { | |
| cx: 50, | |
| cy: 50, | |
| r: 20 | |
| } | |
| }, | |
| { | |
| type: 'circle', | |
| shape: { | |
| cx: 150, | |
| cy: 150, | |
| r: 20 | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| elements: [ | |
| { | |
| type: 'circle', | |
| shape: { | |
| cx: 100, | |
| cy: 100, | |
| r: 20 | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| }); | |
| expect(!!getECModel(chart).getComponent('graphic')).toEqual(true); | |
| expect(getECModel(chart).getComponent('graphic', 1) == null).toEqual(true); | |
| }); | |
| it('replace', function () { | |
| chart.setOption({ | |
| graphic: { | |
| type: 'circle', | |
| name: 'a', | |
| shape: { | |
| cx: 50, | |
| cy: 50, | |
| r: 20 | |
| }, | |
| style: { | |
| fill: 'green', | |
| stroke: 'pink', | |
| lineWidth: 3 | |
| } | |
| } | |
| }); | |
| let els: Element[]; | |
| els = getGraphicElements(chart, 'graphic'); | |
| expect(els.length === 2).toEqual(true); | |
| expect(els[0].type === 'group').toEqual(true); | |
| expect(els[1].name === 'a' && els[1].type === 'circle').toEqual(true); | |
| chart.setOption({ | |
| graphic: { | |
| type: 'rect', | |
| $action: 'replace', | |
| name: 'b', | |
| shape: { | |
| x: 50, | |
| y: 50, | |
| width: 20, | |
| height: 60 | |
| }, | |
| style: { | |
| fill: 'green', | |
| stroke: 'pink', | |
| lineWidth: 3 | |
| } | |
| } | |
| }); | |
| els = getGraphicElements(chart, 'graphic'); | |
| expect(els.length === 2).toEqual(true); | |
| expect(els[0].type === 'group').toEqual(true); | |
| expect(els[1].name === 'b' && els[1].type === 'rect').toEqual(true); | |
| expect((els[1] as any).shape && (els[1] as any).shape.width === 20).toEqual(true); | |
| }); | |
| function getDeleteSourceOption() { | |
| return { | |
| graphic: [ | |
| { | |
| type: 'text', | |
| name: 'textname', | |
| style: { | |
| text: 'asdf哈呵', | |
| font: '40px sans-serif', | |
| x: 100, | |
| y: 40 | |
| } | |
| }, | |
| { | |
| id: 'rrr', | |
| name: 'ringname', | |
| type: 'ring', | |
| shape: { | |
| cx: 50, | |
| cy: 150, | |
| r: 20, | |
| r0: 5 | |
| } | |
| }, | |
| { | |
| id: 'xxx', | |
| name: 'rectname', | |
| type: 'rect', | |
| shape: { | |
| x: 250, | |
| y: 50, | |
| width: 20, | |
| height: 80 | |
| } | |
| } | |
| ] | |
| }; | |
| } | |
| function checkDeteteSource(chart: EChartsType) { | |
| const els = getGraphicElements(chart, 'graphic'); | |
| expect(els.length === 4); | |
| expect(els[1].type === 'text' && els[1].name === 'textname').toEqual(true); | |
| expect(els[2].type === 'ring' && els[2].name === 'ringname').toEqual(true); | |
| expect(els[3].type === 'rect' && els[3].name === 'rectname').toEqual(true); | |
| } | |
| it('deleteBy$action', function () { | |
| chart.setOption(getDeleteSourceOption()); | |
| checkDeteteSource(chart); | |
| chart.setOption({ | |
| graphic: { | |
| id: 'rrr', | |
| $action: 'remove' | |
| } | |
| }); | |
| const els = getGraphicElements(chart, 'graphic'); | |
| expect(els.length === 3); | |
| expect(els[1].type === 'text' && els[1].name === 'textname').toEqual(true); | |
| expect(els[2].type === 'rect' && els[2].name === 'rectname').toEqual(true); | |
| }); | |
| it('deleteBySetOptionNotMerge', function () { | |
| chart.setOption(getDeleteSourceOption()); | |
| checkDeteteSource(chart); | |
| chart.setOption({ | |
| graphic: { | |
| type: 'rect', | |
| name: 'rectname2', | |
| shape: { | |
| y: 100, | |
| x: 250, | |
| width: 40, | |
| height: 140 | |
| }, | |
| style: { | |
| fill: 'blue' | |
| } | |
| } | |
| }, true); | |
| const els = getGraphicElements(chart, 'graphic'); | |
| expect(els.length === 2); | |
| expect(els[1].type === 'rect' && els[1].name === 'rectname2').toEqual(true); | |
| }); | |
| it('deleteByClear', function () { | |
| chart.setOption(getDeleteSourceOption()); | |
| checkDeteteSource(chart); | |
| chart.clear(); | |
| const els = getGraphicElements(chart, 'graphic'); | |
| expect(els.length === 0); | |
| }); | |
| function checkMergeElements(chart: EChartsType, merged: boolean): void { | |
| const makeIdentityTransformProps = () => ({ | |
| x: 0, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0 | |
| }); | |
| propHasAll(getGraphicElements(chart, 'graphic'), [ | |
| { | |
| ...makeIdentityTransformProps() | |
| }, | |
| { | |
| ...makeIdentityTransformProps(), | |
| style: {}, | |
| shape: { | |
| x: !merged ? 250 : 350, | |
| y: 50, | |
| width: 20, | |
| height: 80 | |
| // r: 0 | |
| } | |
| }, | |
| { | |
| ...makeIdentityTransformProps() | |
| }, | |
| { | |
| ...makeIdentityTransformProps(), | |
| style: { | |
| fill: !merged ? 'yellow' : 'pink' | |
| }, | |
| shape: { | |
| x: 30, | |
| y: 30, | |
| width: 10, | |
| height: 20 | |
| // r: 0 | |
| } | |
| }, | |
| { | |
| ...makeIdentityTransformProps(), | |
| style: !merged | |
| ? {} | |
| : { | |
| fill: 'green' | |
| }, | |
| shape: { | |
| cx: !merged ? 50 : 150, | |
| cy: 150, | |
| r: 20, | |
| r0: 5 | |
| } | |
| } | |
| ]); | |
| } | |
| it('mergeTroughFlatForamt', function () { | |
| chart.setOption({ | |
| graphic: [ | |
| { | |
| type: 'rect', | |
| shape: { | |
| x: 250, | |
| y: 50, | |
| width: 20, | |
| height: 80 | |
| } | |
| }, | |
| { | |
| type: 'group', | |
| children: [ | |
| { | |
| id: 'ing', | |
| type: 'rect', | |
| shape: { | |
| x: 30, | |
| y: 30, | |
| width: 10, | |
| height: 20 | |
| }, | |
| style: { | |
| fill: 'yellow' | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| id: 'rrr', | |
| type: 'ring', | |
| shape: { | |
| cx: 50, | |
| cy: 150, | |
| r: 20, | |
| r0: 5 | |
| } | |
| } | |
| ] | |
| }); | |
| checkMergeElements(chart, false); | |
| chart.setOption({ | |
| graphic: [ | |
| { | |
| shape: { | |
| x: 350 | |
| } | |
| }, | |
| { | |
| id: 'rrr', | |
| shape: { | |
| cx: 150 | |
| }, | |
| style: { | |
| fill: 'green' | |
| } | |
| }, | |
| // flat mode | |
| { | |
| id: 'ing', | |
| style: { | |
| fill: 'pink' | |
| } | |
| } | |
| ] | |
| }); | |
| checkMergeElements(chart, true); | |
| }); | |
| }); | |
| describe('groupLRTB', function () { | |
| function getOption() { | |
| return { | |
| graphic: [ | |
| { | |
| type: 'text', | |
| bottom: 0, | |
| right: 0, | |
| rotation: Math.PI / 4, | |
| style: { | |
| font: '24px Microsoft YaHei', | |
| text: '全屏右下角' | |
| }, | |
| z: 100 | |
| }, | |
| tmpConvertImageOption({ | |
| id: 'uriimg', | |
| type: 'image', | |
| originX: 20, | |
| originY: 20, | |
| left: 10, | |
| top: 10, | |
| style: { | |
| image: imageURI, | |
| width: 80, | |
| height: 80, | |
| opacity: 0.5 | |
| } | |
| }), | |
| { | |
| type: 'group', | |
| id: 'gr', | |
| width: 230, | |
| height: 110, | |
| x: 70, | |
| y: 90, | |
| children: [ | |
| { | |
| type: 'rect', | |
| shape: { | |
| width: 230, | |
| height: 80 | |
| }, | |
| style: { | |
| stroke: 'red', | |
| fill: 'transparent', | |
| lineWidth: 2 | |
| }, | |
| z: 100 | |
| }, | |
| { | |
| type: 'rect', | |
| shape: { | |
| width: 60, | |
| height: 110 | |
| }, | |
| style: { | |
| stroke: 'red', | |
| fill: 'transparent', | |
| lineWidth: 2 | |
| }, | |
| z: 100 | |
| }, | |
| { | |
| id: 'grouptext', | |
| type: 'text', | |
| bottom: 0, | |
| right: 0, | |
| rotation: 0.5, | |
| style: { | |
| font: '14px Microsoft YaHei', | |
| text: 'group最右下角' | |
| }, | |
| z: 100 | |
| } | |
| ] | |
| }, | |
| { | |
| type: 'text', | |
| bottom: 0, | |
| left: 'center', | |
| style: { | |
| font: '18px sans-serif', | |
| text: '全屏最下中间\n这是多行文字\n这是第三行' | |
| }, | |
| z: 100 | |
| } | |
| ] | |
| }; | |
| } | |
| function checkLocations(chart: EChartsType, uriimgChanged?: boolean) { | |
| propHasAll(getGraphicElements(chart, 'graphic'), [ | |
| { | |
| x: 0, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0 | |
| }, | |
| {/* FIXME: node-canvas measure issue casue behavior different from browser. comment out it temporarily. | |
| x: 98.17662350913716, | |
| y: 133.02943725152284, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0.7853981633974483, | |
| style: { | |
| font: '24px Microsoft YaHei', | |
| text: '全屏右下角', | |
| textVerticalAlign: null, | |
| verticalAlign: null | |
| } | |
| */}, | |
| !uriimgChanged | |
| ? tmpConvertImageOption({ | |
| x: 10, | |
| y: 10, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| height: 80, | |
| opacity: 0.5, | |
| width: 80, | |
| image: imageURI | |
| } | |
| }) | |
| : tmpConvertImageOption({ | |
| x: 61, | |
| y: 45, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| height: 60, | |
| opacity: 0.5, | |
| width: 78, | |
| image: imageURI | |
| } | |
| }), | |
| { | |
| x: 70, | |
| y: 90, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0 | |
| }, | |
| { | |
| x: 0, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| stroke: 'red', | |
| fill: 'transparent', | |
| lineWidth: 2 | |
| }, | |
| shape: { | |
| width: 230, | |
| height: 80, | |
| x: 0, | |
| y: 0 | |
| // r: 0, | |
| } | |
| }, | |
| { | |
| x: 0, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| stroke: 'red', | |
| fill: 'transparent', | |
| lineWidth: 2 | |
| }, | |
| shape: { | |
| width: 60, | |
| height: 110, | |
| x: 0, | |
| y: 0 | |
| // r: 0, | |
| } | |
| }, | |
| {/* FIXME: node-canvas measure issue casue behavior different from browser. comment out it temporarily. | |
| x: 145.47972137162424, | |
| y: 97.71384413353478, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0.5, | |
| style: { | |
| font: '14px Microsoft YaHei', | |
| text: 'group最右下角', | |
| textVerticalAlign: null, | |
| verticalAlign: null | |
| } | |
| */}, | |
| {/* FIXME: node-canvas measure issue casue behavior different from browser. comment out it temporarily. | |
| x: 46, | |
| y: 96, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| font: '18px sans-serif', | |
| text: '全屏最下中间\n这是多行文字\n这是第三行', | |
| textVerticalAlign: null, | |
| verticalAlign: null | |
| } | |
| */} | |
| ]); | |
| } | |
| function checkResizedLocations(chart: EChartsType) { | |
| propHasAll(getGraphicElements(chart, 'graphic'), [ | |
| { | |
| x: 0, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0 | |
| }, | |
| {/* FIXME: node-canvas measure issue casue behavior different from browser. comment out it temporarily. | |
| x: 98.17662350913716, | |
| y: 133.02943725152286, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0.7853981633974483, | |
| style: { | |
| font: '24px Microsoft YaHei', | |
| text: '全屏右下角', | |
| textVerticalAlign: null, | |
| verticalAlign: null | |
| } | |
| */}, | |
| tmpConvertImageOption({ | |
| x: 10, | |
| y: 10, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| image: imageURI, | |
| width: 80, | |
| height: 80, | |
| opacity: 0.5 | |
| } | |
| }), | |
| { | |
| x: 70, | |
| y: 90, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0 | |
| }, | |
| { | |
| x: 0, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| stroke: 'red', | |
| fill: 'transparent', | |
| lineWidth: 2 | |
| }, | |
| shape: { | |
| width: 230, | |
| height: 80, | |
| x: 0, | |
| y: 0 | |
| // r: 0, | |
| } | |
| }, | |
| { | |
| x: 0, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| stroke: 'red', | |
| fill: 'transparent', | |
| lineWidth: 2 | |
| }, | |
| shape: { | |
| width: 60, | |
| height: 110, | |
| x: 0, | |
| y: 0 | |
| // r: 0, | |
| } | |
| }, | |
| {/* FIXME: node-canvas measure issue casue behavior different from browser. comment out it temporarily. | |
| x: 145.47972137162424, | |
| y: 97.71384413353478, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0.5, | |
| style: { | |
| font: '14px Microsoft YaHei', | |
| text: 'group最右下角', | |
| textVerticalAlign: null, | |
| verticalAlign: null | |
| } | |
| */}, | |
| {/* FIXME: node-canvas measure issue casue behavior different from browser. comment out it temporarily. | |
| x: 46, | |
| y: 96, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| font: '18px sans-serif', | |
| text: '全屏最下中间\n这是多行文字\n这是第三行', | |
| textVerticalAlign: null, | |
| verticalAlign: null | |
| } | |
| */} | |
| ]); | |
| } | |
| it('getAndGet', function () { | |
| const myChart = createChart({ | |
| width: 200, | |
| height: 150 | |
| }); | |
| myChart.setOption(getOption()); | |
| checkLocations(myChart); | |
| // Set option using getOption | |
| chart.setOption(myChart.getOption()); | |
| // Check again, should be the same as before. | |
| checkLocations(myChart); | |
| myChart.dispose(); | |
| }); | |
| // Test modify location by setOption. | |
| // And test center and middle. | |
| it('modifyAndCenter', function () { | |
| const myChart = createChart({ | |
| width: 200, | |
| height: 150 | |
| }); | |
| myChart.setOption(getOption()); | |
| checkLocations(myChart); | |
| myChart.setOption({ | |
| graphic: [tmpConvertImageOption({ | |
| id: 'uriimg', | |
| left: 'center', | |
| top: 'middle', | |
| style: { | |
| width: 78, | |
| height: 60 | |
| } | |
| })] | |
| }); | |
| checkLocations(myChart, true); | |
| myChart.dispose(); | |
| }); | |
| it('resize', function () { | |
| const myChart = createChart({ | |
| width: 200, | |
| height: 150 | |
| }); | |
| myChart.setOption(getOption()); | |
| checkLocations(myChart); | |
| myChart.resize({ | |
| width: 220, | |
| height: 300 | |
| }); | |
| checkResizedLocations(myChart); | |
| myChart.dispose(); | |
| }); | |
| }); | |
| describe('boundingAndRotation', function () { | |
| function getOption(): EChartsOption { | |
| return { | |
| legend: { | |
| data: ['高度(km)与气温(°C)变化关系'] | |
| }, | |
| xAxis: { | |
| }, | |
| yAxis: { | |
| type: 'category', | |
| data: ['0', '10', '20', '30', '40', '50', '60', '70', '80'] | |
| }, | |
| graphic: [ | |
| tmpConvertImageOption({ | |
| type: 'image', | |
| id: 'img', | |
| z: -10, | |
| right: 0, | |
| top: 0, | |
| bounding: 'raw', | |
| originX: 75, | |
| originY: 75, | |
| style: { | |
| fill: '#000', | |
| image: imageURI, | |
| width: 150, | |
| height: 150, | |
| opacity: 0.4 | |
| } as any | |
| }), | |
| { | |
| type: 'group', | |
| id: 'rectgroup1', | |
| bottom: 0, | |
| right: 0, | |
| bounding: 'raw', | |
| children: [ | |
| { | |
| type: 'rect', | |
| left: 'center', | |
| top: 'center', | |
| shape: { | |
| width: 20, | |
| height: 80 | |
| }, | |
| style: { | |
| stroke: 'green', | |
| fill: 'transparent' | |
| } | |
| }, | |
| { | |
| type: 'rect', | |
| left: 'center', | |
| top: 'center', | |
| shape: { | |
| width: 80, | |
| height: 20 | |
| }, | |
| style: { | |
| stroke: 'green', | |
| fill: 'transparent' | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| type: 'rect', | |
| id: 'rect2', | |
| bottom: 0, | |
| right: 'center', | |
| shape: { | |
| width: 50, | |
| height: 80 | |
| }, | |
| style: { | |
| stroke: 'green', | |
| fill: 'transparent' | |
| } | |
| }, | |
| { | |
| type: 'group', | |
| id: 'textGroup1', | |
| left: '10%', | |
| top: 'center', | |
| scaleX: 1, | |
| scaleY: 0.5, | |
| children: [ | |
| { | |
| type: 'rect', | |
| z: 100, | |
| left: 'center', | |
| top: 'center', | |
| shape: { | |
| width: 170, | |
| height: 70 | |
| }, | |
| style: { | |
| fill: '#fff', | |
| stroke: '#999', | |
| lineWidth: 2, | |
| shadowBlur: 8, | |
| shadowOffsetX: 3, | |
| shadowOffsetY: 3, | |
| shadowColor: 'rgba(0,0,0,0.3)' | |
| } | |
| }, | |
| { | |
| type: 'text', | |
| z: 100, | |
| top: 'middle', | |
| left: 'center', | |
| style: { | |
| text: [ | |
| '横轴表示温度,单位是°C', | |
| '纵轴表示高度,单位是km', | |
| '右上角有一个图片做的水印' | |
| ].join('\n'), | |
| font: '12px Microsoft YaHei' | |
| } | |
| } | |
| ] | |
| } | |
| ], | |
| series: [ | |
| { | |
| name: '高度(km)与气温(°C)变化关系', | |
| type: 'line', | |
| data: [15, -50, -56.5, -46.5, -22.1, -2.5, -27.7, -55.7, -76.5] | |
| } | |
| ] | |
| }; | |
| } | |
| function checkLocations(chart: EChartsType, rotated?: boolean) { | |
| propHasAll(getGraphicElements(chart, 'graphic'), [ | |
| { | |
| x: 0, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0 | |
| }, | |
| tmpConvertImageOption({ | |
| x: 350, | |
| y: 0, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: !rotated ? 0 : 0.6283185307179586, | |
| style: { | |
| // fill: '#000', | |
| image: imageURI, | |
| width: 150, | |
| height: 150, | |
| opacity: 0.4 | |
| } | |
| }), | |
| { | |
| x: 500, | |
| y: 400, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: !rotated ? 0 : 0.6283185307179586 | |
| }, | |
| { | |
| x: -10, | |
| y: -40, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| stroke: 'green', | |
| fill: 'transparent' | |
| }, | |
| shape: { | |
| width: 20, | |
| height: 80, | |
| x: 0, | |
| y: 0 | |
| // r: 0, | |
| } | |
| }, | |
| { | |
| x: -40, | |
| y: -10, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| stroke: 'green', | |
| fill: 'transparent' | |
| }, | |
| shape: { | |
| width: 80, | |
| height: 20, | |
| x: 0, | |
| y: 0 | |
| // r: 0, | |
| } | |
| }, | |
| { | |
| x: !rotated ? 225 : 206.2631650489274, | |
| y: !rotated ? 319.5 : 334.5802393266705, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: !rotated ? 0 : 0.6283185307179586, | |
| style: { | |
| stroke: 'green', | |
| fill: 'transparent' | |
| }, | |
| shape: { | |
| width: 50, | |
| height: 80, | |
| x: 0, | |
| y: 0 | |
| // r: 0, | |
| } | |
| }, | |
| { | |
| x: !rotated ? 136 : 130.15559605751, | |
| y: 200, | |
| scaleX: 1, | |
| scaleY: 0.5, | |
| rotation: !rotated ? 0 : 0.6283185307179586 | |
| }, | |
| { | |
| x: -85, | |
| y: -35, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| fill: '#fff', | |
| stroke: '#999', | |
| lineWidth: 2, | |
| shadowBlur: 8, | |
| shadowOffsetX: 3, | |
| shadowOffsetY: 3, | |
| shadowColor: 'rgba(0,0,0,0.3)' | |
| }, | |
| shape: { | |
| width: 170, | |
| height: 70, | |
| x: 0, | |
| y: 0 | |
| // r: 0, | |
| } | |
| }, | |
| {/* FIXME: node-canvas measure issue casue behavior different from browser. comment out it temporarily. | |
| x: -72, | |
| y: -18, | |
| scaleX: 1, | |
| scaleY: 1, | |
| rotation: 0, | |
| style: { | |
| text: '横轴表示温度,单位是°C\n纵轴表示高度,单位是km\n右上角有一个图片做的水印', | |
| font: '12px Microsoft YaHei', | |
| textVerticalAlign: null, | |
| verticalAlign: null | |
| } | |
| */} | |
| ]); | |
| } | |
| it('bounding', function () { | |
| chart.setOption(getOption()); | |
| checkLocations(chart); | |
| // Set option using getOption | |
| chart.setOption(chart.getOption()); | |
| // Check again, should be the same as before. | |
| checkLocations(chart); | |
| const rotation = Math.PI / 5; | |
| chart.setOption({ | |
| graphic: [{ | |
| id: 'img', | |
| bounding: 'raw', | |
| originX: 75, | |
| originY: 75, | |
| rotation: rotation | |
| } as any, { | |
| id: 'rectgroup1', | |
| rotation: rotation | |
| }, { | |
| id: 'rect2', | |
| rotation: rotation | |
| }, { | |
| id: 'textGroup1', | |
| rotation: rotation | |
| }] | |
| }); | |
| checkLocations(chart, true); | |
| }); | |
| }); | |
| }); |