123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- /**
- * 说明:
- * el: 挂载的dom节点
- * chartData 图表数据集合
- * config 支持配置的文本,点击事件函数
- * type 判断图表类型,有以下几个参数
- * {
- * ve-histogram 柱状图
- * ve-finehistogram 柱状图+折线图
- * ve-treemap 树形图
- * ve-line 折线图
- * }
- */
- var chartTemplate =
- `
- <template>
- <ve-histogram
- v-if='type==="ve-histogram"'
- :id="type"
- :colors="histogramChart.options.colors"
- :width="histogramChart.options.width"
- :height="histogramChart.options.height"
- :data="chartData"
- :settings="histogramChart.options.settings"
- :after-config="histogramChart.options.config"
- :after-set-option="extend"
- :extend="histogramChart.defaultOptions"
- >
- </ve-histogram>
- <ve-histogram
- v-else-if='type==="ve-finehistogram"'
- :id="type"
- :height="barLineChart.options.height"
- :width="barLineChart.options.width ? barLineChart.options.width : null"
- :colors="barLineChart.options.colors"
- :data="chartData"
- :settings="barLineChart.options.settings"
- :after-config="barLineChart.options.config"
- :after-set-option="barExtend"
- :extend="barLineChart.defaultOptions"
- >
- </ve-histogram>
- <div v-else-if='type==="ve-treemap"' class="rect-tree-map-chart" style="height: 100%"></div>
- <ve-line
- v-else-if='type==="ve-line"'
- :data="chartData"
- :height="lineChart.options.height"
- :after-config="lineChart.options.config"
- :extend="lineChart.defaultOption"
- >
- </ve-line>
- </template>
- `
- window.proxy.vComponentChart = function (el, chartData, config, type) {
- new Vue({
- delimiters: ['${', '}'],
- el: el,
- template: chartTemplate,
- data () {
- return {
- myChart: null,
- type: type,
- chartData: {},
- // histogram 柱状图
- histogramChart: {},
- // barLineChart 柱状图+折线图
- barLineChart: {},
- // treeMapChart 树形图
- treeMapChart: {},
- // lineChart 折线图
- lineChart: {}
- }
- },
- created () {
- this.chartData = chartData
- this.getChartConfig()
- },
- mounted () {
- if(this.type === 've-treemap') {
- this.updateChartView()
- } else if (this.type === 've-line') {
- this.mergeExtendOptions()
- }
- },
- methods: {
- IsPC () {
- var userAgentInfo = navigator.userAgent
- var Agents = ["Android", "iPhone",
- "SymbianOS", "Windows Phone",
- "iPad", "iPod"]
- var flagPc = true
- for (var v = 0; v < Agents.length; v++) {
- if (userAgentInfo.indexOf(Agents[v]) > 0) {
- flagPc = false;
- break;
- }
- }
- return flagPc;
- },
- // 判断类型,取对应配置
- getChartConfig () {
- if (this.type === 've-histogram') {
- this.histogramChart = {
- options: {
- colors: ['#FF9F3F', '#05A5F2'],
- width: '100%',
- height: '100%',
- settings: {}
- },
- defaultOptions: {
- grid: {
- top: 20
- },
- xAxis: {
- axisLabel: {
- margin: 10,
- interval: 1, // 强制显示x轴所有刻度
- fontSize: 12
- },
- nameLocation: 'start',
- nameTextStyle: {
- fontSize: 12,
- align: 'left',
- padding: [70, 0, 0, 50],
- color: '#9B9CA3'
- }
- },
- yAxis (item) {
- Object.assign(item[0], {
- splitLine: {
- lineStyle: {
- type: 'dashed',
- width: 0.5
- }
- },
- axisLabel: {
- margin: 2,
- fontSize: 12,
- formatter: (value, index) => value.toString().replace(/,/, '') + '%'
- }
- })
-
- Object.assign(item[1], {
- splitLine: {
- show: false
- },
- axisLabel: {
- show: false,
- fontSize: 12,
- formatter: (value, index) => value.toString().replace(/,/, '')
- }
- })
- return item
- },
- tooltip: {
- trigger: 'axis',
- confine: true,
- backgroundColor: '#fff',
- axisPointer: {
- type: 'shadow',
- shadowStyle: {
- color: 'rgba(42, 190, 209,0.1)'
- },
- z: 3
- },
- textStyle: {
- color: '#171826',
- fontSize: 12
- },
- padding: [7, 12],
- extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08);transform: translate3d(0,0,0)',
- formatter: this.tooltipFormatter
- },
- legend: {
- orient: 'horizontal',
- icon: 'rect',
- bottom: 20,
- align: 'left',
- itemGap: 20,
- itemWidth: 9,
- itemHeight: 9,
- textStyle: {
- fontSize: 10,
- lineHeight: 14,
- verticalAlign: 'bottom',
- rich: {
- a: {
- fontSize: 16,
- verticalAlign: 'top',
- align: 'center',
- padding: [0, 15, 28, 0]
- },
- b: {
- fontSize: 14,
- align: 'center',
- padding: [0, 15, 0, 0],
- lineHeight: 25
- }
- }
- },
- formatter: name => name
- }
- }
- }
- } else if (this.type === 've-finehistogram') {
- this.barLineChart = {
- options: {
- height: '100%',
- width: '100%',
- colors: ['#05A6F3', '#FF3A20'],
- settings: {
- showLine: [chartData.columns[2]],
- axisSite: { right: [chartData.columns[2]] }
- },
- config: this.newTimeConfig
- },
- defaultOptions: {
- grid: {
- top: 20
- },
- xAxis: {
- axisLabel: {
- margin: 10,
- interval: 0, // 强制显示x轴所有刻度
- fontSize: 12
- },
- nameLocation: 'start',
- nameTextStyle: {
- fontSize: 12,
- align: 'left',
- padding: [70, 0, 0, 50],
- color: '#9B9CA3'
- }
- },
- yAxis (item) {
- item[0].splitLine = {
- lineStyle: {
- type: 'dashed',
- width: 0.5
- }
- }
- item[0].axisLabel = {
- margin: 2,
- fontSize: 12
- }
- item[1].splitLine = {
- show: false
- }
- item[1].axisLabel = {
- show: false,
- fontSize: 12
- }
- item[0].axisLabel.formatter = (value, index) => {
- return value.toString().replace(/,/, '')
- }
- item[1].axisLabel.formatter = (value, index) => {
- return value.toString().replace(/,/, '')
- }
- return item
- },
- tooltip: {
- trigger: 'axis',
- confine: true,
- backgroundColor: '#fff',
- axisPointer: {
- type: 'shadow',
- shadowStyle: {
- color: 'rgba(42, 190, 209,0.1)'
- },
- z: 3
- },
- textStyle: {
- color: '#171826',
- fontSize: 12
- },
- padding: [7, 12],
- extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08);transform: translate3d(0,0,0)'
- },
- legend: {
- orient: 'horizontal',
- icon: 'circle',
- bottom: 0,
- align: 'left',
- itemWidth: 8,
- itemHeight: 8,
- itemGap: 20,
- textStyle: {
- fontSize: 12,
- rich: {
- a: {
- fontSize: 16,
- verticalAlign: 'top',
- align: 'center',
- padding: [0, 15, 28, 0]
- },
- b: {
- fontSize: 14,
- align: 'center',
- padding: [0, 15, 0, 0],
- lineHeight: 25
- }
- }
- },
- formatter: (name) => {
- if (name === '企业数量') {
- name = name + '(个)'
- }
- return name
- }
- }
- }
- }
- } else if (this.type === 've-treemap') {
- this.treeMapChart = {
- options: {
- title: {
- subtext: '单位:个、万元',
- left: '0',
- top: '-8px',
- textStyle: {
- color: '#000',
- fontWeight: 'normal'
- }
- },
- tooltip: {
- formatter: this.treetooltipFormatter
- }
- },
- defaultOptions: {
- legend: {
- show: true,
- selectedMode: 'single',
- data: [],
- bottom: 0,
- itemGap: 5
- },
- tooltip: {
- backgroundColor: '#fff',
- confine: true,
- textStyle: {
- color: '#171826',
- fontSize: 12
- },
- padding: [7, 12],
- extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
- borderWidth: 2,
- borderColor: '#F5F6F7'
- },
- series: [
- {
- type: 'treemap',
- width: '100%',
- // height: '85%',
- // top: '15%',
- roam: false, // 是否开启拖拽漫游(移动和缩放)
- nodeClick: false, // 点击节点后的行为,false无反应
- breadcrumb: {
- show: false
- },
- label: { // 描述了每个矩形中,文本标签的样式。
- normal: {
- show: true,
- position: ['10%', '40%']
- }
- },
- itemStyle: {
- normal: {
- show: true,
- textStyle: {
- color: '#fff',
- fontSize: 16
- },
- borderWidth: 1,
- borderColor: '#fff'
- },
- emphasis: {
- label: {
- show: true
- }
- }
- },
- data: [
- // {
- // name: 'xxx',
- // value: 122
- // },
- // {
- // name: 'yyy',
- // value: 122
- // }
- ]
- }
- ]
- }
- }
- } else if (this.type === 've-line') {
- let _this = this
- this.lineChart = {
- options: {
- height: '100%',
- colors: ['#05A6F3', '#FF9F40'],
- config: this.configOptions
- },
- extend: {
- yAxis: {
- axisLabel: {
- formatter: p => p + '%'
- }
- }
- },
- defaultOption: {
- color: ['#05A6F3', '#FF9F40'],
- xAxis: {
- axisLabel: {
- formatter: function (params) {
- var arr = params.split('~')
- var isPc = _this.IsPC()
- if (arr.length === 2 && !isPc) {
- return arr.join('\n-')
- } else {
- return params
- }
- },
- textStyle: {
- color: '#626262',
- fontSize: 10
- },
- interval: 0
- }
- },
- grid: {
- top: 10,
- left: 12,
- right: 12
- },
- yAxis: {
- splitLine: {
- lineStyle: {
- type: 'dashed',
- width: 0.5
- }
- },
- nameGap: 15,
- nameTextStyle: {
- fontSize: 12,
- align: 'left',
- color: '#9B9CA3',
- padding: [0, 0, 0, -30]
- },
- axisLabel: {
- margin: 2,
- fontSize: 12,
- color: '#5F5E64',
- interval: 'auto',
- formatter: (value, index) => {
- return value.toString().replace(/,/, '')
- }
- }
- },
- legend: {
- orient: 'horizontal',
- icon: 'circle',
- bottom: 10,
- itemWidth: 8,
- itemHeight: 8,
- itemGap: 40,
- textStyle: {
- color: '#5F5E64',
- fontSize: 12
- }
- },
- series: {
- type: 'line',
- showSymbol: false,
- smooth: false,
- symbol: 'circle',
- symbolSize: 3,
- itemStyle: {
- borderColor: '#fff',
- borderWidth: 1
- }
- },
- tooltip: {
- backgroundColor: '#fff',
- confine: true,
- axisPointer: {
- type: 'line',
- lineStyle: {
- width: 2,
- color: '#2ABED1'
- },
- z: 3
- },
- textStyle: {
- color: '#171826',
- fontSize: 12
- },
- padding: [7, 12],
- extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
- borderWidth: 2,
- borderColor: '#F5F6F7'
- },
- lineStyle: {
- width: 0.5
- }
- }
- }
- }
- },
- // S--histogram--S
- extend (chart) {
- chart.setOption({
- series: [
- {
- type: 'bar',
- barMaxWidth: 20
- },
- {
- type: 'bar',
- barMaxWidth: 20
- }
- ]
- })
- },
- tooltipFormatter (params) {
- let tip = `<div style="padding-top:2px;color:#9B9CA3;">${params[0].name}</div>`
- for (let i = 0; i < params.length; i++) {
- if (params[i].value === undefined || params[i].value === '') {
- params[i].value = 0
- }
- if (i === 0) {
- tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '%<br/>'
- } else if (i === 1) {
- tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '%<br/>'
- }
- }
- return tip
- },
- // E--histogram--E
- // S--barLineChart--S
- barExtend (chart) {
- chart.setOption({
- series: [{
- type: 'bar',
- barMaxWidth: 20
- }, {
- type: 'line',
- smooth: false,
- symbol: 'none'
- }]
- })
- },
- newTimeConfig (options) {
- options.xAxis[0].axisLabel.rotate = 60
- options.xAxis[0].axisLabel.interval = 'auto'
-
- options.yAxis[1].axisLabel.show = true
-
- if (this.chartData.rows.length > 12) {
- // 设置时间轴
- Object.assign(options, {
- // grid解决dataZoom文字被隐藏的问题
- // https://github.com/apache/echarts/issues/11601
- grid: {
- left: '5%',
- right: '13%'
- },
- dataZoom: {
- show: true, // 显示滚动条
- realtime: true, // 拖动时,是否实时更新系列的视图
- type: 'slider',
- height: 20,
- bottom: 0,
- textStyle: {
- fontSize: 10
- }
- }
- })
- }
-
- options.legend.bottom = 30
- options.legend.data = [
- { icon: 'rect', name: this.chartData.columns[1] },
- { icon: 'line', name: this.chartData.columns[2] }
- ]
-
- options.tooltip.axisPointer.shadowStyle.color = 'rgba(5,166,243,0.1)'
- options.tooltip.formatter = params => {
- let tip = `<div style="padding-top:2px;color:#9B9CA3;">${params[0].name}</div>`
- for (let i = 0; i < params.length; i++) {
- if (params[i].value === undefined || params[i].value === '') {
- params[i].value = 0
- }
- if (params[i].seriesName.indexOf('环比') === -1) {
- const match = params[i].seriesName.match(/((.*))$/g)
- let unit = ''
- if (Array.isArray(match)) {
- unit = match.join('').replace(/[()]/g, '')
- }
- tip = tip + params[i].marker + params[i].seriesName.replace(`(${unit})`, '') + ':' + params[i].value + unit + '<br/>'
- } else {
- tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '%' + '<br/>'
- }
- }
- return tip
- }
- return options
- },
- // E--barLineChart--E
- // S--treeMapChart--S
- updateChartView () {
- this.myChart = echarts.init(this.$el, 'light')
- if (!this.myChart) return
- this.mergeOptions()
- this.myChart.setOption(this.treeMapChart.defaultOptions)
- window.addEventListener('resize', () => {
- // this.myChart.resize()
- })
- },
- mergeOptions () {
- // 设置数据
- this.treeMapChart.defaultOptions.series[0].data = this.chartData
- // 设置图例?
- this.treeMapChart.defaultOptions.legend.data = this.chartData.map(item => {
- return item.name
- })
-
- _.merge(this.treeMapChart.defaultOptions, this.treeMapChart.options)
- },
- treetooltipFormatter (params) {
- const item = params.data
- let tip = `<span style="display:inline-block;margin-right:5px;border-radius:8px;width:8px;height:8px;background-color:${params.color};"></span>${params.name}<br />`
- if (item && item.value) {
- tip += `<div>项目数量:${item.value}个<div>`
- }
- if (item && item.amount) {
- tip += `<div>项目金额:${item.amount}万元<div>`
- }
- return tip
- },
- // E--treeMapChart--E
- // S--lineChart--S
- configOptions (options) {
- // 面积颜色-渐变
- Object.assign(options.series[0], {
- areaStyle: {
- normal: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- {
- offset: 0,
- color: 'rgba(42, 190, 209, 0.12)'
- },
- {
- offset: 1,
- color: 'rgba(42, 190, 209, 0)'
- }
- ], false)
- }
- }
- })
- Object.assign(options.series[1], {
- areaStyle: {
- normal: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- {
- offset: 0,
- color: 'rgba(255, 159, 63, 0.12)'
- },
- {
- offset: 1,
- color: 'rgba(255, 159, 63, 0)'
- }
- ], false)
- }
- }
- })
-
- Object.assign(options.legend, {
- icon: 'rect'
- })
-
- options.tooltip.formatter = params => {
- let tip = `<div style="padding-top:2px;color:#9B9CA3;">${params[0].name}</div>`
- for (let i = 0; i < params.length; i++) {
- params[i].marker = '<span style="display:inline-block;margin-right:5px;border-radius:8px;width:8px;height:8px;background-color:' + params[i].color + ';"></span>'
- tip += params[i].marker + params[i].seriesName + ':' + params[i].value[1].toString().replace(/,/, '') + '%' + '<br/>'
- }
- return tip
- }
- return options
- },
- mergeExtendOptions () {
- _.merge(this.lineChart.defaultOption, this.lineChart.extend)
- }
- // E--lineChart--E
- }
- })
- }
|