From f518ce4ec4732a6418547de9683315013e7fe423 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Thu, 27 Feb 2025 14:17:27 +0800 Subject: [PATCH 1/2] fix: fix pos issue with dynamic texture, optmize performance for dynamic texture --- .../fix-dynamic-texture_2025-02-27-06-18.json | 10 + .../base-texture-contribution-render.ts | 58 ++- .../__tests__/browser/src/pages/richtext.ts | 18 +- .../__tests__/browser/src/pages/vchart.ts | 353 ++++++++++++++++-- 4 files changed, 388 insertions(+), 51 deletions(-) create mode 100644 common/changes/@visactor/vrender-core/fix-dynamic-texture_2025-02-27-06-18.json diff --git a/common/changes/@visactor/vrender-core/fix-dynamic-texture_2025-02-27-06-18.json b/common/changes/@visactor/vrender-core/fix-dynamic-texture_2025-02-27-06-18.json new file mode 100644 index 000000000..8957d1b66 --- /dev/null +++ b/common/changes/@visactor/vrender-core/fix-dynamic-texture_2025-02-27-06-18.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-core", + "comment": "fix: fix pos issue with dynamic texture, optmize performance for dynamic texture", + "type": "none" + } + ], + "packageName": "@visactor/vrender-core" +} diff --git a/packages/vrender-core/src/render/contributions/render/contributions/base-texture-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/base-texture-contribution-render.ts index 252153623..0173039d3 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/base-texture-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/base-texture-contribution-render.ts @@ -3,6 +3,7 @@ import { BaseRenderContributionTime } from '../../../../common/enums'; import { createSymbol } from '../../../../graphic'; import type { IBaseRenderContribution, + ICanvas, IContext2d, IDrawContext, IGraphic, @@ -279,11 +280,31 @@ export class DefaultBaseTextureRenderContribution implements IBaseRenderContribu if (textureOptions && textureOptions.dynamicTexture) { // 动态纹理 - context.save(); - context.setCommonStyle(graphic, graphic.attribute, x, y, graphicAttribute); - context.clip(); - const { gridConfig = {} } = textureOptions; + const { gridConfig = {}, useNewCanvas } = textureOptions; const b = graphic.AABBBounds; + x = b.x1; + y = b.y1; + const originalContext = context; + + let newCanvas: ICanvas; + if (useNewCanvas) { + newCanvas = canvasAllocate.allocate({ width: b.width(), height: b.height(), dpr: context.dpr }); + const ctx = newCanvas.getContext('2d'); + ctx.clearRect(0, 0, b.width(), b.height()); + x = 0; + y = 0; + context = ctx; + } + originalContext.save(); + // 避免本级已经transform过了,再用Bounds就重复了 + if (graphic.parent && !graphic.transMatrix.onlyTranslate()) { + const { scrollX = 0, scrollY = 0 } = graphic.parent.attribute; + originalContext.setTransformFromMatrix(graphic.parent.globalTransMatrix); + originalContext.translate(scrollX, scrollY, true); + } + originalContext.setCommonStyle(graphic, graphic.attribute, x, y, graphicAttribute); + originalContext.clip(); + const width = b.width(); const height = b.height(); const padding = texturePadding; @@ -311,11 +332,36 @@ export class DefaultBaseTextureRenderContribution implements IBaseRenderContribu context.closePath(); } context.fillStyle = textureColor; - textureOptions.dynamicTexture(context, i, j, gridRows, gridColumns, textureRatio, graphic); + textureOptions.dynamicTexture( + context, + i, + j, + gridRows, + gridColumns, + textureRatio, + graphic, + b.width(), + b.height() + ); } } + if (useNewCanvas) { + // 不使用外部的opacity,动态纹理的opacity自己设置 + originalContext.globalAlpha = 1; + originalContext.drawImage( + newCanvas.nativeCanvas, + 0, + 0, + newCanvas.nativeCanvas.width, + newCanvas.nativeCanvas.height, + b.x1, + b.y1, + b.width() * originalContext.dpr, + b.height() * originalContext.dpr + ); + } - context.restore(); + originalContext.restore(); } else if (pattern) { context.highPerformanceSave(); context.setCommonStyle(graphic, graphic.attribute, x, y, graphicAttribute); diff --git a/packages/vrender/__tests__/browser/src/pages/richtext.ts b/packages/vrender/__tests__/browser/src/pages/richtext.ts index 2503c39c3..a03debc8d 100644 --- a/packages/vrender/__tests__/browser/src/pages/richtext.ts +++ b/packages/vrender/__tests__/browser/src/pages/richtext.ts @@ -972,13 +972,11 @@ export const page = () => { 'PingFang SC,Helvetica Neue,Microsoft Yahei,system-ui,-apple-system,segoe ui,Roboto,Helvetica,Arial,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol', textAlign: 'center', textBaseline: 'middle', - boundsPadding: [10, 0, 10, 0], fontWeight: 'normal', fillOpacity: 1, ellipsis: true, pickable: true, lineJoin: 'bevel', - stroke: '#ffffff', _debug_bounds: true, zIndex: -1, // maxLineWidth: 200, @@ -989,23 +987,19 @@ export const page = () => { // lineWidth: 0, textConfig: [ { - text: '空值0\n', + text: '', fontSize: 12, textAlign: 'left', fill: '#1F2329' - }, - { - text: '8%', - fontSize: 12, - textAlign: 'left', - fill: '#646A73' } ], z: 0, + width: 0, + height: 0 // width: 30, - width: 31, + // width: 31, // width: 0, - height: 80 + // height: 80 // maxWidth: 200 }); @@ -1034,7 +1028,7 @@ export const page = () => { // .replaceAll('"', '\\"')}; width: 30; height: 30; id: circle-0" />` // ); - // shapes.length = 0; + shapes.length = 0; shapes.push(rt); diff --git a/packages/vrender/__tests__/browser/src/pages/vchart.ts b/packages/vrender/__tests__/browser/src/pages/vchart.ts index 4c1b0e99d..a5dea7823 100644 --- a/packages/vrender/__tests__/browser/src/pages/vchart.ts +++ b/packages/vrender/__tests__/browser/src/pages/vchart.ts @@ -20,57 +20,344 @@ export const page = () => { let i = 0; const spec = { - type: 'bar', - data: [ - { - id: 'barData', - values: [ - { month: 'Monday', sales: 22 }, - { month: 'Tuesday', sales: 13 }, - { month: 'Wednesday', sales: 25 }, - { month: 'Thursday', sales: 29 }, - { month: 'Friday', sales: 38 } - ] - } - ], - bar: { + type: 'area', + data: { + values: [ + { type: 'Nail polish', country: 'Africa', value: 4229 }, + { type: 'Nail polish', country: 'EU', value: 4376 }, + { type: 'Nail polish', country: 'China', value: 3054 }, + { type: 'Nail polish', country: 'USA', value: 12814 }, + { type: 'Eyebrow pencil', country: 'Africa', value: 3932 }, + { type: 'Eyebrow pencil', country: 'EU', value: 3987 }, + { type: 'Eyebrow pencil', country: 'China', value: 5067 }, + { type: 'Eyebrow pencil', country: 'USA', value: 13012 }, + { type: 'Rouge', country: 'Africa', value: 5221 }, + { type: 'Rouge', country: 'EU', value: 3574 }, + { type: 'Rouge', country: 'China', value: 7004 }, + { type: 'Rouge', country: 'USA', value: 11624 }, + { type: 'Lipstick', country: 'Africa', value: 9256 }, + { type: 'Lipstick', country: 'EU', value: 4376 }, + { type: 'Lipstick', country: 'China', value: 9054 }, + { type: 'Lipstick', country: 'USA', value: 8814 }, + { type: 'Eyeshadows', country: 'Africa', value: 3308 }, + { type: 'Eyeshadows', country: 'EU', value: 4572 }, + { type: 'Eyeshadows', country: 'China', value: 12043 }, + { type: 'Eyeshadows', country: 'USA', value: 12998 }, + { type: 'Eyeliner', country: 'Africa', value: 5432 }, + { type: 'Eyeliner', country: 'EU', value: 3417 }, + { type: 'Eyeliner', country: 'China', value: 15067 }, + { type: 'Eyeliner', country: 'USA', value: 12321 }, + { type: 'Foundation', country: 'Africa', value: 13701 }, + { type: 'Foundation', country: 'EU', value: 5231 }, + { type: 'Foundation', country: 'China', value: 10119 }, + { type: 'Foundation', country: 'USA', value: 10342 }, + { type: 'Lip gloss', country: 'Africa', value: 4008 }, + { type: 'Lip gloss', country: 'EU', value: 4572 }, + { type: 'Lip gloss', country: 'China', value: 12043 }, + { type: 'Lip gloss', country: 'USA', value: 22998 }, + { type: 'Mascara', country: 'Africa', value: 18712 }, + { type: 'Mascara', country: 'EU', value: 6134 }, + { type: 'Mascara', country: 'China', value: 10419 }, + { type: 'Mascara', country: 'USA', value: 11261 } + ] + }, + title: { + visible: true, + text: '100% stacked area chart of cosmetic products sales' + }, + line: false, + point: false, + area: { style: { + // boundsMode: 'imprecise', + _debug_bounds: true, texture: 'square', - textureSize: 6, + textureSize: 10, texturePadding: 1, textureRatio: 0, textureColor: 'orange', - textureOptions: { - dynamicTexture: ( - ctx: any, - row: number, - column: number, - rowCount: number, - columnCount: number, - ratio: number, - graphic: any - ) => { - const _r = VRenderKits.randomOpacity(ctx, row, column, rowCount, columnCount, ratio, graphic, 0.5, 0.5); - ctx.globalAlpha = _r; - ctx.fill(); - } + textureOptions: datum => { + const func = + datum.country === 'Africa' + ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => + VRender.randomOpacity(ctx, row, column, rowCount, columnCount, ratio, graphic, 0.3) + : datum.country === 'EU' + ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => + VRender.columnLeftToRight(ctx, row, column, rowCount, columnCount, ratio, graphic) + : datum.country === 'China' + ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => + VRender.columnEdgeToCenter(ctx, row, column, rowCount, columnCount, ratio, graphic) + : (ctx, row, column, rowCount, columnCount, ratio, graphic) => + VRender.particleEffect(ctx, row, column, rowCount, columnCount, ratio, graphic); + return { + useNewCanvas: true, + dynamicTexture: (ctx, row, column, rowCount, columnCount, ratio, graphic) => { + const _r = func(ctx, row, column, rowCount, columnCount, ratio, graphic); + ctx.globalAlpha = _r; + ctx.fillStyle = + datum.country === 'Africa' + ? '#00C1D4' + : datum.country === 'EU' + ? '#FF2F92' + : datum.country === 'China' + ? '#000CEF' + : '#FEC000'; + ctx.fill(); + } + }; } } }, animationAppear: { - bar: { + area: { channel: { - textureRatio: { from: 0, to: 1 } + textureRatio: { + from: 0, + to: 1 + } }, easing: 'linear', duration: 3000, loop: true } }, - xField: 'month', - yField: 'sales' + percent: true, + xField: 'type', + yField: 'value', + seriesField: 'country', + legends: [{ visible: true, position: 'middle', orient: 'bottom' }], + axes: [ + { + orient: 'left', + label: { + formatMethod(val) { + return `${(val * 100).toFixed(2)}%`; + } + } + } + ] }; + // const spec = { + // type: 'pie', + // data: [ + // { + // id: 'id0', + // values: [ + // { type: 'oxygen', value: '46.60' }, + // { type: 'silicon', value: '27.72' }, + // { type: 'aluminum', value: '8.13' }, + // { type: 'iron', value: '5' }, + // { type: 'calcium', value: '3.63' }, + // { type: 'sodium', value: '2.83' }, + // { type: 'potassium', value: '2.59' }, + // { type: 'others', value: '3.5' } + // ] + // } + // ], + // outerRadius: 0.8, + // valueField: 'value', + // categoryField: 'type', + // title: { + // visible: true, + // text: 'Statistics of Surface Element Content' + // }, + // legends: { + // visible: true, + // orient: 'left' + // }, + // label: { + // visible: true + // }, + // pie: { + // style: { + // boundsMode: 'imprecise', + // // _debug_bounds: true, + // texture: 'square', + // textureSize: 5, + // texturePadding: 1, + // textureRatio: 0, + // textureColor: 'orange', + // textureOptions: datum => { + // const colorPools = [ + // { background: '#FFFFFF', particleColor: '#00C1D4' }, + // { background: '#000000', particleColor: '#FF2F92' }, + // { background: '#FFFFFF', particleColor: '#000000' }, + // { background: '#000000', particleColor: '#FFFFFF' } + // ]; + // return { + // dynamicTexture: (ctx, row, column, rowCount, columnCount, ratio, graphic) => { + // const _r = VRenderKits.spiralEffect(ctx, row, column, rowCount, columnCount, ratio, graphic); + // ctx.globalAlpha = _r; + // const i = row * columnCount + column; + // ctx.fillStyle = colorPools[i % colorPools.length].particleColor; + // ctx.fill(); + // } + // }; + // } + // } + // }, + // animationAppear: { + // pie: { + // channel: { + // textureRatio: { + // from: 0, + // to: 1 + // } + // }, + // easing: 'linear', + // duration: 3000, + // loop: true + // } + // }, + // tooltip: { + // mark: { + // content: [ + // { + // key: datum => datum['type'], + // value: datum => datum['value'] + '%' + // } + // ] + // } + // } + // }; + + // const spec = { + // type: 'bar', + // data: [ + // { + // id: 'barData', + // values: [ + // { + // State: 'WY', + // Age: 'Under 5 Years', + // Population: 25635 + // }, + // { + // State: 'WY', + // Age: '5 to 13 Years', + // Population: 1890 + // }, + // { + // State: 'WY', + // Age: '14 to 17 Years', + // Population: 9314 + // }, + // { + // State: 'DC', + // Age: 'Under 5 Years', + // Population: 30352 + // }, + // { + // State: 'DC', + // Age: '5 to 13 Years', + // Population: 20439 + // }, + // { + // State: 'DC', + // Age: '14 to 17 Years', + // Population: 10225 + // }, + // { + // State: 'VT', + // Age: 'Under 5 Years', + // Population: 38253 + // }, + // { + // State: 'VT', + // Age: '5 to 13 Years', + // Population: 42538 + // }, + // { + // State: 'VT', + // Age: '14 to 17 Years', + // Population: 15757 + // }, + // { + // State: 'ND', + // Age: 'Under 5 Years', + // Population: 51896 + // }, + // { + // State: 'ND', + // Age: '5 to 13 Years', + // Population: 67358 + // }, + // { + // State: 'ND', + // Age: '14 to 17 Years', + // Population: 18794 + // }, + // { + // State: 'AK', + // Age: 'Under 5 Years', + // Population: 72083 + // }, + // { + // State: 'AK', + // Age: '5 to 13 Years', + // Population: 85640 + // }, + // { + // State: 'AK', + // Age: '14 to 17 Years', + // Population: 22153 + // } + // ] + // } + // ], + // xField: 'State', + // yField: 'Population', + // seriesField: 'Age', + // percent: true, + // stack: true, + // axes: [{ orient: 'bottom', bandPadding: 0 }], + // bar: { + // style: { + // texture: 'square', + // textureSize: 10, + // texturePadding: 1, + // textureRatio: 0, + // textureColor: 'orange', + // textureOptions: datum => { + // console.log(datum); + // const func = + // datum.Age === 'Under 5 Years' + // ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => + // VRender.randomOpacity(ctx, row, column, rowCount, columnCount, ratio, graphic, 0.3) + // : datum.Age === '5 to 13 Years' + // ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => + // VRender.columnLeftToRight(ctx, row, column, rowCount, columnCount, ratio, graphic) + // : (ctx, row, column, rowCount, columnCount, ratio, graphic) => + // VRender.columnRightToLeft(ctx, row, column, rowCount, columnCount, ratio, graphic); + // return { + // dynamicTexture: (ctx, row, column, rowCount, columnCount, ratio, graphic) => { + // const _r = func(ctx, row, column, rowCount, columnCount, ratio, graphic); + // ctx.globalAlpha = _r; + // const i = row * columnCount + column; + // ctx.fillStyle = + // datum.Age === 'Under 5 Years' ? 'red' : datum.Age === '5 to 13 Years' ? 'blue' : 'green'; + // ctx.fill(); + // } + // }; + // } + // } + // }, + // animationAppear: { + // bar: { + // channel: { + // textureRatio: { + // from: 0, + // to: 1 + // } + // }, + // easing: 'linear', + // duration: 3000, + // loop: true + // } + // } + // }; + const chartSpace = new window.ChartSpace.default(spec, { dom: 'container' }); From 05c0e4eb37101fdd59ba0a87bc172a3e3ce056e3 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Thu, 27 Feb 2025 15:47:00 +0800 Subject: [PATCH 2/2] feat: support beforeDynamicTexture --- .../base-texture-contribution-render.ts | 11 + .../__tests__/browser/src/pages/vchart.ts | 261 ++++++++++++------ 2 files changed, 185 insertions(+), 87 deletions(-) diff --git a/packages/vrender-core/src/render/contributions/render/contributions/base-texture-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/base-texture-contribution-render.ts index 0173039d3..15523a922 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/base-texture-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/base-texture-contribution-render.ts @@ -327,6 +327,17 @@ export class DefaultBaseTextureRenderContribution implements IBaseRenderContribu for (let j = 0; j < gridColumns; j++) { const _x = x + cellSize / 2 + j * cellSize; const _y = y + cellSize / 2 + i * cellSize; + textureOptions.beforeDynamicTexture?.( + context, + i, + j, + gridRows, + gridColumns, + textureRatio, + graphic, + b.width(), + b.height() + ); context.beginPath(); if (parsedPath.draw(context, Math.min(sizeW - gutterColumn, sizeH - gutterRow), _x, _y, 0) === false) { context.closePath(); diff --git a/packages/vrender/__tests__/browser/src/pages/vchart.ts b/packages/vrender/__tests__/browser/src/pages/vchart.ts index a5dea7823..635b5fcf7 100644 --- a/packages/vrender/__tests__/browser/src/pages/vchart.ts +++ b/packages/vrender/__tests__/browser/src/pages/vchart.ts @@ -19,89 +19,60 @@ export const page = () => { const data = [['430(9%)'], ['1,428(23%)'], ['1,386(29%)'], ['1,676(27%)'], ['860(18%)']]; let i = 0; + const path = + 'M 8.25 -11 L 11 -11 V -8.25 L -8.25 11 H -11 V 8.25 L 8.25 -11 Z M -11 -11 H -8.3789 L -11 -8.2539 V -11 Z M 11 11 H 8.3789 L 11 8.2539 V 11 Z'; + const spec = { - type: 'area', - data: { - values: [ - { type: 'Nail polish', country: 'Africa', value: 4229 }, - { type: 'Nail polish', country: 'EU', value: 4376 }, - { type: 'Nail polish', country: 'China', value: 3054 }, - { type: 'Nail polish', country: 'USA', value: 12814 }, - { type: 'Eyebrow pencil', country: 'Africa', value: 3932 }, - { type: 'Eyebrow pencil', country: 'EU', value: 3987 }, - { type: 'Eyebrow pencil', country: 'China', value: 5067 }, - { type: 'Eyebrow pencil', country: 'USA', value: 13012 }, - { type: 'Rouge', country: 'Africa', value: 5221 }, - { type: 'Rouge', country: 'EU', value: 3574 }, - { type: 'Rouge', country: 'China', value: 7004 }, - { type: 'Rouge', country: 'USA', value: 11624 }, - { type: 'Lipstick', country: 'Africa', value: 9256 }, - { type: 'Lipstick', country: 'EU', value: 4376 }, - { type: 'Lipstick', country: 'China', value: 9054 }, - { type: 'Lipstick', country: 'USA', value: 8814 }, - { type: 'Eyeshadows', country: 'Africa', value: 3308 }, - { type: 'Eyeshadows', country: 'EU', value: 4572 }, - { type: 'Eyeshadows', country: 'China', value: 12043 }, - { type: 'Eyeshadows', country: 'USA', value: 12998 }, - { type: 'Eyeliner', country: 'Africa', value: 5432 }, - { type: 'Eyeliner', country: 'EU', value: 3417 }, - { type: 'Eyeliner', country: 'China', value: 15067 }, - { type: 'Eyeliner', country: 'USA', value: 12321 }, - { type: 'Foundation', country: 'Africa', value: 13701 }, - { type: 'Foundation', country: 'EU', value: 5231 }, - { type: 'Foundation', country: 'China', value: 10119 }, - { type: 'Foundation', country: 'USA', value: 10342 }, - { type: 'Lip gloss', country: 'Africa', value: 4008 }, - { type: 'Lip gloss', country: 'EU', value: 4572 }, - { type: 'Lip gloss', country: 'China', value: 12043 }, - { type: 'Lip gloss', country: 'USA', value: 22998 }, - { type: 'Mascara', country: 'Africa', value: 18712 }, - { type: 'Mascara', country: 'EU', value: 6134 }, - { type: 'Mascara', country: 'China', value: 10419 }, - { type: 'Mascara', country: 'USA', value: 11261 } - ] - }, - title: { - visible: true, - text: '100% stacked area chart of cosmetic products sales' - }, - line: false, - point: false, - area: { + type: 'linearProgress', + data: [ + { + id: 'id0', + values: [ + { + type: 'Tradition Industries', + value: 0.795, + text: '79.5%' + }, + { + type: 'Business Companies', + value: 0.25, + text: '25%' + }, + { + type: 'Customer-facing Companies', + value: 0.065, + text: '6.5%' + } + ] + } + ], + direction: 'horizontal', + xField: 'value', + yField: 'type', + seriesField: 'type', + progress: { style: { // boundsMode: 'imprecise', _debug_bounds: true, - texture: 'square', - textureSize: 10, - texturePadding: 1, - textureRatio: 0, + texture: path, + textureSize: 30, + texturePadding: 0, + textureRatio: 1, textureColor: 'orange', textureOptions: datum => { - const func = - datum.country === 'Africa' - ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => - VRender.randomOpacity(ctx, row, column, rowCount, columnCount, ratio, graphic, 0.3) - : datum.country === 'EU' - ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => - VRender.columnLeftToRight(ctx, row, column, rowCount, columnCount, ratio, graphic) - : datum.country === 'China' - ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => - VRender.columnEdgeToCenter(ctx, row, column, rowCount, columnCount, ratio, graphic) - : (ctx, row, column, rowCount, columnCount, ratio, graphic) => - VRender.particleEffect(ctx, row, column, rowCount, columnCount, ratio, graphic); return { - useNewCanvas: true, + // useNewCanvas: true, + beforeDynamicTexture: (ctx, row, column, rowCount, columnCount, ratio, graphic) => { + const dx = ratio - 0.5; + const size = 30; + ctx.translate(dx * size, 0); + }, dynamicTexture: (ctx, row, column, rowCount, columnCount, ratio, graphic) => { - const _r = func(ctx, row, column, rowCount, columnCount, ratio, graphic); - ctx.globalAlpha = _r; - ctx.fillStyle = - datum.country === 'Africa' - ? '#00C1D4' - : datum.country === 'EU' - ? '#FF2F92' - : datum.country === 'China' - ? '#000CEF' - : '#FEC000'; + const dx = ratio - 0.5; + const size = 30; + ctx.translate(-dx * size, 0); + ctx.fillStyle = 'white'; + ctx.globalAlpha = 0.6; ctx.fill(); } }; @@ -109,7 +80,7 @@ export const page = () => { } }, animationAppear: { - area: { + progress: { channel: { textureRatio: { from: 0, @@ -121,23 +92,139 @@ export const page = () => { loop: true } }, - percent: true, - xField: 'type', - yField: 'value', - seriesField: 'country', - legends: [{ visible: true, position: 'middle', orient: 'bottom' }], + cornerRadius: 20, + bandWidth: 30, axes: [ { orient: 'left', - label: { - formatMethod(val) { - return `${(val * 100).toFixed(2)}%`; - } - } - } + label: { visible: true }, + type: 'band', + domainLine: { visible: false }, + tick: { visible: false } + }, + { orient: 'bottom', label: { visible: true }, type: 'linear', visible: false } ] }; + // const spec = { + // type: 'area', + // data: { + // values: [ + // { type: 'Nail polish', country: 'Africa', value: 4229 }, + // { type: 'Nail polish', country: 'EU', value: 4376 }, + // { type: 'Nail polish', country: 'China', value: 3054 }, + // { type: 'Nail polish', country: 'USA', value: 12814 }, + // { type: 'Eyebrow pencil', country: 'Africa', value: 3932 }, + // { type: 'Eyebrow pencil', country: 'EU', value: 3987 }, + // { type: 'Eyebrow pencil', country: 'China', value: 5067 }, + // { type: 'Eyebrow pencil', country: 'USA', value: 13012 }, + // { type: 'Rouge', country: 'Africa', value: 5221 }, + // { type: 'Rouge', country: 'EU', value: 3574 }, + // { type: 'Rouge', country: 'China', value: 7004 }, + // { type: 'Rouge', country: 'USA', value: 11624 }, + // { type: 'Lipstick', country: 'Africa', value: 9256 }, + // { type: 'Lipstick', country: 'EU', value: 4376 }, + // { type: 'Lipstick', country: 'China', value: 9054 }, + // { type: 'Lipstick', country: 'USA', value: 8814 }, + // { type: 'Eyeshadows', country: 'Africa', value: 3308 }, + // { type: 'Eyeshadows', country: 'EU', value: 4572 }, + // { type: 'Eyeshadows', country: 'China', value: 12043 }, + // { type: 'Eyeshadows', country: 'USA', value: 12998 }, + // { type: 'Eyeliner', country: 'Africa', value: 5432 }, + // { type: 'Eyeliner', country: 'EU', value: 3417 }, + // { type: 'Eyeliner', country: 'China', value: 15067 }, + // { type: 'Eyeliner', country: 'USA', value: 12321 }, + // { type: 'Foundation', country: 'Africa', value: 13701 }, + // { type: 'Foundation', country: 'EU', value: 5231 }, + // { type: 'Foundation', country: 'China', value: 10119 }, + // { type: 'Foundation', country: 'USA', value: 10342 }, + // { type: 'Lip gloss', country: 'Africa', value: 4008 }, + // { type: 'Lip gloss', country: 'EU', value: 4572 }, + // { type: 'Lip gloss', country: 'China', value: 12043 }, + // { type: 'Lip gloss', country: 'USA', value: 22998 }, + // { type: 'Mascara', country: 'Africa', value: 18712 }, + // { type: 'Mascara', country: 'EU', value: 6134 }, + // { type: 'Mascara', country: 'China', value: 10419 }, + // { type: 'Mascara', country: 'USA', value: 11261 } + // ] + // }, + // title: { + // visible: true, + // text: '100% stacked area chart of cosmetic products sales' + // }, + // line: false, + // point: false, + // area: { + // style: { + // // boundsMode: 'imprecise', + // _debug_bounds: true, + // texture: 'square', + // textureSize: 10, + // texturePadding: 1, + // textureRatio: 0, + // textureColor: 'orange', + // textureOptions: datum => { + // const func = + // datum.country === 'Africa' + // ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => + // VRender.randomOpacity(ctx, row, column, rowCount, columnCount, ratio, graphic, 0.3) + // : datum.country === 'EU' + // ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => + // VRender.columnLeftToRight(ctx, row, column, rowCount, columnCount, ratio, graphic) + // : datum.country === 'China' + // ? (ctx, row, column, rowCount, columnCount, ratio, graphic) => + // VRender.columnEdgeToCenter(ctx, row, column, rowCount, columnCount, ratio, graphic) + // : (ctx, row, column, rowCount, columnCount, ratio, graphic) => + // VRender.particleEffect(ctx, row, column, rowCount, columnCount, ratio, graphic); + // return { + // useNewCanvas: true, + // dynamicTexture: (ctx, row, column, rowCount, columnCount, ratio, graphic) => { + // const _r = func(ctx, row, column, rowCount, columnCount, ratio, graphic); + // ctx.globalAlpha = _r; + // ctx.fillStyle = + // datum.country === 'Africa' + // ? '#00C1D4' + // : datum.country === 'EU' + // ? '#FF2F92' + // : datum.country === 'China' + // ? '#000CEF' + // : '#FEC000'; + // ctx.fill(); + // } + // }; + // } + // } + // }, + // animationAppear: { + // area: { + // channel: { + // textureRatio: { + // from: 0, + // to: 1 + // } + // }, + // easing: 'linear', + // duration: 3000, + // loop: true + // } + // }, + // percent: true, + // xField: 'type', + // yField: 'value', + // seriesField: 'country', + // legends: [{ visible: true, position: 'middle', orient: 'bottom' }], + // axes: [ + // { + // orient: 'left', + // label: { + // formatMethod(val) { + // return `${(val * 100).toFixed(2)}%`; + // } + // } + // } + // ] + // }; + // const spec = { // type: 'pie', // data: [