beyond-rails 0.0.189 → 0.0.194

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/src/js/components/Alert.js +1 -1
  3. data/src/js/components/Autocomplete.js +1 -1
  4. data/src/js/components/AutocompleteMenu.js +1 -1
  5. data/src/js/components/BarChart.js +452 -0
  6. data/src/js/components/Btn.js +1 -1
  7. data/src/js/components/Checkbox.js +1 -1
  8. data/src/js/components/DateInput.js +1 -1
  9. data/src/js/components/DateMenu.js +1 -1
  10. data/src/js/components/DateTimeRanger.js +1 -1
  11. data/src/js/components/Datepicker.js +1 -1
  12. data/src/js/components/DatepickerBtnArrow.js +1 -1
  13. data/src/js/components/Dropdown.js +1 -1
  14. data/src/js/components/LineChart.js +553 -0
  15. data/src/js/components/Menu.js +1 -1
  16. data/src/js/components/Modal.js +1 -1
  17. data/src/js/components/Navbar.js +1 -1
  18. data/src/js/components/Radio.js +1 -1
  19. data/src/js/components/SearchDropdown.js +1 -1
  20. data/src/js/components/Sidebar.js +1 -1
  21. data/src/js/components/Tabbox.js +1 -1
  22. data/src/js/components/TimeInput.js +1 -1
  23. data/src/js/components/TimeMenu.js +1 -1
  24. data/src/js/components/Timepicker.js +1 -1
  25. data/src/js/components/Toast.js +1 -1
  26. data/src/js/components/ToastItem.js +1 -1
  27. data/src/js/components/Tooltip.js +1 -1
  28. data/src/js/decorators/chartCommon.js +222 -0
  29. data/src/js/{utils → decorators}/supportDom.js +1 -1
  30. data/src/js/index.js +6 -2
  31. data/src/js/utils/index.js +10 -1
  32. data/src/js/utils/isDef.js +3 -0
  33. data/src/js/utils/isInt.js +3 -0
  34. data/src/js/utils/isUndef.js +3 -0
  35. data/src/sass/_beyond.scss +1 -0
  36. data/src/sass/components/_breadcrumb.scss +4 -7
  37. data/src/sass/components/_chart.scss +14 -0
  38. metadata +10 -3
@@ -1,4 +1,4 @@
1
- import supportDom from '../utils/supportDom'
1
+ import supportDom from '../decorators/supportDom'
2
2
 
3
3
  @supportDom
4
4
  export default class Menu {
@@ -1,4 +1,4 @@
1
- import supportDom from '../utils/supportDom'
1
+ import supportDom from '../decorators/supportDom'
2
2
  import { noop } from '../utils'
3
3
 
4
4
  let globalModalId = 0
@@ -1,4 +1,4 @@
1
- import supportDom from '../utils/supportDom'
1
+ import supportDom from '../decorators/supportDom'
2
2
 
3
3
  @supportDom
4
4
  export default class Navbar {
@@ -1,4 +1,4 @@
1
- import supportDom from '../utils/supportDom'
1
+ import supportDom from '../decorators/supportDom'
2
2
 
3
3
  @supportDom
4
4
  export default class Radio {
@@ -1,5 +1,5 @@
1
1
  import getFloatedTargetPos from '../utils/getFloatedTargetPos'
2
- import supportDom from '../utils/supportDom'
2
+ import supportDom from '../decorators/supportDom'
3
3
  import getKey from '../utils/getKey'
4
4
  import { debounce, noop, toPixel, throttle } from '../utils'
5
5
 
@@ -1,4 +1,4 @@
1
- import supportDom from '../utils/supportDom'
1
+ import supportDom from '../decorators/supportDom'
2
2
 
3
3
  @supportDom
4
4
  export default class Sidebar {
@@ -1,4 +1,4 @@
1
- import supportDom from '../utils/supportDom'
1
+ import supportDom from '../decorators/supportDom'
2
2
  import Dropdown from './Dropdown'
3
3
  import { noop } from '../utils'
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_TIMEZONE } from '../consts'
2
- import supportDom from '../utils/supportDom'
2
+ import supportDom from '../decorators/supportDom'
3
3
  import isTouchDevice from '../utils/isTouchDevice'
4
4
  import { format } from '../utils'
5
5
 
@@ -1,5 +1,5 @@
1
1
  import getFloatedTargetPos from '../utils/getFloatedTargetPos'
2
- import supportDom from '../utils/supportDom'
2
+ import supportDom from '../decorators/supportDom'
3
3
  import { getHours, getMinutes, range, toPixel } from '../utils'
4
4
 
5
5
  @supportDom
@@ -1,7 +1,7 @@
1
1
  import TimeInput from './TimeInput'
2
2
  import TimeMenu from './TimeMenu'
3
3
  import { DEFAULT_TIMEZONE } from '../consts'
4
- import supportDom from '../utils/supportDom'
4
+ import supportDom from '../decorators/supportDom'
5
5
  import {
6
6
  dateToTimestamp,
7
7
  noop,
@@ -1,4 +1,4 @@
1
- import supportDom from '../utils/supportDom'
1
+ import supportDom from '../decorators/supportDom'
2
2
  import ToastItem from './ToastItem'
3
3
 
4
4
  @supportDom
@@ -1,4 +1,4 @@
1
- import supportDom from '../utils/supportDom'
1
+ import supportDom from '../decorators/supportDom'
2
2
 
3
3
  @supportDom
4
4
  export default class ToastItem {
@@ -1,5 +1,5 @@
1
1
  import getFloatedTargetPos from '../utils/getFloatedTargetPos'
2
- import supportDom from '../utils/supportDom'
2
+ import supportDom from '../decorators/supportDom'
3
3
  import { toPixel } from '../utils'
4
4
 
5
5
  const TOOLTIP_PLACEMENTS = ['top', 'bottom', 'left', 'right']
@@ -0,0 +1,222 @@
1
+ import isDef from '../utils/isDef'
2
+ import isUndef from '../utils/isUndef'
3
+ import { getDomPos, range, toPixel, isFunction } from '../utils'
4
+
5
+ export default function chartCommon(target) {
6
+
7
+ return class extends target {
8
+
9
+ init() {
10
+ this.layers = []
11
+ if (isFunction(super.init)) {
12
+ super.init()
13
+ }
14
+ }
15
+
16
+ get firstLayer() {
17
+ return this.layers[0]
18
+ }
19
+
20
+ addLayer() {
21
+ const { dom } = this
22
+ const canvas = document.createElement('canvas')
23
+ canvas.style.position = 'absolute'
24
+ canvas.style.top = 0
25
+ canvas.style.left = 0
26
+ canvas.style.right = 0
27
+ canvas.style.bottom = 0
28
+ const ctx = canvas.getContext('2d')
29
+
30
+ this.setCanvasSize(canvas)
31
+ this.layers.push({ canvas, ctx })
32
+
33
+ dom.style.position = 'relative'
34
+ dom.appendChild(canvas)
35
+ }
36
+
37
+ bindMedia() {
38
+ if (this.media) {
39
+ return
40
+ }
41
+ this.media = window.matchMedia(`(resolution: ${this.dpr}dppx)`)
42
+ this._handleDprChange = this.handleDprChange.bind(this)
43
+ this.media.addListener(this._handleDprChange)
44
+ }
45
+
46
+ clear() {
47
+ const { ctx } = this
48
+ ctx.fillStyle = this.bgColor
49
+ ctx.fillRect(0, 0, this.width, this.height)
50
+ }
51
+
52
+ fillCircle(ctx, x, y, radius, style, alpha) {
53
+ ctx.save()
54
+ ctx.beginPath()
55
+ ctx.arc(x, y, radius, 0, 2 * Math.PI)
56
+ ctx.fillStyle = style
57
+ ctx.globalAlpha = alpha || 1
58
+ ctx.fill()
59
+ ctx.closePath()
60
+ ctx.restore()
61
+ }
62
+
63
+ getAutoStep(firstValue, lastValue, pointsLength) {
64
+ return (lastValue - firstValue) / (pointsLength - 1)
65
+ }
66
+
67
+ getHighestCanvas() {
68
+ const { layers, canvas } = this
69
+ if (layers.length === 0) {
70
+ return canvas
71
+ }
72
+ return layers[layers.length - 1].canvas
73
+ }
74
+
75
+ // real position in window including scrolling distance
76
+ getMousePos(canvasMousePos) {
77
+ const domPos = getDomPos(this.dom)
78
+ return {
79
+ x: domPos.x + canvasMousePos.x,
80
+ y: domPos.y + canvasMousePos.y
81
+ }
82
+ }
83
+
84
+ getMousePosInCanvas(event) {
85
+ const rect = this.canvas.getBoundingClientRect()
86
+ return {
87
+ x: event.clientX - rect.left,
88
+ y: event.clientY - rect.top
89
+ }
90
+ }
91
+
92
+ getLengthTotalData(gap, gutter, values, measureLength, toLabel) {
93
+
94
+ const valueCount = values.length
95
+ const marked = {}
96
+
97
+ // mark the first and last
98
+ marked[0] = true
99
+ marked[valueCount - 1] = true
100
+
101
+ // Check whether a value can be marked next
102
+ // For example, gap is 2
103
+ //
104
+ // values: 1 2 3 4 5 6 7
105
+ // marked: v v
106
+ //
107
+ // 4 will only be marked because it has enough gap on left and right side.
108
+ const hasGap = index => {
109
+ return range(index - gap, index).every(i => isUndef(marked[i])) &&
110
+ range(index + 1, index + gap + 1).every(i => isUndef(marked[i]))
111
+ }
112
+
113
+ return values.reduce((res, value, i) => {
114
+
115
+ if (i === 0) {
116
+ const label = toLabel(value)
117
+ const length = measureLength(label)
118
+ const lengthTotal = res.lengthTotal + length + gutter
119
+ const rows = res.rows.slice()
120
+ rows.push({ label, length, value })
121
+ return { lengthTotal, rows }
122
+ }
123
+ if (i === (valueCount - 1)) {
124
+ const label = toLabel(value)
125
+ const length = measureLength(label)
126
+ const lengthTotal = res.lengthTotal + length
127
+ const rows = res.rows.slice()
128
+ rows.push({ label, length, value })
129
+ return { lengthTotal, rows }
130
+ }
131
+ if (hasGap(i)) {
132
+ const label = toLabel(value)
133
+ marked[i] = true
134
+ const length = measureLength(label)
135
+ const lengthTotal = res.lengthTotal + length + gutter
136
+ const rows = res.rows.slice()
137
+ rows.push({ label, length, value })
138
+ return { lengthTotal, rows }
139
+ }
140
+ return res
141
+ }, {
142
+ lengthTotal: 0,
143
+ rows: []
144
+ })
145
+ }
146
+
147
+ getStepStartEnd(step, firstValue, lastValue) {
148
+
149
+ const stepStart = parseInt(firstValue / step, 10) * step
150
+ let stepEnd = parseInt(lastValue / step, 10) * step
151
+
152
+ if (stepEnd < lastValue) {
153
+ stepEnd += step
154
+ }
155
+ return [stepStart, stepEnd]
156
+ }
157
+
158
+ measureWidth(value) {
159
+ return this.ctx.measureText(value).width
160
+ }
161
+
162
+ raf(fn) {
163
+ if (isDef(window.requestAnimationFrame)) {
164
+ return window.requestAnimationFrame(fn)
165
+ }
166
+ return fn()
167
+ }
168
+
169
+ removeAllLayers() {
170
+ const { dom } = this
171
+ this.layers.forEach(layer => {
172
+ const { canvas } = layer
173
+ if (dom.contains(canvas)) {
174
+ dom.removeChild(canvas)
175
+ }
176
+ })
177
+ }
178
+
179
+ setCanvas() {
180
+ const canvas = document.createElement('canvas')
181
+ const ctx = canvas.getContext('2d')
182
+
183
+ this.canvas = canvas
184
+ this.ctx = ctx
185
+ this.setCanvasFontSize(this.canvas, this.fontSize)
186
+ this.setCanvasSize(canvas)
187
+
188
+ this.dom.appendChild(canvas)
189
+ }
190
+
191
+ setCanvasFontSize(canvas, fontSize) {
192
+ const ctx = canvas.getContext('2d')
193
+ const args = ctx.font.split(' ')
194
+ ctx.font = fontSize + 'px ' + args[args.length - 1]
195
+ }
196
+
197
+ setCanvasSize(canvas) {
198
+ const { dpr, width, height } = this
199
+
200
+ // https://coderwall.com/p/vmkk6a/how-to-make-the-canvas-not-look-like-crap-on-retina
201
+ canvas.width = width * dpr
202
+ canvas.height = height * dpr
203
+ canvas.style.width = toPixel(width)
204
+ canvas.style.height = toPixel(height)
205
+ canvas.getContext('2d').scale(dpr, dpr)
206
+ }
207
+
208
+ setDomWidthIfNeeded() {
209
+ if (isUndef(this.options.width)) {
210
+ this.width = this.dom.offsetWidth
211
+ }
212
+ }
213
+
214
+ setDpr() {
215
+ this.dpr = window.devicePixelRatio || 1
216
+ }
217
+
218
+ unbindMedia() {
219
+ this.media.removeListener(this._handleDprChange)
220
+ }
221
+ }
222
+ }
@@ -1,4 +1,4 @@
1
- import { isFunction } from './index'
1
+ import { isFunction } from '../utils'
2
2
  import createdComponents from '../consts/createdComponents'
3
3
 
4
4
  export default function supportDom(target) {
@@ -6,19 +6,21 @@ import './polyfills/nodeRemove'
6
6
  import './polyfills/elementDataset'
7
7
  import Alert from './components/Alert'
8
8
  import Autocomplete from './components/Autocomplete'
9
+ import BarChart from './components/BarChart'
9
10
  import Btn from './components/Btn'
10
11
  import Checkbox from './components/Checkbox'
11
12
  import DateTimeRanger from './components/DateTimeRanger'
12
13
  import Datepicker from './components/Datepicker'
13
14
  import Dropdown from './components/Dropdown'
15
+ import LineChart from './components/LineChart'
14
16
  import Menu from './components/Menu'
15
17
  import Modal from './components/Modal'
16
18
  import Navbar from './components/Navbar'
17
19
  import Radio from './components/Radio'
18
20
  import SearchDropdown from './components/SearchDropdown'
19
21
  import Sidebar from './components/Sidebar'
20
- import Timepicker from './components/Timepicker'
21
22
  import Tabbox from './components/Tabbox'
23
+ import Timepicker from './components/Timepicker'
22
24
  import Toast from './components/Toast'
23
25
  import Tooltip from './components/Tooltip'
24
26
  import bind from './utils/bind'
@@ -28,19 +30,21 @@ import unbindAll from './utils/unbindAll'
28
30
  export {
29
31
  Alert,
30
32
  Autocomplete,
33
+ BarChart,
31
34
  Btn,
32
35
  Checkbox,
33
36
  DateTimeRanger,
34
37
  Datepicker,
35
38
  Dropdown,
39
+ LineChart,
36
40
  Menu,
37
41
  Modal,
38
42
  Navbar,
39
43
  Radio,
40
44
  SearchDropdown,
41
45
  Sidebar,
42
- Timepicker,
43
46
  Tabbox,
47
+ Timepicker,
44
48
  Toast,
45
49
  Tooltip,
46
50
  bind,
@@ -33,6 +33,10 @@ import isFunction from 'lodash.isfunction'
33
33
  import noop from 'lodash.noop'
34
34
  import range from 'lodash.range'
35
35
  import throttle from 'lodash.throttle'
36
+ import uniqBy from 'lodash.uniqby'
37
+ import sortBy from 'lodash.sortby'
38
+
39
+ import mem from 'mem'
36
40
 
37
41
  export {
38
42
  // @superlanding
@@ -69,5 +73,10 @@ export {
69
73
  isFunction,
70
74
  noop,
71
75
  range,
72
- throttle
76
+ throttle,
77
+ uniqBy,
78
+ sortBy,
79
+
80
+ // others
81
+ mem
73
82
  }
@@ -0,0 +1,3 @@
1
+ export default function isDef(value) {
2
+ return (typeof value !== 'undefined')
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function isInt(value) {
2
+ return (value % 1) === 0
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function isUndef(value) {
2
+ return (typeof value === 'undefined')
3
+ }
@@ -50,3 +50,4 @@
50
50
  @import './components/_tooltip';
51
51
  @import './components/_switch';
52
52
  @import './components/_mega-menu';
53
+ @import './components/_chart';
@@ -4,17 +4,14 @@
4
4
  padding: .75rem 1rem;
5
5
  margin-bottom: 1rem;
6
6
  list-style: none;
7
- .breadcrumb-item + .breadcrumb-item::before {
7
+ li + li::before {
8
8
  display: inline-block;
9
9
  padding-right: .7rem;
10
10
  padding-left: .7rem;
11
- color: #6c757d;
11
+ color: $text-color-strong;
12
12
  content: '/';
13
13
  }
14
- .breadcrumb-item.active {
15
- color: #6c757d;
16
- }
17
- .breadcrumb-item a {
18
- color: #000;
14
+ li:last-child {
15
+ color: $text-color-strong;
19
16
  }
20
17
  }
@@ -0,0 +1,14 @@
1
+ .chart {
2
+ font-family: Roboto;
3
+ }
4
+
5
+ .chart-menu {
6
+ display: none;
7
+ position: absolute;
8
+ background-color: #fff;
9
+ padding: 10px 13px;
10
+ box-shadow: 4px 4px 15px 1px rgba(68, 68, 72, .12);
11
+ color: #3c4257;
12
+ z-index: 1;
13
+ border: 1px solid #e8e8e8;
14
+ }