Commit 9e69639a authored by Jenny's avatar Jenny

feat: 横向柱状图点击弹框

parent 9a44378f
<template> <template>
<uni-ec-canvas class="uni-ec-canvas" id="horizontal-bar" ref="horizontalBarCanvas" canvas-id="horizontal-bar-chart" <uni-ec-canvas
:ec="ec"></uni-ec-canvas> class="uni-ec-canvas"
id="horizontal-bar"
ref="horizontalBarCanvas"
canvas-id="horizontal-bar-chart"
:ec="ec"
></uni-ec-canvas>
</template> </template>
<script> <script>
import uniEcCanvas from '@/uni-ec-canvas/uni-ec-canvas' import uniEcCanvas from '@/uni-ec-canvas/uni-ec-canvas'
import echartElementData from '@/mixins/echartElementData.js' import echartElementData from '@/mixins/echartElementData.js'
import { import { DATAZOOM_DEFAULT } from '@/mixins/zoomConfig.js'
DATAZOOM_DEFAULT let chart = null
} from '@/mixins/zoomConfig.js' let lastCount = 0 // 记录datazoom最后一次滑动的数值数量
let chart = null
let lastCount = 0 // 记录datazoom最后一次滑动的数值数量
export default { export default {
name: "HorizontalBar", name: 'HorizontalBar',
mixins: [echartElementData], mixins: [echartElementData],
data() { data() {
return { return {
ec: { ec: {
lazyLoad: true, lazyLoad: true,
option: {} option: {}
}, },
labelShow: false, // 记录当前设置的label.show的值 labelShow: false, // 记录当前设置的label.show的值
index: 0, // 记录dataZoom切换当前的下标 index: 0 // 记录dataZoom切换当前的下标
} }
}, },
components: { components: {
uniEcCanvas uniEcCanvas
}, },
created() { created() {
this.labelShow = this.elementInfo.option.dataset.show this.labelShow = this.elementInfo.option.dataset.show
}, },
mounted() { mounted() {
this.$refs['horizontalBarCanvas'].init(this.inited) this.$refs['horizontalBarCanvas'].init(this.inited)
}, },
methods: { methods: {
inited(canvas, width, height, canvasDpr) { inited(canvas, width, height, canvasDpr) {
chart = this.$echarts.init(canvas, null, { chart = this.$echarts.init(canvas, null, {
width: width, width: width,
height: height, height: height,
devicePixelRatio: canvasDpr devicePixelRatio: canvasDpr
}) })
canvas.setChart(chart) canvas.setChart(chart)
const { const {
dataList: { dataList: { categories, series }
categories, } = this.elementData
series, const that = this
} that.ec.option = {
} = this.elementData ...that.elementInfo.option,
const that = this yAxis: {
that.ec.option = { ...that.elementInfo.option.yAxis,
...that.elementInfo.option, data: categories
yAxis: { },
...that.elementInfo.option.yAxis, tooltip: that.dealTooltip(that.elementInfo.option.tooltip),
data: categories dataZoom:
}, that.elementInfo.dataZoom && that.elementInfo.dataZoom.show
tooltip: that.dealTooltip(that.elementInfo.option.tooltip), ? [
dataZoom: that.elementInfo.dataZoom && that.elementInfo.dataZoom.show ? [{ {
...that.elementInfo.dataZoom, ...that.elementInfo.dataZoom,
...DATAZOOM_DEFAULT ...DATAZOOM_DEFAULT
}] : [{ }
show: false ]
}], : [
series: that.dealSeriesData(series) {
} show: false
chart.setOption(that.ec.option) }
chart.on('click', event => { ],
const { series: that.dealSeriesData(series)
preview, }
images chart.setOption(that.ec.option)
} = that.elementData.dataList chart.on('click', event => {
var urls = [] const { preview, images, popup, data } = that.elementData.dataList
var caches = uni.getStorageSync('cacheImages') var urls = []
images.forEach(url => { var caches = uni.getStorageSync('cacheImages')
if (caches.hasOwnProperty(url)) { images &&
urls.push(caches[url]) images.forEach(url => {
} else { if (caches.hasOwnProperty(url)) {
urls.push(url) urls.push(caches[url])
} } else {
}) urls.push(url)
// 特殊处理,如果preview为true,代表点击显示图片 }
if (preview) { })
uni.previewImage({ // 特殊处理,如果preview为true,代表点击显示图片
current: event.dataIndex, if (preview) {
urls: urls uni.previewImage({
}) current: event.dataIndex,
} else { urls: urls
that.handleEchartsClick(event) })
} } else if (popup) {
}) uni.$emit('showBarDetail', {
chart.on('datazoom', event => { popupShow: true,
// 传递参数给其他组件 popupData: data[event.dataIndex]
that.echartsDataZoom(event) })
// 处理dataZoom的拖动事件 } else {
that.handleDataZoomEvent(event) that.handleEchartsClick(event)
}) }
return chart })
}, chart.on('datazoom', event => {
initChart() { // 传递参数给其他组件
// 等待子组件完全挂载完成---chart初始化完成 that.echartsDataZoom(event)
this.$nextTick().then(() => { // 处理dataZoom的拖动事件
const { that.handleDataZoomEvent(event)
categories, })
series, return chart
preview, },
images initChart() {
} = this.elementData.dataList // 等待子组件完全挂载完成---chart初始化完成
if (this.labelShow) { this.$nextTick().then(() => {
// 处理初始状态时,数值显示的数量是否超过了配置的最大值 const { categories, series, preview, images } =
let count = categories.length this.elementData.dataList
if (this.elementInfo.dataZoom && this.elementInfo.dataZoom.show) { if (this.labelShow) {
count = count * (this.elementInfo.dataZoom.end - this.elementInfo.dataZoom.start) / 100 // 处理初始状态时,数值显示的数量是否超过了配置的最大值
} let count = categories.length
if (this.elementInfo.option.dataset.maxCount != null && count > this.elementInfo.option.dataset.maxCount) { if (this.elementInfo.dataZoom && this.elementInfo.dataZoom.show) {
this.elementInfo.option.dataset.show = false count =
} (count *
lastCount = count (this.elementInfo.dataZoom.end -
} this.elementInfo.dataZoom.start)) /
100
}
if (
this.elementInfo.option.dataset.maxCount != null &&
count > this.elementInfo.option.dataset.maxCount
) {
this.elementInfo.option.dataset.show = false
}
lastCount = count
}
const dealSeries = this.dealSeriesData(series) const dealSeries = this.dealSeriesData(series)
this.$set(this.ec.option, 'yAxis.data', categories) this.$set(this.ec.option, 'yAxis.data', categories)
this.$set(this.ec.option, 'series', dealSeries) this.$set(this.ec.option, 'series', dealSeries)
this.$set(this.ec.option, 'dataZoom', this.elementInfo.dataZoom && this.elementInfo.dataZoom this.$set(
.show ? [{ this.ec.option,
...this.elementInfo.dataZoom, 'dataZoom',
...DATAZOOM_DEFAULT this.elementInfo.dataZoom && this.elementInfo.dataZoom.show
}] : [{ ? [
show: false {
}]) ...this.elementInfo.dataZoom,
if (chart) { ...DATAZOOM_DEFAULT
const option = chart.getOption() }
option.series = dealSeries ]
// 重新setOption,使得设置的formatter生效 : [
chart.setOption(option) {
if (Number(dealSeries[0].barWidth)) { show: false
const height = categories.length * (Number(dealSeries[0].barWidth) + 5) + 25 }
uni.$emit('handleUpdateHeight', height) ]
chart.resize({ )
width: chart.getWidth(), if (chart) {
height const option = chart.getOption()
}) option.series = dealSeries
} // 重新setOption,使得设置的formatter生效
} chart.setOption(option)
if (preview) { if (Number(dealSeries[0].barWidth)) {
this.cacheImages(images) const height =
} categories.length * (Number(dealSeries[0].barWidth) + 5) + 25
}) uni.$emit('handleUpdateHeight', height)
}, chart.resize({
/** width: chart.getWidth(),
* height
* @param tooltip 表单的tooltip设置 })
*/ }
dealTooltip(tooltip) { }
if (!tooltip) { if (preview) {
return this.cacheImages(images)
} }
if (tooltip.formatter && tooltip.formatter.length) { })
return { },
...tooltip, /**
formatter: (val) => { *
return this.$u.common.converFunction(tooltip.formatter, val) * @param tooltip 表单的tooltip设置
}, */
trigger: "axis" dealTooltip(tooltip) {
} if (!tooltip) {
} return
return { }
...tooltip, if (tooltip.formatter && tooltip.formatter.length) {
trigger: "axis" return {
} ...tooltip,
}, formatter: val => {
/** return this.$u.common.converFunction(tooltip.formatter, val)
* 处理数据 },
*/ trigger: 'axis'
dealSeriesData(data) { }
if (!data) return }
const that = this return {
const newData = data.map(item => { ...tooltip,
const config = { trigger: 'axis'
type: 'bar', }
...that.elementInfo.option.bar, },
label: { /**
...that.elementInfo.option.dataset, * 处理数据
formatter: val => { */
return that.$u.common.converFunction(that.elementInfo.option.dataset dealSeriesData(data) {
.formatter, val) if (!data) return
} const that = this
} const newData = data.map(item => {
} const config = {
return { type: 'bar',
...item, ...that.elementInfo.option.bar,
...config label: {
} ...that.elementInfo.option.dataset,
}) formatter: val => {
return newData return that.$u.common.converFunction(
}, that.elementInfo.option.dataset.formatter,
/** val
* 缓存图片数据 )
*/ }
cacheImages(images) { }
var caches = uni.getStorageSync('cacheImages') }
if (!caches) { return {
caches = {} ...item,
} ...config
images.forEach(url => { }
// 如果包含当前url,就不再下载 })
if (!caches.hasOwnProperty(url)) { return newData
uni.downloadFile({ },
url: url, /**
success: (res) => { * 缓存图片数据
if (res.statusCode === 200) { */
caches[url] = res.tempFilePath cacheImages(images) {
uni.setStorageSync('cacheImages', caches) var caches = uni.getStorageSync('cacheImages')
} if (!caches) {
} caches = {}
}) }
} images.forEach(url => {
}) // 如果包含当前url,就不再下载
}, if (!caches.hasOwnProperty(url)) {
/** uni.downloadFile({
* 响应dataZoom的滑动事件 url: url,
* event: 包含dataZoom的start和end success: res => {
*/ if (res.statusCode === 200) {
handleDataZoomEvent(event) { caches[url] = res.tempFilePath
var count = this.elementData.dataList.categories.length * (event.end - event.start) / 100 uni.setStorageSync('cacheImages', caches)
// 给小程序里面赋值datas,如果存在且不为空,代表可以左右滑动切换 }
if (this.elementData.dataList.datas && this.elementData.dataList.datas.length) { }
count = this.elementData.dataList.datas[this.index].categories.length * (event.end - event.start) / 100 })
this.switchData(event, count) }
} })
// 当前图表初始设置了labelShow=true时,才判断超过最大个数隐藏 },
if (this.labelShow) { /**
this.dealLabelShowStatus(event, count) * 响应dataZoom的滑动事件
} * event: 包含dataZoom的start和end
lastCount = count */
}, handleDataZoomEvent(event) {
/** var count =
* 处理图表的数值是否显示 (this.elementData.dataList.categories.length *
* 超过maxCount个时隐藏点的数值 (event.end - event.start)) /
* event: 包含dataZoom的start和end 100
* count: 当前图表显示的数量 // 给小程序里面赋值datas,如果存在且不为空,代表可以左右滑动切换
*/ if (
dealLabelShowStatus(event, count) { this.elementData.dataList.datas &&
var flag = false this.elementData.dataList.datas.length
const maxCount = this.elementInfo.option.dataset.maxCount ) {
if (lastCount < count && lastCount <= maxCount && count > maxCount) { count =
// 放大的情况 (this.elementData.dataList.datas[this.index].categories.length *
flag = true (event.end - event.start)) /
} 100
if (lastCount > count && lastCount >= maxCount && count < maxCount) { this.switchData(event, count)
// 缩小的情况 }
flag = true // 当前图表初始设置了labelShow=true时,才判断超过最大个数隐藏
} if (this.labelShow) {
if (flag) { this.dealLabelShowStatus(event, count)
const series = this.ec.option.series }
series.map(item => { lastCount = count
item.label.show = count <= this.elementInfo.option.dataset.maxCount },
}) /**
this.$set(this.ec.option, 'series', series) * 处理图表的数值是否显示
this.$set(this.ec.option, 'dataZoom.start', event.start) * 超过maxCount个时隐藏点的数值
this.$set(this.ec.option, 'dataZoom.end', event.end) * event: 包含dataZoom的start和end
} * count: 当前图表显示的数量
}, */
/** dealLabelShowStatus(event, count) {
* 处理数据的切换 var flag = false
* 滑块滚动到最左边或者最右边去切换上一个或者下一个数据 const maxCount = this.elementInfo.option.dataset.maxCount
* event: 包含dataZoom的start和end if (lastCount < count && lastCount <= maxCount && count > maxCount) {
* count: 当前图表显示的数量 // 放大的情况
*/ flag = true
switchData(event, count) { }
const categories = this.elementData.dataList.datas[this.index].categories if (lastCount > count && lastCount >= maxCount && count < maxCount) {
// 容错在一个百分点内,认为是滑块滚动 // 缩小的情况
const flag = Math.abs(lastCount - count) <= categories.length / 100 ? true : false flag = true
if (flag && event.end === 100 && this.index != this.elementData.dataList.datas.length - 1) { }
this.index += 1 if (flag) {
this.setChartDatas(event) const series = this.ec.option.series
} series.map(item => {
if (flag && event.start === 0 && this.index != 0) { item.label.show = count <= this.elementInfo.option.dataset.maxCount
this.index -= 1 })
this.setChartDatas(event) this.$set(this.ec.option, 'series', series)
} this.$set(this.ec.option, 'dataZoom.start', event.start)
}, this.$set(this.ec.option, 'dataZoom.end', event.end)
setChartDatas(event) { }
const categories = this.elementData.dataList.datas[this.index].categories },
const series = this.elementData.dataList.datas[this.index].series /**
const dealSeries = this.dealSeriesData(series) * 处理数据的切换
this.$set(this.ec.option, 'yAxis.data', categories) * 滑块滚动到最左边或者最右边去切换上一个或者下一个数据
this.$set(this.ec.option, 'series', dealSeries) * event: 包含dataZoom的start和end
this.$set(this.ec.option, 'dataZoom.start', event.start) * count: 当前图表显示的数量
this.$set(this.ec.option, 'dataZoom.end', event.end) */
} switchData(event, count) {
} const categories = this.elementData.dataList.datas[this.index].categories
} // 容错在一个百分点内,认为是滑块滚动
const flag =
Math.abs(lastCount - count) <= categories.length / 100 ? true : false
if (
flag &&
event.end === 100 &&
this.index != this.elementData.dataList.datas.length - 1
) {
this.index += 1
this.setChartDatas(event)
}
if (flag && event.start === 0 && this.index != 0) {
this.index -= 1
this.setChartDatas(event)
}
},
setChartDatas(event) {
const categories = this.elementData.dataList.datas[this.index].categories
const series = this.elementData.dataList.datas[this.index].series
const dealSeries = this.dealSeriesData(series)
this.$set(this.ec.option, 'yAxis.data', categories)
this.$set(this.ec.option, 'series', dealSeries)
this.$set(this.ec.option, 'dataZoom.start', event.start)
this.$set(this.ec.option, 'dataZoom.end', event.end)
}
}
}
</script> </script>
<style scoped>
</style>
<template>
<u-modal
class="model-data"
v-model="popupShow"
:closeOnClickOverlay="true"
title="明细"
@close="close"
@confirm="close"
>
<view class="slot-content">
<view v-for="(val, key) in popupData" class="data-view">
<view class="data-key ellipsis">{{ key }}</view>
<view class="data-val ellipsis">{{ val }}</view>
</view>
</view>
</u-modal>
</template>
<script>
export default {
name: 'ModelData',
data() {
return {}
},
props: {
popupData: {
type: Object,
default: () => {}
},
popupShow: {
type: Boolean,
default: false
}
},
methods: {
close() {
console.log(1)
uni.$emit('showBarDetail', {
popupShow: false,
popupData: {}
})
}
}
}
</script>
<style scoped>
.model-data {
position: relative;
z-index: 9999999;
}
.slot-content {
margin: 10px;
font-size: 12px;
border: 1px solid #eee;
border-radius: 5px;
}
.data-view {
display: flex;
align-self: center;
border-bottom: 1px solid #eee;
padding: 5px;
}
.data-key {
min-width: 28%;
margin-right: 10px;
border-right: 1px solid #eee;
}
</style>
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
height: `${element.type == 'HorizontalBar' && horizontalBarHeight ? horizontalBarHeight : parseInt(element.height * scale)}px`, height: `${element.type == 'HorizontalBar' && horizontalBarHeight ? horizontalBarHeight : parseInt(element.height * scale)}px`,
left: `${parseInt(element.left * scale)}px`, left: `${parseInt(element.left * scale)}px`,
top: `${parseInt(element.top * scale)}px`, top: `${parseInt(element.top * scale)}px`,
zIndex: `${element.type == 'NormalTabs' || element.type == 'DateTimePicker' ? 999999 : index + 1}` zIndex: `${element.type == 'NormalTabs' || element.type == 'DateTimePicker' ? 9999 : index + 1}`
}" }"
> >
<!-- 普通柱状图 --> <!-- 普通柱状图 -->
...@@ -59,6 +59,12 @@ ...@@ -59,6 +59,12 @@
<!-- <Table v-if="element.type == 'NormalTable'" :elementInfo="element"></Table> --> <!-- <Table v-if="element.type == 'NormalTable'" :elementInfo="element"></Table> -->
</view> </view>
</template> </template>
<ModelData
style="position: relative;z-index: 99999;"
:popupShow="popupShow"
:popupData="popupData"
></ModelData>
</view> </view>
</template> </template>
...@@ -70,7 +76,9 @@ ...@@ -70,7 +76,9 @@
timename: null, timename: null,
pageScrollTop: 0, pageScrollTop: 0,
stickyTables: [], // 设置了吸顶的table stickyTables: [], // 设置了吸顶的table
horizontalBarHeight: 0 horizontalBarHeight: 0,
popupShow: false,
popupData: {}
} }
}, },
computed: { computed: {
...@@ -145,6 +153,11 @@ ...@@ -145,6 +153,11 @@
uni.$on('handleUpdateHeight', (height) => { uni.$on('handleUpdateHeight', (height) => {
that.horizontalBarHeight = height that.horizontalBarHeight = height
}) })
uni.$on('showBarDetail', data => {
const { popupShow, popupData } = data
that.popupShow = popupShow
that.popupData = popupData
})
}, },
onHide() { onHide() {
// 移除监听事件 // 移除监听事件
......
...@@ -26,4 +26,10 @@ ...@@ -26,4 +26,10 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
display:block; display:block;
}
.ellipsis {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment