Advertisement
Chessington

Untitled

Jun 19th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.01 KB | None | 0 0
  1. import _ from 'lodash'
  2. import React from 'react'
  3. import {View, Text} from 'react-native'
  4.  
  5. const SINGLE_SERIES_WITH_NUMBERS = 0
  6. const SINGLE_SERIES_WITH_OBJECTS = 1
  7. const MULTI_SERIES = 2
  8.  
  9. function flattenData (data) {
  10. let numberCount = 0
  11. let objectWithYCount = 0
  12. let multiSeriesCount = 0
  13. let length = data.length
  14. data.map((obj) => {
  15. if (typeof obj === 'number') {
  16. numberCount++
  17. } else if (typeof obj === 'object') {
  18. if (typeof obj.y === 'number') {
  19. objectWithYCount++
  20. } else if (Array.isArray(obj.data)) {
  21. multiSeriesCount++
  22. }
  23. }
  24. })
  25.  
  26. if (numberCount === length || objectWithYCount === length) {
  27. return [{
  28. seriesName: '',
  29. data: data
  30. }]
  31. } else if (multiSeriesCount === length) {
  32. return data
  33. } else {
  34. return [{
  35. seriesName: '',
  36. data: []
  37. }]
  38. }
  39. }
  40.  
  41. function getMinMaxValue (data) {
  42. let values = []
  43.  
  44. data.map((value) => {
  45. if (typeof value === 'number') {
  46. values.push(value)
  47. } else if (typeof value === 'object') {
  48. if (typeof value.y === 'number') {
  49. values.push(value.y)
  50. } else if (Array.isArray(value.data)) {
  51. value.data.map((v) => {
  52. if (typeof v === 'number') {
  53. values.push(v)
  54. } else if (typeof v === 'object' && typeof v.y === 'number') {
  55. values.push(v.y)
  56. }
  57. })
  58. }
  59. }
  60. })
  61.  
  62. if (values.length === 0) return 0
  63.  
  64. return [Math.max.apply(null, values),Math.min.apply(null, values)]
  65. }
  66.  
  67. export const initData = (dataProp, height, gap, numberOfPoints = 5) => {
  68. let guideArray, max, min, sortedData
  69. if (!dataProp || !Array.isArray(dataProp) || dataProp.length === 0) {
  70. return {
  71. sortedData: [],
  72. max: 0,
  73. min:0,
  74. guideArray: []
  75. }
  76. }
  77.  
  78. let minmax = getMinMaxValue(dataProp)
  79. max = minmax[0]
  80. min = Math.floor(minmax[1] / 10) * 10
  81.  
  82. guideArray = getGuideArray(max, min, height, numberOfPoints)
  83.  
  84. dataProp = flattenData(dataProp)
  85.  
  86. sortedData = refineData(dataProp, max, min, height, gap)
  87.  
  88. return {
  89. sortedData: sortedData,
  90. max: max,
  91. selectedIndex: null,
  92. nowHeight: 200,
  93. nowWidth: 200,
  94. scrollPosition: 0,
  95. nowX: 0,
  96. nowY: 0,
  97. guideArray: guideArray
  98. }
  99. }
  100.  
  101. export const refineData = (flattenData, max, min, height, gap) => {
  102. let result = []
  103.  
  104. flattenData.map((series) => {
  105. let dataProp = series.data
  106. let object = {
  107. seriesName: series.seriesName,
  108. seriesColor: series.color
  109. }
  110. let data = []
  111. let length = dataProp.length
  112. let simpleTypeCount = 0
  113. let objectTypeCount = 0
  114.  
  115. for (let i = 0; i < length; i++) {
  116. let maxClone = max
  117.  
  118. if (maxClone === 0) {
  119. maxClone = 1
  120. }
  121. let dataObject = {}
  122.  
  123. if (typeof dataProp[i] === 'number') {
  124. simpleTypeCount++
  125. dataObject.ratioY = (dataProp[i]-min) / (maxClone-min) * height
  126. dataObject.y = dataProp[i]
  127. dataObject = {
  128. gap: i * gap,
  129. ratioY: (dataProp[i]-70) / (maxClone-min) * height,
  130. y: dataProp[i]
  131. }
  132. } else if (typeof dataProp[i] === 'object') {
  133. let isEmpty = false
  134. if (dataProp[i].y === null) {
  135. let nullCount = 0
  136. for (let j = i; j < dataProp.length; j++) {
  137. if (dataProp[j].y) {
  138. break
  139. } else {
  140. nullCount++
  141. }
  142. }
  143. dataProp[i].y = dataProp[i - 1].y + (dataProp[i + nullCount].y - dataProp[i - 1].y) / (nullCount + 1)
  144. isEmpty = true
  145. /* if (dataProp[i + 1] && dataProp[i - 1]) {
  146. dataProp[i].y = (dataProp[i - 1].y + dataProp[i + 1].y) / 2
  147. isEmpty = true
  148. } */
  149. }
  150. if (typeof dataProp[i].y === 'number' && dataProp[i].x) {
  151. objectTypeCount++
  152. dataObject = {
  153. gap: i * gap,
  154. ratioY: (dataProp[i].y -min) / (maxClone-min) * height,
  155. x: dataProp[i].x,
  156. y: dataProp[i].y,
  157. isEmpty: isEmpty
  158. }
  159. }
  160. }
  161. data.push(dataObject)
  162. }
  163.  
  164. // validation
  165. let isValidate = false
  166. if (simpleTypeCount === length || objectTypeCount === length) {
  167. isValidate = true
  168. }
  169.  
  170. if (isValidate) {
  171. object.data = data.sort((a, b) => {
  172. return a['gap'] - b['gap']
  173. // return a[0] - b[0]
  174. })
  175. } else {
  176. object.data = []
  177. }
  178.  
  179. result.push(object)
  180. })
  181.  
  182. return result
  183. }
  184.  
  185. export const getGuideArray = (max, min, height, numberOfPoints = 5) => {
  186. let x = parseInt(max)
  187. let xy = parseInt(max)
  188.  
  189. let arr = []
  190. let length
  191. let temp
  192. let postfix = ''
  193.  
  194. if (x === 0) {
  195. return []
  196. }
  197.  
  198. if (x > -1 && x < 1000) {
  199. x = Math.round(x * 10)
  200. temp = 1
  201. } else if (x >= 1000 && x < 1000000) {
  202. postfix = 'K'
  203. x = Math.round(x / 100)
  204. temp = 1000
  205. } else if (x >= 1000000 && x < 1000000000) {
  206. postfix = 'M'
  207. x = Math.round(x / 100000)
  208. temp = 1000000
  209. } else {
  210. postfix = 'B'
  211. x = Math.round(x / 100000000)
  212. temp = 1000000000
  213. }
  214. length = x.toString().length
  215.  
  216. x = _.round(x, -1 * length + 1) / 10
  217. let first = parseInt(x.toString()[0])
  218.  
  219. if (first > -1 && first < 3) { // 1,2
  220. x = 2.5 * x / first
  221. } else if (first > 2 && first < 6) { // 4,5
  222. x = 5 * x / first
  223. } else {
  224. x = 10 * x / first
  225. }
  226.  
  227. for (let i = 1; i < numberOfPoints + 1; i++) {
  228. let v = xy / numberOfPoints * i
  229. let incr = (xy - min) / numberOfPoints
  230. let val = min + (i*incr)
  231. //arr.push([val + postfix, v * temp / max * height, 1 * temp / max * height])
  232. arr.push([val + postfix, height / numberOfPoints * i, 1 * temp / max * height])
  233.  
  234. }
  235.  
  236. return arr
  237. }
  238.  
  239. export const drawYAxis = (color = '#e0e0e0') => {
  240. return (
  241. <View style={{
  242. borderRightWidth: 1,
  243. borderColor: color,
  244. width: 1,
  245. height: '100%',
  246. marginRight: 0
  247.  
  248. }} />
  249.  
  250. )
  251. }
  252.  
  253. export const drawYAxisLabels = (arr, height, minValue, color = '#000000') => {
  254. return (
  255. <View style={{
  256. width: 30,
  257. height: height,
  258. justifyContent: 'flex-end',
  259. alignItems: 'flex-end',
  260. marginBottom: minValue && arr && arr.length > 0 ? -1 * arr[0][2] * minValue : null,
  261. overflow: 'hidden'
  262. }}>
  263.  
  264. {arr.length === 0 ? (
  265. <View
  266. key={'guide0'}
  267. style={{
  268. bottom: 0,
  269. position: 'absolute'
  270. }}>
  271. <Text style={{fontSize: 11}}>0</Text>
  272. </View>
  273. ) : arr.map((v, i) => {
  274. if (v[1] > height) return null
  275. return (
  276. <View
  277. key={'guide' + i}
  278. style={{
  279. bottom: v[1] - 5,
  280. position: 'absolute'
  281. }}>
  282. <Text style={{fontSize: 11, color: color}}>{v[0]}</Text>
  283. </View>
  284. )
  285. })}
  286.  
  287. </View>
  288. )
  289. }
  290. export const drawGuideLine = (arr, color = '#e0e0e0') => {
  291. return (
  292. <View style={{
  293. width: '100%',
  294. height: '100%',
  295. position: 'absolute'
  296. }}>
  297.  
  298. {arr.map((v, i) => {
  299. return (
  300. <View
  301. key={'guide' + i}
  302. style={{
  303. width: '100%',
  304. borderTopWidth: 1,
  305. borderTopColor: color,
  306. bottom: v[1],
  307. position: 'absolute'
  308. }} />
  309. )
  310. })}
  311.  
  312. </View>
  313. )
  314. }
  315.  
  316. export const numberWithCommas = (x, summary = true) => {
  317. let postfix = ''
  318. if (summary) {
  319. if (x >= 1000 && x < 1000000) {
  320. postfix = 'K'
  321. x = Math.round(x / 100) / 10
  322. } else if (x >= 1000000 && x < 1000000000) {
  323. postfix = 'M'
  324. x = Math.round(x / 100000) / 10
  325. } else if (x >= 1000000000 && x < 1000000000000) {
  326. postfix = 'B'
  327. x = Math.round(x / 100000000) / 10
  328. }
  329. }
  330.  
  331. return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + postfix
  332. }
  333.  
  334. export const drawXAxis = (color = '#e0e0e0') => {
  335. return (
  336. <View style={{
  337. width: '100%',
  338. borderTopWidth: 1,
  339. borderTopColor: color
  340. }} />
  341. )
  342. }
  343. export const drawXAxisLabels = (sortedData, gap, color = '#000000', showEvenNumberXaxisLabel) => {
  344. return (
  345. <View style={{
  346. width: '100%',
  347. paddingVertical: 10,
  348. height: 10
  349. }}>
  350. {sortedData.map((data, i) => {
  351. // if (data[3] && i % 2 === 1) {
  352. if (data['x'] && i % 2 === 1 || !showEvenNumberXaxisLabel) {
  353. return (
  354. <View key={'label' + i} style={{
  355. position: 'absolute',
  356. // left: data[0] - gap / 2,
  357. left: data['gap'] - gap / 2,
  358. width: gap,
  359. alignItems: 'center'
  360. }}>
  361. <Text style={{fontSize: 9, color: color}}>
  362. {
  363. // data[3]
  364. data['x']
  365. }
  366. </Text>
  367. </View>
  368. )
  369. } else {
  370. return null
  371. }
  372. })}
  373. </View>
  374. )
  375. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement