diff --git a/README.md b/README.md index 381747fe16..a3547dffcf 100644 --- a/README.md +++ b/README.md @@ -70,11 +70,11 @@ const chart = new Chart({ // Specify visualization. chart - .interval() // Create an interval mark and add it to the chart. - .data(data) // Bind data for this mark. - .encode('x', 'genre') // Assign genre column to x position channel. - .encode('y', 'sold') // Assign sold column to y position channel. - .encode('color', 'genre'); // Assign genre column to color channel. + .interval() // Create an interval mark and add it to the chart. + .data(data) // Bind data for this mark. + .encode('x', 'genre') // Assign genre column to x position channel. + .encode('y', 'sold') // Assign sold column to y position channel. + .encode('color', 'genre'); // Assign genre column to color channel. // Render visualization. chart.render(); diff --git a/__tests__/integration/snapshots/static/mockIntervalSeriesOrder.svg b/__tests__/integration/snapshots/static/mockIntervalSeriesOrder.svg new file mode 100644 index 0000000000..096690317c --- /dev/null +++ b/__tests__/integration/snapshots/static/mockIntervalSeriesOrder.svg @@ -0,0 +1,1251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 普通330铝 + + + + + + + + + + + + + + + + + + + + 普通500铝 + + + + + + + + + + + + + + + + + + + + 330铝 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 青岛啤酒 + + + + + + + 百威啤酒 + + + + + + + 黄河啤酒 + + + + + + + 千岛湖啤酒 + + + + + + + + + 品牌 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 20000 + + + + + + + 40000 + + + + + + + 60000 + + + + + + + 80000 + + + + + + + 100000 + + + + + + + + + 上期收入 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/__tests__/integration/snapshots/static/productIntervalStackedGrouped.svg b/__tests__/integration/snapshots/static/productIntervalStackedGrouped.svg index f7cf58b77e..cd1552319b 100644 --- a/__tests__/integration/snapshots/static/productIntervalStackedGrouped.svg +++ b/__tests__/integration/snapshots/static/productIntervalStackedGrouped.svg @@ -6,16 +6,16 @@ color-interpolation-filters="sRGB" > - - + + - + - + - + - + - + @@ -820,10 +820,10 @@ - + - - - - - + + + + + - + - + - - - - - + + + + + - - - - + - - + + - + - - - - - - + - - - - 60 - - - - + - + diff --git a/__tests__/plots/static/index.ts b/__tests__/plots/static/index.ts index d9496b1b39..5951cf3e3e 100644 --- a/__tests__/plots/static/index.ts +++ b/__tests__/plots/static/index.ts @@ -336,3 +336,4 @@ export { flareElementPointMoveAreaNormalizeY } from './flare-element-point-move- export { stackBarAnnotationStyleText } from './stack-bar-annotation-style-text'; export { githubStarIntervalDarkThemeTransparent } from './github-star-interval-dark-theme-transparent'; export { diamondIntervalGroupX } from './diamond-interval-group-x'; +export { mockIntervalSeriesOrder } from './mock-interval-series-order'; diff --git a/__tests__/plots/static/mock-interval-series-order.ts b/__tests__/plots/static/mock-interval-series-order.ts new file mode 100644 index 0000000000..5f870a23df --- /dev/null +++ b/__tests__/plots/static/mock-interval-series-order.ts @@ -0,0 +1,27 @@ +import { G2Spec } from '../../../src'; + +export function mockIntervalSeriesOrder(): G2Spec { + return { + type: 'interval', + data: [ + { 品牌: '青岛啤酒', 上期收入: 43062, 产品: '普通330铝' }, + { 品牌: '青岛啤酒', 上期收入: 100058, 产品: '普通500铝' }, + { 品牌: '青岛啤酒', 上期收入: 25123, 产品: '330铝' }, + { 品牌: '百威啤酒', 上期收入: 50264.253, 产品: '330铝' }, + { 品牌: '百威啤酒', 上期收入: 57803, 产品: '普通330铝' }, + { 品牌: '百威啤酒', 上期收入: 82342, 产品: '普通500铝' }, + { 品牌: '黄河啤酒', 上期收入: 79286, 产品: '普通500铝' }, + { 品牌: '黄河啤酒', 上期收入: 43473, 产品: '330铝' }, + { 品牌: '黄河啤酒', 上期收入: 56775, 产品: '普通330铝' }, + { 品牌: '千岛湖啤酒', 上期收入: 54418, 产品: '330铝' }, + { 品牌: '千岛湖啤酒', 上期收入: 65048, 产品: '普通330铝' }, + { 品牌: '千岛湖啤酒', 上期收入: 72355, 产品: '普通500铝' }, + ], + encode: { + x: '品牌', + y: '上期收入', + color: '产品', + }, + transform: [{ type: 'dodgeX' }], + }; +} diff --git a/src/transform/diffY.ts b/src/transform/diffY.ts index bf879c6fb7..aec6b7904c 100644 --- a/src/transform/diffY.ts +++ b/src/transform/diffY.ts @@ -2,7 +2,7 @@ import { deepMix } from '@antv/util'; import { TransformComponent as TC } from '../runtime'; import { DiffYTransform } from '../spec'; import { column, columnOf, maybeColumnOf } from './utils/helper'; -import { normalizeComparator, createGroups, applyOrder } from './utils/order'; +import { createGroups } from './utils/order'; export type DiffYOptions = Omit; @@ -34,7 +34,7 @@ export const DiffY: TC = (options = {}) => { // Get the max Y of current group with current Y exclude. const max = Math.max(...YG.filter((_, _i) => _i !== idx)); // Diff Y value. - newY1[i] = Y[i] > max ? max : Y[i]; + newY1[i] = +Y[i] > max ? max : Y[i]; } } diff --git a/src/transform/dodgeX.ts b/src/transform/dodgeX.ts index b276b3ea18..eeb37db053 100644 --- a/src/transform/dodgeX.ts +++ b/src/transform/dodgeX.ts @@ -24,14 +24,26 @@ export const DodgeX: TC = (options = {}) => { const [Y] = columnOf(encode, 'y'); const [S] = maybeColumnOf(encode, 'series', 'color'); const domainSeries = domainOf(S, scaleSeries); + const newMark = deepMix({}, mark, { + scale: { + series: { + domain: domainSeries, + paddingInner: padding, + }, + }, + }); // Create groups and apply specified order for each group. const groups = createGroups(groupBy, I, mark); const createComparator = normalizeComparator(orderBy); + + if (!createComparator) { + return [I, deepMix(newMark, { encode: { series: column(S) } })]; + } + + // Sort and Update series for each mark related to series domain. const comparator = createComparator(data, Y, S); if (comparator) applyOrder(groups, comparator); - - // Update series for each mark related to series domain. const newS = new Array(I.length); for (const G of groups) { if (reverse) G.reverse(); @@ -42,15 +54,9 @@ export const DodgeX: TC = (options = {}) => { return [ I, - deepMix({}, mark, { - scale: { - series: { - domain: domainSeries, - paddingInner: padding, - }, - }, + deepMix(newMark, { encode: { - series: column(newS), + series: column(orderBy ? newS : S), }, }), ]; diff --git a/src/transform/stackY.ts b/src/transform/stackY.ts index ced97db47d..c4e991622f 100644 --- a/src/transform/stackY.ts +++ b/src/transform/stackY.ts @@ -35,7 +35,7 @@ export const StackY: TC = (options = {}) => { // Create groups and apply specified order for each group. const groups = createGroups(groupBy, I, mark); - const createComparator = normalizeComparator(orderBy); + const createComparator = normalizeComparator(orderBy) ?? (() => null); const comparator = createComparator(data, Y, S); if (comparator) applyOrder(groups, comparator); diff --git a/src/transform/utils/order.ts b/src/transform/utils/order.ts index 9d8ef2ce20..7057f661b6 100644 --- a/src/transform/utils/order.ts +++ b/src/transform/utils/order.ts @@ -34,14 +34,16 @@ export function createGroups( return Array.from(group(I, key).values()); } -export function normalizeComparator(order: Order): IndexComparatorFactory { +export function normalizeComparator( + order: Order, +): IndexComparatorFactory | null { if (Array.isArray(order)) return createFieldsOrder(order); if (typeof order === 'function') return createFunctionOrder(order); if (order === 'series') return createSeriesOrder; if (order === 'value') return createValueOrder; if (order === 'sum') return createSumOrder; if (order === 'maxIndex') return createMaxIndexOrder; - return () => null; + return null; } export function applyOrder(groups: number[][], comparator: IndexComparator) {