Chart.js:用折线图比较两个时期,例如 Google 分析
Chart.js: compare two periods like Google Analytics with a line chart
我正在使用 chart.js 2.6.0 库。
我正在尝试制作类似 Google 分析比较功能的比较折线图:Screenshot
我必须比较电子商务的两个收入日期期间。
我想画两个不同标签的 x 轴,一个 x 轴用于第一个周期,一个 x 轴用于第二个周期。
现在我可以画两条线,每个周期一条,还有两个 xAxes,但我只能使用一组标签,得到以下结果:
screeshot
显然是错误的,线上的每个周期 - 两个点对应于周期 1 标签(请参阅第二个屏幕截图中的悬停信息窗口)
这是我的代码
var ctx = $("#ordersCompareChart");
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: data.labels,
datasets: [{
borderColor: "#E25F5F",
label: 'Period 1: From ' + $('#from_first').val() + ' to ' + $('#to_first').val(),
data: data.values_first,
borderWidth: 3,
xAxisID: "x-axis-1",
},
{
borderColor: "#2793DB",
label: 'Period 2: From ' + $('#from_second').val() + ' to ' + $('#to_second').val(),
data: data.values_second,
borderWidth: 3,
xAxisID: "x-axis-2",
},
]
},
options: {
scales: {
xAxes: [
{
display: true,
tipe: "time",
scaleLabel: {
display: true,
labelString: 'Period 1'
},
id: "x-axis-1"
},
{
display: true,
tipe: "time",
id: "x-axis-2",
labels: data.labels_second,
scaleLabel: {
display: true,
labelString: 'Period 2'
},
id: "x-axis-2"
}
],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Total'
},
ticks: {
callback: function(value, index, values) {
return value.toLocaleString("de-DE",{style:"currency", currency:"EUR"});
}
}
}]
}
}
});
感谢能回答的人
抱歉之前没有回答
这是一个有效的 fiddle
https://jsfiddle.net/7L0fu4er/10/
让我们解释一下我的解决方案:
使用 Charts.js 你只能为两个 x 轴使用一组标签,解决方法是用数组的每个值的 2 个日期填充标签数组,之后,你必须调用每个 xAxe 的 "ticks" 方法中的回调将使用分隔符(在我的例子中为“#”)拆分日期。
在我们的例子中,我们想要显示两个时期(比如每天、本周和上周的电子商务收入),您的标签数组将如下所示:
{labels: ["09/01/2018#02/01/2018","10/01/2018#03/01/2018"] ...}
如果您看到第一个值 "09/01/2018#02/01/2018"
,“#”字符之前的日期是第 1 个日期,第二个是第 2 个日期。
所以
第一。您必须构建标签数组,每个周期的天数必须与每个周期值
相同
给每个xAxe一个唯一的Id
为每个将详细说明每个标签数组值的 xAxe 调用 "ticks" 回调,这样您就可以拆分并绘制每天的正确日期
希望对你有所帮助
我知道这是一个老问题,但我找到了一个很好的解决方案,我使用 .net 框架。
1- 制作一个存储过程以从数据库中获取今年的所有数据 GroupBy 数据和月份的前 3 个字母:
SELECT sum(anything) AS something , MAX ( Convert(char(3), tb.date, 0)) AS ALL_MONTHS
FROM table tb WHERE YEAR(tb.date) = YEAR(CURRENT_TIMESTAMP)
GROUP BY YEAR(tb.date), MONTH(tb.date)
ORDER BY YEAR(tb.date), MONTH(tb.date)
2-做一个存储过程从数据库中获取去年的所有数据,类似于步骤
1 但 where 子句是这样的:
............. 年(tb.date)= 年(GETDATE())- 1 .........
表示减去当前年份。
3-controller发送数据到view后,在View页面使用JS操作数据
注意:有 12 个月,所以制作一个 12 个月的数组,这样只有一个标签,但数据将根据从 js 循环函数接收的索引计算出月份的位置.
/////-- 图表------------------------------------ --------------
var salesChartCanvas = $('#salesChart').get(0).getContext('2d')
var months = @Html.Raw(Json.Encode(Model.expChartMonths));
var total = @Html.Raw(Json.Encode(Model.expChartTotal));
var Lastmonths = @Html.Raw(Json.Encode(Model.expChartMonthsLast));
var Lasttotal = @Html.Raw(Json.Encode(Model.expChartTotalLast));
var arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var arr2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
function getMonthFromString(mon) {
return new Date(Date.parse(mon + " 1, 2021")).getMonth()
}
function getMonth(mon) {
return new Date(Date.parse(mon + " 1, 2021")).getMonth()
}
//this year
for (var x = 0; x < months.length; x++) { arr2[getMonth(months[x])] = total[x] }
//last year
for (var i = 0; i < Lastmonths.length; i++) { arr[getMonthFromString(Lastmonths[i])] = Lasttotal[i] }
var salesChartData = {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
datasets: [
{
label: 'This Year Expenses',
fill: false,
backgroundColor: 'rgba(60,141,188,0.9)',
borderColor: 'rgba(60,141,188,0.8)',
pointRadius: 5,
pointColor: '#3b8bba',
pointStrokeColor: 'rgba(60,141,188,1)',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(60,141,188,1)',
data: arr2
}
,
{
label: 'Last Year Expenses',
fill: false,
backgroundColor: 'rgba(210, 214, 222, 1)',
borderColor: 'rgba(210, 214, 222, 1)',
pointRadius: 5,
pointColor: 'rgba(210, 214, 222, 1)',
pointStrokeColor: '#c1c7d1',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(220,220,220,1)',
data: arr
}
]
}
我正在使用 chart.js 2.6.0 库。
我正在尝试制作类似 Google 分析比较功能的比较折线图:Screenshot
我必须比较电子商务的两个收入日期期间。
我想画两个不同标签的 x 轴,一个 x 轴用于第一个周期,一个 x 轴用于第二个周期。
现在我可以画两条线,每个周期一条,还有两个 xAxes,但我只能使用一组标签,得到以下结果: screeshot
显然是错误的,线上的每个周期 - 两个点对应于周期 1 标签(请参阅第二个屏幕截图中的悬停信息窗口)
这是我的代码
var ctx = $("#ordersCompareChart");
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: data.labels,
datasets: [{
borderColor: "#E25F5F",
label: 'Period 1: From ' + $('#from_first').val() + ' to ' + $('#to_first').val(),
data: data.values_first,
borderWidth: 3,
xAxisID: "x-axis-1",
},
{
borderColor: "#2793DB",
label: 'Period 2: From ' + $('#from_second').val() + ' to ' + $('#to_second').val(),
data: data.values_second,
borderWidth: 3,
xAxisID: "x-axis-2",
},
]
},
options: {
scales: {
xAxes: [
{
display: true,
tipe: "time",
scaleLabel: {
display: true,
labelString: 'Period 1'
},
id: "x-axis-1"
},
{
display: true,
tipe: "time",
id: "x-axis-2",
labels: data.labels_second,
scaleLabel: {
display: true,
labelString: 'Period 2'
},
id: "x-axis-2"
}
],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Total'
},
ticks: {
callback: function(value, index, values) {
return value.toLocaleString("de-DE",{style:"currency", currency:"EUR"});
}
}
}]
}
}
});
感谢能回答的人
抱歉之前没有回答
这是一个有效的 fiddle https://jsfiddle.net/7L0fu4er/10/
让我们解释一下我的解决方案:
使用 Charts.js 你只能为两个 x 轴使用一组标签,解决方法是用数组的每个值的 2 个日期填充标签数组,之后,你必须调用每个 xAxe 的 "ticks" 方法中的回调将使用分隔符(在我的例子中为“#”)拆分日期。
在我们的例子中,我们想要显示两个时期(比如每天、本周和上周的电子商务收入),您的标签数组将如下所示:
{labels: ["09/01/2018#02/01/2018","10/01/2018#03/01/2018"] ...}
如果您看到第一个值 "09/01/2018#02/01/2018"
,“#”字符之前的日期是第 1 个日期,第二个是第 2 个日期。
所以
第一。您必须构建标签数组,每个周期的天数必须与每个周期值
相同
给每个xAxe一个唯一的Id
为每个将详细说明每个标签数组值的 xAxe 调用 "ticks" 回调,这样您就可以拆分并绘制每天的正确日期
希望对你有所帮助
我知道这是一个老问题,但我找到了一个很好的解决方案,我使用 .net 框架。
1- 制作一个存储过程以从数据库中获取今年的所有数据 GroupBy 数据和月份的前 3 个字母:
SELECT sum(anything) AS something , MAX ( Convert(char(3), tb.date, 0)) AS ALL_MONTHS
FROM table tb WHERE YEAR(tb.date) = YEAR(CURRENT_TIMESTAMP)
GROUP BY YEAR(tb.date), MONTH(tb.date)
ORDER BY YEAR(tb.date), MONTH(tb.date)
2-做一个存储过程从数据库中获取去年的所有数据,类似于步骤 1 但 where 子句是这样的:
............. 年(tb.date)= 年(GETDATE())- 1 .........
表示减去当前年份。
3-controller发送数据到view后,在View页面使用JS操作数据
注意:有 12 个月,所以制作一个 12 个月的数组,这样只有一个标签,但数据将根据从 js 循环函数接收的索引计算出月份的位置.
/////-- 图表------------------------------------ --------------
var salesChartCanvas = $('#salesChart').get(0).getContext('2d')
var months = @Html.Raw(Json.Encode(Model.expChartMonths));
var total = @Html.Raw(Json.Encode(Model.expChartTotal));
var Lastmonths = @Html.Raw(Json.Encode(Model.expChartMonthsLast));
var Lasttotal = @Html.Raw(Json.Encode(Model.expChartTotalLast));
var arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var arr2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
function getMonthFromString(mon) {
return new Date(Date.parse(mon + " 1, 2021")).getMonth()
}
function getMonth(mon) {
return new Date(Date.parse(mon + " 1, 2021")).getMonth()
}
//this year
for (var x = 0; x < months.length; x++) { arr2[getMonth(months[x])] = total[x] }
//last year
for (var i = 0; i < Lastmonths.length; i++) { arr[getMonthFromString(Lastmonths[i])] = Lasttotal[i] }
var salesChartData = {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
datasets: [
{
label: 'This Year Expenses',
fill: false,
backgroundColor: 'rgba(60,141,188,0.9)',
borderColor: 'rgba(60,141,188,0.8)',
pointRadius: 5,
pointColor: '#3b8bba',
pointStrokeColor: 'rgba(60,141,188,1)',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(60,141,188,1)',
data: arr2
}
,
{
label: 'Last Year Expenses',
fill: false,
backgroundColor: 'rgba(210, 214, 222, 1)',
borderColor: 'rgba(210, 214, 222, 1)',
pointRadius: 5,
pointColor: 'rgba(210, 214, 222, 1)',
pointStrokeColor: '#c1c7d1',
pointHighlightFill: '#fff',
pointHighlightStroke: 'rgba(220,220,220,1)',
data: arr
}
]
}