weixinxiaochengxu/pages/trend/trend.js

220 lines
6.2 KiB
JavaScript

var app = getApp()
var drawChart = require("../../utils/chart").drawChart
var COLORS = ["#e53e3e", "#3182ce", "#38a169", "#d69e2e", "#805ad5", "#dd6b20", "#319795", "#d53f8c"]
Page({
data: {
items: [],
filterItems: [],
viewMode: "month",
filterMonth: "",
filterYear: "",
customStart: "",
customEnd: "",
hasData: false,
colors: COLORS
},
onLoad: function () {
var today = this.formatDate(new Date(), "day")
var month = today.slice(0, 7)
var year = today.slice(0, 4)
var items = app.globalData.items
this.setData({
items: items,
filterItems: items.slice(),
filterMonth: month,
filterYear: year,
customStart: month,
customEnd: month
})
},
onReady: function () {
this._initCanvas()
},
onShow: function () {
var items = app.globalData.items
if (items.length !== this.data.items.length ||
items.some(function (v, i) { return v !== this.data.items[i] }, this)) {
this.setData({ items: items })
var newFilter = items.filter(function (i) { return this.data.items.indexOf(i) === -1 }, this)
if (newFilter.length > 0) {
this.setData({ filterItems: this.data.filterItems.concat(newFilter) })
}
}
if (this._canvasReady) {
this.refreshChart()
}
},
_initCanvas: function () {
var that = this
wx.createSelectorQuery().in(this)
.select("#trendCanvas")
.boundingClientRect(function (rect) {
if (!rect || rect.width <= 0) return
var dpr = wx.getWindowInfo().pixelRatio
that._canvasW = rect.width
that._canvasH = rect.height
that.canvasCtx = wx.createCanvasContext('trendCanvas', that)
that.canvasCtx.scale(dpr, dpr)
that._canvasReady = true
that.refreshChart()
})
.exec()
},
getDateRange: function () {
var viewMode = this.data.viewMode
var filterMonth = this.data.filterMonth
var filterYear = this.data.filterYear
var customStart = this.data.customStart
var customEnd = this.data.customEnd
var start, end, parts, y, m, sy, sm, ey, em
if (viewMode === "month") {
parts = filterMonth.split("-")
y = Number(parts[0])
m = Number(parts[1])
start = new Date(y, m - 1, 1)
end = new Date(y, m, 0)
} else if (viewMode === "year") {
y = parseInt(filterYear)
start = new Date(y, 0, 1)
end = new Date(y, 11, 31)
} else {
parts = customStart.split("-")
sy = Number(parts[0])
sm = Number(parts[1])
parts = customEnd.split("-")
ey = Number(parts[0])
em = Number(parts[1])
start = new Date(sy, sm - 1, 1)
end = new Date(ey, em, 0)
}
return { start: start, end: end }
},
refreshChart: function () {
var records = app.globalData.records
var filterItems = this.data.filterItems
var range = this.getDateRange()
var start = range.start
var end = range.end
var inRange = function (r) {
var d = new Date(r.date + "T00:00:00")
return d >= start && d <= end
}
var filtered = records.filter(function (r) {
return inRange(r) && filterItems.indexOf(r.item) > -1
})
if (filtered.length === 0) {
this.setData({ hasData: false })
return
}
var dateMap = {}
filtered.forEach(function (r) {
if (!dateMap[r.date]) dateMap[r.date] = {}
if (!dateMap[r.date][r.item]) {
dateMap[r.date][r.item] = { sum: 0, count: 0 }
}
dateMap[r.date][r.item].sum += r.value
dateMap[r.date][r.item].count += 1
})
var dates = Object.keys(dateMap).sort()
var xLabels = dates.map(function (d) { return d.slice(5) })
var series = filterItems.map(function (fi) {
return {
name: fi,
data: dates.map(function (d) {
var entry = dateMap[d][fi]
if (!entry) return null
return Math.round((entry.sum / entry.count) * 100) / 100
})
}
})
this._chartData = { xLabels: xLabels, series: series }
var that = this
this.setData({ hasData: true }, function () { that.drawChart() })
},
drawChart: function () {
if (!this.canvasCtx || !this._canvasW || !this._canvasH) return
var chartData = this._chartData
if (!chartData || !chartData.xLabels.length) return
var filterItems = this.data.filterItems
var items = this.data.items
var colors = this.data.colors
var that = this
drawChart(this.canvasCtx, this._canvasW, this._canvasH, {
xLabels: chartData.xLabels,
series: chartData.series,
colors: filterItems.map(function (fi) {
return colors[items.indexOf(fi) % colors.length]
})
})
},
onSwitchMode: function (e) {
var that = this
this.setData({ viewMode: e.currentTarget.dataset.mode }, function () { that.refreshChart() })
},
onMonthChange: function (e) {
var that = this
this.setData({ filterMonth: e.detail.value }, function () { that.refreshChart() })
},
onYearChange: function (e) {
var that = this
this.setData({ filterYear: e.detail.value }, function () { that.refreshChart() })
},
onCustomStartChange: function (e) {
var that = this
this.setData({ customStart: e.detail.value }, function () { that.refreshChart() })
},
onCustomEndChange: function (e) {
var that = this
this.setData({ customEnd: e.detail.value }, function () { that.refreshChart() })
},
onToggleItem: function (e) {
var item = e.currentTarget.dataset.item
var filterItems = this.data.filterItems.slice()
var idx = filterItems.indexOf(item)
var that = this
if (idx > -1) {
if (filterItems.length <= 1) {
wx.showToast({ title: "至少保留一个项目", icon: "none" })
return
}
filterItems.splice(idx, 1)
} else {
filterItems.push(item)
}
this.setData({ filterItems: filterItems }, function () { that.refreshChart() })
},
formatDate: function (d, mode) {
var y = d.getFullYear()
var m = String(d.getMonth() + 1)
if (m.length === 1) m = "0" + m
var day = String(d.getDate())
if (day.length === 1) day = "0" + day
if (mode === "year") return String(y)
if (mode === "month") return y + "-" + m
return y + "-" + m + "-" + day
}
})