| New file |
| | |
| | | <template> |
| | | <view class="echarts-container"> |
| | | <!-- #ifdef H5 || APP-PLUS --> |
| | | <view |
| | | :id="chartId" |
| | | class="echarts-chart" |
| | | :style="chartStyle" |
| | | ></view> |
| | | <!-- #endif --> |
| | | |
| | | <!-- #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO --> |
| | | <view class="mp-not-supported"> |
| | | <text class="mp-text">图表组件暂不支持小程序平台</text> |
| | | </view> |
| | | <!-- #endif --> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'EChartsLine', |
| | | props: { |
| | | chartData: { |
| | | type: Object, |
| | | default: () => ({ |
| | | categories: [], |
| | | series: [] |
| | | }) |
| | | }, |
| | | width: { |
| | | type: [Number, String], |
| | | default: 400 |
| | | }, |
| | | height: { |
| | | type: [Number, String], |
| | | default: 250 |
| | | }, |
| | | colors: { |
| | | type: Array, |
| | | default: () => ['#1890FF', '#F04864'] |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | chartId: '', |
| | | chartInstance: null |
| | | } |
| | | }, |
| | | computed: { |
| | | chartStyle() { |
| | | const w = typeof this.width === 'number' ? `${this.width}px` : this.width |
| | | const h = typeof this.height === 'number' ? `${this.height}px` : this.height |
| | | return { width: w, height: h } |
| | | } |
| | | }, |
| | | created() { |
| | | // Generate unique chart ID |
| | | this.chartId = 'echarts-line-' + Math.random().toString(36).substr(2, 9) |
| | | }, |
| | | mounted() { |
| | | // Delay initialization to ensure DOM is ready |
| | | setTimeout(() => { |
| | | this.initChart() |
| | | }, 100) |
| | | }, |
| | | watch: { |
| | | chartData: { |
| | | handler(newData) { |
| | | if (this.chartInstance) { |
| | | this.updateChart(newData) |
| | | } |
| | | }, |
| | | deep: true |
| | | } |
| | | }, |
| | | methods: { |
| | | initChart() { |
| | | // #ifdef H5 |
| | | this.initH5Chart() |
| | | // #endif |
| | | |
| | | // #ifdef APP-PLUS |
| | | this.initAppChart() |
| | | // #endif |
| | | |
| | | // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO |
| | | this.initMpChart() |
| | | // #endif |
| | | }, |
| | | |
| | | initH5Chart() { |
| | | // For H5 platform, use the existing echarts from qiun-data-charts |
| | | this.$nextTick(() => { |
| | | try { |
| | | const echarts = window.echarts |
| | | if (echarts) { |
| | | this.createChart(echarts) |
| | | } else { |
| | | // Fallback: load from qiun-data-charts |
| | | import('../../uni_modules/qiun-data-charts/static/h5/echarts.min.js').then(module => { |
| | | const echarts = window.echarts || module.default |
| | | this.createChart(echarts) |
| | | }).catch(err => { |
| | | console.error('Failed to load ECharts for H5:', err) |
| | | }) |
| | | } |
| | | } catch (error) { |
| | | console.error('Error initializing H5 chart:', error) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | initAppChart() { |
| | | // For App platform |
| | | this.$nextTick(() => { |
| | | try { |
| | | const echarts = window.echarts |
| | | if (echarts) { |
| | | this.createChart(echarts) |
| | | } else { |
| | | // Load from qiun-data-charts |
| | | import('../../uni_modules/qiun-data-charts/static/app-plus/echarts.min.js').then(module => { |
| | | const echarts = window.echarts || module.default |
| | | this.createChart(echarts) |
| | | }).catch(err => { |
| | | console.error('Failed to load ECharts for App:', err) |
| | | }) |
| | | } |
| | | } catch (error) { |
| | | console.error('Error initializing App chart:', error) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | initMpChart() { |
| | | // For mini-program platforms |
| | | this.$nextTick(() => { |
| | | try { |
| | | // Use the same approach as qiun-data-charts for mini-programs |
| | | const echarts = window.echarts |
| | | if (echarts) { |
| | | this.createChart(echarts) |
| | | } else { |
| | | console.warn('ECharts not available in mini-program environment') |
| | | } |
| | | } catch (error) { |
| | | console.error('Error initializing mini-program chart:', error) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | createChart(echarts) { |
| | | try { |
| | | const chartDom = document.getElementById(this.chartId) |
| | | if (!chartDom) { |
| | | console.error('Chart DOM element not found with ID:', this.chartId) |
| | | return |
| | | } |
| | | |
| | | this.chartInstance = echarts.init(chartDom, null, { |
| | | devicePixelRatio: window.devicePixelRatio |
| | | }) |
| | | this.updateChart(this.chartData) |
| | | |
| | | // Handle window resize for H5 |
| | | // #ifdef H5 |
| | | window.addEventListener('resize', this.handleResize) |
| | | // #endif |
| | | } catch (error) { |
| | | console.error('Error creating chart:', error) |
| | | } |
| | | }, |
| | | |
| | | updateChart(data) { |
| | | if (!this.chartInstance || !data || !data.categories || !data.series) { |
| | | return |
| | | } |
| | | |
| | | const option = { |
| | | color: this.colors, |
| | | grid: { |
| | | top: '25%', |
| | | left: '5%', |
| | | right: '5%', |
| | | bottom: '10%', |
| | | containLabel: true |
| | | }, |
| | | legend: { |
| | | show: true, |
| | | top: '5%', |
| | | itemGap: 20, |
| | | textStyle: { |
| | | color: '#666666', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: data.categories, |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#CCCCCC' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | color: '#666666', |
| | | fontSize: 12 |
| | | }, |
| | | axisTick: { |
| | | show: false |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#CCCCCC' |
| | | } |
| | | }, |
| | | axisLabel: { |
| | | color: '#666666', |
| | | fontSize: 12 |
| | | }, |
| | | splitLine: { |
| | | lineStyle: { |
| | | type: 'dashed', |
| | | color: '#333333' |
| | | } |
| | | }, |
| | | axisTick: { |
| | | show: false |
| | | } |
| | | }, |
| | | series: data.series.map((serie, index) => ({ |
| | | name: serie.name, |
| | | type: 'line', |
| | | data: serie.data, |
| | | smooth: false, |
| | | lineStyle: { |
| | | width: 3, |
| | | color: this.colors[index % this.colors.length] |
| | | }, |
| | | itemStyle: { |
| | | color: this.colors[index % this.colors.length] |
| | | }, |
| | | symbol: 'circle', |
| | | symbolSize: 8, |
| | | emphasis: { |
| | | itemStyle: { |
| | | borderWidth: 2, |
| | | borderColor: '#fff', |
| | | scale: 1.5 |
| | | } |
| | | } |
| | | })), |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | backgroundColor: 'rgba(0, 0, 0, 0.8)', |
| | | borderColor: '#333', |
| | | borderWidth: 1, |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | }, |
| | | formatter: function(params) { |
| | | let result = params[0].axisValue + '<br/>' |
| | | params.forEach(param => { |
| | | result += `${param.seriesName}: ${param.value}<br/>` |
| | | }) |
| | | return result |
| | | } |
| | | } |
| | | } |
| | | |
| | | this.chartInstance.setOption(option, true) |
| | | }, |
| | | |
| | | handleResize() { |
| | | if (this.chartInstance) { |
| | | this.chartInstance.resize() |
| | | } |
| | | }, |
| | | |
| | | // Method to manually resize chart |
| | | resize() { |
| | | if (this.chartInstance) { |
| | | this.chartInstance.resize() |
| | | } |
| | | } |
| | | }, |
| | | |
| | | beforeDestroy() { |
| | | if (this.chartInstance) { |
| | | this.chartInstance.dispose() |
| | | this.chartInstance = null |
| | | } |
| | | |
| | | // #ifdef H5 |
| | | window.removeEventListener('resize', this.handleResize) |
| | | // #endif |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .echarts-container { |
| | | width: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .echarts-chart { |
| | | display: block; |
| | | } |
| | | |
| | | .mp-not-supported { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: rgba(0, 0, 0, 0.1); |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .mp-text { |
| | | color: #999; |
| | | font-size: 14px; |
| | | text-align: center; |
| | | } |
| | | </style> |
| | |
| | | <view class="panel-content"> |
| | | <view class="panel-header"> |
| | | <text class="panel-title">入出库统计</text> |
| | | <text class="panel-sub-title">ORDER STATISTICS</text> |
| | | <text class="panel-sub-title">STATISTICS</text> |
| | | </view> |
| | | <view class="chart-container"> |
| | | <qiun-data-charts |
| | | <EChartsLine |
| | | v-if="isLineChartReady" |
| | | type="line" |
| | | :opts="lineChartOpts" |
| | | :chartData="lineChartData" |
| | | :ontouch="true" |
| | | :colors="['#1890FF', '#F04864']" |
| | | width="100%" |
| | | height="100%" |
| | | /> |
| | | <view v-else class="chart-loading" style="display: flex; align-items: center; justify-content: center; height: 100%; color: #999;"> |
| | | <text>加载中...</text> |
| | |
| | | <view class="st-head-item">任务: {{station.taskNo}}</view> |
| | | <view class="st-head-item">类型: {{station.ioTypeName}}</view> |
| | | <view class="st-head-item" v-if="station.barcode">托盘: {{station.barcode}}</view> |
| | | <view class="st-head-item">物料数: {{station.wrkDetls.length}}</view> |
| | | <!-- <view class="st-head-item">物料数: {{station.wrkDetls.length}}</view> --> |
| | | </view> |
| | | |
| | | <!-- Station Body (Material List) --> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import EChartsLine from '@/components/EChartsLine/EChartsLine.vue' |
| | | import { serverUrl, versionText as localVersionText, versionType as localVersionType } from '../../config' |
| | | /* API Constants */ |
| | | const IO_TYPE_NAME_MAP = { |
| | |
| | | } |
| | | |
| | | export default { |
| | | components: { |
| | | EChartsLine |
| | | }, |
| | | data() { |
| | | return { |
| | | serverUrl, |
| | |
| | | { name: '入库', data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }, |
| | | { name: '出库', data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] } |
| | | ] |
| | | }, |
| | | lineChartOpts: { |
| | | color: ['#1890FF', '#F04864'], |
| | | padding: [15,10,0,15], |
| | | legend: { show: true, position: 'top', float: 'center' }, |
| | | xAxis: { disableGrid: true, fontColor: '#666666' }, |
| | | yAxis: { gridType: 'dash', gridColor: '#333333', fontColor: '#666666', splitNumber: 5 }, |
| | | extra: { |
| | | line: { |
| | | type: 'straight', |
| | | width: 2 |
| | | } |
| | | } |
| | | }, |
| | | ringChartData: { |
| | | series: [{ |