beyond-rails 0.0.236 → 0.0.242
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/src/js/components/BarChart.js +3 -8
- data/src/js/components/LineChart.js +11 -48
- data/src/js/components/PieChart.js +241 -0
- data/src/js/consts/index.js +10 -0
- data/src/js/decorators/chartCommon.js +67 -1
- data/src/js/decorators/supportDom.js +6 -1
- data/src/js/index.js +2 -0
- data/src/js/jquery/bindBtnFn.js +26 -11
- data/src/js/utils/dom.js +11 -1
- data/src/js/utils/isFn.js +3 -0
- data/src/sass/components/_btn.scss +4 -0
- data/src/sass/components/_chart.scss +21 -0
- data/src/sass/components/_modal.scss +14 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b3bbdec941b619698d3d2056d2f14b9e5ac05a9ceca5da77cae6ed3b92880e4
|
4
|
+
data.tar.gz: da7470c133596ff14a1f6223b44877e62c60d0b8519a7cceb1a2c60384aaece5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb5ad03f6463c486d3d4fd258893a89e597f9fba5638eb4a1da711885e93a8e27905b0d247c320534b92a28c62129609fd43bf56d4de5cdcc8b665365a57ce31
|
7
|
+
data.tar.gz: d8a09786eea15028edc4d9b38d5531e02c6656707f7f5dcf976aa0e21d2473c7657cf27fb770687b126668033c5170083c7c89422938da4b113ddd4752d18b8d
|
@@ -4,12 +4,7 @@ import isDef from '../utils/isDef'
|
|
4
4
|
import isUndef from '../utils/isUndef'
|
5
5
|
import isInt from '../utils/isInt'
|
6
6
|
import { mem, range, sortBy, throttle, uniqBy } from '../utils'
|
7
|
-
|
8
|
-
const defaultBarStyles = [
|
9
|
-
'#5469d4',
|
10
|
-
'#7c54d4',
|
11
|
-
'#a254d4'
|
12
|
-
]
|
7
|
+
import { DEFAULT_CHART_STYLES } from '../consts'
|
13
8
|
|
14
9
|
@supportDom
|
15
10
|
@chartCommon
|
@@ -35,8 +30,8 @@ export default class BarChart {
|
|
35
30
|
this.yLabelMargin = isDef(options.yLanelMargin) ? options.yLabelMargin : 14
|
36
31
|
|
37
32
|
this.fontSize = options.fontSize || 12
|
38
|
-
this.
|
39
|
-
this.barStyles = options.barStyles ||
|
33
|
+
this.bg = options.bg || '#fff'
|
34
|
+
this.barStyles = options.barStyles || DEFAULT_CHART_STYLES
|
40
35
|
|
41
36
|
this.yLabelRows = []
|
42
37
|
this.barPosMap = new Map()
|
@@ -3,6 +3,7 @@ import chartCommon from '../decorators/chartCommon'
|
|
3
3
|
import isDef from '../utils/isDef'
|
4
4
|
import isUndef from '../utils/isUndef'
|
5
5
|
import { mem, range, sortBy, throttle, uniqBy } from '../utils'
|
6
|
+
import { DEFAULT_CHART_STYLES } from '../consts'
|
6
7
|
|
7
8
|
/**
|
8
9
|
* -------------------------------------------------------------------------------------------------
|
@@ -27,11 +28,6 @@ import { mem, range, sortBy, throttle, uniqBy } from '../utils'
|
|
27
28
|
* v |
|
28
29
|
* --------------------------------------------------------------------------------------------------
|
29
30
|
**/
|
30
|
-
const defaultLineStyles = [
|
31
|
-
'#5469d4',
|
32
|
-
'#7c54d4',
|
33
|
-
'#a254d4'
|
34
|
-
]
|
35
31
|
|
36
32
|
@supportDom
|
37
33
|
@chartCommon
|
@@ -56,16 +52,15 @@ export default class LineChart {
|
|
56
52
|
this.xLabelMargin = isDef(options.xLabelMargin) ? options.xLabelMargin : 10
|
57
53
|
this.yLabelMargin = isDef(options.yLanelMargin) ? options.yLabelMargin : 10
|
58
54
|
|
59
|
-
this.lineStyles = options.lineStyles ||
|
55
|
+
this.lineStyles = options.lineStyles || DEFAULT_CHART_STYLES
|
60
56
|
|
61
|
-
this.
|
57
|
+
this.bg = options.bg || '#fff'
|
62
58
|
this.fontSize = options.fontSize || 12
|
63
59
|
|
64
60
|
this.xStep = options.xStep
|
65
61
|
this.yStep = options.yStep
|
66
62
|
|
67
63
|
this.lineLabels = options.lineLabels || []
|
68
|
-
this.lineLabelMargin = isDef(options.lineLabelMargin) ? options.lineLabelMargin : 20
|
69
64
|
|
70
65
|
this.pointPosMap = new Map()
|
71
66
|
this.xLabelRows = []
|
@@ -78,6 +73,7 @@ export default class LineChart {
|
|
78
73
|
this.setDpr()
|
79
74
|
this.setDomSizeIfNeeded()
|
80
75
|
this.setCanvas()
|
76
|
+
this.setLabelBox()
|
81
77
|
this.clear()
|
82
78
|
this.bindMedia()
|
83
79
|
this.bindPointMouseOver()
|
@@ -93,8 +89,7 @@ export default class LineChart {
|
|
93
89
|
}
|
94
90
|
|
95
91
|
get contentHeight() {
|
96
|
-
return this.height - (this.yPadding * 2) - this.xLabelMargin -
|
97
|
-
this.xLabelHeight - this.lineLabelBoxHeight
|
92
|
+
return this.height - (this.yPadding * 2) - this.xLabelMargin - this.xLabelHeight
|
98
93
|
}
|
99
94
|
|
100
95
|
get firstX() {
|
@@ -115,17 +110,6 @@ export default class LineChart {
|
|
115
110
|
return yLabelRows[yLabelRows.length - 1].value
|
116
111
|
}
|
117
112
|
|
118
|
-
get lineLabelHeight() {
|
119
|
-
return this.fontSize
|
120
|
-
}
|
121
|
-
|
122
|
-
get lineLabelBoxHeight() {
|
123
|
-
if (this.lineLabels.length > 0) {
|
124
|
-
return this.lineLabelMargin + this.lineLabelHeight
|
125
|
-
}
|
126
|
-
return 0
|
127
|
-
}
|
128
|
-
|
129
113
|
get xAxisStart() {
|
130
114
|
return this.xPadding + (this.xLabelWidth / 2)
|
131
115
|
}
|
@@ -145,7 +129,7 @@ export default class LineChart {
|
|
145
129
|
}
|
146
130
|
|
147
131
|
get yAxisStart() {
|
148
|
-
return this.height - this.yPadding -
|
132
|
+
return this.height - this.yPadding -
|
149
133
|
this.xLabelHeight - this.xLabelMargin + (this.yLabelHeight / 2)
|
150
134
|
}
|
151
135
|
|
@@ -185,7 +169,6 @@ export default class LineChart {
|
|
185
169
|
this.drawYAxis()
|
186
170
|
this.drawBgLines()
|
187
171
|
this.drawLines()
|
188
|
-
this.drawLineLables()
|
189
172
|
}
|
190
173
|
|
191
174
|
drawBgLines() {
|
@@ -232,29 +215,6 @@ export default class LineChart {
|
|
232
215
|
})
|
233
216
|
}
|
234
217
|
|
235
|
-
drawLineLables() {
|
236
|
-
const { ctx, lineStyles, lineLabelHeight } = this
|
237
|
-
const rectSize = 7
|
238
|
-
|
239
|
-
const rectGutter = 7
|
240
|
-
const labelGutter = 14
|
241
|
-
const rectMargin = 1
|
242
|
-
const y = this.height - this.yPadding
|
243
|
-
let x = this.xPadding
|
244
|
-
|
245
|
-
this.lineLabels.forEach((name, i) => {
|
246
|
-
ctx.fillStyle = lineStyles[i] || '#000'
|
247
|
-
ctx.fillRect(x, y - lineLabelHeight + rectMargin, rectSize, rectSize)
|
248
|
-
|
249
|
-
x += (rectSize + rectGutter)
|
250
|
-
ctx.fillStyle = '#000'
|
251
|
-
ctx.textAlign = 'left'
|
252
|
-
ctx.textBaseline = 'top'
|
253
|
-
ctx.fillText(name, x, y - lineLabelHeight)
|
254
|
-
x += (ctx.measureText(name).width + labelGutter)
|
255
|
-
})
|
256
|
-
}
|
257
|
-
|
258
218
|
clearVerticalLine() {
|
259
219
|
const { ctx } = this.firstLayer
|
260
220
|
ctx.clearRect(0, 0, this.width, this.height)
|
@@ -279,7 +239,7 @@ export default class LineChart {
|
|
279
239
|
drawXAxis() {
|
280
240
|
const { ctx, firstX, xLabelRows, xAxisStart, xRatio } = this
|
281
241
|
|
282
|
-
const y = this.height - this.yPadding
|
242
|
+
const y = this.height - this.yPadding
|
283
243
|
|
284
244
|
const scaleMargin = 4
|
285
245
|
const scaleSize = 4
|
@@ -538,7 +498,10 @@ export default class LineChart {
|
|
538
498
|
return this.raf(() => this.clear())
|
539
499
|
}
|
540
500
|
this.setPointPos()
|
541
|
-
this.raf(() =>
|
501
|
+
this.raf(() => {
|
502
|
+
this.drawLabels(this.lineLabels, this.lineStyles)
|
503
|
+
this.draw()
|
504
|
+
})
|
542
505
|
}
|
543
506
|
|
544
507
|
setPointPos() {
|
@@ -0,0 +1,241 @@
|
|
1
|
+
import supportDom from '../decorators/supportDom'
|
2
|
+
import chartCommon from '../decorators/chartCommon'
|
3
|
+
import isDef from '../utils/isDef'
|
4
|
+
import isUndef from '../utils/isUndef'
|
5
|
+
import { throttle } from '../utils'
|
6
|
+
import { DEFAULT_CHART_STYLES } from '../consts'
|
7
|
+
|
8
|
+
@supportDom
|
9
|
+
@chartCommon
|
10
|
+
export default class PieChart {
|
11
|
+
|
12
|
+
constructor(dom, options = {}) {
|
13
|
+
this.dom = dom
|
14
|
+
this.data = []
|
15
|
+
this.total = 0
|
16
|
+
|
17
|
+
this.options = options
|
18
|
+
this.height = options.height
|
19
|
+
this.width = options.width
|
20
|
+
this.padding = isDef(options.padding) ? options.padding : 30
|
21
|
+
this.styles = options.styles || DEFAULT_CHART_STYLES
|
22
|
+
this.bg = options.bg || '#fff'
|
23
|
+
|
24
|
+
this.init()
|
25
|
+
}
|
26
|
+
|
27
|
+
init() {
|
28
|
+
this.setDpr()
|
29
|
+
this.setDomSizeIfNeeded()
|
30
|
+
this.setCanvas()
|
31
|
+
this.setLabelBox()
|
32
|
+
this.clear()
|
33
|
+
this.bindMedia()
|
34
|
+
this.bindPointMouseOver()
|
35
|
+
}
|
36
|
+
|
37
|
+
get x() {
|
38
|
+
return this.width / 2
|
39
|
+
}
|
40
|
+
|
41
|
+
get y() {
|
42
|
+
return this.height / 2
|
43
|
+
}
|
44
|
+
|
45
|
+
get radius() {
|
46
|
+
return this.contentWidth / 2
|
47
|
+
}
|
48
|
+
|
49
|
+
get pieWidth() {
|
50
|
+
return this.radius * .3
|
51
|
+
}
|
52
|
+
|
53
|
+
get centerCircleRadius() {
|
54
|
+
return this.radius - this.pieWidth
|
55
|
+
}
|
56
|
+
|
57
|
+
get contentWidth() {
|
58
|
+
return this.width - (this.padding * 2)
|
59
|
+
}
|
60
|
+
|
61
|
+
get contentHeight() {
|
62
|
+
return this.height - (this.padding * 2)
|
63
|
+
}
|
64
|
+
|
65
|
+
bindPointMouseOver() {
|
66
|
+
if (isUndef(this.options.onPieMouseOver)) {
|
67
|
+
return
|
68
|
+
}
|
69
|
+
if (! ('onmousemove' in this.canvas)) {
|
70
|
+
return
|
71
|
+
}
|
72
|
+
this.addLayer()
|
73
|
+
const canvas = this.getHighestCanvas()
|
74
|
+
this.addEvent(canvas, 'mousemove', throttle(this.handleMouseMove.bind(this), 30))
|
75
|
+
}
|
76
|
+
|
77
|
+
draw() {
|
78
|
+
this.clear()
|
79
|
+
this.drawPie()
|
80
|
+
}
|
81
|
+
|
82
|
+
drawPie() {
|
83
|
+
const { x, y, radius, centerCircleRadius, ctx, total } = this
|
84
|
+
|
85
|
+
let distance = 0
|
86
|
+
|
87
|
+
this.data.forEach((row, i) => {
|
88
|
+
|
89
|
+
const ratio = (row.value / total)
|
90
|
+
const startAngle = Math.PI * (-.5 + 2 * distance)
|
91
|
+
const endAngle = Math.PI * (-.5 + 2 * (distance + ratio))
|
92
|
+
|
93
|
+
const options = {
|
94
|
+
style: this.styles[i]
|
95
|
+
}
|
96
|
+
this.fillArc(ctx, x, y, radius, startAngle, endAngle, options)
|
97
|
+
distance += ratio
|
98
|
+
})
|
99
|
+
|
100
|
+
this.fillCircle(ctx, x, y, centerCircleRadius, '#fff')
|
101
|
+
}
|
102
|
+
|
103
|
+
handleDprChange() {
|
104
|
+
this.setDpr()
|
105
|
+
this.refresh()
|
106
|
+
}
|
107
|
+
|
108
|
+
getPosAngle(x1, y1, x2, y2) {
|
109
|
+
|
110
|
+
let x = x2
|
111
|
+
let y = y2
|
112
|
+
|
113
|
+
if (x1 >= 0) {
|
114
|
+
x -= x1
|
115
|
+
}
|
116
|
+
if (y1 >= 0) {
|
117
|
+
y -= y1
|
118
|
+
}
|
119
|
+
if (x1 < 0) {
|
120
|
+
x += x1
|
121
|
+
}
|
122
|
+
if (y2 < 0) {
|
123
|
+
y += y2
|
124
|
+
}
|
125
|
+
|
126
|
+
let angle = Math.atan2(y, x) * 180 / Math.PI
|
127
|
+
if (angle < 0) {
|
128
|
+
angle = 180 + (180 + angle)
|
129
|
+
}
|
130
|
+
return (angle + 90) % 360
|
131
|
+
}
|
132
|
+
|
133
|
+
handleMouseMove(event) {
|
134
|
+
|
135
|
+
const { x, y } = this
|
136
|
+
const canvasMousePos = this.getMousePosInCanvas(event)
|
137
|
+
const mousePos = this.getMousePos(canvasMousePos)
|
138
|
+
const mouseX = canvasMousePos.x
|
139
|
+
const mouseY = canvasMousePos.y
|
140
|
+
|
141
|
+
const distanceToCenterPoint = Math.sqrt(Math.pow(mouseX - x, 2) +
|
142
|
+
Math.pow(mouseY - y, 2))
|
143
|
+
|
144
|
+
const inCenterCircle = distanceToCenterPoint <= this.centerCircleRadius
|
145
|
+
|
146
|
+
this.clearSliceGlow()
|
147
|
+
|
148
|
+
if (inCenterCircle) {
|
149
|
+
return this.options.onPieMouseOver(mousePos, null)
|
150
|
+
}
|
151
|
+
|
152
|
+
const inPieCircle = distanceToCenterPoint <= this.radius
|
153
|
+
if (! inPieCircle) {
|
154
|
+
return this.options.onPieMouseOver(mousePos, null)
|
155
|
+
}
|
156
|
+
const angle = this.getPosAngle(x, y, mouseX, mouseY)
|
157
|
+
const matchedRow = this.data.find(row => {
|
158
|
+
return (row.startAngle <= angle) && (angle <= row.endAngle)
|
159
|
+
})
|
160
|
+
if (matchedRow) {
|
161
|
+
this.drawSliceGlow(matchedRow)
|
162
|
+
this.options.onPieMouseOver(mousePos, matchedRow)
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
drawSliceGlow(row) {
|
167
|
+
const index = this.data.findIndex(r => r === row)
|
168
|
+
this.clearSliceGlow()
|
169
|
+
const { x, y, radius, centerCircleRadius } = this
|
170
|
+
const ctx = this.firstLayer.canvas.getContext('2d')
|
171
|
+
|
172
|
+
const delta = 90 * Math.PI / 180
|
173
|
+
const startAngle = (row.startAngle * Math.PI / 180) - delta
|
174
|
+
const endAngle = (row.endAngle * Math.PI / 180) - delta
|
175
|
+
|
176
|
+
const options = {
|
177
|
+
style: this.styles[index],
|
178
|
+
alpha: .3
|
179
|
+
}
|
180
|
+
const radiusDelta = (radius - centerCircleRadius) * .3
|
181
|
+
this.fillArc(ctx, x, y, radius + radiusDelta, startAngle, endAngle, options)
|
182
|
+
this.fillCircle(this.firstLayer.ctx, x, y, centerCircleRadius, '#fff')
|
183
|
+
}
|
184
|
+
|
185
|
+
clearSliceGlow() {
|
186
|
+
const ctx = this.firstLayer.canvas.getContext('2d')
|
187
|
+
ctx.clearRect(0, 0, this.width, this.height)
|
188
|
+
}
|
189
|
+
|
190
|
+
refresh() {
|
191
|
+
this.raf(() => {
|
192
|
+
this.clearCanvasSize(this.canvas)
|
193
|
+
this.layers.forEach(layer => this.clearCanvasSize(layer.canvas))
|
194
|
+
this.setDomSizeIfNeeded()
|
195
|
+
this.setCanvasSize(this.canvas)
|
196
|
+
this.layers.forEach(layer => this.setCanvasSize(layer.canvas))
|
197
|
+
this.draw()
|
198
|
+
})
|
199
|
+
}
|
200
|
+
|
201
|
+
setAngles(data) {
|
202
|
+
const { total } = this
|
203
|
+
let startAngle = 0
|
204
|
+
return data.map(row => {
|
205
|
+
const endAngle = startAngle + ((row.value / total) * 360)
|
206
|
+
const nextRow = Object.assign({}, row, { startAngle, endAngle })
|
207
|
+
startAngle = endAngle
|
208
|
+
return nextRow
|
209
|
+
})
|
210
|
+
}
|
211
|
+
|
212
|
+
handleLabelMouseOver(index) {
|
213
|
+
this.drawSliceGlow(this.data[index])
|
214
|
+
}
|
215
|
+
|
216
|
+
handleLabelMouseLeave(index) {
|
217
|
+
this.clearSliceGlow()
|
218
|
+
}
|
219
|
+
|
220
|
+
setData(data) {
|
221
|
+
this.total = data.reduce((t, row) => t + row.value, 0)
|
222
|
+
this.data = this.setAngles(data)
|
223
|
+
this.raf(() => {
|
224
|
+
const labels = this.data.map(row => row.label)
|
225
|
+
this.drawLabels(labels, this.styles)
|
226
|
+
this.draw()
|
227
|
+
})
|
228
|
+
}
|
229
|
+
|
230
|
+
destroy() {
|
231
|
+
const { dom, canvas } = this
|
232
|
+
|
233
|
+
this.unbindMedia()
|
234
|
+
this.removeAllLayers()
|
235
|
+
|
236
|
+
if (dom.contains(canvas)) {
|
237
|
+
dom.removeChild(canvas)
|
238
|
+
dom.style.removeProperty('position')
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}
|
data/src/js/consts/index.js
CHANGED
@@ -3,3 +3,13 @@ import locale from 'date-fns/locale/zh-TW'
|
|
3
3
|
export const DEFAULT_TIMEZONE = 'Asia/Taipei'
|
4
4
|
|
5
5
|
export const DEFAULT_LOCALE = locale
|
6
|
+
|
7
|
+
export const DEFAULT_CHART_STYLES = [
|
8
|
+
'#5469d4',
|
9
|
+
'#7c54d4',
|
10
|
+
'#a254d4',
|
11
|
+
'#c040a2',
|
12
|
+
'#ff5604',
|
13
|
+
'#0be4e3',
|
14
|
+
'#00d924'
|
15
|
+
]
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import raf from '../utils/raf'
|
2
2
|
import isUndef from '../utils/isUndef'
|
3
|
+
import isFn from '../utils/isFn'
|
3
4
|
import { getDomPos, range, toPixel, isFunction } from '../utils'
|
5
|
+
import { DEFAULT_CHART_STYLES } from '../consts'
|
4
6
|
|
5
7
|
export default function chartCommon(target) {
|
6
8
|
|
@@ -12,6 +14,7 @@ export default function chartCommon(target) {
|
|
12
14
|
}
|
13
15
|
|
14
16
|
init() {
|
17
|
+
this.offLabels = []
|
15
18
|
this.layers = []
|
16
19
|
if (isFunction(super.init)) {
|
17
20
|
super.init()
|
@@ -50,10 +53,15 @@ export default function chartCommon(target) {
|
|
50
53
|
|
51
54
|
clear() {
|
52
55
|
const { ctx } = this
|
53
|
-
ctx.fillStyle = this.
|
56
|
+
ctx.fillStyle = this.bg
|
54
57
|
ctx.fillRect(0, 0, this.width, this.height)
|
55
58
|
}
|
56
59
|
|
60
|
+
getHypotenuse(x1, y1, x2, y2) {
|
61
|
+
return Math.sqrt(Math.pow(x2 - x1, 2) +
|
62
|
+
Math.pow(y2 - y1, 2))
|
63
|
+
}
|
64
|
+
|
57
65
|
fillCircle(ctx, x, y, radius, style, alpha) {
|
58
66
|
ctx.save()
|
59
67
|
ctx.beginPath()
|
@@ -65,6 +73,18 @@ export default function chartCommon(target) {
|
|
65
73
|
ctx.restore()
|
66
74
|
}
|
67
75
|
|
76
|
+
fillArc(ctx, x, y, radius, startAngle = 0, endAngle = 2 * Math.PI, options = {}) {
|
77
|
+
ctx.save()
|
78
|
+
ctx.beginPath()
|
79
|
+
ctx.arc(x, y, radius, startAngle, endAngle)
|
80
|
+
ctx.fillStyle = options.style || '#555'
|
81
|
+
ctx.globalAlpha = options.alpha || 1
|
82
|
+
ctx.lineTo(x, y)
|
83
|
+
ctx.fill()
|
84
|
+
ctx.closePath()
|
85
|
+
ctx.restore()
|
86
|
+
}
|
87
|
+
|
68
88
|
getAutoStep(firstValue, lastValue, pointsLength) {
|
69
89
|
return (lastValue - firstValue) / (pointsLength - 1)
|
70
90
|
}
|
@@ -186,6 +206,52 @@ export default function chartCommon(target) {
|
|
186
206
|
this.dom.appendChild(canvas)
|
187
207
|
}
|
188
208
|
|
209
|
+
setLabelBox() {
|
210
|
+
const box = document.createElement('div')
|
211
|
+
box.className = 'chart-box'
|
212
|
+
this.labelBox = box
|
213
|
+
this.dom.appendChild(box)
|
214
|
+
}
|
215
|
+
|
216
|
+
drawLabels(labels, styles = DEFAULT_CHART_STYLES) {
|
217
|
+
if (labels.length <= 0) {
|
218
|
+
return
|
219
|
+
}
|
220
|
+
const { labelBox, handleLabelMouseOver, handleLabelMouseLeave } = this
|
221
|
+
this.dom.style.backgroundColor = this.bg
|
222
|
+
|
223
|
+
this.offLabels.forEach(off => off())
|
224
|
+
labelBox.innerHTML = ''
|
225
|
+
|
226
|
+
this.offLabels.length = 0
|
227
|
+
|
228
|
+
labels.forEach((label, i) => {
|
229
|
+
|
230
|
+
const div = document.createElement('div')
|
231
|
+
div.className = 'chart-box-item'
|
232
|
+
|
233
|
+
const square = document.createElement('div')
|
234
|
+
square.className = 'chart-box-square'
|
235
|
+
square.style.backgroundColor = styles[i]
|
236
|
+
div.appendChild(square)
|
237
|
+
|
238
|
+
const span = document.createElement('span')
|
239
|
+
span.textContent = label
|
240
|
+
div.appendChild(span)
|
241
|
+
|
242
|
+
labelBox.appendChild(div)
|
243
|
+
|
244
|
+
if (isFn(handleLabelMouseOver)) {
|
245
|
+
const off = this.addEvent(div, 'mouseover', () => this.handleLabelMouseOver(i))
|
246
|
+
this.offLabels.push(off)
|
247
|
+
}
|
248
|
+
if (isFn(handleLabelMouseLeave)) {
|
249
|
+
const off = this.addEvent(div, 'mouseleave', () => this.handleLabelMouseLeave(i))
|
250
|
+
this.offLabels.push(off)
|
251
|
+
}
|
252
|
+
})
|
253
|
+
}
|
254
|
+
|
189
255
|
setCanvasFontSize(canvas, fontSize) {
|
190
256
|
const ctx = canvas.getContext('2d')
|
191
257
|
const args = ctx.font.split(' ')
|
@@ -25,7 +25,12 @@ export default function supportDom(target) {
|
|
25
25
|
|
26
26
|
addEvent(dom, name, func) {
|
27
27
|
dom.addEventListener(name, func)
|
28
|
-
|
28
|
+
const listener = { dom, name, func }
|
29
|
+
this._listeners.push(listener)
|
30
|
+
|
31
|
+
return () => {
|
32
|
+
this._listeners = this._listeners.filter(l => l !== listener)
|
33
|
+
}
|
29
34
|
}
|
30
35
|
|
31
36
|
removeEvents() {
|
data/src/js/index.js
CHANGED
@@ -17,6 +17,7 @@ import LineChart from './components/LineChart'
|
|
17
17
|
import Menu from './components/Menu'
|
18
18
|
import Modal from './components/Modal'
|
19
19
|
import Navbar from './components/Navbar'
|
20
|
+
import PieChart from './components/PieChart'
|
20
21
|
import Radio from './components/Radio'
|
21
22
|
import SearchDropdown from './components/SearchDropdown'
|
22
23
|
import Sidebar from './components/Sidebar'
|
@@ -53,6 +54,7 @@ export {
|
|
53
54
|
Menu,
|
54
55
|
Modal,
|
55
56
|
Navbar,
|
57
|
+
PieChart,
|
56
58
|
Radio,
|
57
59
|
SearchDropdown,
|
58
60
|
Sidebar,
|
data/src/js/jquery/bindBtnFn.js
CHANGED
@@ -1,17 +1,32 @@
|
|
1
1
|
export default function bindBtnFn(beyond, $) {
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
$.fn.btn = function() {
|
6
|
-
|
7
|
-
const btns = this.map((i, dom) => new Btn(dom))
|
8
|
-
|
9
|
-
this.showLoader = btns.each((i, a) => a.showLoader())
|
10
|
-
|
11
|
-
this.hideLoader = btns.each((i, a) => a.hideLoader())
|
12
|
-
|
13
|
-
this.destroy = () => btns.each((i, a) => a.destroy())
|
3
|
+
$.fn.btn = function(type) {
|
14
4
|
|
5
|
+
if (type === 'loading') {
|
6
|
+
initBtns(this)
|
7
|
+
this.each((i, dom) => dom._btn.showLoader())
|
8
|
+
}
|
9
|
+
else if (type === 'reset') {
|
10
|
+
initBtns(this)
|
11
|
+
this.each((i, dom) => dom._btn.hideLoader())
|
12
|
+
}
|
13
|
+
else if (type === 'destroy') {
|
14
|
+
this.each((i, dom) => {
|
15
|
+
if (dom._btn) {
|
16
|
+
dom._btn.destroy()
|
17
|
+
delete dom._btn
|
18
|
+
}
|
19
|
+
})
|
20
|
+
}
|
15
21
|
return this
|
16
22
|
}
|
17
23
|
}
|
24
|
+
|
25
|
+
function initBtns(self, options) {
|
26
|
+
const { Btn } = beyond
|
27
|
+
self.each((i, dom) => {
|
28
|
+
if (! dom._btn) {
|
29
|
+
dom._btn = new Btn(dom)
|
30
|
+
}
|
31
|
+
})
|
32
|
+
}
|
data/src/js/utils/dom.js
CHANGED
@@ -5,7 +5,17 @@ const unloadRows = []
|
|
5
5
|
const onPage = row => {
|
6
6
|
const { controller, action } = row
|
7
7
|
const { dataset } = document.body
|
8
|
-
|
8
|
+
|
9
|
+
let controllerMatched = (dataset.controller === controller)
|
10
|
+
let actionMatched = (dataset.action === action)
|
11
|
+
|
12
|
+
if (controller === '*') {
|
13
|
+
controllerMatched = true
|
14
|
+
}
|
15
|
+
if (action === '*') {
|
16
|
+
actionMatched = true
|
17
|
+
}
|
18
|
+
return controllerMatched && actionMatched
|
9
19
|
}
|
10
20
|
|
11
21
|
export const $ = (selector, dom = document) => dom.querySelector(selector)
|
@@ -12,3 +12,24 @@
|
|
12
12
|
z-index: 1;
|
13
13
|
border: 1px solid #e8e8e8;
|
14
14
|
}
|
15
|
+
|
16
|
+
.chart-box {
|
17
|
+
display: flex;
|
18
|
+
justify-content: center;
|
19
|
+
flex-wrap: wrap;
|
20
|
+
padding-left: 14px;
|
21
|
+
padding-right: 14px;
|
22
|
+
padding-bottom: 10px;
|
23
|
+
.chart-box-item {
|
24
|
+
cursor: default;
|
25
|
+
font-size: 12px;
|
26
|
+
display: inline-flex;
|
27
|
+
align-items: center;
|
28
|
+
margin-right: 1.4em;
|
29
|
+
.chart-box-square {
|
30
|
+
transform: translateY(1px);
|
31
|
+
@include size(10px);
|
32
|
+
margin-right: .5em;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
@@ -20,8 +20,22 @@
|
|
20
20
|
background-color: #fff;
|
21
21
|
margin: 20px auto 0;
|
22
22
|
max-width: 600px;
|
23
|
+
&.modal-sm {
|
24
|
+
max-width: 400px;
|
25
|
+
}
|
26
|
+
&.modal-lg {
|
27
|
+
max-width: 900px;
|
28
|
+
}
|
29
|
+
&.modal-xl {
|
30
|
+
max-width: 1140px;
|
31
|
+
}
|
23
32
|
@media (max-width: $screen-sm) {
|
24
33
|
max-width: 90%;
|
34
|
+
&.modal-sm,
|
35
|
+
&.modal-lg,
|
36
|
+
&.modal-xl {
|
37
|
+
max-width: 90%;
|
38
|
+
}
|
25
39
|
}
|
26
40
|
}
|
27
41
|
&.js-active {
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beyond-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.242
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kmsheng
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-11-
|
12
|
+
date: 2020-11-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sassc
|
@@ -140,6 +140,7 @@ files:
|
|
140
140
|
- src/js/components/Menu.js
|
141
141
|
- src/js/components/Modal.js
|
142
142
|
- src/js/components/Navbar.js
|
143
|
+
- src/js/components/PieChart.js
|
143
144
|
- src/js/components/Radio.js
|
144
145
|
- src/js/components/SearchDropdown.js
|
145
146
|
- src/js/components/Sidebar.js
|
@@ -194,6 +195,7 @@ files:
|
|
194
195
|
- src/js/utils/getKey.js
|
195
196
|
- src/js/utils/index.js
|
196
197
|
- src/js/utils/isDef.js
|
198
|
+
- src/js/utils/isFn.js
|
197
199
|
- src/js/utils/isInt.js
|
198
200
|
- src/js/utils/isStr.js
|
199
201
|
- src/js/utils/isTouchDevice.js
|