diff --git a/.github/workflows/pr-preview.yml b/.github/workflows/pr-preview.yml index 70804d19d7..5ff31130f9 100644 --- a/.github/workflows/pr-preview.yml +++ b/.github/workflows/pr-preview.yml @@ -46,10 +46,12 @@ jobs: workflow: ${{ github.event.workflow.id }} run_id: ${{ github.event.workflow_run.id }} name: pr_preview + path: pr-dist if_no_artifact_found: fail - name: Output PR metadata id: pr-metadata + working-directory: pr-dist run: | echo "NUMBER=$(cat pr_number)" >> $GITHUB_OUTPUT echo "COMMIT_SHA=$(cat pr_commit_sha)" >> $GITHUB_OUTPUT @@ -59,6 +61,7 @@ jobs: env: PR_NUMBER: ${{ steps.pr-metadata.outputs.NUMBER }} SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} + working-directory: pr-dist run: | export SURGE_DOMAIN=https://echarts-pr-$PR_NUMBER.surge.sh npx surge --project ./package --domain $SURGE_DOMAIN --token $SURGE_TOKEN diff --git a/.vscode/settings.json b/.vscode/settings.json index c7c1623bc4..68348ac459 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "typescript.tsdk": "./node_modules/typescript/lib" -} \ No newline at end of file + "typescript.tsdk": "./node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true +} diff --git a/src/chart/candlestick/CandlestickSeries.ts b/src/chart/candlestick/CandlestickSeries.ts index 019e1c55f4..f152fce2cf 100644 --- a/src/chart/candlestick/CandlestickSeries.ts +++ b/src/chart/candlestick/CandlestickSeries.ts @@ -124,7 +124,6 @@ class CandlestickSeriesModel extends SeriesModel { }, emphasis: { - scale: true, itemStyle: { borderWidth: 2 } diff --git a/src/chart/candlestick/CandlestickView.ts b/src/chart/candlestick/CandlestickView.ts index 3d05e81c70..728291424c 100644 --- a/src/chart/candlestick/CandlestickView.ts +++ b/src/chart/candlestick/CandlestickView.ts @@ -20,7 +20,7 @@ import * as zrUtil from 'zrender/src/core/util'; import ChartView from '../../view/Chart'; import * as graphic from '../../util/graphic'; -import { setStatesStylesFromModel } from '../../util/states'; +import { setStatesStylesFromModel, toggleHoverEmphasis } from '../../util/states'; import Path, { PathProps } from 'zrender/src/graphic/Path'; import {createClipPath} from '../helper/createClipPathFromCoordSys'; import CandlestickSeriesModel, { CandlestickDataItemOption } from './CandlestickSeries'; @@ -33,6 +33,7 @@ import { CoordinateSystemClipArea } from '../../coord/CoordinateSystem'; import Model from '../../model/Model'; import { saveOldStyle } from '../../animation/basicTransition'; import Element from 'zrender/src/Element'; +import { getBorderColor, getColor } from './candlestickVisual'; const SKIP_PROPS = ['color', 'borderColor'] as const; @@ -294,6 +295,19 @@ function setBoxCommon(el: NormalBoxPath, data: SeriesData, dataIndex: number, is el.__simpleBox = isSimpleBox; setStatesStylesFromModel(el, itemModel); + + const sign = data.getItemLayout(dataIndex).sign; + zrUtil.each(el.states, (state, stateName) => { + const stateModel = itemModel.getModel(stateName as any); + const color = getColor(sign, stateModel); + const borderColor = getBorderColor(sign, stateModel) || color; + const stateStyle = state.style || (state.style = {}); + color && (stateStyle.fill = color); + borderColor && (stateStyle.stroke = borderColor); + }); + + const emphasisModel = itemModel.getModel('emphasis'); + toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); } function transInit(points: number[][], itemLayout: CandlestickItemLayout) { @@ -391,12 +405,9 @@ function createLarge( function setLargeStyle(sign: number, el: LargeBoxPath, seriesModel: CandlestickSeriesModel, data: SeriesData) { // TODO put in visual? - let borderColor = seriesModel.get(['itemStyle', sign > 0 ? 'borderColor' : 'borderColor0']) + const borderColor = getBorderColor(sign, seriesModel) // Use color for border color by default. - || seriesModel.get(['itemStyle', sign > 0 ? 'color' : 'color0']); - if (sign === 0) { - borderColor = seriesModel.get(['itemStyle', 'borderColorDoji']); - } + || getColor(sign, seriesModel); // Color must be excluded. // Because symbol provide setColor individually to set fill and stroke diff --git a/src/chart/candlestick/candlestickVisual.ts b/src/chart/candlestick/candlestickVisual.ts index 8882d63333..a665ea3b69 100644 --- a/src/chart/candlestick/candlestickVisual.ts +++ b/src/chart/candlestick/candlestickVisual.ts @@ -29,6 +29,21 @@ const dojiBorderColorQuery = ['itemStyle', 'borderColorDoji'] as const; const positiveColorQuery = ['itemStyle', 'color'] as const; const negativeColorQuery = ['itemStyle', 'color0'] as const; +export function getColor(sign: number, model: Model>) { + return model.get( + sign > 0 ? positiveColorQuery : negativeColorQuery + ); +} + +export function getBorderColor(sign: number, model: Model>) { + return model.get( + sign === 0 ? dojiBorderColorQuery + : sign > 0 + ? positiveBorderColorQuery + : negativeBorderColorQuery + ); +} + const candlestickVisual: StageHandler = { seriesType: 'candlestick', @@ -39,22 +54,6 @@ const candlestickVisual: StageHandler = { performRawSeries: true, reset: function (seriesModel: CandlestickSeriesModel, ecModel) { - - function getColor(sign: number, model: Model>) { - return model.get( - sign > 0 ? positiveColorQuery : negativeColorQuery - ); - } - - function getBorderColor(sign: number, model: Model>) { - return model.get( - sign === 0 ? dojiBorderColorQuery - : sign > 0 - ? positiveBorderColorQuery - : negativeBorderColorQuery - ); - } - // Only visible series has each data be visual encoded if (ecModel.isSeriesFiltered(seriesModel)) { return; diff --git a/src/chart/line/LineView.ts b/src/chart/line/LineView.ts index 9672eb720b..be4ff3571e 100644 --- a/src/chart/line/LineView.ts +++ b/src/chart/line/LineView.ts @@ -624,6 +624,8 @@ class LineView extends ChartView { this._symbolDraw = symbolDraw; this._lineGroup = lineGroup; + + this._changePolyState = zrUtil.bind(this._changePolyState, this); } render(seriesModel: LineSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) { @@ -885,9 +887,7 @@ class LineView extends ChartView { toggleHoverEmphasis(polygon, focus, blurScope, emphasisDisabled); } - const changePolyState = (toState: DisplayState) => { - this._changePolyState(toState); - }; + const changePolyState = this._changePolyState; data.eachItemGraphicEl(function (el) { // Switch polyline / polygon state if element changed its state. diff --git a/src/chart/pie/labelLayout.ts b/src/chart/pie/labelLayout.ts index 934b49cadc..5052ca236b 100644 --- a/src/chart/pie/labelLayout.ts +++ b/src/chart/pie/labelLayout.ts @@ -89,7 +89,7 @@ function adjustSingleSide( const rA = r + item.len; const rA2 = rA * rA; // Use ellipse implicit function to calculate x - const dx = Math.sqrt((1 - Math.abs(dy * dy / rB2)) * rA2); + const dx = Math.sqrt(Math.abs((1 - dy * dy / rB2) * rA2)); const newX = cx + (dx + item.len2) * dir; const deltaX = newX - item.label.x; const newTargetWidth = item.targetTextWidth - deltaX * dir; diff --git a/src/chart/treemap/TreemapSeries.ts b/src/chart/treemap/TreemapSeries.ts index 571475e714..a38446ed85 100644 --- a/src/chart/treemap/TreemapSeries.ts +++ b/src/chart/treemap/TreemapSeries.ts @@ -144,7 +144,9 @@ export interface TreemapSeriesNodeItemOption extends TreemapSeriesVisualOption, color?: ColorString[] | 'none' - decal?: DecalObject[] | 'none' + decal?: DecalObject[] | 'none', + + cursor?: string } export interface TreemapSeriesOption diff --git a/src/chart/treemap/TreemapView.ts b/src/chart/treemap/TreemapView.ts index bc59c28544..a0b892e1ee 100644 --- a/src/chart/treemap/TreemapView.ts +++ b/src/chart/treemap/TreemapView.ts @@ -877,6 +877,9 @@ function renderNode( // Only for enabling highlight/downplay. data.setItemGraphicEl(thisNode.dataIndex, group); + const cursorStyle = nodeModel.getShallow('cursor'); + cursorStyle && content.attr('cursor', cursorStyle); + enableHoverFocus(group, focusOrIndices, blurScope); } diff --git a/src/component/axis/CartesianAxisView.ts b/src/component/axis/CartesianAxisView.ts index 3cc48e3041..abc3e8cff7 100644 --- a/src/component/axis/CartesianAxisView.ts +++ b/src/component/axis/CartesianAxisView.ts @@ -123,6 +123,8 @@ const axisElementBuilders: Record = {}; + + const actionLegendIndices: number[] = []; + ecModel.eachComponent({ mainType: 'legend', query: payload }, function (legendModel: LegendModel) { + if (isAllSelect) { legendModel[methodName](); } else { legendModel[methodName](payload.name); - isSelected = legendModel.isSelected(payload.name); } - const legendData = legendModel.getData(); - each(legendData, function (model) { - const name = model.get('name'); - // Wrap element - if (name === '\n' || name === '') { - return; - } - const isItemSelected = legendModel.isSelected(name); - if (selectedMap.hasOwnProperty(name)) { - // Unselected if any legend is unselected - selectedMap[name] = selectedMap[name] && isItemSelected; - } - else { - selectedMap[name] = isItemSelected; - } + + makeSelectedMap(legendModel, selectedMap); + + actionLegendIndices.push(legendModel.componentIndex); + }); + + const allSelectedMap: Record = {}; + + // make selectedMap from all legend components + ecModel.eachComponent('legend', function (legendModel: LegendModel) { + each(selectedMap, function (isSelected, name) { + // Force other legend has same selected status + // Or the first is toggled to true and other are toggled to false + // In the case one legend has some item unSelected in option. And if other legend + // doesn't has the item, they will assume it is selected. + legendModel[isSelected ? 'select' : 'unSelect'](name); }); + + makeSelectedMap(legendModel, allSelectedMap); }); + // Return the event explicitly - return (methodName === 'allSelect' || methodName === 'inverseSelect') + return isAllSelect ? { - selected: selectedMap + selected: allSelectedMap, + // return legendIndex array to tell the developers which legends are allSelect / inverseSelect + legendIndex: actionLegendIndices } : { name: payload.name, - selected: selectedMap + selected: allSelectedMap }; } -export function installLegendAction(registers) { +function makeSelectedMap(legendModel: LegendModel, out?: Record) { + const selectedMap: Record = out || {}; + each(legendModel.getData(), function (model) { + const name = model.get('name'); + // Wrap element + if (name === '\n' || name === '') { + return; + } + const isItemSelected = legendModel.isSelected(name); + if (hasOwn(selectedMap, name)) { + // Unselected if any legend is unselected + selectedMap[name] = selectedMap[name] && isItemSelected; + } + else { + selectedMap[name] = isItemSelected; + } + }); + return selectedMap; +} + +export function installLegendAction(registers: EChartsExtensionInstallRegisters) { /** * @event legendToggleSelect * @type {Object} @@ -113,4 +135,4 @@ export function installLegendAction(registers) { 'legendUnSelect', 'legendunselected', curry(legendSelectActionHandler, 'unSelect') ); -} \ No newline at end of file +} diff --git a/src/coord/Axis.ts b/src/coord/Axis.ts index 5a33a33973..bdaca28735 100644 --- a/src/coord/Axis.ts +++ b/src/coord/Axis.ts @@ -302,7 +302,7 @@ function fixOnBandTicksCoords( let diffSize; if (ticksLen === 1) { ticksCoords[0].coord = axisExtent[0]; - last = ticksCoords[1] = {coord: axisExtent[1]}; + last = ticksCoords[1] = {coord: axisExtent[1], tickValue: ticksCoords[0].tickValue}; } else { const crossLen = ticksCoords[ticksLen - 1].tickValue - ticksCoords[0].tickValue; @@ -315,7 +315,7 @@ function fixOnBandTicksCoords( const dataExtent = axis.scale.getExtent(); diffSize = 1 + dataExtent[1] - ticksCoords[ticksLen - 1].tickValue; - last = {coord: ticksCoords[ticksLen - 1].coord + shift * diffSize}; + last = {coord: ticksCoords[ticksLen - 1].coord + shift * diffSize, tickValue: dataExtent[1] + 1}; ticksCoords.push(last); } diff --git a/src/coord/axisCommonTypes.ts b/src/coord/axisCommonTypes.ts index 5ebdab3a1c..fe4e4fc6f6 100644 --- a/src/coord/axisCommonTypes.ts +++ b/src/coord/axisCommonTypes.ts @@ -258,7 +258,11 @@ interface MinorTickOption { interface SplitLineOption { show?: boolean, - interval?: 'auto' | number | ((index:number, value: string) => boolean) + interval?: 'auto' | number | ((index:number, value: string) => boolean), + // true | false + showMinLine?: boolean, + // true | false + showMaxLine?: boolean, // colors will display in turn lineStyle?: LineStyleOption } diff --git a/src/coord/axisDefault.ts b/src/coord/axisDefault.ts index 4d2c6674b3..ae589f365a 100644 --- a/src/coord/axisDefault.ts +++ b/src/coord/axisDefault.ts @@ -93,6 +93,8 @@ const defaultOption: AxisBaseOption = { }, splitLine: { show: true, + showMinLine: true, + showMaxLine: true, lineStyle: { color: ['#E0E6F1'], width: 1, diff --git a/src/coord/axisHelper.ts b/src/coord/axisHelper.ts index 53485fb31e..76d42a8d16 100644 --- a/src/coord/axisHelper.ts +++ b/src/coord/axisHelper.ts @@ -115,7 +115,7 @@ function adjustScaleForOverflow( // Get Axis Length const axisExtent = model.axis.getExtent(); - const axisLength = axisExtent[1] - axisExtent[0]; + const axisLength = Math.abs(axisExtent[1] - axisExtent[0]); // Get bars on current base axis and calculate min and max overflow const barsOnCurrentAxis = retrieveColumnLayout(barWidthAndOffset, model.axis); diff --git a/src/coord/axisTickLabelBuilder.ts b/src/coord/axisTickLabelBuilder.ts index e7f7bbb088..329ad6447b 100644 --- a/src/coord/axisTickLabelBuilder.ts +++ b/src/coord/axisTickLabelBuilder.ts @@ -84,8 +84,11 @@ export function createAxisLabels(axis: Axis): { const custom = axis.getLabelModel().get('customValues'); if (custom) { const labelFormatter = makeLabelFormatter(axis); + const extent = axis.scale.getExtent(); + const tickNumbers = tickValuesToNumbers(axis, custom); + const ticks = zrUtil.filter(tickNumbers, val => val >= extent[0] && val <= extent[1]); return { - labels: tickValuesToNumbers(axis, custom).map(numval => { + labels: zrUtil.map(ticks, numval => { const tick = {value: numval}; return { formattedLabel: labelFormatter(tick), @@ -115,8 +118,10 @@ export function createAxisTicks(axis: Axis, tickModel: AxisBaseModel): { } { const custom = axis.getTickModel().get('customValues'); if (custom) { + const extent = axis.scale.getExtent(); + const tickNumbers = tickValuesToNumbers(axis, custom); return { - ticks: tickValuesToNumbers(axis, custom) + ticks: zrUtil.filter(tickNumbers, val => val >= extent[0] && val <= extent[1]) }; } // Only ordinal scale support tick interval diff --git a/src/i18n/langSV.ts b/src/i18n/langSV.ts new file mode 100644 index 0000000000..83f3874ca9 --- /dev/null +++ b/src/i18n/langSV.ts @@ -0,0 +1,144 @@ +/* + * 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. + */ + +/** + * Language: Swedish. + */ + +export default { + time: { + month: [ + 'januari', 'februari', 'mars', 'april', 'maj', 'juni', + 'juli', 'augusti', 'september', 'oktober', 'november', 'december', + ], + monthAbbr: [ + 'jan', 'feb', 'mar', 'apr', 'maj', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec', + ], + dayOfWeek: [ + 'söndag', 'måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag', + ], + dayOfWeekAbbr: [ + 'sön', 'mån', 'tis', 'ons', 'tor', 'fre', 'lör', + ], + }, + legend: { + selector: { + all: 'Alla', + inverse: 'Omvänd', + }, + }, + toolbox: { + brush: { + title: { + rect: 'Rektangelurval', + polygon: 'Lassomarkering', + lineX: 'Vågrätt urval', + lineY: 'Lodrätt urval', + keep: 'Behåll urval', + clear: 'Rensa urval', + }, + }, + dataView: { + title: 'Datavy', + lang: ['Datavy', 'Stäng', 'Uppdatera'], + }, + dataZoom: { + title: { + zoom: 'Zooma', + back: 'Återställ zoom', + }, + }, + magicType: { + title: { + line: 'Byt till linjediagram', + bar: 'Byt till stapeldiagram', + stack: 'Stapla', + tiled: 'Sida vid sida', + }, + }, + restore: { + title: 'Återställ', + }, + saveAsImage: { + title: 'Spara som bild', + lang: ['Högerklicka för att spara bild'], + }, + }, + series: { + typeNames: { + pie: 'Cirkeldiagram', + bar: 'Stapeldiagram', + line: 'Linjediagram', + scatter: 'Punktdiagram', + effectScatter: 'Punktdiagram med rippeleffekt', + radar: 'Radardiagram', + tree: 'Träd', + treemap: 'Trädkarta', + boxplot: 'Lådagram', + candlestick: 'Candlestick', + k: 'K-linjediagram', + heatmap: 'Värmekarta', + map: 'Karta', + parallel: 'Parallella koordinater', + lines: 'Linjediagram', + graph: 'Relationsgraf', + sankey: 'Sankeydiagram', + funnel: 'Trattdiagram', + gauge: 'Mätare', + pictorialBar: 'Bildstapel', + themeRiver: 'Tematisk flod', + sunburst: 'Solburstdiagram', + custom: 'Anpassat', + chart: 'Diagram', + }, + }, + aria: { + general: { + withTitle: 'Detta är ett diagram om "{title}"', + withoutTitle: 'Detta är ett diagram', + }, + series: { + single: { + prefix: '', + withName: ' med typnamn {name}.', + withoutName: ' med typ {seriesType}.', + }, + multiple: { + prefix: '. Det består av {seriesCount} serier.', + withName: ' Serien {seriesId} är en {seriesType} som representerar {seriesName}.', + withoutName: ' Serien {seriesId} är en {seriesType}.', + separator: { + middle: '', + end: '', + }, + }, + }, + data: { + allData: 'Data är som följer: ', + partialData: 'De första {displayCnt} objekten är: ', + withName: 'datavärdet för {name} är {value}', + withoutName: '{value}', + separator: { + middle: ', ', + end: '. ', + }, + }, + }, + }; \ No newline at end of file diff --git a/src/util/types.ts b/src/util/types.ts index 653b687d91..1d085c198f 100644 --- a/src/util/types.ts +++ b/src/util/types.ts @@ -1733,7 +1733,8 @@ export interface AriaLabelOption { separator?: { middle?: string; end?: string; - } + }, + excludeDimensionId?: number[] } } diff --git a/src/visual/aria.ts b/src/visual/aria.ts index a184776274..33187c4f9d 100644 --- a/src/visual/aria.ts +++ b/src/visual/aria.ts @@ -218,11 +218,14 @@ export default function ariaVisual(ecModel: GlobalModel, api: ExtensionAPI) { const middleSeparator = labelModel.get(['data', 'separator', 'middle']); const endSeparator = labelModel.get(['data', 'separator', 'end']); + const excludeDimensionId = labelModel.get(['data', 'excludeDimensionId']); const dataLabels = []; for (let i = 0; i < data.count(); i++) { if (i < maxDataCnt) { const name = data.getName(i); - const value = data.getValues(i); + const value = !excludeDimensionId ? data.getValues(i) + : zrUtil.filter(data.getValues(i), (v, j) => + zrUtil.indexOf(excludeDimensionId, j) === -1); const dataLabel = labelModel.get(['data', name ? 'withName' : 'withoutName']); dataLabels.push( replace(dataLabel, { diff --git a/test/axis-customTicks.html b/test/axis-customTicks.html index 24f9c7dc97..7f79f099d8 100644 --- a/test/axis-customTicks.html +++ b/test/axis-customTicks.html @@ -38,6 +38,8 @@
+
+
+ + + + + diff --git a/test/axis-splitLine.html b/test/axis-splitLine.html new file mode 100644 index 0000000000..2dfd1a320d --- /dev/null +++ b/test/axis-splitLine.html @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + +
+ + + + + + diff --git a/test/candlestick-case.html b/test/candlestick-case.html index 2e5a33f747..6a408a644a 100644 --- a/test/candlestick-case.html +++ b/test/candlestick-case.html @@ -38,7 +38,7 @@
- +
@@ -363,6 +363,55 @@ }); + diff --git a/test/legend-action.html b/test/legend-action.html new file mode 100644 index 0000000000..90dda2e3f2 --- /dev/null +++ b/test/legend-action.html @@ -0,0 +1,136 @@ + + + + + + + + + + + + +
+ + + + diff --git a/test/runTest/actions/__meta__.json b/test/runTest/actions/__meta__.json index 26eac6dd21..c9abb1e8c8 100644 --- a/test/runTest/actions/__meta__.json +++ b/test/runTest/actions/__meta__.json @@ -45,7 +45,7 @@ "calendar-heatmap": 1, "calendar-month": 1, "candlestick": 2, - "candlestick-case": 1, + "candlestick-case": 2, "candlestick-empty": 1, "candlestick-large": 4, "candlestick-large2": 1, @@ -122,6 +122,7 @@ "label-position": 1, "largeLine-tooltip": 1, "legend": 11, + "legend-action": 1, "legend-visualMapColor": 2, "line": 1, "line-animation": 1, diff --git a/test/runTest/actions/candlestick-case.json b/test/runTest/actions/candlestick-case.json index bc02692b43..0b07b405ea 100644 --- a/test/runTest/actions/candlestick-case.json +++ b/test/runTest/actions/candlestick-case.json @@ -1 +1 @@ -[{"name":"Action 1","ops":[{"type":"mousedown","time":300,"x":50,"y":77},{"type":"mouseup","time":423,"x":50,"y":77},{"time":424,"delay":400,"type":"screenshot-auto"}],"scrollY":0,"scrollX":0,"timestamp":1626405373145}] \ No newline at end of file +[{"name":"Action 1","ops":[{"type":"mousedown","time":300,"x":50,"y":77},{"type":"mouseup","time":423,"x":50,"y":77},{"time":424,"delay":400,"type":"screenshot-auto"}],"scrollY":0,"scrollX":0,"timestamp":1626405373145},{"name":"Action 2","ops":[{"type":"mousemove","time":303,"x":145,"y":215},{"type":"mousemove","time":505,"x":169,"y":336},{"type":"mousemove","time":722,"x":170,"y":369},{"type":"screenshot","time":1492},{"type":"mousemove","time":1769,"x":199,"y":364},{"type":"mousemove","time":1969,"x":287,"y":329},{"type":"mousemove","time":2172,"x":315,"y":329},{"type":"screenshot","time":2995},{"type":"mousemove","time":3319,"x":318,"y":329},{"type":"mousemove","time":3523,"x":446,"y":340},{"type":"mousemove","time":3742,"x":462,"y":343},{"type":"screenshot","time":4427},{"type":"mousemove","time":4885,"x":462,"y":344},{"type":"mousemove","time":5085,"x":639,"y":376},{"type":"mousemove","time":5290,"x":638,"y":381},{"type":"screenshot","time":6027}],"scrollY":357,"scrollX":0,"timestamp":1719893340178}] \ No newline at end of file diff --git a/test/runTest/actions/legend-action.json b/test/runTest/actions/legend-action.json new file mode 100644 index 0000000000..bd0b61577f --- /dev/null +++ b/test/runTest/actions/legend-action.json @@ -0,0 +1 @@ +[{"name":"Action 1","ops":[{"type":"mousemove","time":301,"x":470,"y":19},{"type":"mousemove","time":500,"x":289,"y":47},{"type":"mousemove","time":700,"x":197,"y":115},{"type":"mousemove","time":903,"x":188,"y":132},{"type":"mousedown","time":1024,"x":188,"y":132},{"type":"mouseup","time":1169,"x":188,"y":132},{"time":1170,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":1483,"x":201,"y":132},{"type":"mousemove","time":1689,"x":273,"y":120},{"type":"mousemove","time":1900,"x":325,"y":117},{"type":"mousemove","time":2103,"x":242,"y":126},{"type":"mousemove","time":2266,"x":242,"y":127},{"type":"mousedown","time":2408,"x":257,"y":133},{"type":"mousemove","time":2469,"x":257,"y":133},{"type":"mouseup","time":2552,"x":257,"y":133},{"time":2553,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":2899,"x":261,"y":133},{"type":"mousemove","time":3099,"x":268,"y":132},{"type":"mousemove","time":3299,"x":297,"y":129},{"type":"mousedown","time":3472,"x":299,"y":129},{"type":"mousemove","time":3503,"x":299,"y":129},{"type":"mouseup","time":3646,"x":299,"y":129},{"time":3647,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":4016,"x":304,"y":129},{"type":"mousemove","time":4216,"x":474,"y":132},{"type":"mousemove","time":4421,"x":548,"y":141},{"type":"mousemove","time":4669,"x":525,"y":131},{"type":"mousedown","time":4681,"x":525,"y":131},{"type":"mouseup","time":4816,"x":525,"y":131},{"time":4817,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":4999,"x":526,"y":130},{"type":"mousemove","time":5199,"x":622,"y":130},{"type":"mousemove","time":5399,"x":646,"y":131},{"type":"mousedown","time":5521,"x":651,"y":132},{"type":"mousemove","time":5604,"x":651,"y":133},{"type":"mouseup","time":5655,"x":651,"y":133},{"time":5656,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":5886,"x":651,"y":133},{"type":"mousemove","time":6050,"x":651,"y":134},{"type":"mousemove","time":6333,"x":661,"y":135},{"type":"mousemove","time":6533,"x":689,"y":134},{"type":"mousedown","time":6648,"x":690,"y":134},{"type":"mousemove","time":6736,"x":690,"y":134},{"type":"mouseup","time":6759,"x":690,"y":134},{"time":6760,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":6983,"x":688,"y":134},{"type":"mousemove","time":7187,"x":659,"y":133},{"type":"mousedown","time":7304,"x":659,"y":133},{"type":"mouseup","time":7438,"x":659,"y":133},{"time":7439,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":7699,"x":651,"y":133},{"type":"mousemove","time":7899,"x":583,"y":135},{"type":"mousemove","time":8105,"x":521,"y":135},{"type":"mousedown","time":8203,"x":521,"y":135},{"type":"mouseup","time":8310,"x":521,"y":135},{"time":8311,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":8432,"x":542,"y":135},{"type":"mousemove","time":8636,"x":640,"y":135},{"type":"mousemove","time":8870,"x":656,"y":134},{"type":"mousedown","time":8896,"x":656,"y":134},{"type":"mouseup","time":9038,"x":656,"y":134},{"time":9039,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":9184,"x":654,"y":130},{"type":"mousemove","time":9387,"x":613,"y":109},{"type":"mousemove","time":9599,"x":582,"y":96},{"type":"mousemove","time":9803,"x":577,"y":94},{"type":"mousedown","time":9927,"x":577,"y":94},{"type":"mouseup","time":10136,"x":577,"y":94},{"time":10137,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":10401,"x":574,"y":93},{"type":"mousemove","time":10603,"x":407,"y":94},{"type":"mousemove","time":10820,"x":304,"y":94},{"type":"mousemove","time":11116,"x":301,"y":94},{"type":"mousedown","time":11319,"x":296,"y":97},{"type":"mousemove","time":11323,"x":296,"y":97},{"type":"mouseup","time":11430,"x":296,"y":97},{"time":11431,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":11616,"x":296,"y":98},{"type":"mousemove","time":11817,"x":246,"y":118},{"type":"mousemove","time":12021,"x":218,"y":135},{"type":"mousedown","time":12137,"x":218,"y":135},{"type":"mouseup","time":12230,"x":218,"y":135},{"time":12231,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":12382,"x":293,"y":133},{"type":"mousemove","time":12583,"x":397,"y":129},{"type":"mousemove","time":12786,"x":441,"y":129},{"type":"mousedown","time":12804,"x":441,"y":129},{"type":"mouseup","time":12886,"x":441,"y":129},{"time":12887,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":12950,"x":419,"y":128},{"type":"mousemove","time":13154,"x":244,"y":79},{"type":"mousemove","time":13366,"x":244,"y":91},{"type":"mousedown","time":13431,"x":245,"y":92},{"type":"mousemove","time":13569,"x":245,"y":92},{"type":"mouseup","time":13574,"x":245,"y":92},{"time":13575,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":13749,"x":256,"y":94},{"type":"mousemove","time":13949,"x":451,"y":91},{"type":"mousemove","time":14153,"x":473,"y":88},{"type":"mousedown","time":14353,"x":473,"y":87},{"type":"mousemove","time":14371,"x":473,"y":87},{"type":"mouseup","time":14520,"x":473,"y":87},{"time":14521,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":15049,"x":474,"y":87},{"type":"mousemove","time":15252,"x":516,"y":83},{"type":"mousemove","time":15487,"x":519,"y":92},{"type":"mousemove","time":15736,"x":514,"y":97},{"type":"mousedown","time":15920,"x":514,"y":97},{"type":"mouseup","time":16054,"x":514,"y":97},{"time":16055,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":16666,"x":531,"y":94},{"type":"mousemove","time":16870,"x":612,"y":81}],"scrollY":0,"scrollX":0,"timestamp":1720675612620}] \ No newline at end of file diff --git a/test/runTest/package-lock.json b/test/runTest/package-lock.json index cd221ad51a..2cce4e0929 100644 --- a/test/runTest/package-lock.json +++ b/test/runTest/package-lock.json @@ -2416,9 +2416,9 @@ "dev": true }, "node_modules/socket.io-client/node_modules/socket.io-parser": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz", - "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.4.tgz", + "integrity": "sha512-z/pFQB3x+EZldRRzORYW1vwVO8m/3ILkswtnpoeU6Ve3cbMWkmHEWDAVJn4QJtchiiFTo5j7UG2QvwxvaA9vow==", "dev": true, "dependencies": { "component-emitter": "~1.3.0", @@ -4724,9 +4724,9 @@ "dev": true }, "socket.io-parser": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz", - "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.4.tgz", + "integrity": "sha512-z/pFQB3x+EZldRRzORYW1vwVO8m/3ILkswtnpoeU6Ve3cbMWkmHEWDAVJn4QJtchiiFTo5j7UG2QvwxvaA9vow==", "dev": true, "requires": { "component-emitter": "~1.3.0", diff --git a/test/treemap-cursor.html b/test/treemap-cursor.html new file mode 100644 index 0000000000..2a415d4ccb --- /dev/null +++ b/test/treemap-cursor.html @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + +
+
+ + + + diff --git a/test/ut/spec/series/aria-columns-exclude.test.ts b/test/ut/spec/series/aria-columns-exclude.test.ts new file mode 100644 index 0000000000..08df08f50d --- /dev/null +++ b/test/ut/spec/series/aria-columns-exclude.test.ts @@ -0,0 +1,97 @@ +/* + * 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 { EChartsType } from '@/src/echarts'; +import { createChart, getECModel } from '../../core/utHelper'; + +describe('aria, omit data', function () { + let chart: EChartsType; + const option = { + 'aria': { + 'enabled': true, + 'data': { + 'excludeDimensionId': [0, 1, 2] + }, + }, + 'dataset': [ + { + 'dimensions': [ + 'lng', + 'lat', + 'name', + 'value', + 'capacity', + ], + 'source': [ + [ + 1.58285827, + 42.099784969, + 'Llosa del Cavall (Navès)', + 17.945, + 80, + ], + [ + 0.960270444, + 41.134931354, + 'Riudecanyes', + 0.401, + 5.32, + ], + ] + + } + ], + 'series': [ + { + 'coordinateSystem': 'geo', + 'encode': { + 'itemName': 'name' + }, + 'type': 'scatter', + } + ], + }; + beforeEach(function () { + chart = createChart(); + }); + + afterEach(function () { + chart.dispose(); + }); + + it('specified columns should be omitted from Aria (geolocation and name)', () => { + chart.setOption(option); + const el = chart.getDom(); + const ariaValue = el.getAttribute('aria-label'); + expect(ariaValue).toContain('Llosa del Cavall (Navès) is 17.945, 80'); + expect(ariaValue).toContain('Riudecanyes is 0.401, 5.32'); + expect(ariaValue).not.toContain(1.58285827); + expect(ariaValue).not.toContain(42.099784969); + expect(ariaValue).not.toContain(0.960270444); + expect(ariaValue).not.toContain(41.134931354); + }); + + it('should not modify the data of the chart', async () => { + chart.setOption(option); + const listData = getECModel(chart).getSeries()[0].getData(); + expect(listData.getValues(0)).toEqual([1.58285827, 42.099784969, 'Llosa del Cavall (Navès)', 17.945, 80]); + expect(listData.getValues(1)).toEqual([0.960270444, 41.134931354, 'Riudecanyes', 0.401, 5.32]); + }); + +});