forked from github/dataease
commit
1d04c5c9fa
@ -367,6 +367,9 @@ public class ChartViewService {
|
||||
mapChart = transScatterData(xAxis, yAxis, view, data, extBubble);
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "radar")) {
|
||||
mapChart = transRadarChartData(xAxis, yAxis, view, data);
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "text")
|
||||
|| StringUtils.containsIgnoreCase(view.getType(), "gauge")) {
|
||||
mapChart = transNormalChartData(xAxis, yAxis, view, data);
|
||||
} else {
|
||||
mapChart = transChartData(xAxis, yAxis, view, data);
|
||||
}
|
||||
@ -476,6 +479,44 @@ public class ChartViewService {
|
||||
return map;
|
||||
}
|
||||
|
||||
// 常规图形
|
||||
private Map<String, Object> transNormalChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
|
||||
List<String> x = new ArrayList<>();
|
||||
List<Series> series = new ArrayList<>();
|
||||
for (ChartViewFieldDTO y : yAxis) {
|
||||
Series series1 = new Series();
|
||||
series1.setName(y.getName());
|
||||
series1.setType(view.getType());
|
||||
series1.setData(new ArrayList<>());
|
||||
series.add(series1);
|
||||
}
|
||||
for (String[] d : data) {
|
||||
StringBuilder a = new StringBuilder();
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
if (i == xAxis.size() - 1) {
|
||||
a.append(d[i]);
|
||||
} else {
|
||||
a.append(d[i]).append("\n");
|
||||
}
|
||||
}
|
||||
x.add(a.toString());
|
||||
for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) {
|
||||
int j = i - xAxis.size();
|
||||
try {
|
||||
series.get(j).getData().add(new BigDecimal(StringUtils.isEmpty(d[i]) ? "0" : d[i]));
|
||||
} catch (Exception e) {
|
||||
series.get(j).getData().add(new BigDecimal(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map.put("x", x);
|
||||
map.put("series", series);
|
||||
return map;
|
||||
}
|
||||
|
||||
// radar图
|
||||
private Map<String, Object> transRadarChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewWithBLOBs view, List<String[]> data) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
|
1
frontend/src/icons/svg/treemap.svg
Normal file
1
frontend/src/icons/svg/treemap.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg t="1628490858856" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2380" width="200" height="200"><path d="M64 128h512v448H64z m0 512h512v256H64z m576-192h320v448H640z m0-320h320v256H640z" p-id="2381"></path></svg>
|
After Width: | Height: | Size: 263 B |
@ -832,7 +832,11 @@ export default {
|
||||
axis_label_rotate: 'Label Rotate',
|
||||
chart_scatter_bubble: 'Bubble',
|
||||
chart_scatter: 'Scatter',
|
||||
bubble_size: 'Bubble Size'
|
||||
bubble_size: 'Bubble Size',
|
||||
chart_treemap: 'Tree Map',
|
||||
drill: 'Drill',
|
||||
drag_block_treemap_label: 'Color Label',
|
||||
drag_block_treemap_size: 'Color Size'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
|
||||
|
@ -832,7 +832,11 @@ export default {
|
||||
axis_label_rotate: '標簽角度',
|
||||
chart_scatter_bubble: '氣泡圖',
|
||||
chart_scatter: '散點圖',
|
||||
bubble_size: '氣泡大小'
|
||||
bubble_size: '氣泡大小',
|
||||
chart_treemap: '矩形樹圖',
|
||||
drill: '鉆取',
|
||||
drag_block_treemap_label: '色塊標簽',
|
||||
drag_block_treemap_size: '色塊大小'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: '有多個sheet頁面,默認抽取第一個',
|
||||
|
@ -832,7 +832,11 @@ export default {
|
||||
axis_label_rotate: '标签角度',
|
||||
chart_scatter_bubble: '气泡图',
|
||||
chart_scatter: '散点图',
|
||||
bubble_size: '气泡大小'
|
||||
bubble_size: '气泡大小',
|
||||
chart_treemap: '矩形树图',
|
||||
drill: '钻取',
|
||||
drag_block_treemap_label: '色块标签',
|
||||
drag_block_treemap_size: '色块大小'
|
||||
},
|
||||
dataset: {
|
||||
sheet_warn: '有多个 Sheet 页,默认抽取第一个',
|
||||
|
@ -689,3 +689,39 @@ export const BASE_SCATTER = {
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const BASE_TREEMAP = {
|
||||
title: {
|
||||
text: '',
|
||||
textStyle: {
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {},
|
||||
legend: {
|
||||
show: true,
|
||||
type: 'scroll',
|
||||
itemWidth: 10,
|
||||
itemHeight: 10,
|
||||
icon: 'rect'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
// name: '',
|
||||
type: 'treemap',
|
||||
// radius: ['0%', '60%'],
|
||||
// avoidLabelOverlap: false,
|
||||
// emphasis: {
|
||||
// itemStyle: {
|
||||
// shadowBlur: 10,
|
||||
// shadowOffsetX: 0,
|
||||
// shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
// }
|
||||
// },
|
||||
data: []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -31,8 +31,6 @@ export function baseFunnelOption(chart_option, chart) {
|
||||
chart_option.series[0].label = customAttr.label
|
||||
}
|
||||
const valueArr = chart.data.series[0].data
|
||||
// max value
|
||||
chart_option.series[0].max = Math.max.apply(Math, valueArr)
|
||||
for (let i = 0; i < valueArr.length; i++) {
|
||||
// const y = {
|
||||
// name: chart.data.x[i],
|
||||
@ -44,7 +42,7 @@ export function baseFunnelOption(chart_option, chart) {
|
||||
y.itemStyle = {
|
||||
color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha)
|
||||
}
|
||||
y.type = 'funnel'
|
||||
// y.type = 'funnel'
|
||||
chart_option.series[0].data.push(y)
|
||||
}
|
||||
}
|
||||
|
53
frontend/src/views/chart/chart/treemap/treemap.js
Normal file
53
frontend/src/views/chart/chart/treemap/treemap.js
Normal file
@ -0,0 +1,53 @@
|
||||
import { hexColorToRGBA } from '@/views/chart/chart/util'
|
||||
import { componentStyle } from '../common/common'
|
||||
|
||||
export function baseTreemapOption(chart_option, chart) {
|
||||
// 处理shape attr
|
||||
let customAttr = {}
|
||||
if (chart.customAttr) {
|
||||
customAttr = JSON.parse(chart.customAttr)
|
||||
if (customAttr.color) {
|
||||
chart_option.color = customAttr.color.colors
|
||||
}
|
||||
// tooltip
|
||||
if (customAttr.tooltip) {
|
||||
const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip))
|
||||
const reg = new RegExp('\n', 'g')
|
||||
tooltip.formatter = tooltip.formatter.replace(reg, '<br/>')
|
||||
chart_option.tooltip = tooltip
|
||||
}
|
||||
}
|
||||
// 处理data
|
||||
if (chart.data) {
|
||||
chart_option.title.text = chart.title
|
||||
if (chart.data.series.length > 0) {
|
||||
// chart_option.series[0].name = chart.data.series[0].name
|
||||
// size
|
||||
if (customAttr.size) {
|
||||
// chart_option.series[0].radius = [customAttr.size.pieInnerRadius + '%', customAttr.size.pieOuterRadius + '%']
|
||||
}
|
||||
// label
|
||||
if (customAttr.label) {
|
||||
// chart_option.series[0].label = customAttr.label
|
||||
}
|
||||
const valueArr = chart.data.series[0].data
|
||||
for (let i = 0; i < valueArr.length; i++) {
|
||||
// const y = {
|
||||
// name: chart.data.x[i],
|
||||
// value: valueArr[i]
|
||||
// }
|
||||
const y = valueArr[i]
|
||||
y.name = chart.data.x[i]
|
||||
// color
|
||||
y.itemStyle = {
|
||||
color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha)
|
||||
}
|
||||
// y.type = 'treemap'
|
||||
chart_option.series[0].data.push(y)
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log(chart_option);
|
||||
componentStyle(chart_option, chart)
|
||||
return chart_option
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { BASE_BAR, BASE_LINE, HORIZONTAL_BAR, BASE_PIE, BASE_FUNNEL, BASE_RADAR, BASE_GAUGE, BASE_MAP, BASE_SCATTER } from '../chart/chart'
|
||||
import { BASE_BAR, BASE_LINE, HORIZONTAL_BAR, BASE_PIE, BASE_FUNNEL, BASE_RADAR, BASE_GAUGE, BASE_MAP, BASE_SCATTER, BASE_TREEMAP } from '../chart/chart'
|
||||
import { baseBarOption, stackBarOption, horizontalBarOption, horizontalStackBarOption } from '../chart/bar/bar'
|
||||
import { baseLineOption, stackLineOption } from '../chart/line/line'
|
||||
import { basePieOption, rosePieOption } from '../chart/pie/pie'
|
||||
@ -14,6 +14,7 @@ import { baseFunnelOption } from '../chart/funnel/funnel'
|
||||
import { baseRadarOption } from '../chart/radar/radar'
|
||||
import { baseGaugeOption } from '../chart/gauge/gauge'
|
||||
import { baseScatterOption } from '../chart/scatter/scatter'
|
||||
import { baseTreemapOption } from '../chart/treemap/treemap'
|
||||
// import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import { uuid } from 'vue-uuid'
|
||||
import { geoJson } from '@/api/map/map'
|
||||
@ -98,6 +99,8 @@ export default {
|
||||
chart_option = baseGaugeOption(JSON.parse(JSON.stringify(BASE_GAUGE)), chart)
|
||||
} else if (chart.type === 'scatter') {
|
||||
chart_option = baseScatterOption(JSON.parse(JSON.stringify(BASE_SCATTER)), chart)
|
||||
} else if (chart.type === 'treemap') {
|
||||
chart_option = baseTreemapOption(JSON.parse(JSON.stringify(BASE_TREEMAP)), chart)
|
||||
}
|
||||
|
||||
if (chart.type === 'map') {
|
||||
@ -145,6 +148,9 @@ export default {
|
||||
window.onresize = function() {
|
||||
chart.resize()
|
||||
}
|
||||
chart.on('click',function(param) {
|
||||
console.log(param)
|
||||
})
|
||||
},
|
||||
chartResize() {
|
||||
// 指定图表的配置项和数据
|
||||
|
@ -163,23 +163,18 @@
|
||||
<svg-icon icon-class="line-stack" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="pie" label="pie">
|
||||
<span :title="$t('chart.chart_pie')">
|
||||
<svg-icon icon-class="pie" class="chart-icon" />
|
||||
<el-radio value="scatter" label="scatter">
|
||||
<span :title="$t('chart.chart_scatter')">
|
||||
<svg-icon icon-class="scatter" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="pie-rose" label="pie-rose">
|
||||
<span :title="$t('chart.chart_pie_rose')">
|
||||
<svg-icon icon-class="pie-rose" class="chart-icon" />
|
||||
<el-radio value="map" label="map">
|
||||
<span :title="$t('chart.chart_map')">
|
||||
<svg-icon icon-class="map" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
|
||||
<el-radio value="funnel" label="funnel">
|
||||
<span :title="$t('chart.chart_funnel')">
|
||||
<svg-icon icon-class="funnel" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="radar" label="radar">
|
||||
<span :title="$t('chart.chart_radar')">
|
||||
<svg-icon icon-class="radar" class="chart-icon" />
|
||||
@ -190,19 +185,28 @@
|
||||
<svg-icon icon-class="gauge" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="map" label="map">
|
||||
<span :title="$t('chart.chart_map')">
|
||||
<svg-icon icon-class="map" class="chart-icon" />
|
||||
<el-radio value="pie" label="pie">
|
||||
<span :title="$t('chart.chart_pie')">
|
||||
<svg-icon icon-class="pie" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="scatter" label="scatter">
|
||||
<span :title="$t('chart.chart_scatter')">
|
||||
<svg-icon icon-class="scatter" class="chart-icon" />
|
||||
<el-radio value="pie-rose" label="pie-rose">
|
||||
<span :title="$t('chart.chart_pie_rose')">
|
||||
<svg-icon icon-class="pie-rose" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="funnel" label="funnel">
|
||||
<span :title="$t('chart.chart_funnel')">
|
||||
<svg-icon icon-class="funnel" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
|
||||
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
|
||||
<el-radio value="treemap" label="treemap">
|
||||
<span :title="$t('chart.chart_treemap')">
|
||||
<svg-icon icon-class="treemap" class="chart-icon" />
|
||||
</span>
|
||||
</el-radio>
|
||||
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
|
||||
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
|
||||
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
|
||||
@ -213,7 +217,7 @@
|
||||
</el-row>
|
||||
<el-row style="color: #909399;">
|
||||
<span>
|
||||
<span v-show="chart.type && (chart.type.includes('pie') || chart.type.includes('funnel') || chart.type.includes('text') || chart.type.includes('gauge'))">
|
||||
<span v-show="chart.type && (chart.type.includes('pie') || chart.type.includes('funnel') || chart.type.includes('text') || chart.type.includes('gauge') || chart.type.includes('treemap'))">
|
||||
Tips: {{ $t('chart.only_one_quota') }}
|
||||
</span>
|
||||
<!-- <span v-show="chart.type && (chart.type.includes('text'))">-->
|
||||
@ -245,7 +249,7 @@
|
||||
</el-row>
|
||||
<el-row class="padding-lr">
|
||||
<span style="width: 80px;text-align: right;">
|
||||
<span>钻取</span>
|
||||
<span>{{ $t('chart.drill') }}</span>
|
||||
/
|
||||
<span>{{ $t('chart.dimension') }}</span>
|
||||
</span>
|
||||
@ -274,7 +278,8 @@
|
||||
<span v-else-if="view.type && view.type.includes('pie')">{{ $t('chart.drag_block_pie_label') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('funnel')">{{ $t('chart.drag_block_funnel_split') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('radar')">{{ $t('chart.drag_block_radar_label') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('map')">{{ $t('chart.area') }}</span>
|
||||
<span v-else-if="view.type && view.type === 'map'">{{ $t('chart.area') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('treemap')">{{ $t('chart.drag_block_treemap_label') }}</span>
|
||||
/
|
||||
<span>{{ $t('chart.dimension') }}</span>
|
||||
</span>
|
||||
@ -305,7 +310,8 @@
|
||||
<span v-else-if="view.type && view.type.includes('radar')">{{ $t('chart.drag_block_radar_length') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('gauge')">{{ $t('chart.drag_block_gauge_angel') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('text')">{{ $t('chart.drag_block_label_value') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('map')">{{ $t('chart.chart_data') }}</span>
|
||||
<span v-else-if="view.type && view.type === 'map'">{{ $t('chart.chart_data') }}</span>
|
||||
<span v-else-if="view.type && view.type.includes('tree')">{{ $t('chart.drag_block_treemap_size') }}</span>
|
||||
/
|
||||
<span>{{ $t('chart.quota') }}</span>
|
||||
</span>
|
||||
@ -421,10 +427,10 @@
|
||||
<el-collapse-item name="color" :title="$t('chart.color')">
|
||||
<color-selector :param="param" class="attr-selector" :chart="chart" @onColorChange="onColorChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-show="chart.type !== 'map'" name="size" :title="$t('chart.size')">
|
||||
<el-collapse-item v-show="chart.type !== 'map' && chart.type !== 'treemap'" name="size" :title="$t('chart.size')">
|
||||
<size-selector :param="param" class="attr-selector" :chart="chart" @onSizeChange="onSizeChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-show="!view.type.includes('table') && !view.type.includes('text')" name="label" :title="$t('chart.label')">
|
||||
<el-collapse-item v-show="!view.type.includes('table') && !view.type.includes('text') && view.type !== 'treemap'" name="label" :title="$t('chart.label')">
|
||||
<label-selector :param="param" class="attr-selector" :chart="chart" @onLabelChange="onLabelChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-show="!view.type.includes('table') && !view.type.includes('text')" name="tooltip" :title="$t('chart.tooltip')">
|
||||
@ -453,7 +459,7 @@
|
||||
<el-collapse-item name="title" :title="$t('chart.title')">
|
||||
<title-selector :param="param" class="attr-selector" :chart="chart" @onTextChange="onTextChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item v-show="view.type && !view.type.includes('map') && !view.type.includes('table') && !view.type.includes('text')" name="legend" :title="$t('chart.legend')">
|
||||
<el-collapse-item v-show="view.type && view.type !== 'map' && !view.type.includes('table') && !view.type.includes('text') && chart.type !== 'treemap'" name="legend" :title="$t('chart.legend')">
|
||||
<legend-selector :param="param" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="background" :title="$t('chart.background')">
|
||||
@ -864,6 +870,9 @@ export default {
|
||||
if (view.type === 'line-stack' && trigger === 'chart') {
|
||||
view.customAttr.size.lineArea = true
|
||||
}
|
||||
if (view.type === 'treemap' && trigger === 'chart') {
|
||||
view.customAttr.label.show = true
|
||||
}
|
||||
view.customFilter.forEach(function(ele) {
|
||||
if (ele && !ele.filter) {
|
||||
ele.filter = []
|
||||
|
Loading…
Reference in New Issue
Block a user