220 lines
6.2 KiB
JavaScript
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
|
|
}
|
|
})
|