@@ -3,49 +3,180 @@ title: flexX
33order : 2
44---
55
6- 根据指定通道设置 x 比例尺的 flex 属性,实现不等宽矩形的效果。
6+ ## 概述
77
8- ## 开始使用
8+ flexX 是一个用于调整柱形图宽度的转换方法。它允许根据数据值动态调整柱形的宽度,使得柱形的宽度能够反映另一个数据维度,从而在可视化中展示更多的信息维度。这种转换特别适用于:
99
10- <img alt =" flexX " src =" https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*NfBaTZtrUhoAAAAAAAAAAAAADmJ7AQ/original " width =" 600 " />
10+ 1 . 需要同时展示两个定量变量的场景,如国家 GDP(宽度)和人均 GDP(高度)的关系
11+ 2 . 展示市场份额和细分结构的商业分析图表
12+ 3 . 人口统计数据的多维度可视化,如人口总数(宽度)和年龄分布(高度)
13+ 4 . 销售数据分析,如销售总额(宽度)和利润率(高度)的关系
1114
12- 在对应的 mark 中有 transform 方法可以使用数据的变换 。
15+ 通过 flexX 转换,我们可以在传统柱状图的基础上增加一个额外的数据维度,使图表更加信息丰富 。
1316
14- ``` ts
15- import { Chart } from ' @antv/g2' ;
16-
17- const chart = new Chart ({
18- container: ' container' ,
19- width: 1000 ,
20- paddingBottom: 100 ,
21- });
22-
23- chart
24- .interval ()
25- .data ({
26- type: ' fetch' ,
27- value:
28- ' https://gw.alipayobjects.com/os/bmw-prod/90873879-09d7-4842-a493-03fb560267bc.csv' ,
29- })
30- .transform ({ type: ' flexX' , field: ' gdp' })
31- .encode (' x' , ' country' )
32- .encode (' y' , ' value' )
33- .encode (' color' , ' country' )
34- .axis (' y' , { labelFormatter: ' ~s' });
35-
36- chart .render ();
17+ ``` js | ob
18+ (() => {
19+ const chart = new G2.Chart ();
20+ chart .options ({
21+ width: 800 ,
22+ height: 400 ,
23+ paddingLeft: 60 ,
24+ });
25+
26+ chart
27+ .interval ()
28+ .data ([
29+ { category: ' 电子产品' , sales: 1200000 , profitRate: 0.15 },
30+ { category: ' 服装' , sales: 800000 , profitRate: 0.25 },
31+ { category: ' 食品' , sales: 600000 , profitRate: 0.12 },
32+ { category: ' 家具' , sales: 400000 , profitRate: 0.18 },
33+ { category: ' 图书' , sales: 200000 , profitRate: 0.3 },
34+ ])
35+ .transform ({ type: ' flexX' , field: ' sales' })
36+ .encode (' x' , ' category' )
37+ .encode (' y' , ' profitRate' )
38+ .encode (' color' , ' category' )
39+ .scale (' y' , { nice: true })
40+ .axis (' y' , {
41+ title: ' 利润率' ,
42+ labelFormatter: ' .0%' ,
43+ });
44+
45+ chart .render ();
46+ return chart .getContainer ();
47+ })();
3748```
3849
39- ## 选项
50+ ## 使用场景
51+
52+ 1 . ** 不等宽柱形图** :当需要柱子的宽度反映数据的某个维度时,例如国家 GDP 总量决定柱子宽度,而柱高展示人均 GDP。
4053
41- | 属性 | 描述 | 类型 | 默认值 |
42- | ------- | ------------------------------------------- | ------------------------------------- | ------ |
43- | field | 指定生成权重数组的字段,优先级比 channel 高 | ` string ` \| ` (d: any) => Primitive[] ` | |
44- | channel | 指定生成权重数组的通道 | ` string ` | ` y ` |
45- | reducer | 聚合每一组权重的函数 | ` Reducer ` | ` sum ` |
54+ 2 . ** 马利梅柯图(Marimekko Chart)** :结合 stackY 和 normalizeY 转换,可以创建复杂的商业分析图表,展示市场份额和细分数据。
55+ <br />
56+ 使用国家 GDP 总量作为柱形宽度,人均 GDP 作为柱形高度:
57+
58+ ``` js | ob
59+ (() => {
60+ const chart = new G2.Chart ();
61+ chart .options ({
62+ width: 1000 ,
63+ paddingBottom: 100 ,
64+ });
65+
66+ chart
67+ .interval ()
68+ .data ({
69+ type: ' fetch' ,
70+ value:
71+ ' https://gw.alipayobjects.com/os/bmw-prod/90873879-09d7-4842-a493-03fb560267bc.csv' ,
72+ })
73+ .transform ({ type: ' flexX' , field: ' gdp' })
74+ .encode (' x' , ' country' )
75+ .encode (' y' , ' value' )
76+ .encode (' color' , ' country' )
77+ .axis (' y' , { labelFormatter: ' ~s' });
78+ chart .render ();
79+ return chart .getContainer ();
80+ })();
81+ ```
82+
83+ ## 配置项
84+
85+ | 属性 | 描述 | 类型 | 默认值 | 必选 |
86+ | ------- | ---------------------- | ------------------------------------- | ------ | ---- |
87+ | field | 指定生成权重数组的字段 | ` string ` \| ` (d: any) => Primitive[] ` | - | 否 |
88+ | channel | 指定生成权重数组的通道 | string | ` y ` | 否 |
89+ | reducer | 聚合每一组权重的函数 | ` Reducer ` | sum | 否 |
90+
91+ ### 类型定义
4692
4793``` ts
94+ // 基础数据类型
4895type Primitive = number | string | boolean | Date ;
4996
97+ // 聚合函数类型
5098type Reducer = ' sum' | ((I : number [], V : Primitive []) => Primitive );
5199```
100+
101+ ### 参数说明
102+
103+ - ** field** : 用于指定柱形宽度的数据字段。当设置了 field 时,其优先级高于 channel。
104+ - ** channel** : 指定用于计算柱形宽度的编码通道,默认使用 'y' 通道的值。
105+ - ** reducer** : 聚合函数,用于计算最终的宽度值。默认使用 'sum' 求和。
106+
107+ ## 示例
108+
109+ ### 1. 马利梅柯图(Marimekko Chart)
110+
111+ 结合 stackY 和 normalizeY 转换创建市场分析图:
112+
113+ ``` js | ob
114+ (() => {
115+ const chart = new G2.Chart ();
116+ chart .options ({
117+ width: 900 ,
118+ height: 800 ,
119+ paddingLeft: 0 ,
120+ paddingRight: 0 ,
121+ });
122+
123+ chart
124+ .interval ()
125+ .data ({
126+ type: ' fetch' ,
127+ value:
128+ ' https://gw.alipayobjects.com/os/bmw-prod/3041da62-1bf4-4849-aac3-01a387544bf4.csv' ,
129+ })
130+ .transform ({ type: ' flexX' , reducer: ' sum' })
131+ .transform ({ type: ' stackY' })
132+ .transform ({ type: ' normalizeY' })
133+ .encode (' x' , ' market' )
134+ .encode (' y' , ' value' )
135+ .encode (' color' , ' segment' )
136+ .scale (' x' , { paddingOuter: 0 , paddingInner: 0.01 });
137+ chart .render ();
138+ return chart .getContainer ();
139+ })();
140+ ```
141+
142+ 在这个例子中,flexX 转换使得每个市场部分的宽度与其总价值成正比,结合堆叠和归一化处理,可以清晰地展示市场份额的分布情况。
143+
144+ 这个例子展示了如何使用 flexX 来可视化人口数据,其中柱子的宽度表示州/省的总人口数量,高度表示人口密度,颜色区分不同地区。
145+
146+ ### 2. 时间序列数据分析
147+
148+ 展示每月销售数据,使用交易量作为宽度,价格变化率作为高度:
149+
150+ ``` js | ob
151+ (() => {
152+ const chart = new G2.Chart ();
153+ chart .options ({
154+ type: ' interval' ,
155+ width: 800 ,
156+ height: 400 ,
157+ paddingLeft: 60 ,
158+ data: [
159+ { month: ' 1月' , volume: 5000 , priceChange: 0.08 },
160+ { month: ' 2月' , volume: 8000 , priceChange: - 0.05 },
161+ { month: ' 3月' , volume: 12000 , priceChange: 0.12 },
162+ { month: ' 4月' , volume: 6000 , priceChange: - 0.03 },
163+ { month: ' 5月' , volume: 9000 , priceChange: 0.15 },
164+ { month: ' 6月' , volume: 15000 , priceChange: - 0.08 },
165+ ],
166+ encode: {
167+ x: ' month' ,
168+ y: ' priceChange' ,
169+ color : (d ) => (d .priceChange > 0 ? ' red' : ' green' ),
170+ },
171+ transform: [{ type: ' flexX' , field: ' volume' }],
172+ scale: { y: { nice: true } },
173+ style: { radius: 4 },
174+ axis: { y: { title: ' 价格变化率' , labelFormatter: ' .0%' } },
175+ });
176+
177+ chart .render ();
178+ return chart .getContainer ();
179+ })();
180+ ```
181+
182+ 这个时间序列示例展示了如何使用 flexX 来可视化交易数据,其中柱形的宽度表示交易量大小,高度表示价格变化率,颜色区分涨跌情况。通过这种方式,我们可以同时观察到交易活跃度和价格走势的关系。
0 commit comments