Commit d49786f8e280bcb1dd0b00299d3ce12c196c9fdb

Authored by 徐烜
1 parent a9b53576

1、增强bsth-line-chart-list组件,可分页,有不同的分页模式

2、添加bsth-line-chart-list-pageMode类,将分页模式逻辑写入其中
front-end/h5/src/components/core/plugins/bsth/bsth-line-chart-list-pageMode.js 0 → 100644
  1 +/**
  2 + * 一般分页类。
  3 + */
  4 +class NormalPage {
  5 + /**
  6 + * 构造函数。
  7 + * @param page 页码(从0开始)
  8 + * @param pageSize 每页多少记录
  9 + * @param result 总的记录列表(array)
  10 + */
  11 + constructor (page, pageSize, result) {
  12 + this.page = 0
  13 + this.pageSize = pageSize === 0 ? 1 : pageSize
  14 + this.allDataSet = result
  15 + // ----------- 内部计算值 ----------- //
  16 + this.count = this.allDataSet.length // 总记录数
  17 + this.pageCount = Math.ceil(this.count / this.pageSize) // 总页数
  18 + this.currentPageDataSet = this.allDataSet.slice( // 当前页数据
  19 + this.page * this.pageSize,
  20 + this.page * this.pageSize + this.pageSize)
  21 + }
  22 +
  23 + /**
  24 + * 重新设置总的记录列表。
  25 + * @param result
  26 + */
  27 + set dataSet (result) {
  28 + this.allDataSet = result
  29 + this.count = result.length
  30 + this.pageCount = Math.ceil(this.count / this.pageSize)
  31 + if (this.page > this.pageCount - 1) {
  32 + this.page = this.pageCount - 1
  33 + }
  34 + this.currentPageDataSet = this.allDataSet.slice(
  35 + this.page * this.pageSize,
  36 + this.page * this.pageSize + this.pageSize)
  37 + }
  38 + resetPageSize (val) {
  39 + this.pageSize = val
  40 + this.pageCount = Math.ceil(this.count / this.pageSize)
  41 + if (this.page > this.pageCount - 1) {
  42 + this.page = this.pageCount - 1
  43 + }
  44 + this.currentPageDataSet = this.allDataSet.slice(
  45 + this.page * this.pageSize,
  46 + this.page * this.pageSize + this.pageSize)
  47 + }
  48 + /**
  49 + * 获取当前页,不翻页
  50 + * @return {*}
  51 + */
  52 + get currentPage () {
  53 + return this.currentPageDataSet
  54 + }
  55 + /**
  56 + * 返回当前页,并计算下一页数据,如果当前页是最后一页,则下一页跳转到第一页
  57 + */
  58 + next () {
  59 + // 当前页面记录列表
  60 + let currentPageDataSet = this.currentPageDataSet
  61 + // 计算下一页数据,如果当前是最后一页,跳转到第一页
  62 + this.page++
  63 + if (this.page > this.pageCount - 1) {
  64 + this.page = 0
  65 + }
  66 + this.currentPageDataSet = this.allDataSet.slice(
  67 + this.page * this.pageSize,
  68 + this.page * this.pageSize + this.pageSize)
  69 + return currentPageDataSet
  70 + }
  71 +}
  72 +
  73 +/**
  74 + * 滚动分页类。
  75 + */
  76 +class ScrollPage {
  77 + // TODO:
  78 +}
  79 +
  80 +export {
  81 + NormalPage as NormalPageClass,
  82 + ScrollPage as ScrollPageClass
  83 +}
front-end/h5/src/components/core/plugins/bsth/bsth-line-chart-list.js
@@ -3,8 +3,9 @@ @@ -3,8 +3,9 @@
3 */ 3 */
4 import PropTypes from '@luban-h5/plugin-common-props' 4 import PropTypes from '@luban-h5/plugin-common-props'
5 5
6 -import TestData from 'core/plugins/bsth/bsth-line-char-list_testData'  
7 -import TestData2 from 'core/plugins/bsth/bsth-line-chart_testData' 6 +import Utils from 'core/plugins/bsth/bsth-utils'
  7 +import { NormalPageClass } from 'core/plugins/bsth/bsth-line-chart-list-pageMode'
  8 +import TestData from 'core/plugins/bsth/bsth-line-chart-list_testData'
8 9
9 export default { 10 export default {
10 extra: { 11 extra: {
@@ -35,7 +36,29 @@ export default { @@ -35,7 +36,29 @@ export default {
35 line_chart_outer_div_width: 0, // 线路图外层div宽度 36 line_chart_outer_div_width: 0, // 线路图外层div宽度
36 line_chart_outer_div_height: 0, // 线路图外层div高度 37 line_chart_outer_div_height: 0, // 线路图外层div高度
37 internalDataSet: [], // 内部总数据 38 internalDataSet: [], // 内部总数据
38 - viewPortDataSet: [] // 可视区域对应的数据 39 + sourceDataSet: { // 原始数据
  40 + route: [], // 路由数据
  41 + gps: [] // gps数据
  42 + },
  43 + /**
  44 + * 监控外部数据变化(preview下通过ajax获取定时获取外部数据)
  45 + * 时间间隔定义成prop gps_data_refresh_minute
  46 + */
  47 + watchSourceDataSetTimer: {
  48 + timer: null,
  49 + count: 0
  50 + },
  51 + /**
  52 + * 监控翻页数据变化(priview下定时翻页)
  53 + * 翻页间隔定义成prop pageable_millisecond
  54 + */
  55 + watchPageTimer: {
  56 + timer: null,
  57 + count: 0
  58 + },
  59 + normalPageMode: null, // 一般分页处理器
  60 + scrollPageMode: null, // 滚动分页处理器
  61 + pageDataSet: [] // 分页对应的数据
39 } 62 }
40 }, 63 },
41 props: { 64 props: {
@@ -44,8 +67,14 @@ export default { @@ -44,8 +67,14 @@ export default {
44 label: '模式', 67 label: '模式',
45 visible: false 68 visible: false
46 }), 69 }),
  70 + // --------------- 数据属性 -------------- //
  71 + _flag_1_: PropTypes.string({ label: '', component: null, extra (h) { return (<hr data-label='数据属性' class='bsth-line-item-divider'/>) } }),
  72 + page_size: PropTypes.number({ label: '每页显示线路图数量', defaultValue: 5, layout: { prefixCls: 'bsth-line' } }),
  73 + pageable_mode: PropTypes.select({ label: '分页模式', defaultValue: 'normal', options: [{ label: '一般翻页', value: 'normal' }, { label: '滚动翻页', value: 'scroll' }], layout: { prefixCls: 'bsth-line' } }),
  74 + pageable_millisecond: PropTypes.number({ label: '自动翻页间隔(毫秒)', defaultValue: 2000, layout: { prefixCls: 'bsth-line' } }),
  75 + gps_data_refresh_minute: PropTypes.number({ label: 'gps数据刷新间隔(分钟)', defaultValue: 1, layout: { prefixCls: 'bsth-line' } }),
47 // --------------- 外层css属性 --------------- // 76 // --------------- 外层css属性 --------------- //
48 - _flag_2_: PropTypes.string({ label: '', component: null, extra: function(h) {return (<hr data-label="外层css属性" class="bsth-line-item-divider"/>)} }), 77 + _flag_2_: PropTypes.string({ label: '', component: null, extra (h) { return (<hr data-label='外层css属性' class='bsth-line-item-divider'/>) } }),
49 margin_left: PropTypes.number({ label: '图左边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), 78 margin_left: PropTypes.number({ label: '图左边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }),
50 margin_right: PropTypes.number({ label: '图右边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), 79 margin_right: PropTypes.number({ label: '图右边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }),
51 margin_top: PropTypes.number({ label: '图上边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), 80 margin_top: PropTypes.number({ label: '图上边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }),
@@ -53,7 +82,7 @@ export default { @@ -53,7 +82,7 @@ export default {
53 border_size: PropTypes.number({ label: '图边框宽度', defaultValue: 1, layout: { prefixCls: 'bsth-line' } }), 82 border_size: PropTypes.number({ label: '图边框宽度', defaultValue: 1, layout: { prefixCls: 'bsth-line' } }),
54 background_color: PropTypes.color({ label: '背景颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } }), 83 background_color: PropTypes.color({ label: '背景颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } }),
55 // --------------- 内部线路模拟图外层css属性 --------------- // 84 // --------------- 内部线路模拟图外层css属性 --------------- //
56 - _flag_3_: PropTypes.string({ label: '', component: null, extra: function(h) {return (<hr data-label="内部线路模拟图外层css属性" class="bsth-line-item-divider"></hr>)} }), 85 + _flag_3_: PropTypes.string({ label: '', component: null, extra (h) { return (<hr data-label='内部线路模拟图外层css属性' class='bsth-line-item-divider'></hr>) } }),
57 line_chart_margin_left: PropTypes.number({ label: '图左边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), 86 line_chart_margin_left: PropTypes.number({ label: '图左边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }),
58 line_chart_margin_right: PropTypes.number({ label: '图右边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), 87 line_chart_margin_right: PropTypes.number({ label: '图右边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }),
59 line_chart_margin_top: PropTypes.number({ label: '图上边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), 88 line_chart_margin_top: PropTypes.number({ label: '图上边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }),
@@ -61,7 +90,7 @@ export default { @@ -61,7 +90,7 @@ export default {
61 line_chart_border_size: PropTypes.number({ label: '图边框宽度', defaultValue: 1, layout: { prefixCls: 'bsth-line' } }), 90 line_chart_border_size: PropTypes.number({ label: '图边框宽度', defaultValue: 1, layout: { prefixCls: 'bsth-line' } }),
62 line_chart_background_color: PropTypes.color({ label: '背景颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } }), 91 line_chart_background_color: PropTypes.color({ label: '背景颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } }),
63 // --------------- 内部线路模拟图内层css属性 --------------- // 92 // --------------- 内部线路模拟图内层css属性 --------------- //
64 - _flag_4_: PropTypes.string({ label: '', component: null, extra: function(h) {return (<hr data-label="内部线路模拟图内层css属性" class="bsth-line-item-divider"></hr>)} }), 93 + _flag_4_: PropTypes.string({ label: '', component: null, extra (h) { return (<hr data-label='内部线路模拟图内层css属性' class='bsth-line-item-divider'></hr>) } }),
65 chart_left_padding: PropTypes.number({ label: '内部线路图距离左边padding', defaultValue: 30, layout: { prefixCls: 'bsth-line' } }), 94 chart_left_padding: PropTypes.number({ label: '内部线路图距离左边padding', defaultValue: 30, layout: { prefixCls: 'bsth-line' } }),
66 chart_right_padding: PropTypes.number({ label: '内部线路图居中修正padding', defaultValue: 30, layout: { prefixCls: 'bsth-line' } }), 95 chart_right_padding: PropTypes.number({ label: '内部线路图居中修正padding', defaultValue: 30, layout: { prefixCls: 'bsth-line' } }),
67 chart_center_top_padding: PropTypes.number({ label: '内部线路图居中修正padding', defaultValue: 4, layout: { prefixCls: 'bsth-line' } }), 96 chart_center_top_padding: PropTypes.number({ label: '内部线路图居中修正padding', defaultValue: 4, layout: { prefixCls: 'bsth-line' } }),
@@ -84,9 +113,6 @@ export default { @@ -84,9 +113,6 @@ export default {
84 chart_gps_down_merge_text_f_color: PropTypes.color({ label: '下行合并gps车辆文本颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } }) 113 chart_gps_down_merge_text_f_color: PropTypes.color({ label: '下行合并gps车辆文本颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } })
85 }, 114 },
86 render () { 115 render () {
87 - const lineRouteData = TestData.route_test_data  
88 - const lineGpsData = TestData.gps_test_data  
89 -  
90 const innerDivStyle = { 116 const innerDivStyle = {
91 'width': this.list_width + 'px', 117 'width': this.list_width + 'px',
92 'height': this.list_height + 'px', 118 'height': this.list_height + 'px',
@@ -99,19 +125,40 @@ export default { @@ -99,19 +125,40 @@ export default {
99 'position': 'relative' 125 'position': 'relative'
100 } 126 }
101 127
  128 + const bsthLineChartDataList = []
  129 + for (let data of this.pageDataSet) {
  130 + bsthLineChartDataList.push({ // TODO:还有其他属性数据
  131 + useMode: 'child',
  132 + editorMode: this.editorMode,
  133 + line_chart_outer_div_width: this.line_chart_outer_div_width,
  134 + line_chart_outer_div_height: this.line_chart_outer_div_height,
  135 + line_route_data: data.route,
  136 + line_gps_data: data.gps,
  137 + line_name: data.lineName,
  138 + line_code: data.lineCode
  139 + })
  140 + }
  141 +
102 /* 最外层div对应编辑器的通用样式 */ 142 /* 最外层div对应编辑器的通用样式 */
103 return ( 143 return (
104 <div> 144 <div>
105 <div style={innerDivStyle}> 145 <div style={innerDivStyle}>
106 - <bsth-line-chart  
107 - editorMode={this.editorMode}  
108 - useMode='child'  
109 - line_chart_outer_div_width={this.line_chart_outer_div_width}  
110 - line_chart_outer_div_height={this.line_chart_outer_div_height}  
111 - line_route_data={lineRouteData}  
112 - line_gps_data={lineGpsData}  
113 - >  
114 - </bsth-line-chart> 146 + {
  147 + bsthLineChartDataList.map(item => {
  148 + return (
  149 + <bsth-line-chart
  150 + useMode={item.useMode}
  151 + editorMode={item.editorMode}
  152 + line_chart_outer_div_width={item.line_chart_outer_div_width}
  153 + line_chart_outer_div_height={item.line_chart_outer_div_height}
  154 + line_route_data_child={item.line_route_data}
  155 + line_gps_data_child={item.line_gps_data}
  156 + line_name={item.line_name}
  157 + line_code={item.line_code}
  158 + />
  159 + )
  160 + })
  161 + }
115 </div> 162 </div>
116 </div> 163 </div>
117 ) 164 )
@@ -121,26 +168,59 @@ export default { @@ -121,26 +168,59 @@ export default {
121 let $jQuery = this.private_jQuery 168 let $jQuery = this.private_jQuery
122 this.list_width = $jQuery(this.$el).width() - this.margin_left - this.margin_right - this.border_size * 2 169 this.list_width = $jQuery(this.$el).width() - this.margin_left - this.margin_right - this.border_size * 2
123 this.list_height = $jQuery(this.$el).height() - this.margin_top - this.margin_bottom - this.border_size * 2 170 this.list_height = $jQuery(this.$el).height() - this.margin_top - this.margin_bottom - this.border_size * 2
124 - // 开启外部元素长宽监控计数  
125 - this.watchWidthHeightTimer.count++  
126 // 线路图外层div长宽就是列表长宽,因为线路图作为子组件无法编辑通用样式,最外穿div的margin,border一律为0 171 // 线路图外层div长宽就是列表长宽,因为线路图作为子组件无法编辑通用样式,最外穿div的margin,border一律为0
127 this.line_chart_outer_div_width = this.list_width 172 this.line_chart_outer_div_width = this.list_width
128 - this.line_chart_outer_div_height = this.list_height 173 + this.line_chart_outer_div_height = Math.floor(this.list_height / this.page_size)
  174 + // 开启外部元素长宽监控计数
  175 + /**
  176 + * 开启外部元素长宽监控逻辑
  177 + * 1、必须在编辑模式下启效果,否则无效
  178 + */
  179 + if (this.editorMode === 'edit') {
  180 + this.watchWidthHeightTimer.count++
  181 + }
  182 + // 开启原始数据监控计数(preview监控变化,edit模式下使用测试数据)
  183 + if (this.editorMode === 'preview') {
  184 + this.watchSourceDataSetTimer.count++
  185 + } else {
  186 + this.sourceDataSet.route = TestData.lineRouteList
  187 + this.sourceDataSet.gps = TestData.lineGpsList
  188 + this.private_computeInternalDataSet(this.sourceDataSet.route, this.sourceDataSet.gps)
  189 + }
  190 + // 开启翻页数据变化监控计数(preview监控变化)
  191 + if (this.editorMode === 'preview') {
  192 + this.watchPageTimer.count++
  193 + }
  194 + // 定义分页处理器
  195 + if (this.pageable_mode === 'normal') {
  196 + this.normalPageMode = new NormalPageClass(0, this.page_size, this.internalDataSet)
  197 + this.pageDataSet = this.normalPageMode.next()
  198 + } else if (this.pageable_mode === 'scroll') {
  199 + throw new Error('滚动分页模式还未实现')
  200 + } else {
  201 + throw new Error('未知分页模式=' + this.pageable_mode)
  202 + }
129 }, 203 },
130 destroyed () { 204 destroyed () {
131 // 组件删除的时候,删除监控定时器 205 // 组件删除的时候,删除监控定时器
132 - let timer = this.watchWidthHeightTimer.timer  
133 - if (timer) {  
134 - clearTimeout(timer) 206 + let timer1 = this.watchWidthHeightTimer.timer
  207 + if (timer1) {
  208 + clearTimeout(timer1)
135 this.watchWidthHeightTimer.timer = null 209 this.watchWidthHeightTimer.timer = null
136 } 210 }
  211 + let timer2 = this.watchSourceDataSetTimer.timer
  212 + if (timer2) {
  213 + clearTimeout(timer2)
  214 + this.watchSourceDataSetTimer.timer = null
  215 + }
  216 + let timer3 = this.watchPageTimer.timer
  217 + if (timer3) {
  218 + clearTimeout(timer3)
  219 + this.watchPageTimer.timer = null
  220 + }
137 }, 221 },
138 watch: { 222 watch: {
139 - /**  
140 - * 开启外部元素长宽监控逻辑  
141 - * 1、必须在编辑模式下启效果,否则无效  
142 - */  
143 - 'watchWidthHeightTimer.count' () { // 定时器监控 223 + 'watchWidthHeightTimer.count' () { // 长宽定时器监控
144 let timer = this.watchWidthHeightTimer.timer 224 let timer = this.watchWidthHeightTimer.timer
145 if (timer) { 225 if (timer) {
146 clearTimeout(timer) 226 clearTimeout(timer)
@@ -149,25 +229,257 @@ export default { @@ -149,25 +229,257 @@ export default {
149 229
150 let self = this 230 let self = this
151 let $jQuery = this.private_jQuery 231 let $jQuery = this.private_jQuery
  232 + self.watchWidthHeightTimer.timer = setTimeout(function () {
  233 + // 处理逻辑
  234 + let width = $jQuery(self.$el).width()
  235 + let height = $jQuery(self.$el).height()
  236 +
  237 + if (width !== self.list_width) {
  238 + self.list_width = width - self.margin_left - self.margin_right - self.border_size * 2
  239 + self.line_chart_outer_div_width = self.list_width
  240 + }
  241 + if (height !== self.list_height) {
  242 + self.list_height = height - self.margin_top - self.margin_bottom - self.border_size * 2
  243 + self.line_chart_outer_div_height = Math.floor(self.list_height / self.page_size)
  244 + }
  245 +
  246 + self.watchWidthHeightTimer.count++
  247 + }, self.watchWidthHeightTimer.millisecond)
  248 + },
  249 + 'watchSourceDataSetTimer.count' () { // 原始数据定时器监控
  250 + let timer = this.watchSourceDataSetTimer.timer
  251 + if (timer) {
  252 + clearTimeout(timer)
  253 + this.watchSourceDataSetTimer.timer = null
  254 + }
  255 +
  256 + let self = this
  257 + self.watchSourceDataSetTimer.timer = setTimeout(function() {
  258 + // TODO:处理逻辑,之后用jsonp获取数据,获取完数据后更新,进行如下操作
  259 + // TODO:self.private_computeInternalDataSet(self.sourceDataSet.route, self.sourceDataSet.gps)
  260 + // TODO:self.normalPageMode.dataSet = self.internalDataSet
  261 + // TODO:self.pageDataSet = self.normalPageMode.currentPage
  262 + // TODO:以下数据是测试代码
  263 + self.sourceDataSet.route = TestData.lineRouteList
  264 + self.sourceDataSet.gps = TestData.lineGpsList
  265 + self.private_computeInternalDataSet(self.sourceDataSet.route, self.sourceDataSet.gps)
  266 + self.normalPageMode.dataSet = self.internalDataSet
  267 + self.pageDataSet = self.normalPageMode.currentPage
  268 + self.watchSourceDataSetTimer.count++
  269 + }, self.gps_data_refresh_minute * 60 * 1000)
  270 + },
  271 + 'watchPageTimer.count' () { // 翻页数据定时器监控
  272 + let timer = this.watchPageTimer.timer
  273 + if (timer) {
  274 + clearTimeout(timer)
  275 + this.watchPageTimer.timer = null
  276 + }
  277 +
  278 + let self = this
  279 + self.watchPageTimer.timer = setTimeout(function() {
  280 + if (self.pageable_mode === 'normal') {
  281 + self.pageDataSet = self.normalPageMode.next()
  282 + } else if (self.pageable_mode === 'scroll') {
  283 + throw new Error('滚动分页模式还未实现')
  284 + } else {
  285 + throw new Error('未知分页模式=' + self.pageable_mode)
  286 + }
  287 + self.watchPageTimer.count++
  288 + }, self.pageable_millisecond)
  289 + },
  290 + // ----------------- 数据属性 ---------------- //
  291 + page_size (val) {
  292 + let self = this
152 if (self.editorMode === 'edit') { 293 if (self.editorMode === 'edit') {
153 - self.watchWidthHeightTimer.timer = setTimeout(function () {  
154 - // 处理逻辑  
155 - let width = $jQuery(self.$el).width()  
156 - let height = $jQuery(self.$el).height() 294 + if (self.pageable_mode === 'normal') {
  295 + self.normalPageMode.resetPageSize(val)
  296 + self.pageDataSet = self.normalPageMode.currentPage
  297 + } else if (self.pageable_mode === 'scroll') {
  298 + throw new Error('滚动分页模式还未实现')
  299 + } else {
  300 + throw new Error('未知分页模式=' + self.pageable_mode)
  301 + }
  302 + }
  303 + self.line_chart_outer_div_height = Math.floor(self.list_height / self.page_size)
  304 + },
  305 + // ----------------- 本身宽高 监控 ---------------- //
  306 + list_width () {
  307 + let self = this
  308 + self.line_chart_outer_div_width = self.list_width
  309 + },
  310 + list_height () {
  311 + let self = this
  312 + self.line_chart_outer_div_height = Math.floor(self.list_height / self.page_size)
  313 + },
  314 + // ----------------- 外层css属性 监控 ----------------- //
  315 + margin_left () {
  316 + let self = this
  317 + self.list_width = self.list_width - self.margin_left - self.margin_right - self.border_size * 2
  318 + },
  319 + margin_right () {
  320 + let self = this
  321 + self.list_width = self.list_width - self.margin_left - self.margin_right - self.border_size * 2
  322 + },
  323 + margin_top () {
  324 + let self = this
  325 + self.list_height = self.list_height - self.margin_top - self.margin_bottom - self.border_size * 2
  326 + },
  327 + margin_bottom () {
  328 + let self = this
  329 + self.list_height = self.list_height - self.margin_top - self.margin_bottom - self.border_size * 2
  330 + },
  331 + border_size () {
  332 + let self = this
  333 + self.list_width = self.list_width - self.margin_left - self.margin_right - self.border_size * 2
  334 + self.list_height = self.list_height - self.margin_top - self.margin_bottom - self.border_size * 2
  335 + }
  336 + },
  337 + methods: {
  338 + /**
  339 + * 创建内部数据(线路模拟图数据格式)。
  340 + * @param up 上行站点数据
  341 + * @param down 下行站点数据
  342 + * @return {*}
  343 + * 数据示例:
  344 + * {
  345 + * names: ["A起点站"], // 站点名字数组
  346 + * ids: ["ACODE_0", "ACODE_1"], // 站点编码_上下行
  347 + * type: 2, // 0:上行 1:下行 2:同名合并 3:异名合并
  348 + * stationMark: "B" // 站点表识
  349 + * }
  350 + * @private
  351 + */
  352 + private_createInternalData (up, down) {
  353 + if (up === null && down === null) {
  354 + return null
  355 + }
  356 + let [names, type, ids, mark] = [null, 2, null, null]
  357 + if (up === null) {
  358 + type = 1
  359 + names = [down.stationName]
  360 + ids = [down.stationCode + '_' + down.directions]
  361 + mark = down.stationMark
  362 + } else if (down === null) {
  363 + type = 0
  364 + names = [up.stationName]
  365 + ids = [up.stationCode + '_' + up.directions]
  366 + mark = up.stationMark
  367 + } else {
  368 + names = [up.stationName]
  369 + ids = [up.stationCode + '_' + up.directions, down.stationCode + '_' + down.directions]
  370 + mark = up.stationMark
  371 + if (up.stationName !== down.stationName) {
  372 + type = 3
  373 + names.push(down.stationName)
  374 + }
  375 + }
  376 + return {
  377 + names: names,
  378 + ids: ids,
  379 + type: type,
  380 + stationMark: mark
  381 + }
  382 + },
  383 + /**
  384 + * 计算内部总数据。
  385 + */
  386 + private_computeInternalDataSet (routeData, gpsData) {
  387 + let self = this
  388 +
  389 + // 1、按照线路名字_线路编码分组数据
  390 + let routeGroupByLineNameCode = Utils.listGroupBy(routeData, function (d) {
  391 + return d.lineName + '_' + d.lineCode
  392 + })
  393 + let gpsGroupByLineNameCode = Utils.listGroupBy(gpsData, function (d) {
  394 + return d.lineName + '_' + d.lineCode
  395 + })
  396 + // 2、获取线路名字_线路编码列表(按照线路名字排序)
  397 + let lineNameCodeList = []
  398 + let routeGroupByLineNameCodeKeys = Object.keys(routeGroupByLineNameCode)
  399 + for (let key of routeGroupByLineNameCodeKeys) {
  400 + lineNameCodeList.push(key)
  401 + }
  402 + lineNameCodeList.sort(function (a, b) {
  403 + return a.localeCompare(b)
  404 + })
  405 + // 3、处理数据,循环计算每条线路的数据
  406 + if (lineNameCodeList.length === 0) {
  407 + return
  408 + } else {
  409 + self.internalDataSet = []
  410 + }
  411 + for (let key of lineNameCodeList) {
  412 + let lineName = key.split('_')[0]
  413 + let lineCode = key.split('_')[1]
157 414
158 - if (width !== self.list_width) {  
159 - self.list_width = width - self.margin_left - self.margin_right - self.border_size * 2  
160 - self.line_chart_outer_div_width = self.list_width 415 + // 3.1 定义内部数据
  416 + let internalData = {
  417 + lineName: lineName,
  418 + lineCode: lineCode,
  419 + route: [],
  420 + gps: []
  421 + }
  422 + // 3.2 处理路由数据
  423 + // 3.2.1 获取指定线路路由
  424 + let lineRoute = routeGroupByLineNameCode[key]
  425 + // 3.2.2 按照directions方向分组
  426 + let lineRouteGroupByDir = Utils.listGroupBy(lineRoute, function (d) {
  427 + return d.directions
  428 + })
  429 + // 3.2.3 排序分组,上行升序,下行降序(下行降序为了后面进行站点名合并)
  430 + try {
  431 + lineRouteGroupByDir[0].sort(function (a, b) {
  432 + return a.stationRouteCode - b.stationRouteCode
  433 + })
  434 + lineRouteGroupByDir[1].sort(function (a, b) {
  435 + return b.stationRouteCode - a.stationRouteCode
  436 + })
  437 + } catch (e) {
  438 + console.log('站定路由数据异常!')
  439 + console.log(e)
  440 + }
  441 +
  442 + // TODO:如果是环线,lineRouteGroupByDir[1] = []
  443 + /**
  444 + * 3.2.4 核心合并算法。
  445 + */
  446 + let mergeRouteData = []
  447 + let dirUpData
  448 + let dirDownData
  449 + for (let i = 0; i < 888; i++) {
  450 + dirUpData = lineRouteGroupByDir[0][i]
  451 + dirDownData = lineRouteGroupByDir[1][i]
  452 + if (dirUpData != null && dirDownData != null && dirUpData.stationName !== dirDownData.stationName) {
  453 + // arr2 包含 a1
  454 + let ii = Utils.listIndexOf(lineRouteGroupByDir[1], dirUpData, 'stationName')
  455 + if (ii > i) {
  456 + Utils.insertNullToList(lineRouteGroupByDir[0], i, ii - i)
  457 + i -= 1
  458 + continue
  459 + }
  460 + // arr1 包含 a2
  461 + ii = Utils.listIndexOf(lineRouteGroupByDir[0], dirDownData, 'stationName')
  462 + if (ii > i) {
  463 + Utils.insertNullToList(lineRouteGroupByDir[1], i, ii - i)
  464 + i -= 1
  465 + continue
  466 + }
161 } 467 }
162 - if (height !== self.list_height) {  
163 - self.list_height = height - self.margin_top - self.margin_bottom - self.border_size * 2  
164 - self.line_chart_outer_div_height = self.list_height 468 +
  469 + if (dirUpData == null && dirDownData == null) {
  470 + break
165 } 471 }
  472 + mergeRouteData.splice(i, 1, self.private_createInternalData(dirUpData, dirDownData))
  473 + }
  474 + internalData.route = mergeRouteData
166 475
167 - self.watchWidthHeightTimer.count++  
168 - }, self.watchWidthHeightTimer.millisecond) 476 + // 3.3 处理gps数据
  477 + if (gpsGroupByLineNameCode[key]) {
  478 + internalData.gps = gpsGroupByLineNameCode[key]
  479 + }
  480 + // 3.4 处理总数据集
  481 + self.internalDataSet.push(internalData)
169 } 482 }
170 } 483 }
171 } 484 }
172 - // methods () {}  
173 } 485 }
front-end/h5/src/components/core/plugins/bsth/bsth-line-char-list_testData.js renamed to front-end/h5/src/components/core/plugins/bsth/bsth-line-chart-list_testData.js
front-end/h5/src/components/core/plugins/bsth/bsth-line-chart.js
@@ -66,6 +66,18 @@ export default { @@ -66,6 +66,18 @@ export default {
66 label: 'line-chart-outer-div样式的div高度', 66 label: 'line-chart-outer-div样式的div高度',
67 visible: false 67 visible: false
68 }), 68 }),
  69 + line_route_data_child: { // 作为子组件,父对象传值
  70 + type: Array,
  71 + default: function () {
  72 + return []
  73 + }
  74 + },
  75 + line_gps_data_child: { // 作为子组件,父对象传值
  76 + type: Array,
  77 + default: function () {
  78 + return []
  79 + }
  80 + },
69 // 数据属性 81 // 数据属性
70 _flag_1_: PropTypes.string({ label: '', component: null, extra: function(h) {return (<hr data-label="数据属性" class="bsth-line-item-divider"></hr>)} }), 82 _flag_1_: PropTypes.string({ label: '', component: null, extra: function(h) {return (<hr data-label="数据属性" class="bsth-line-item-divider"></hr>)} }),
71 line_name: PropTypes.string({ label: '线路名称', defaultValue: '线路1', layout: { prefixCls: 'bsth-line' } }), 83 line_name: PropTypes.string({ label: '线路名称', defaultValue: '线路1', layout: { prefixCls: 'bsth-line' } }),
@@ -155,11 +167,18 @@ export default { @@ -155,11 +167,18 @@ export default {
155 let $jQuery = this.private_jQuery 167 let $jQuery = this.private_jQuery
156 this.line_width = $jQuery(this.$el).width() - this.margin_left - this.margin_right 168 this.line_width = $jQuery(this.$el).width() - this.margin_left - this.margin_right
157 this.line_height = $jQuery(this.$el).height() - this.margin_top - this.margin_bottom 169 this.line_height = $jQuery(this.$el).height() - this.margin_top - this.margin_bottom
158 - 170 + if (this.useMode === 'child') {
  171 + this.line_width = this.line_chart_outer_div_width - this.margin_left - this.margin_right
  172 + this.line_height = this.line_chart_outer_div_height - this.margin_top - this.margin_bottom
  173 + }
159 // 测试数据 174 // 测试数据
160 - this.line_route_data = TestData.route_test_data  
161 - this.line_gps_data = TestData.gps_test_data  
162 - 175 + if (this.useMode === 'alone') {
  176 + this.line_route_data = TestData.route_test_data
  177 + this.line_gps_data = TestData.gps_test_data
  178 + } else {
  179 + this.line_route_data = this.line_route_data_child
  180 + this.line_gps_data = this.line_gps_data_child
  181 + }
163 // 开启外部元素长宽监控计数 182 // 开启外部元素长宽监控计数
164 /** 183 /**
165 * 开启外部元素长宽监控逻辑(class='line-chart-outer-div') 184 * 开启外部元素长宽监控逻辑(class='line-chart-outer-div')
@@ -211,16 +230,28 @@ export default { @@ -211,16 +230,28 @@ export default {
211 */ 230 */
212 line_chart_outer_div_width: function (val) { 231 line_chart_outer_div_width: function (val) {
213 let self = this 232 let self = this
214 - if (this.useMode === 'child') { 233 + if (self.useMode === 'child') {
215 self.line_width = val - self.margin_left - self.margin_right 234 self.line_width = val - self.margin_left - self.margin_right
216 } 235 }
217 }, 236 },
218 line_chart_outer_div_height: function (val) { 237 line_chart_outer_div_height: function (val) {
219 let self = this 238 let self = this
220 - if (this.useMode === 'child') { 239 + if (self.useMode === 'child') {
221 self.line_height = val - self.margin_top - self.margin_bottom 240 self.line_height = val - self.margin_top - self.margin_bottom
222 } 241 }
223 }, 242 },
  243 + line_route_data_child: function (val) {
  244 + let self = this
  245 + if (self.useMode === 'child') {
  246 + self.line_route_data = val
  247 + }
  248 + },
  249 + line_gps_data_child: function (val) {
  250 + let self = this
  251 + if (self.useMode === 'child') {
  252 + self.line_gps_data = val
  253 + }
  254 + },
224 // ----------- 数据属性 ----------- // 255 // ----------- 数据属性 ----------- //
225 line_route_data: function (currentVal, oldVal) { 256 line_route_data: function (currentVal, oldVal) {
226 let self = this 257 let self = this
front-end/h5/src/components/core/plugins/bsth/bsth-utils.js
@@ -50,5 +50,46 @@ export default { @@ -50,5 +50,46 @@ export default {
50 } 50 }
51 51
52 return true; 52 return true;
  53 + },
  54 + /**
  55 + * 按照分组key值分组列表数组
  56 + * @param list 对象数组
  57 + * @param groupKeyFun 分组key函数(参数为列表数组中的每个元素)
  58 + */
  59 + listGroupBy (list, groupKeyFun) {
  60 + let rs = {}
  61 + for (let value of list) {
  62 + let key = groupKeyFun(value)
  63 + if (!rs[key]) {
  64 + rs[key] = []
  65 + }
  66 + rs[key].push(value)
  67 + }
  68 + return rs
  69 + },
  70 + /**
  71 + * 比较对象指定属性值第一次在数组对象中出现的位置。
  72 + * @param list 对象数组
  73 + * @param obj1 对象
  74 + * @param objProperty 对象属性名
  75 + */
  76 + listIndexOf (list, obj1, objProperty) {
  77 + for (let j = 0, len = list.length; j < len; j++) {
  78 + if (list[j] != null && obj1[objProperty] === list[j][objProperty]) {
  79 + return j
  80 + }
  81 + }
  82 + return -1
  83 + },
  84 + /**
  85 + * 在数组的指定位置插入指定数量的null。
  86 + * @param list 数组
  87 + * @param i 指定位置
  88 + * @param size null的数量
  89 + */
  90 + insertNullToList (list, i, size) {
  91 + for (let j = 0; j < size; j++) {
  92 + list.splice(j + i, 0, null)
  93 + }
53 } 94 }
54 } 95 }