同比环比数据可视化

cybozu发表于:2023年06月07日 13:27:57更新于:2024年06月19日 13:28:15

开发者中心包含此范例模板(同比环比数据可视化),请前往开发者中心下载学习。

Index

引言

数据分析和可视化在现代商业环境中变得越来越重要。随着数据的迅速增长,我们需要有效的工具来解释和理解这些数据。

数据可视化提供了一种直观的方式,帮助我们从海量数据中提取有意义的见解,以支持业务决策。


同比环比图作为一种常见的数据可视化工具,提供了一种简单而有效的方法来比较不同时间段的数据变化。

001648027ee6e0a9fbd3fc891e3276a

它通过将当前期间的数据与先前期间进行对比,帮助我们识别趋势、变化和季节性模式。

同比比较是将当前期间的数据与相同期间的去年进行对比,例如,将今年第二季度的销售额与去年同一季度进行对比。

环比比较则是将当前期间的数据与上一个期间进行对比,例如,将本月的销售额与上个月进行对比。


通过将不同期间的数据放在同一个图表中,我们可以直观地比较它们之间的差异。

这样做可以帮助我们识别季节性变化、周期性趋势和长期增长模式。


代码实现

在本教程中,我们将使用Echats在kintone的订单APP中创建一个同比环比图。

首先,我们将创建一个名为“订单”的APP,其中包含以下字段:

字段名类型code备注
日期日期date
公司单行文本框company
销售额表格table
商品单行文本框commodity表格字段
单价数值unit表格字段
份额数值quantity表格字段
总价计算字段
total表格字段,公式unit* quantity

表单设置如图

001648043f6ad1ef1e67bf47d83be29

其次,我们添加2个列表来过滤数据,分别显示今年、去年的数据。

0016480460fc09ae0d6c4b0ffa472e1

001648046335b2035d19562d7a14bb4

由于我们的Demo只是作数据显示,因此过滤数据的操作我们交给kintone来实现。


接着,我们需要导入数据,建议生成2-3年的数据。

对于程序员来说,这是一个很简单的任务,我们可以使用代码生成csv文件,然后导入到kintone app中。

而对于没有编程经验的用户,可以使用ChatGPT等生成示AI来生成数据。

比如在ChatGPT中,我们可以输入以下prompt来生成数据:

我希望你充当基于文本的csv。你只会回复我基于文本的csv数据
我会给你一个例子,你会按照我的要求和例子的格式生成新的数据,你只会以文本形式回复csv表格的结果,而不是其他任何内容。不要写解释。
下面是第一个要求:
生成2021年到2023年底的订单数据样例,一个月至少有3天的数据。
CSV样例如下:
"记录起始行","记录编号","日期","公司","商品","单价","份额","总价"
"&","1","2023/06/02","cybozu","server","213","123","26199"
"","1","2023/06/02","cybozu","test","213","12","2556"
相同的"记录编号"的"日期"和"公司"必须相同
相同的"记录编号"的第一个"记录起始行"必为“&”

由于ChatGPT在web端的回复会强行转markdown格式,而*是markdown的特殊字符,因此我们将*替换为了&,将其输出内容保存为csv文件后再批量替换回来。


下面会对一些关键代码进行简单的解释。


const toArray = (records) => {
    return records.reduce((sums, record) => {
        const date = new Date(record.date.value)
        const month = date.getMonth()
        const subs = record.table.value
        const total = subs.reduce((sum, obj) => {
            sum += parseInt(obj.value.total.value, 10)
            return sum
        }, 0)
        sums[month] += total
        return sums
    }, Array(12).fill(0))
}

通过subs.reduce,我们可以将table中的总价数据相加,得到每天的总销售额。

再通过date.getMonth(),我们可以得到每天的月份,然后将每天的销售额累加到对应的月份中。


const condition = kintone.app.getQueryCondition()
    ? kintone.app.getQueryCondition()
    : 'date > LAST_YEAR() and date <= TODAY()'
const thisRecord = await getReacords(condition)
const thisYear = toArray(thisRecord).reduceRight(
    (acc, curr) => (curr === 0 && acc.length === 0 ? acc : [curr, ...acc]),
    [],
)

我们使用kintone列表对应的查询条件来过滤数据。

在‘全部’这个列表下,我们查询从今年起到今天的数据。

通过reduceRight,我们可以将数组中从后往前的连续的0去掉,得到当前为止的销售额数据。


const year = new Date(thisRecord[0].date.value).getFullYear()
const regx = /(?:and|or)?\s*date\s*(?:>|<|=|>=|<=)\s*(?:\w+\(\)|"\d{4}-\d{2}-\d{2}")\s*(?:and|or)?/g
const query = condition.replaceAll(regx, '')
const lastCondition = `date < "${year}-01-01" and date >= "${year - 1}-01-01" ${
    query.trim().length > 0 ? ` and ${query}` : ``
}`

为了获取去年的数据,我们需要将今年的查询条件中的日期条件去掉,然后再加上去年的日期条件。


const yoY = thisYear.map((data, index) =>
lastYear[index] > 0 ? ((data - lastYear[index]) / lastYear[index]) * 100 : 1,
)
const moM = thisYear.map((data, index) => {
const cardinality = index === 0 ? lastYear[11] : thisYear[index - 1]
return cardinality > 0 ? ((data - cardinality) / cardinality) * 100 : 1
})

同比、环比算法都是一样的,只是分母不同。


toolbox: {
    feature: {
        dataView: { show: true, readOnly: false },
        saveAsImage: { show: true },
    },
},

保留Echarts的数据视图和图片导出功能。

{
    name: 'YoY',
    type: 'line',
    data: yoY,
    yAxisIndex: 1,
},
{
    name: 'MoM',
    type: 'line',
    data: moM,
    yAxisIndex: 1,
},

最后通过Echarts的图表来展示数据,将同比、环比数据和右边的百分比轴绑定。


总结

本教程中,我们使用Echarts在kintone的销售APP中创建了一个同比环比图。

我们可以通过同比环比图来分析销售额的季节性变化、周期性趋势和长期增长模式。

通过这次的自定义开发,我们拓展了kintone的图表功能,让kintone可以更好的满足我们的业务需求。