fix:添加echart桑基图

main
liu.shiyi 9 months ago
parent 12ef633d26
commit 1a0d067d41

@ -349,7 +349,6 @@ import { predefineColors } from 'data-room-ui/js/utils/colorList'
export default {
name: 'BarSetting',
components: {
ColorSelect,
ColorPicker,
PosWhSetting,
SettingTitle,

@ -0,0 +1,268 @@
<!--
@name:
@description:
@author: byx
@time: 桑基图
-->
<template>
<div
:id="config.code + 'wrap'"
class="bs-design-wrap bs-bar"
style="width: 100%; height: 100%"
>
<div
:id="`chart${config.code}`"
style="width: 100%; height: 100%"
/>
</div>
</template>
<script>
import 'insert-css'
import * as echarts from 'echarts'
import commonMixins from 'data-room-ui/js/mixins/commonMixins.js'
import paramsMixins from 'data-room-ui/js/mixins/paramsMixins'
import linkageMixins from 'data-room-ui/js/mixins/linkageMixins'
export default {
name: 'Sankey',
mixins: [paramsMixins, commonMixins, linkageMixins],
props: {
id: {
type: String,
default: ''
},
config: {
type: Object,
default: () => ({})
}
},
data () {
return {
currentDeep: 0,
mapList: [],
charts: null,
hasData: false,
level: '',
option: {},
links: [],
yData: []
}
},
computed: {
},
watch: {
},
mounted () {
this.chartInit()
//
this.chartResize()
},
beforeDestroy () {
this.charts?.clear()
},
methods: {
chartResize () {
window.addEventListener('resize', () => {
if (this.charts) {
this.charts.resize()
}
})
const dom = document.getElementById(`${this.config.code}wrap`)
if (dom) {
this.resizeObserver = new ResizeObserver(() => {
if (this.charts) {
this.charts.resize()
}
})
this.resizeObserver.observe(dom)
}
},
chartInit () {
const config = this.config
// keycodelist
if (this.config.code === this.config.key || this.isPreview) {
//
this.changeDataByCode(config).then((res) => {
//
// config = this.changeStyle(res)
this.newChart(config)
}).catch(() => {
})
} else {
// changeStylekey,chart
this.changeData(config).then((res) => {
//
this.newChart(config)
})
}
},
/**
* 数据格式化
* 该方法继承自commonMixins
* @param {*} config
* @param {Array} data
*/
dataFormatting (config, _data) {
const data = _data?.data
if (data && data.length) {
const list = data.map(item => [item[config.dataSource.dimensionField], item[config.dataSource.metricField]])?.flat() || []
//
this.yData = [...new Set(list)]?.map(item => ({ name: item }))
this.links = data.map(item => ({
source: item[config.dataSource.dimensionField],
target: item[config.dataSource.metricField],
value: item[config.dataSource.seriesField]
}))
} else {
this.links = [
{
source: 'a',
target: 'a1',
value: 5
},
{
source: 'a',
target: 'a2',
value: 3
},
{
source: 'b',
target: 'b1',
value: 8
},
{
source: 'a',
target: 'b1',
value: 3
},
{
source: 'b1',
target: 'a1',
value: 1
},
{
source: 'b1',
target: 'c',
value: 2
}
]
this.yData = [
{ name: 'a' },
{ name: 'b' },
{ name: 'a1' },
{ name: 'a2' },
{ name: 'b1' },
{ name: 'c' }
]
}
return config
},
//
updateChartData (config) {
this.handleOption(config)
this.charts.setOption(this.option)
},
changeStyle (config) {
this.handleOption(config)
this.charts.setOption(this.option)
},
/**
* 初始化地图
* 该方法继承自commonMixins
* @param {*} config
*/
async newChart (config) {
if (this.charts) {
this.charts.dispose()
}
this.charts = echarts.init(
document.getElementById(`chart${this.config.code}`)
)
// optionechartsoption
this.handleOption(config)
this.charts.setOption(this.option)
},
/**
* 处理配置项option
* @param {*} config
*/
handleOption (config) {
this.option = {
tooltip: {
//
show: true,
trigger: 'item',
axisPointer: {
type: 'line'
}
},
series: [
{
type: 'sankey',
label: {
show: true,
position: config.customize.normal.labelPosition || 'right',
color: config.customize.normal.labelColor || '#fff',
fontSize: config.customize.normal.labelSize || 12,
fontWeight: config.customize.normal.labelFontWeight || 'bold'
},
itemStyle: {
borderColor: config.customize.normal.itemBorderColor || '#aaa',
borderWidth: config.customize.normal.itemBorderWidth || 1,
borderType: config.customize.normal.itemBorderType || 'solid'
},
lineStyle: {
color: config.customize.normal.lineColor || 'gradient',
curveness: config.customize.normal.lineCurveness || 0.5//
},
emphasis: { //
disabled: false,
focus: 'trajectory',
label: {
color: config.customize.emphasis.labelColor || '#fff',
fontSize: config.customize.emphasis.labelSize || 12,
fontWeight: config.customize.normal.labelFontWeight || 'bold',
},
itemStyle: {
borderColor: config.customize.emphasis.itemBorderColor || '#aaa',
borderWidth: config.customize.emphasis.itemBorderWidth || 1,
borderType: config.customize.emphasis.itemBorderType || 'solid'
},
lineStyle: {
color: config.customize.emphasis.lineColor || 'gradient'
}
},
data: this.yData,
links: this.links
}
]
}
}
}
}
</script>
<style lang="scss" scoped>
@import '../../assets/style/echartStyle';
.light-theme {
background-color: #ffffff;
color: #000000;
}
.auto-theme {
background-color: rgba(0, 0, 0, 0);
}
.bs-design-wrap {
position: relative;
.button {
position: absolute;
z-index: 999;
}
}
</style>

@ -0,0 +1,496 @@
<template>
<div class="bs-setting-wrap">
<el-form
ref="form"
:model="config"
label-width="90px"
label-position="left"
class="setting-body bs-el-form"
>
<SettingTitle>标题</SettingTitle>
<div class="lc-field-body">
<el-form-item
label="标题"
label-width="100px"
>
<el-input
v-model="config.title"
placeholder="请输入标题"
clearable
/>
</el-form-item>
</div>
<SettingTitle>位置</SettingTitle>
<div class="lc-field-body">
<PosWhSetting :config="config" />
</div>
<SettingTitle v-if="config.border">
边框
</SettingTitle>
<div class="lc-field-body">
<BorderSetting
v-if="config.border"
label-width="100px"
:config="config.border"
:big-title="config.title"
/>
</div>
<SettingTitle>旋转</SettingTitle>
<div class="lc-field-body">
<RotateSetting
:config="config"
/>
</div>
<SettingTitle>图表</SettingTitle>
<div class="lc-field-body">
<el-form-item
label="图形背景色"
label-width="100px"
>
<el-radio-group
v-model="lineColorType"
style="margin-bottom: 8px;"
>
<el-radio :label="'theme'">
颜色字段
</el-radio>
<el-radio :label="'customize'">
自定义
</el-radio>
</el-radio-group>
<el-select
v-if="lineColorType === 'theme'"
v-model="config.customize.normal.lineColor"
popper-class="bs-el-select"
class="bs-el-select"
placeholder="请选择颜色字段"
>
<el-option
v-for="item in colorFields"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<ColorPicker
v-if="lineColorType === 'customize'"
v-model="config.customize.normal.lineColor"
:predefine-colors="predefineThemeColors"
/>
</el-form-item>
<el-form-item
label="图形弯曲度"
label-width="100px"
>
<el-input-number
v-model="config.customize.normal.lineCurveness"
class="bs-el-input-number"
/>
</el-form-item>
<el-form-item
label="矩形边框色"
label-width="100px"
>
<ColorPicker
v-model="config.customize.normal.itemBorderColor"
:predefine-colors="predefineThemeColors"
/>
</el-form-item>
<el-form-item
label="矩形边框宽度"
label-width="100px"
>
<el-input-number
v-model="config.customize.normal.itemBorderWidth"
class="bs-el-input-number"
/>
</el-form-item>
<el-form-item
label="矩形边框样式"
label-width="100px"
>
<el-select
v-model="config.customize.normal.itemBorderType"
popper-class="bs-el-select"
class="bs-el-select"
placeholder="请选择位置"
>
<el-option
v-for="item in borderTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label="标签位置"
label-width="100px"
>
<el-select
v-model="config.customize.normal.labelPosition"
popper-class="bs-el-select"
class="bs-el-select"
placeholder="请选择位置"
>
<el-option
v-for="item in labelPositionList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label="标签颜色"
label-width="100px"
>
<ColorPicker
v-model="config.customize.normal.labelColor"
:predefine-colors="predefineThemeColors"
/>
</el-form-item>
<el-form-item
label="标签字体大小"
label-width="100px"
>
<el-input-number
v-model="config.customize.normal.labelSize"
class="bs-el-input-number"
/>
</el-form-item>
<el-form-item
label="标签字体粗细"
label-width="100px"
>
<el-select
v-model="config.customize.normal.labelFontWeight"
popper-class="bs-el-select"
class="bs-el-select"
placeholder="请选择位置"
>
<el-option
v-for="item in fontWeightList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</div>
<SettingTitle>
高亮设置
</SettingTitle>
<div class="lc-field-body">
<el-form-item
label="图形背景色"
label-width="100px"
>
<el-radio-group v-model="lineColorType">
<el-radio :label="'theme'">
颜色字段
</el-radio>
<el-radio :label="'customize'">
自定义
</el-radio>
</el-radio-group>
<el-select
v-if="lineColorType === 'theme'"
v-model="config.customize.emphasis.lineColor"
popper-class="bs-el-select"
class="bs-el-select"
placeholder="请选择颜色字段"
>
<el-option
v-for="item in colorFields"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<ColorPicker
v-if="lineColorType === 'customize'"
v-model="config.customize.emphasis.lineColor"
:predefine-colors="predefineThemeColors"
/>
</el-form-item>
<el-form-item
label="矩形边框色"
label-width="100px"
>
<ColorPicker
v-model="config.customize.emphasis.itemBorderColor"
:predefine-colors="predefineThemeColors"
/>
</el-form-item>
<el-form-item
label="矩形边框宽度"
label-width="100px"
>
<el-input-number
v-model="config.customize.emphasis.itemBorderWidth"
class="bs-el-input-number"
/>
</el-form-item>
<el-form-item
label="矩形边框样式"
label-width="100px"
>
<el-select
v-model="config.customize.emphasis.itemBorderType"
popper-class="bs-el-select"
class="bs-el-select"
placeholder="请选择位置"
>
<el-option
v-for="item in borderTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label="标签颜色"
label-width="100px"
>
<ColorPicker
v-model="config.customize.emphasis.labelColor"
:predefine-colors="predefineThemeColors"
/>
</el-form-item>
<el-form-item
label="标签字体大小"
label-width="100px"
>
<el-input-number
v-model="config.customize.emphasis.labelSize"
class="bs-el-input-number"
/>
</el-form-item>
<el-form-item
label="标签字体粗细"
label-width="100px"
>
<el-select
v-model="config.customize.emphasis.labelFontWeight"
popper-class="bs-el-select"
class="bs-el-select"
placeholder="请选择位置"
>
<el-option
v-for="item in fontWeightList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</div>
</el-form>
</div>
</template>
<script>
import SettingTitle from 'data-room-ui/SettingTitle/index.vue'
import { chartSettingMixins } from 'data-room-ui/js/mixins/chartSettingMixins'
import ColorSelect from 'data-room-ui/ColorMultipleSelect/index.vue'
import ColorPicker from 'data-room-ui/ColorPicker/index.vue'
import BorderSetting from 'data-room-ui/BigScreenDesign/RightSetting/BorderSetting.vue'
import PosWhSetting from 'data-room-ui/BigScreenDesign/RightSetting/PosWhSetting.vue'
import RotateSetting from 'data-room-ui/BigScreenDesign/RightSetting/RotateSetting.vue'
import { predefineColors } from 'data-room-ui/js/utils/colorList'
export default {
name: 'BarSetting',
components: {
ColorPicker,
SettingTitle,
PosWhSetting,
BorderSetting,
RotateSetting
},
mixins: [chartSettingMixins],
props: {},
data () {
return {
lineColorType: 'theme',
fontWeightList: [
{
label: '正常',
value: 'normal'
},
{
label: '粗体',
value: 'bold'
},
{
label: '加粗',
value: 'bolder'
},
{
label: '细体',
value: 'lighter'
}
],
colorFields: [
{
label: '起始字段',
value: 'source'
},
{
label: '目标字段',
value: 'target'
},
{
label: '渐变色',
value: 'gradient'
}
],
borderTypeList: [
{
label: '实线',
value: 'solid'
},
{
label: '虚线',
value: 'dashed'
},
{
label: '点线',
value: 'dotted'
}
],
labelPositionList: [
{
label: '顶部',
value: 'top'
},
{
label: '底部',
value: 'bottom'
},
{
label: '靠左',
value: 'left'
},
{
label: '靠右',
value: 'right'
},
{
label: '内部',
value: 'inside'
},
{
label: '内部靠左',
value: 'insideLeft'
},
{
label: '内部靠右',
value: 'insideRight'
},
{
label: '内部顶部',
value: 'insideTop '
},
{
label: '内部底部',
value: 'insideBottom'
},
{
label: '内部左上',
value: 'insideTopLeft'
},
{
label: '内部右上',
value: 'insideTopRight'
},
{
label: '内部左下',
value: 'insideBottomLeft'
},
{
label: '内部右下',
value: 'insideBottomRight'
}
],
colors: [],
mapList: [],
predefineThemeColors: predefineColors,
mapTree: [],
currentMap: {},
axisPositionList: [
{
label: '左',
value: 'start'
},
{
label: '中',
value: 'center'
},
{
label: '右',
value: 'end'
}]
}
},
computed: {
config: {
get () {
return this.$store.state.bigScreen.activeItemConfig
},
set (val) {
this.$store.state.bigScreen.activeItemConfig = val
}
}
},
watch: {},
mounted () {
this.colors = this.config.customize.rangeColor
},
methods: {
delColor () {
if (this.colors.length <= 2) return
this.colors.pop()
this.config.customize.rangeColor.pop()
},
addColor () {
this.colors.push('#fff')
},
updateColorScheme (colors) {
this.colors = [...colors]
this.config.customize.rangeColor = [...colors]
}
}
}
</script>
<style lang="scss" scoped>
@import '../../assets/style/settingWrap.scss';
@import '../../assets/style/bsTheme.scss';
//
.add-filter-box {
position: relative;
.add-filter {
margin-left: 90px;
margin-bottom: 10px;
}
.add-filter-btn {
position: absolute;
top: 0;
}
}
.lc-field-body {
padding: 12px 16px;
}
::v-deep .bs-el-slider-dark {
.el-slider__runway {
background-color: var(--bs-el-background-1) !important;
}
}
</style>

@ -0,0 +1,101 @@
import { commonConfig, displayOption } from 'data-room-ui/js/config'
import Icon from 'data-room-ui/assets/images/bigScreenIcon/export'
import cloneDeep from 'lodash/cloneDeep'
export const settingConfig = {
padding: [10, 10, 10, 10],
legend: false,
isGroup: true,
data: [],
color: '',
theme: 'dark',
displayOption: {
...displayOption,
params: {
enable: true
},
dimensionField: {
// 指标
label: '起始节点',
enable: true,
multiple: false // 是否多选
},
metricField: {
label: '目标节点', // 维度/查询字段
enable: true,
multiple: false // 是否多选
},
seriesField: {
// 系列
label: '权重',
enable: true,
multiple: false // 是否多选
}
}
}
const customConfig = {
type: 'sankey',
root: {
version: '2023071001',
contribution: false,
// 绕x轴旋转角度
rotateX: 0,
// 绕y轴旋转角度
rotateY: 0,
// 绕z轴旋转角度
rotateZ: 0,
// 透视距离
perspective: 0,
skewX: 0,
skewY: 0
},
customize: {
// 自定义样式
normal: {
labelPosition: 'right',
labelColor: '#fff',
labelFontSize: 12,
labelFontWeight: 'bold',
itemBorderColor: '#aaa',
itemBorderWidth: 1,
itemBorderType: 'solid',
lineColor: 'gradient',
lineCurveness: 0.5
},
emphasis: {
labelPosition: 'right',
labelColor: '#fff',
labelFontSize: 12,
labelFontWeight: 'bold',
itemBorderColor: '#aaa',
itemBorderWidth: 1,
itemBorderType: 'solid',
lineColor: 'gradient',
lineCurveness: 0.5
}
}
}
export const dataConfig = {
...commonConfig(customConfig)
}
export const sankeyData = {
name: '桑基图',
title: '桑基图',
icon: Icon.getNameList()[18],
border: { type: '', titleHeight: 60, fontSize: 16, isTitle: true, padding: [0, 0, 0, 0] },
className:
'com.gccloud.dataroom.core.module.chart.components.ScreenCandlestickChart',
w: 450,
h: 320,
x: 0,
y: 0,
type: 'sankey',
option: {
...cloneDeep(settingConfig)
},
setting: undefined, // 右侧面板自定义配置
dataHandler: {}, // 数据自定义处理js脚本
...cloneDeep(dataConfig)
}

@ -129,7 +129,7 @@
class="data-form-item"
>
<el-drag-select
v-if="config.option.displayOption.dimensionField.enable && config.option.displayOption.dimensionField.multiple"
v-if="config.option.displayOption.dimensionField.multiple"
v-model="config.dataSource.dimensionFieldList"
class="bs-el-select"
popper-class="bs-el-select"
@ -212,6 +212,36 @@
</el-option>
</el-select>
</el-form-item>
<!--分组-->
<el-form-item
v-if="config.option.displayOption.metricField.enable"
:label="config.option.displayOption.seriesField.label"
prop="dataSource.metricField"
class="data-form-item"
>
<el-select
v-model="config.dataSource.seriesField"
class="bs-el-select"
popper-class="bs-el-select"
clearable
>
<el-option
v-for="(field, index) in dataSourceDataList"
:key="index"
:label="field.comment"
:value="field.name"
>
<div class="source-key-option">
<div>
{{ field.comment !== "" ? field.comment : field.name }}
</div>
<div class="option-txt">
{{ field.name }}
</div>
</div>
</el-option>
</el-select>
</el-form-item>
</template>
<!-- K线图数据配置 -->
<template v-else-if="config.type === 'candlestick'">

@ -7,6 +7,7 @@ import { dataConfig, settingConfig } from '../PlotRender/settingConfig'
import { mapData } from 'data-room-ui/BasicComponents/Map/settingConfig'
import { FlyMapData } from 'data-room-ui/BasicComponents/FlyMap/settingConfig'
import { candlestickData } from 'data-room-ui/BasicComponents/Candlestick/settingConfig'
import { sankeyData } from 'data-room-ui/BasicComponents/Sankey/settingConfig'
// import _ from 'lodash'
import cloneDeep from 'lodash/cloneDeep'
import sortList from './plotListSort'
@ -97,6 +98,6 @@ export function getCustomPlots () {
return list
}
const plots = [...plotList, ...customPlots, candlestickData, mapData, FlyMapData]
const plots = [...plotList, ...customPlots, sankeyData, candlestickData, mapData, FlyMapData]
console.log('plotList', plots)
export default plots

Loading…
Cancel
Save