Merge branch 'master' of ssh://dev.zhiheiot.com:29418/mob-components
# Conflicts:
# common/Tools.js
8 files added
2 files modified
| | |
| | | } |
| | | |
| | | /** |
| | | * 转换周数到日期 |
| | | * @param year |
| | | * @param week |
| | | * @param weekDay 需要输出星期几对应的日期 (1~7) |
| | | * @return {Date} |
| | | */ |
| | | static transWeekIndexToDate(year, week, weekDay) { |
| | | const yearStart = moment([year, 0, 1]); |
| | | const dayLong = 24 * 60 * 60 * 1000; |
| | | const firstWeekLong = (7 - yearStart.day()) * dayLong; |
| | | const weeksLong = (week - 1) * 7 * dayLong; |
| | | const weekDayLong = weekDay * dayLong; |
| | | const dayTimestamp = yearStart.valueOf() + firstWeekLong + weeksLong + weekDayLong; |
| | | return moment(dayTimestamp).format('YYYY-MM-DD'); |
| | | } |
| | | |
| | | /** |
| | | * 显示调试面板(仅支持H5) |
| | | * @param cssSelector |
| | | * @param callback |
| | | */ |
| | | static showDevConsole(cssSelector, callback) { |
| | | static $_showDevConsole(cssSelector, callback) { |
| | | // 只支持 h5 编译 |
| | | if (process.env.TARO_ENV !== 'h5') { |
| | | return; |
| | |
| | | const px = (value - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y; |
| | | console.info(Math.round(px) + 'px'); |
| | | }; |
| | | } |
| | | } |
| | | |
| | | global.Tools = Tools; |
| | |
| | | */ |
| | | |
| | | <template> |
| | | <view |
| | | class="c-loading" |
| | | @tap="evt => handleGoTo()" |
| | | > |
| | | <view class="c-loading"> |
| | | <AtActivityIndicator |
| | | :isOpened="show" |
| | | mode="center" |
New file |
| | |
| | | /** |
| | | * CNumerical - 数值显示 |
| | | * @author Tevin |
| | | */ |
| | | |
| | | <template> |
| | | <view class="c-numerical at-row at-row--wrap"> |
| | | <view |
| | | class="at-col" |
| | | v-for="(item,index) in values2" |
| | | :key="index" |
| | | :class="'at-col-' + valueFlex[index]" |
| | | > |
| | | <view class="c-numerical-value"> |
| | | <text>{{item.integer}}</text> |
| | | <text |
| | | class="c-numerical-decimal" |
| | | :class="item.integer.length>6?'small':''" |
| | | v-if="item.decimal.length>0" |
| | | >.{{item.decimal}}</text> |
| | | </view> |
| | | <view class="c-numerical-title">{{item.title}}</view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import Taro from '@tarojs/taro'; |
| | | import {} from 'taro-ui-vue'; |
| | | import './cNumerical.scss'; |
| | | |
| | | export default { |
| | | name: 'CNumerical', |
| | | components: {}, |
| | | props: { |
| | | values: Array, |
| | | }, |
| | | computed: { |
| | | values2() { |
| | | return ( |
| | | this.values.map(item => ({ |
| | | ...item, |
| | | integer: (item.value + '').split('.')[0] || '', |
| | | decimal: (item.value + '').split('.')[1] || '', |
| | | })) || [] |
| | | ); |
| | | }, |
| | | valueFlex() { |
| | | return this.values.map((item, index) => { |
| | | const surplus = this.values.length % 3; |
| | | if (surplus === 0) { |
| | | return 4; |
| | | } else if (surplus === 1) { |
| | | if (index === this.values.length - 1) { |
| | | return 12; |
| | | } else { |
| | | return 4; |
| | | } |
| | | } else if (surplus === 2) { |
| | | if (index >= this.values.length - 2) { |
| | | return 6; |
| | | } else { |
| | | return 4; |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | }, |
| | | data() { |
| | | return {}; |
| | | }, |
| | | methods: {}, |
| | | }; |
| | | </script> |
New file |
| | |
| | | /** |
| | | * CNumerical - 数值显示 |
| | | * @author Tevin |
| | | */ |
| | | |
| | | @import "../../common/sassMixin"; |
| | | |
| | | .c-numerical { |
| | | text-align: center; |
| | | .at-col { |
| | | padding: 10px 0; |
| | | } |
| | | .c-numerical-value { |
| | | font-size: 40px; |
| | | line-height: 60px; |
| | | .c-numerical-decimal { |
| | | &.small { |
| | | font-size: 30px; |
| | | } |
| | | } |
| | | } |
| | | .c-numerical-title { |
| | | font-size: 30px; |
| | | color: #666; |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * CNumerical |
| | | * @author Tevin |
| | | */ |
| | | |
| | | import CNumerical from '@components/layout/numerical/CNumerical.vue'; |
| | | |
| | | export { |
| | | CNumerical, |
| | | } |
New file |
| | |
| | | /** |
| | | * CECharts |
| | | * @author Tevin |
| | | */ |
| | | |
| | | <template> |
| | | <view class="c-echarts"> |
| | | <canvas |
| | | class="c-echarts-canvas" |
| | | type="2d" |
| | | :id="canvasId" |
| | | :canvasId="canvasId" |
| | | @touchstart="evt => disableTouch ? null : touchStart(evt)" |
| | | @touchmove="evt => disableTouch ? null : touchMove(evt)" |
| | | @touchend="evt => disableTouch ? null : touchEnd(evt)" |
| | | ></canvas> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import WxCanvas from './wxCanvas'; |
| | | import * as echarts from './echarts'; |
| | | import './cECharts.scss'; |
| | | |
| | | let canvasCount = 0; |
| | | const wrapTouch = event => { |
| | | for (let i = 0; i < event.touches.length; ++i) { |
| | | const touch = event.touches[i]; |
| | | touch.offsetX = touch.x; |
| | | touch.offsetY = touch.y; |
| | | } |
| | | return event; |
| | | }; |
| | | |
| | | export default { |
| | | name: 'CECharts', |
| | | components: {}, |
| | | props: { |
| | | canvasId: { |
| | | type: String, |
| | | default: () => |
| | | 'ec-canvas-' + ++canvasCount + '-' + parseInt(Math.random() * 10000), |
| | | }, |
| | | disableTouch: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | onReady: Function, |
| | | }, |
| | | data() { |
| | | return {}; |
| | | }, |
| | | methods: { |
| | | init(callback) { |
| | | // 基础库必须 2.9.0 以上,使用 <canvas type="2d"></canvas>,不支持旧版 |
| | | const query = wx.createSelectorQuery(); |
| | | query |
| | | .select('#' + this.canvasId) |
| | | .fields({ node: true, size: true }) |
| | | .exec(res => { |
| | | const canvasNode = res[0].node; |
| | | this.canvasNode = canvasNode; |
| | | const canvasDpr = wx.getSystemInfoSync().pixelRatio; |
| | | const canvasWidth = res[0].width; |
| | | const canvasHeight = res[0].height; |
| | | const ctx = canvasNode.getContext('2d'); |
| | | const canvas = new WxCanvas(ctx, this.canvasId, true, canvasNode); |
| | | echarts.setCanvasCreator(() => { |
| | | return canvas; |
| | | }); |
| | | if (typeof callback === 'function') { |
| | | callback(canvas, canvasWidth, canvasHeight, canvasDpr); |
| | | } else { |
| | | this.triggerEvent('init', { |
| | | canvas: canvas, |
| | | width: canvasWidth, |
| | | height: canvasHeight, |
| | | dpr: canvasDpr, |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | canvasToTempFilePath(opt) { |
| | | const query = wx.createSelectorQuery().in(this); |
| | | query |
| | | .select('#' + this.canvasId) |
| | | .fields({ node: true, size: true }) |
| | | .exec(res => { |
| | | const canvasNode = res[0].node; |
| | | opt.canvas = canvasNode; |
| | | wx.canvasToTempFilePath(opt); |
| | | }); |
| | | }, |
| | | touchStart(e) { |
| | | if (this.chart && e.touches.length > 0) { |
| | | const touch = e.touches[0]; |
| | | const handler = this.chart.getZr().handler; |
| | | handler.dispatch('mousedown', { |
| | | zrX: touch.x, |
| | | zrY: touch.y, |
| | | preventDefault: () => {}, |
| | | stopImmediatePropagation: () => {}, |
| | | stopPropagation: () => {}, |
| | | }); |
| | | handler.dispatch('mousemove', { |
| | | zrX: touch.x, |
| | | zrY: touch.y, |
| | | preventDefault: () => {}, |
| | | stopImmediatePropagation: () => {}, |
| | | stopPropagation: () => {}, |
| | | }); |
| | | handler.processGesture(wrapTouch(e), 'start'); |
| | | } |
| | | }, |
| | | touchMove(e) { |
| | | if (this.chart && e.touches.length > 0) { |
| | | const touch = e.touches[0]; |
| | | const handler = this.chart.getZr().handler; |
| | | handler.dispatch('mousemove', { |
| | | zrX: touch.x, |
| | | zrY: touch.y, |
| | | preventDefault: () => {}, |
| | | stopImmediatePropagation: () => {}, |
| | | stopPropagation: () => {}, |
| | | }); |
| | | handler.processGesture(wrapTouch(e), 'change'); |
| | | } |
| | | }, |
| | | touchEnd(e) { |
| | | if (this.chart) { |
| | | const touch = e.changedTouches ? e.changedTouches[0] : {}; |
| | | const handler = this.chart.getZr().handler; |
| | | handler.dispatch('mouseup', { |
| | | zrX: touch.x, |
| | | zrY: touch.y, |
| | | preventDefault: () => {}, |
| | | stopImmediatePropagation: () => {}, |
| | | stopPropagation: () => {}, |
| | | }); |
| | | handler.dispatch('click', { |
| | | zrX: touch.x, |
| | | zrY: touch.y, |
| | | preventDefault: () => {}, |
| | | stopImmediatePropagation: () => {}, |
| | | stopPropagation: () => {}, |
| | | }); |
| | | handler.processGesture(wrapTouch(e), 'end'); |
| | | } |
| | | }, |
| | | }, |
| | | mounted() { |
| | | // Disable prograssive because drawImage doesn't support DOM as parameter |
| | | // See https://developers.weixin.qq.com/miniprogram/dev/api/canvas/CanvasContext.drawImage.html |
| | | echarts.registerPreprocessor(option => { |
| | | if (option && option.series) { |
| | | if (option.series.length > 0) { |
| | | option.series.forEach(series => { |
| | | series.progressive = 0; |
| | | }); |
| | | } else if (typeof option.series === 'object') { |
| | | option.series.progressive = 0; |
| | | } |
| | | } |
| | | }); |
| | | setTimeout(() => { |
| | | this.init((canvas, width, height, dpr) => { |
| | | this.chart = echarts.init(canvas, null, { |
| | | width: width, |
| | | height: height, |
| | | devicePixelRatio: dpr, // 像素 |
| | | }); |
| | | canvas.setChart(this.chart); |
| | | this.onReady && this.onReady(this.chart); |
| | | this.chart.setOption({ |
| | | tooltip: { |
| | | backgroundColor: 'rgba(50,50,50,0.7)', |
| | | textStyle: { |
| | | color: '#ffffff', |
| | | }, |
| | | // 重新修正浮窗位置 |
| | | position: (pos, params, dom, rect, size) => { |
| | | const [pX, pY] = pos; |
| | | const [contX, contY] = size.contentSize; |
| | | const [viewX, viewY] = size.viewSize; |
| | | const contentPoint = {}; |
| | | // 鼠标在左侧时 tooltip 显示到右侧 |
| | | if (pX < viewX / 2) { |
| | | contentPoint.right = Math.max(viewX - pX - contX, 0); |
| | | } |
| | | // 鼠标在右侧时 tooltip 显示到左侧。 |
| | | else { |
| | | contentPoint.left = Math.max(pX - contX, 0); |
| | | } |
| | | // 限制不超过底部边界 |
| | | if (pY + contY <= viewY) { |
| | | contentPoint.top = pY; |
| | | } else { |
| | | contentPoint.top = viewY - contY; |
| | | } |
| | | return contentPoint; |
| | | }, |
| | | }, |
| | | }); |
| | | }); |
| | | }, 100); |
| | | }, |
| | | }; |
| | | </script> |
New file |
| | |
| | | /** |
| | | * CECharts |
| | | * @author Tevin |
| | | */ |
| | | |
| | | @import "../../common/sassMixin"; |
| | | |
| | | .c-echarts { |
| | | .c-echarts-canvas { |
| | | display: block; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * qrcode |
| | | * @author Tevin |
| | | */ |
| | | |
| | | import CECharts from '@components/plugins/echarts/CECharts'; |
| | | |
| | | export { |
| | | CECharts |
| | | } |
New file |
| | |
| | | export default class WxCanvas { |
| | | constructor(ctx, canvasId, isNew, canvasNode) { |
| | | this.ctx = ctx; |
| | | this.canvasId = canvasId; |
| | | this.chart = null; |
| | | this.isNew = isNew |
| | | if (isNew) { |
| | | this.canvasNode = canvasNode; |
| | | } |
| | | else { |
| | | this._initStyle(ctx); |
| | | } |
| | | |
| | | // this._initCanvas(zrender, ctx); |
| | | |
| | | this._initEvent(); |
| | | } |
| | | |
| | | getContext(contextType) { |
| | | if (contextType === '2d') { |
| | | return this.ctx; |
| | | } |
| | | } |
| | | |
| | | // canvasToTempFilePath(opt) { |
| | | // if (!opt.canvasId) { |
| | | // opt.canvasId = this.canvasId; |
| | | // } |
| | | // return wx.canvasToTempFilePath(opt, this); |
| | | // } |
| | | |
| | | setChart(chart) { |
| | | this.chart = chart; |
| | | } |
| | | |
| | | addEventListener() { |
| | | // noop |
| | | } |
| | | |
| | | attachEvent() { |
| | | // noop |
| | | } |
| | | |
| | | detachEvent() { |
| | | // noop |
| | | } |
| | | |
| | | _initCanvas(zrender, ctx) { |
| | | zrender.util.getContext = function () { |
| | | return ctx; |
| | | }; |
| | | |
| | | zrender.util.$override('measureText', function (text, font) { |
| | | ctx.font = font || '12px sans-serif'; |
| | | return ctx.measureText(text); |
| | | }); |
| | | } |
| | | |
| | | _initStyle(ctx) { |
| | | ctx.createRadialGradient = () => { |
| | | return ctx.createCircularGradient(arguments); |
| | | }; |
| | | } |
| | | |
| | | _initEvent() { |
| | | this.event = {}; |
| | | const eventNames = [{ |
| | | wxName: 'touchStart', |
| | | ecName: 'mousedown' |
| | | }, { |
| | | wxName: 'touchMove', |
| | | ecName: 'mousemove' |
| | | }, { |
| | | wxName: 'touchEnd', |
| | | ecName: 'mouseup' |
| | | }, { |
| | | wxName: 'touchEnd', |
| | | ecName: 'click' |
| | | }]; |
| | | eventNames.forEach(name => { |
| | | this.event[name.wxName] = e => { |
| | | const touch = e.touches[0]; |
| | | this.chart.getZr().handler.dispatch(name.ecName, { |
| | | zrX: name.wxName === 'tap' ? touch.clientX : touch.x, |
| | | zrY: name.wxName === 'tap' ? touch.clientY : touch.y, |
| | | preventDefault: () => {}, |
| | | stopImmediatePropagation: () => {}, |
| | | stopPropagation: () => {} |
| | | }); |
| | | }; |
| | | }); |
| | | } |
| | | |
| | | set width(w) { |
| | | if (this.canvasNode) this.canvasNode.width = w |
| | | } |
| | | set height(h) { |
| | | if (this.canvasNode) this.canvasNode.height = h |
| | | } |
| | | |
| | | get width() { |
| | | if (this.canvasNode) |
| | | return this.canvasNode.width |
| | | return 0 |
| | | } |
| | | get height() { |
| | | if (this.canvasNode) |
| | | return this.canvasNode.height |
| | | return 0 |
| | | } |
| | | } |