Skip to content

Commit 5f9a935

Browse files
committed
feat: 新增 "如何用 S2 买房" demo
1 parent 987a414 commit 5f9a935

File tree

2 files changed

+301
-0
lines changed

2 files changed

+301
-0
lines changed
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
import React, { useState } from 'react';
2+
import ReactDOM from 'react-dom';
3+
import { Select, InputNumber, Space } from 'antd';
4+
import {
5+
every,
6+
filter, isNil,
7+
last,
8+
map,
9+
omit,
10+
} from 'lodash';
11+
import { SheetComponent } from '@antv/s2-react';
12+
import insertCss from 'insert-css';
13+
14+
const ID_SEPARATOR = '[&]';
15+
const defaultHouseInfo = {
16+
name: ['15#', '16#', '21#', '22#'],
17+
unit: [1, 2],
18+
building: [1, 2, 3, 4, 5],
19+
nearStreet: [true, false],
20+
property: ['公寓', '住宅'],
21+
toward: ['东', '南', '西', '北'],
22+
level: [
23+
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
24+
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39,
25+
],
26+
area: [92, 111, 114, 119, 120, 123, 125, 135, 138],
27+
};
28+
const s2Options = {
29+
width: 700,
30+
height: 580,
31+
pagination: {
32+
pageSize: 50,
33+
current: 1,
34+
},
35+
conditions: {
36+
// 背景 (background) 字段标记
37+
background: [
38+
{
39+
field: 'area',
40+
mapping(value) {
41+
if (value === 123 || value === 119) {
42+
return {
43+
// fill 是背景字段标记下唯一必须的字段,用于指定文本颜色
44+
fill: '#b8e1ff',
45+
};
46+
}
47+
return {
48+
fill: '#fff',
49+
};
50+
},
51+
},
52+
],
53+
},
54+
};
55+
const defaultSortParams = [
56+
{
57+
sortFieldId: 'name',
58+
sortMethod: 'ASC',
59+
},
60+
{
61+
sortFieldId: 'unit',
62+
sortMethod: 'ASC',
63+
},
64+
{
65+
sortFieldId: 'level',
66+
sortFunc: (params) => {
67+
const { data } = params;
68+
return data.sort((a, b) => {
69+
const aNum = last(a.split(ID_SEPARATOR));
70+
const bNum = last(b.split(ID_SEPARATOR));
71+
return aNum - bNum;
72+
});
73+
},
74+
},
75+
];
76+
const dataConfig = {
77+
data: [],
78+
describe: '如何使用 S2 买房',
79+
fields: {
80+
rows: [
81+
'name',
82+
'unit',
83+
'building',
84+
'level',
85+
'nearStreet',
86+
'toward',
87+
'property',
88+
],
89+
columns: [],
90+
values: ['area'],
91+
valueInCols: true,
92+
},
93+
meta: [
94+
{
95+
field: 'name',
96+
name: '楼栋',
97+
},
98+
{
99+
field: 'unit',
100+
name: '单元号',
101+
},
102+
{
103+
field: 'building',
104+
name: '房号',
105+
},
106+
{
107+
field: 'level',
108+
name: '楼层',
109+
},
110+
{
111+
field: 'property',
112+
name: '房屋类型',
113+
},
114+
{
115+
field: 'nearStreet',
116+
name: '是否临街',
117+
},
118+
{
119+
field: 'toward',
120+
name: '朝向',
121+
},
122+
{
123+
field: 'area',
124+
name: '面积',
125+
},
126+
{
127+
field: 'note',
128+
name: '备注',
129+
},
130+
{
131+
field: 'score',
132+
name: '评分',
133+
},
134+
],
135+
sortParams: defaultSortParams,
136+
};
137+
138+
const SelectItem = (props) => {
139+
const { data, dataName, onChange } = props;
140+
141+
return (
142+
<Select
143+
allowClear={true}
144+
placeholder="全部"
145+
style={{ width: '150px' }}
146+
onChange={(value) => {
147+
onChange({
148+
key: dataName,
149+
value: value,
150+
});
151+
}}
152+
>
153+
{map(data, (item) => (
154+
<Select.Option key={`${item}`} value={item}>
155+
{`${item}`}
156+
</Select.Option>
157+
))}
158+
</Select>
159+
);
160+
};
161+
162+
const RangeSelect = (props) => {
163+
const { data, dataName, onChange } = props;
164+
const min = Math.min(...data);
165+
const max = Math.max(...data);
166+
const [info, setInfo] = useState({ min, max });
167+
const handleChange = (value, key) => {
168+
const tempInfo = Object.assign({}, info);
169+
tempInfo[key] = value;
170+
setInfo(tempInfo);
171+
172+
onChange({
173+
key: dataName,
174+
value: [tempInfo.min, tempInfo.max],
175+
});
176+
};
177+
178+
return (
179+
<Space>
180+
<InputNumber
181+
placeholder={'最小值'}
182+
min={min}
183+
max={max}
184+
defaultValue={min}
185+
onChange={(e) => handleChange(e, 'min')}
186+
/>
187+
<InputNumber
188+
placeholder={'最大值'}
189+
min={min}
190+
max={max}
191+
defaultValue={max}
192+
onChange={(e) => handleChange(e, 'max')}
193+
/>
194+
</Space>
195+
);
196+
};
197+
198+
const SelectList = (props) => {
199+
const { filterData } = props;
200+
const [filterInfo, setFilterInfo] = useState({});
201+
202+
const onChange = ({ key, value }) => {
203+
let tempHouseInfo = Object.assign({}, filterInfo);
204+
if (isNil(value)) {
205+
tempHouseInfo = omit(tempHouseInfo, key);
206+
} else {
207+
tempHouseInfo[key] = value;
208+
}
209+
setFilterInfo(tempHouseInfo);
210+
filterData(tempHouseInfo);
211+
};
212+
213+
return (
214+
<div className="select-list">
215+
{map(defaultHouseInfo, (item, key) => {
216+
return (
217+
<Space className="select-item" key={key}>
218+
<span className="select-label"> {key}</span>
219+
{key === 'area' || key === 'level' ? (
220+
<RangeSelect data={item} dataName={key} onChange={onChange} />
221+
) : (
222+
<SelectItem data={item} dataName={key} onChange={onChange} />
223+
)}
224+
</Space>
225+
);
226+
})}
227+
</div>
228+
);
229+
};
230+
231+
const Sheet = ({ data }) => {
232+
const [dataSource, setDataSource] = useState(data);
233+
234+
const filterData = (filterInfo) => {
235+
const result = filter(data, (item) => {
236+
return every(filterInfo, (value, key) => {
237+
if (key === 'area') {
238+
return value[0] <= item.area && value[1] >= item.area;
239+
}
240+
if (key === 'level') {
241+
return value[0] <= item.level && value[1] >= item.level;
242+
}
243+
if(key === 'nearStreet') {
244+
console.log(item.nearStreet, 'item.nearStreet', value, 'value');
245+
console.log(item.nearStreet === value, 'item.nearStreet === value');
246+
}
247+
return item[key] === value;
248+
});
249+
});
250+
setDataSource(result);
251+
};
252+
253+
return (
254+
<div>
255+
<SelectList filterData={filterData} />
256+
<SheetComponent
257+
sheetType={'pivot'}
258+
dataCfg={{ ...dataConfig, data: dataSource }}
259+
options={s2Options}
260+
showPagination={true}
261+
/>
262+
</div>
263+
);
264+
};
265+
266+
fetch(
267+
'https://gw.alipayobjects.com/os/bmw-prod/6420f338-9169-4b1f-b0f0-35f1a8295e67.json',
268+
)
269+
.then((res) => res.json())
270+
.then((data) => {
271+
ReactDOM.render(
272+
<Sheet data={data} />,
273+
document.getElementById('container'),
274+
);
275+
});
276+
277+
// We use 'insert-css' to insert custom styles
278+
// It is recommended to add the style to your own style sheet files
279+
// If you want to copy the code directly, please remember to install the npm package 'insert-css
280+
insertCss(`
281+
.select-item {
282+
margin: 5px 16px 0 0;
283+
}
284+
.select-list {
285+
display: flex;
286+
flex-wrap: wrap;
287+
margin-bottom: 20px;
288+
}
289+
.select-label {
290+
display: inline-block;
291+
width: 80px;
292+
}
293+
`);

s2-site/examples/case/data-preview/demo/meta.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111
"en": "Data Preview Table"
1212
},
1313
"screenshot": "https://gw.alipayobjects.com/zos/antfincdn/nVlBvKDBjT/search.gif"
14+
},
15+
{
16+
"filename": "house.tsx",
17+
"title": {
18+
"zh": "如何用 S2 买房",
19+
"en": "How to buy a house with S2"
20+
},
21+
"screenshot": "https://gw.alipayobjects.com/zos/antfincdn/JgAFxd5G0/maifangfengmian1.gif"
1422
}
1523
]
1624
}

0 commit comments

Comments
 (0)