Commit d49786f8e280bcb1dd0b00299d3ce12c196c9fdb
1 parent
a9b53576
1、增强bsth-line-chart-list组件,可分页,有不同的分页模式
2、添加bsth-line-chart-list-pageMode类,将分页模式逻辑写入其中
Showing
5 changed files
with
515 additions
and
48 deletions
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 | 3 | */ |
| 4 | 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 | 10 | export default { |
| 10 | 11 | extra: { |
| ... | ... | @@ -35,7 +36,29 @@ export default { |
| 35 | 36 | line_chart_outer_div_width: 0, // 线路图外层div宽度 |
| 36 | 37 | line_chart_outer_div_height: 0, // 线路图外层div高度 |
| 37 | 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 | 64 | props: { |
| ... | ... | @@ -44,8 +67,14 @@ export default { |
| 44 | 67 | label: '模式', |
| 45 | 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 | 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 | 78 | margin_left: PropTypes.number({ label: '图左边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), |
| 50 | 79 | margin_right: PropTypes.number({ label: '图右边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), |
| 51 | 80 | margin_top: PropTypes.number({ label: '图上边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), |
| ... | ... | @@ -53,7 +82,7 @@ export default { |
| 53 | 82 | border_size: PropTypes.number({ label: '图边框宽度', defaultValue: 1, layout: { prefixCls: 'bsth-line' } }), |
| 54 | 83 | background_color: PropTypes.color({ label: '背景颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } }), |
| 55 | 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 | 86 | line_chart_margin_left: PropTypes.number({ label: '图左边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), |
| 58 | 87 | line_chart_margin_right: PropTypes.number({ label: '图右边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), |
| 59 | 88 | line_chart_margin_top: PropTypes.number({ label: '图上边margin', defaultValue: 0, layout: { prefixCls: 'bsth-line' } }), |
| ... | ... | @@ -61,7 +90,7 @@ export default { |
| 61 | 90 | line_chart_border_size: PropTypes.number({ label: '图边框宽度', defaultValue: 1, layout: { prefixCls: 'bsth-line' } }), |
| 62 | 91 | line_chart_background_color: PropTypes.color({ label: '背景颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } }), |
| 63 | 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 | 94 | chart_left_padding: PropTypes.number({ label: '内部线路图距离左边padding', defaultValue: 30, layout: { prefixCls: 'bsth-line' } }), |
| 66 | 95 | chart_right_padding: PropTypes.number({ label: '内部线路图居中修正padding', defaultValue: 30, layout: { prefixCls: 'bsth-line' } }), |
| 67 | 96 | chart_center_top_padding: PropTypes.number({ label: '内部线路图居中修正padding', defaultValue: 4, layout: { prefixCls: 'bsth-line' } }), |
| ... | ... | @@ -84,9 +113,6 @@ export default { |
| 84 | 113 | chart_gps_down_merge_text_f_color: PropTypes.color({ label: '下行合并gps车辆文本颜色', defaultValue: '#FFFFFF', layout: { prefixCls: 'bsth-line' } }) |
| 85 | 114 | }, |
| 86 | 115 | render () { |
| 87 | - const lineRouteData = TestData.route_test_data | |
| 88 | - const lineGpsData = TestData.gps_test_data | |
| 89 | - | |
| 90 | 116 | const innerDivStyle = { |
| 91 | 117 | 'width': this.list_width + 'px', |
| 92 | 118 | 'height': this.list_height + 'px', |
| ... | ... | @@ -99,19 +125,40 @@ export default { |
| 99 | 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 | 142 | /* 最外层div对应编辑器的通用样式 */ |
| 103 | 143 | return ( |
| 104 | 144 | <div> |
| 105 | 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 | 162 | </div> |
| 116 | 163 | </div> |
| 117 | 164 | ) |
| ... | ... | @@ -121,26 +168,59 @@ export default { |
| 121 | 168 | let $jQuery = this.private_jQuery |
| 122 | 169 | this.list_width = $jQuery(this.$el).width() - this.margin_left - this.margin_right - this.border_size * 2 |
| 123 | 170 | this.list_height = $jQuery(this.$el).height() - this.margin_top - this.margin_bottom - this.border_size * 2 |
| 124 | - // 开启外部元素长宽监控计数 | |
| 125 | - this.watchWidthHeightTimer.count++ | |
| 126 | 171 | // 线路图外层div长宽就是列表长宽,因为线路图作为子组件无法编辑通用样式,最外穿div的margin,border一律为0 |
| 127 | 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 | 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 | 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 | 222 | watch: { |
| 139 | - /** | |
| 140 | - * 开启外部元素长宽监控逻辑 | |
| 141 | - * 1、必须在编辑模式下启效果,否则无效 | |
| 142 | - */ | |
| 143 | - 'watchWidthHeightTimer.count' () { // 定时器监控 | |
| 223 | + 'watchWidthHeightTimer.count' () { // 长宽定时器监控 | |
| 144 | 224 | let timer = this.watchWidthHeightTimer.timer |
| 145 | 225 | if (timer) { |
| 146 | 226 | clearTimeout(timer) |
| ... | ... | @@ -149,25 +229,257 @@ export default { |
| 149 | 229 | |
| 150 | 230 | let self = this |
| 151 | 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 | 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 | 66 | label: 'line-chart-outer-div样式的div高度', |
| 67 | 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 | 82 | _flag_1_: PropTypes.string({ label: '', component: null, extra: function(h) {return (<hr data-label="数据属性" class="bsth-line-item-divider"></hr>)} }), |
| 71 | 83 | line_name: PropTypes.string({ label: '线路名称', defaultValue: '线路1', layout: { prefixCls: 'bsth-line' } }), |
| ... | ... | @@ -155,11 +167,18 @@ export default { |
| 155 | 167 | let $jQuery = this.private_jQuery |
| 156 | 168 | this.line_width = $jQuery(this.$el).width() - this.margin_left - this.margin_right |
| 157 | 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 | 184 | * 开启外部元素长宽监控逻辑(class='line-chart-outer-div') |
| ... | ... | @@ -211,16 +230,28 @@ export default { |
| 211 | 230 | */ |
| 212 | 231 | line_chart_outer_div_width: function (val) { |
| 213 | 232 | let self = this |
| 214 | - if (this.useMode === 'child') { | |
| 233 | + if (self.useMode === 'child') { | |
| 215 | 234 | self.line_width = val - self.margin_left - self.margin_right |
| 216 | 235 | } |
| 217 | 236 | }, |
| 218 | 237 | line_chart_outer_div_height: function (val) { |
| 219 | 238 | let self = this |
| 220 | - if (this.useMode === 'child') { | |
| 239 | + if (self.useMode === 'child') { | |
| 221 | 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 | 256 | line_route_data: function (currentVal, oldVal) { |
| 226 | 257 | let self = this | ... | ... |
front-end/h5/src/components/core/plugins/bsth/bsth-utils.js
| ... | ... | @@ -50,5 +50,46 @@ export default { |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 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 | } | ... | ... |