我从API获得以下数据结构,它以Data
的数组形式出现,每个Data
元素间隔1小时。
interface Data {
time_bucket: string // ISO8601 string
aggregated_value: number // 0 and up
}
我的计划是将其格式化,使其与d3一起绘制为barchart。条形图有一个选择器,用于将数据分组为week
、day
、month
和year
。我决定创建一个名为groupBy
的函数,它的工作原理与lodash的groupBy
非常相似。它将数据分组到所需的指定组。这是的功能
export function groupBy<T, K extends keyof any> (list: T[], criteria: (item: T) => K): Record<K, T[]> {
return list.reduce<Record<K, T[]>>((prev, curr) => {
const group = criteria(curr)
// eslint-disable-next-line
if (!prev[group]) {
prev[group] = []
}
prev[group].push(curr)
return prev
// eslint-disable-next-line
}, {} as Record<K, T[]>)
}
问题是图的x标度是用YYYY-MM-DD
格式构造的。我想将数据分组到每天,同时将日期格式保持为YYYY-MM-DD
。我现在从运行函数中得到的内容在片段中是这样的。
const data = [
{
time_bucket: '2021-06-01T16:00:00.000Z',
aggregated_value: 20
},
{
time_bucket: '2021-06-01T18:00:00.000Z',
aggregated_value: 20
},
{
time_bucket: '2021-06-02T16:00:00.000Z',
aggregated_value: 40
},
{
time_bucket: '2021-06-02T20:00:00.000Z',
aggregated_value: 40
},
{
time_bucket: '2021-06-03T05:00:00.000Z',
aggregated_value: 60
}
]
function groupBy(list, criteria) {
return list.reduce((prev, curr) => {
const group = criteria(curr)
if (!prev[group]) {
prev[group] = []
}
prev[group].push(curr)
return prev
}, {})
}
console.log(groupBy(data, (item) => dayjs.utc(item.time_bucket).get('date')))
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script src="https://unpkg.com/dayjs@1.8.21/plugin/utc.js"></script>
<script>dayjs.extend(window.dayjs_plugin_utc)</script>
您可以看到输出如下:
{
"1": [
{
"time_bucket": "2021-06-01T16:00:00.000Z",
"aggregated_value": 20
},
{
"time_bucket": "2021-06-01T18:00:00.000Z",
"aggregated_value": 20
}
],
"2": [
{
"time_bucket": "2021-06-02T16:00:00.000Z",
"aggregated_value": 40
},
{
"time_bucket": "2021-06-02T20:00:00.000Z",
"aggregated_value": 40
}
],
"3": [
{
"time_bucket": "2021-06-03T05:00:00.000Z",
"aggregated_value": 60
}
]
}
这就是我想要的
{
"2021-06-01": [
{
"time_bucket": "2021-06-01T16:00:00.000Z",
"aggregated_value": 20
},
{
"time_bucket": "2021-06-01T18:00:00.000Z",
"aggregated_value": 20
}
],
"2021-06-02": [
{
"time_bucket": "2021-06-02T16:00:00.000Z",
"aggregated_value": 40
},
{
"time_bucket": "2021-06-02T20:00:00.000Z",
"aggregated_value": 40
}
],
"2021-06-03": [
{
"time_bucket": "2021-06-03T05:00:00.000Z",
"aggregated_value": 60
}
]
}
我希望函数能够将数据分组到指定的范围中,同时仍然保持YYYY-MM-DD
格式的日期格式,以便我仍然将其映射到我生成的d3
x刻度。dayjs
中是否有任何函数可以做到这一点,或者是否有任何解决方法。非常感谢您的回复。
经过一段时间的研究。我决定将任何日期四舍五入到每个时间范围的开始。
我会在这个例子中这样使用它。
const data = [
{
time_bucket: '2021-06-01T16:00:00.000Z',
aggregated_value: 20
},
{
time_bucket: '2021-06-01T18:00:00.000Z',
aggregated_value: 20
},
{
time_bucket: '2021-06-02T16:00:00.000Z',
aggregated_value: 40
},
{
time_bucket: '2021-06-02T20:00:00.000Z',
aggregated_value: 40
},
{
time_bucket: '2021-06-03T05:00:00.000Z',
aggregated_value: 60
}
]
function groupBy(list, criteria) {
return list.reduce((prev, curr) => {
const group = criteria(curr)
if (!prev[group]) {
prev[group] = []
}
prev[group].push(curr)
return prev
}, {})
}
console.log(groupBy(data, (item) => dayjs.utc(item.time_bucket).startOf('day').format('YYYY-MM-DD')))
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script src="https://unpkg.com/dayjs@1.8.21/plugin/utc.js"></script>
<script>dayjs.extend(window.dayjs_plugin_utc)</script>
通过这种方式,我可以使用从startOf()
暴露的.format()
将数据分组到每个时间范围。