Commit d88ad7e8 by yuwei

项目初始化

parent 00b002e0
......@@ -25,6 +25,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Slf4j
@Service
......@@ -40,14 +41,11 @@ public class ApiMappingEngine {
private ApiMaskServiceFeign apiMaskServiceFeign;
public PageResult<Map<String, Object>> execute(DataApiEntity dataApi, Map<String, Object> params) {
MetadataSourceEntity dataSource = metadataSourceServiceFeign.getMetadataSourceById(dataApi.getExecuteConfig().getSourceId());
if (dataSource == null) {
throw new DataException("API调用查询数据源出错");
}
MetadataSourceEntity dataSource = Optional.ofNullable(metadataSourceServiceFeign.getMetadataSourceById(dataApi.getExecuteConfig().getSourceId())).orElseThrow(() -> new DataException("API调用查询数据源出错"));
DbSchema dbSchema = dataSource.getDbSchema();
DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(),
dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid());
DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty);
DbQuery dbQuery = Optional.ofNullable(dataSourceFactory.createDbQuery(dbQueryProperty)).orElseThrow(() -> new DataException("创建数据查询接口出错"));
// 参数
Integer pageNum = Integer.parseInt((String) params.getOrDefault("pageNum", 1));
Integer pageSize = Integer.parseInt((String) params.getOrDefault("pageSize", 20));
......
package cn.datax.service.data.visual.api.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class ChartColumnParse implements Serializable {
private static final long serialVersionUID=1L;
private String col;
private String alias;
/**
* 指标聚合函数类型
*/
private String aggregateType;
/**
* 指标柱状、折线图表类型
*/
private String seriesType;
}
......@@ -2,10 +2,22 @@ package cn.datax.service.data.visual.api.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.List;
@Data
public class ChartConfig implements Serializable {
private static final long serialVersionUID=1L;
@NotBlank(message = "数据集不能为空")
private String datasetId;
@NotBlank(message = "图表类型不能为空")
private String chartType;
private List<ChartColumnParse> rows;
private List<ChartColumnParse> columns;
@NotEmpty(message = "指标不能为空")
private List<ChartColumnParse> measures;
}
......@@ -74,6 +74,11 @@
<artifactId>data-visual-service-api</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>data-metadata-service-api</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
<build>
......
......@@ -4,7 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients(basePackages = {"cn.datax.service.system.api.feign"})
@EnableFeignClients(basePackages = {"cn.datax.service.system.api.feign", "cn.datax.service.data.metadata.api.feign"})
@SpringCloudApplication
public class DataxVisualApplication {
......
......@@ -3,6 +3,7 @@ package cn.datax.service.data.visual.controller;
import cn.datax.common.core.JsonPage;
import cn.datax.common.core.R;
import cn.datax.common.validate.ValidationGroups;
import cn.datax.service.data.visual.api.dto.ChartConfig;
import cn.datax.service.data.visual.api.dto.ChartDto;
import cn.datax.service.data.visual.api.entity.ChartEntity;
import cn.datax.service.data.visual.api.vo.ChartVo;
......@@ -23,6 +24,7 @@ import org.springframework.web.bind.annotation.*;
import cn.datax.common.base.BaseController;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
......@@ -137,4 +139,10 @@ public class ChartController extends BaseController {
chartService.copyChart(id);
return R.ok();
}
@PostMapping("/data/parser")
public R dataParser(@RequestBody @Validated ChartConfig chartConfig) {
Map<String, Object> map = chartService.dataParser(chartConfig);
return R.ok().setData(map);
}
}
package cn.datax.service.data.visual.service;
import cn.datax.service.data.visual.api.dto.ChartConfig;
import cn.datax.service.data.visual.api.entity.ChartEntity;
import cn.datax.service.data.visual.api.dto.ChartDto;
import cn.datax.common.base.BaseService;
import java.util.List;
import java.util.Map;
/**
* <p>
......@@ -27,4 +29,6 @@ public interface ChartService extends BaseService<ChartEntity> {
void deleteChartBatch(List<String> ids);
void copyChart(String id);
Map<String, Object> dataParser(ChartConfig chartConfig);
}
package cn.datax.service.data.visual.service.impl;
import cn.datax.common.core.DataConstant;
import cn.datax.common.database.DataSourceFactory;
import cn.datax.common.database.DbQuery;
import cn.datax.common.database.constants.DbQueryProperty;
import cn.datax.common.exception.DataException;
import cn.datax.service.data.metadata.api.dto.DbSchema;
import cn.datax.service.data.metadata.api.entity.MetadataSourceEntity;
import cn.datax.service.data.metadata.api.feign.MetadataSourceServiceFeign;
import cn.datax.service.data.visual.api.dto.ChartColumnParse;
import cn.datax.service.data.visual.api.dto.ChartConfig;
import cn.datax.service.data.visual.api.entity.ChartEntity;
import cn.datax.service.data.visual.api.dto.ChartDto;
import cn.datax.service.data.visual.api.entity.DataSetEntity;
import cn.datax.service.data.visual.dao.DataSetDao;
import cn.datax.service.data.visual.service.ChartService;
import cn.datax.service.data.visual.mapstruct.ChartMapper;
import cn.datax.service.data.visual.dao.ChartDao;
......@@ -16,8 +26,8 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
......@@ -37,6 +47,15 @@ public class ChartServiceImpl extends BaseServiceImpl<ChartDao, ChartEntity> imp
@Autowired
private ChartMapper chartMapper;
@Autowired
private DataSetDao dataSetDao;
@Autowired
private DataSourceFactory dataSourceFactory;
@Autowired
private MetadataSourceServiceFeign metadataSourceServiceFeign;
@Override
@Transactional(rollbackFor = Exception.class)
public ChartEntity saveChart(ChartDto chartDto) {
......@@ -81,4 +100,34 @@ public class ChartServiceImpl extends BaseServiceImpl<ChartDao, ChartEntity> imp
copy.setStatus(DataConstant.EnableState.ENABLE.getKey());
chartDao.insert(copy);
}
@Override
public Map<String, Object> dataParser(ChartConfig chartConfig) {
String datasetId = chartConfig.getDatasetId();
DataSetEntity dataSetEntity = Optional.ofNullable(dataSetDao.selectById(datasetId)).orElseThrow(() -> new DataException("获取数据集失败"));
MetadataSourceEntity metadataSourceEntity = Optional.ofNullable(metadataSourceServiceFeign.getMetadataSourceById(dataSetEntity.getSourceId())).orElseThrow(() -> new DataException("获取数据源失败"));
DbSchema dbSchema = metadataSourceEntity.getDbSchema();
DbQueryProperty dbQueryProperty = new DbQueryProperty(metadataSourceEntity.getDbType(), dbSchema.getHost(),
dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid());
DbQuery dbQuery = Optional.ofNullable(dataSourceFactory.createDbQuery(dbQueryProperty)).orElseThrow(() -> new DataException("创建数据查询接口出错"));
List<ChartColumnParse> rows = chartConfig.getRows();
List<ChartColumnParse> columns = chartConfig.getColumns();
List<ChartColumnParse> measures = chartConfig.getMeasures();
String setSql = dataSetEntity.getSetSql();
StringBuilder sql = new StringBuilder();
List<ChartColumnParse> groups = new ArrayList<>();
groups.addAll(rows);
groups.addAll(columns);
String groupJoining = groups.stream().map(s -> s.getCol()).collect(Collectors.joining(", ", " ", ","));
sql.append("SELECT").append(groupJoining);
String measureJoining = Optional.ofNullable(measures).orElse(new ArrayList<>()).stream().map(s -> new StringBuilder().append(s.getAggregateType()).append("(").append(s.getCol()).append(") AS ").append(s.getCol())).collect(Collectors.joining(", ", " ", " "));
sql.append(measureJoining);
sql.append("FROM (").append(setSql).append(") TEMP_VIEW ").append("GROUP BY ").append(groups.stream().map(s -> s.getCol()).collect(Collectors.joining(", ")));
List<Map<String, Object>> data = dbQuery.queryList(sql.toString());
Map<String, Object> map = new HashMap<>(2);
map.put("data", data);
map.put("sql", sql.toString());
return map;
}
}
......@@ -44,3 +44,11 @@ export function copyDataChart(id) {
method: 'post'
})
}
export function dataParser(data) {
return request({
url: '/data/visual/charts/data/parser',
method: 'post',
data: data
})
}
import request from '@/utils/request'
export function listDataSet (data) {
export function listDataSet(data) {
return request({
url: '/data/visual/dataSets/list',
method: 'get',
......@@ -8,7 +8,7 @@ export function listDataSet (data) {
})
}
export function pageDataSet (data) {
export function pageDataSet(data) {
return request({
url: '/data/visual/dataSets/page',
method: 'get',
......@@ -16,28 +16,28 @@ export function pageDataSet (data) {
})
}
export function getDataSet (id) {
export function getDataSet(id) {
return request({
url: '/data/visual/dataSets/' + id,
method: 'get'
})
}
export function delDataSet (id) {
export function delDataSet(id) {
return request({
url: '/data/visual/dataSets/' + id,
method: 'delete'
})
}
export function delDataSets (ids) {
export function delDataSets(ids) {
return request({
url: '/data/visual/dataSets/batch/' + ids,
method: 'delete'
})
}
export function addDataSet (data) {
export function addDataSet(data) {
return request({
url: '/data/visual/dataSets',
method: 'post',
......@@ -45,7 +45,7 @@ export function addDataSet (data) {
})
}
export function updateDataSet (data) {
export function updateDataSet(data) {
return request({
url: '/data/visual/dataSets/' + data.id,
method: 'put',
......@@ -53,7 +53,7 @@ export function updateDataSet (data) {
})
}
export function sqlAnalyse (data) {
export function sqlAnalyse(data) {
return request({
url: '/data/visual/dataSets/sql/analyse',
method: 'post',
......
......@@ -2,6 +2,7 @@ const chartTypes = [
{
name: '表格', value: 'table', icon: 'chart_table',
status: true,
component: 'ChartTable',
rule: {
text: '0个或多个 行维;0个或多个 列维;0个或多个 指标',
check(rows, columns, measures) {
......@@ -12,6 +13,7 @@ const chartTypes = [
{
name: '折线图', value: 'line', icon: 'chart_line',
status: true,
component: 'ChartLine',
rule: {
text: '1个或多个 行维;0个或多个 列维;1个或多个 指标',
check(rows, columns, measures) {
......@@ -22,6 +24,7 @@ const chartTypes = [
{
name: '柱状图', value: 'bar', icon: 'chart_bar',
status: true,
component: 'ChartBar',
rule: {
text: '1个或多个 行维;0个或多个 列维;1个或多个 指标',
check(rows, columns, measures) {
......@@ -32,6 +35,7 @@ const chartTypes = [
{
name: '饼图', value: 'pie', icon: 'chart_pie',
status: true,
component: 'ChartPie',
rule: {
text: '1个或多个 行维;0个或多个 列维;1个或多个 指标',
check(rows, columns, measures) {
......@@ -42,6 +46,7 @@ const chartTypes = [
{
name: '指标卡', value: 'kpi', icon: 'chart_kpi',
status: true,
component: 'ChartKpi',
rule: {
text: '0 行维;0 列维;1 指标',
check(rows, columns, measures) {
......@@ -52,6 +57,7 @@ const chartTypes = [
{
name: '雷达图', value: 'radar', icon: 'chart_radar',
status: true,
component: 'ChartRadar',
rule: {
text: '1个或多个 行维;0个或多个 列维;1个或多个 指标',
check(rows, columns, measures) {
......@@ -62,6 +68,7 @@ const chartTypes = [
{
name: '漏斗图', value: 'funnel', icon: 'chart_funnel',
status: true,
component: 'ChartFunnel',
rule: {
text: '0个或多个 行维;0 列维;1个或多个 指标',
check(rows, columns, measures) {
......@@ -72,6 +79,7 @@ const chartTypes = [
{
name: '散点图', value: 'scatter', icon: 'chart_scatter',
status: true,
component: 'ChartScatter',
rule: {
text: '1个或多个 行维;0个或多个 列维;1个或多个 指标',
check(rows, columns, measures) {
......@@ -82,6 +90,7 @@ const chartTypes = [
{
name: '仪表盘', value: 'gauge', icon: 'chart_gauge',
status: true,
component: 'ChartGauge',
rule: {
text: '0 行维;0 列维;1 指标',
check(rows, columns, measures) {
......@@ -92,6 +101,7 @@ const chartTypes = [
{
name: '矩形树图', value: 'treemap', icon: 'chart_treemap',
status: true,
component: 'ChartTreemap',
rule: {
text: '1个或多个 行维;0 列维;1 指标',
check(rows, columns, measures) {
......@@ -102,6 +112,7 @@ const chartTypes = [
{
name: '词云图', value: 'wordcloud', icon: 'chart_wordcloud',
status: true,
component: 'ChartWordcloud',
rule: {
text: '1个或多个 行维;0 列维;1 指标',
check(rows, columns, measures) {
......@@ -112,6 +123,7 @@ const chartTypes = [
{
name: '水球图', value: 'liquidfill', icon: 'chart_liquidfill',
status: true,
component: 'ChartLiquidfill',
rule: {
text: '0 行维;0 列维;1 指标',
check(rows, columns, measures) {
......@@ -122,6 +134,7 @@ const chartTypes = [
{
name: '桑基图', value: 'sankey', icon: 'chart_sankey',
status: true,
component: 'ChartSankey',
rule: {
text: '1个或多个 行维;0个或多个 列维;1 指标',
check(rows, columns, measures) {
......@@ -132,6 +145,7 @@ const chartTypes = [
{
name: '地图', value: 'geo', icon: 'chart_geo',
status: true,
component: 'ChartGeo',
rule: {
text: '1个或多个 行维;0个或多个 列维;1个或多个 指标',
check(rows, columns, measures) {
......@@ -142,6 +156,7 @@ const chartTypes = [
{
name: '树图', value: 'tree', icon: 'chart_tree',
status: false,
component: 'ChartTree',
rule: {
text: '0 行维;0 列维;0 指标',
check(rows, columns, measures) {
......@@ -152,6 +167,7 @@ const chartTypes = [
{
name: '环形图', value: 'donut', icon: 'chart_donut',
status: false,
component: 'ChartDonut',
rule: {
text: '0 行维;0 列维;0 指标',
check(rows, columns, measures) {
......@@ -162,6 +178,7 @@ const chartTypes = [
{
name: '旭日图', value: 'sunburst', icon: 'chart_sunburst',
status: false,
component: 'ChartSunburst',
rule: {
text: '0 行维;0 列维;0 指标',
check(rows, columns, measures) {
......@@ -172,6 +189,7 @@ const chartTypes = [
{
name: '极区图', value: 'polar', icon: 'chart_polar',
status: false,
component: 'ChartPolar',
rule: {
text: '0 行维;0 列维;0 指标',
check(rows, columns, measures) {
......
......@@ -27,7 +27,7 @@
</div>
<div class="widget-center-container">
<div class="widget-center-header">
<el-button icon="el-icon-view" type="text">
<el-button icon="el-icon-view" type="text" @click="handlePreview">
预览
</el-button>
<el-button icon="el-icon-delete" type="text" @click="handleReset">
......@@ -62,13 +62,13 @@
<div class="widget-center-draggable-text">
<draggable group="measures" :list="widget.measures" @change="handleValueDragChange" class="widget-center-draggable-line">
<div v-for="(item, index) in widget.measures" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.aggregate_type + '(' + item.col + ') -> ' + item.alias : item.aggregate_type + '(' + item.col + ')' }}</el-tag>
<el-tag>{{ item.alias ? item.aggregateType + '(' + item.col + ') -> ' + item.alias : item.aggregateType + '(' + item.col + ')' }}</el-tag>
<el-popover
placement="top"
width="400"
trigger="click"
>
<el-radio-group v-model="item.aggregate_type" size="mini">
<el-radio-group v-model="item.aggregateType" size="mini">
<el-radio label="sum" size="mini">求和</el-radio>
<el-radio label="count" size="mini">计数</el-radio>
<el-radio label="avg" size="mini">平均值</el-radio>
......@@ -85,10 +85,12 @@
<div class="widget-center-pane">
<el-tabs type="card">
<el-tab-pane label="图表预览">
<div class="widget-center-pane-chart">图表预览</div>
<div class="widget-center-pane-chart">
<chart-panel :chart-type.sync="widget.chartType" :data="chartData.data" :schema="widget"/>
</div>
</el-tab-pane>
<el-tab-pane label="查询脚本">
<div class="widget-center-pane-script">查询脚本</div>
<div class="widget-center-pane-script">{{ chartData.sql }}</div>
</el-tab-pane>
</el-tabs>
</div>
......@@ -102,6 +104,14 @@
<el-form-item label="图表名称">
<el-input v-model="datachart.chartName" size="mini" :disabled="true" />
</el-form-item>
<el-form-item label="缩略图">
<el-button type="primary" size="mini" plain style="margin-bottom: 10px;">点击生成</el-button>
<el-image :src="datachart.chartThumbnail ? ('data:image/png;base64,' + datachart.chartThumbnail) : ''">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline" />
</div>
</el-image>
</el-form-item>
<el-form-item label="图表类型">
<div class="chart-type-list">
<span v-for="item in chartTypes" :key="item.value" :class="item.value === widget.chartType ? 'active': ''" @click="item.status && item.rule.check(widget.rows, widget.columns, widget.measures) && changeChart(item.value)">
......@@ -123,15 +133,17 @@
</template>
<script>
import { getDataChart } from '@/api/visual/datachart'
import { getDataChart, dataParser } from '@/api/visual/datachart'
import { getDataSet, listDataSet } from '@/api/visual/dataset'
import draggable from 'vuedraggable'
import chartTypes from '@/utils/visual-chart'
import ChartPanel from './components/ChartPanel'
export default {
name: 'DataChartConfig',
components: {
draggable
draggable,
ChartPanel
},
data() {
return {
......@@ -141,13 +153,21 @@ export default {
chartType: 'table',
rows: [],
columns: [],
measures: []
measures: [],
// 后期添加条件过滤
filters: [],
// 后期添加图表配置项
chartOptions: {}
},
datasetOptions: [],
dataset: {},
dimensions: [],
measures: [],
chartTypes
chartTypes,
chartData: {
data: [],
sql: ''
}
}
},
created() {
......@@ -174,8 +194,7 @@ export default {
if (response.success) {
this.dataset = response.data
this.widget.datasetId = this.dataset.id
this.dimensions = JSON.parse(JSON.stringify(this.dataset.schemaConfig.dimensions))
this.measures = JSON.parse(JSON.stringify(this.dataset.schemaConfig.measures))
this.handleReset()
}
})
},
......@@ -189,14 +208,23 @@ export default {
},
handleValueDragChange(tag) {
if (tag.added) {
this.$set(tag.added.element, 'aggregate_type', 'sum')
this.$set(tag.added.element, 'aggregateType', 'sum')
}
},
handleValueTagClose(index, tag) {
this.widget.measures.splice(index, 1)
tag.aggregate_type = ''
tag.aggregateType = ''
this.measures.push(tag)
},
handlePreview() {
dataParser(this.widget).then(response => {
if (response.success) {
const { data } = response
this.chartData.data = data.data
this.chartData.sql = data.sql
}
})
},
handleReset() {
this.dimensions = JSON.parse(JSON.stringify(this.dataset.schemaConfig.dimensions))
this.measures = JSON.parse(JSON.stringify(this.dataset.schemaConfig.measures))
......@@ -379,6 +407,20 @@ export default {
height: calc(100vh - 40px);
overflow-x: hidden;
overflow-y: auto;
.el-image{
width: 250px;
height: 150px;
::v-deep .image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: #f5f7fa;
color: #909399;
font-size: 30px;
}
}
.chart-type-list {
width: 100%;
display: grid;
......
<template>
<component :is="currentChart.component" :data="data" :schema="schema" :chart-style="chartStyle" />
</template>
<script>
import chartTypes from '@/utils/visual-chart'
import ChartTable from './widgets/ChartTable'
import ChartLine from './widgets/ChartLine'
import ChartBar from './widgets/ChartBar'
import ChartPie from './widgets/ChartPie'
import ChartKpi from './widgets/ChartKpi'
import ChartRadar from './widgets/ChartRadar'
import ChartFunnel from './widgets/ChartFunnel'
import ChartScatter from './widgets/ChartScatter'
import ChartGauge from './widgets/ChartGauge'
import ChartTreemap from './widgets/ChartTreemap'
import ChartWordcloud from './widgets/ChartWordcloud'
import ChartLiquidfill from './widgets/ChartLiquidfill'
import ChartSankey from './widgets/ChartSankey'
import ChartGeo from './widgets/ChartGeo'
import ChartTree from './widgets/ChartTree'
import ChartDonut from './widgets/ChartDonut'
import ChartSunburst from './widgets/ChartSunburst'
import ChartPolar from './widgets/ChartPolar'
export default {
name: 'ChartPanel',
components: {
ChartTable, ChartLine, ChartBar, ChartPie,
ChartKpi, ChartRadar, ChartFunnel, ChartScatter,
ChartGauge, ChartTreemap, ChartWordcloud, ChartLiquidfill,
ChartSankey, ChartGeo, ChartTree, ChartDonut,
ChartSunburst, ChartPolar
},
props: {
data: {
type: Array,
required: true
},
schema: {
type: Object,
required: true
},
chartStyle: {
type: Object,
require: false
},
chartType: {
type: String,
default: 'table'
}
},
data() {
return {
chartTypes
}
},
computed: {
currentChart() {
return chartTypes.find(item => item.value === this.chartType)
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartBar</div>
</template>
<script>
export default {
name: 'ChartBar',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartDonut</div>
</template>
<script>
export default {
name: 'ChartDonut',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartFunnel</div>
</template>
<script>
export default {
name: 'ChartFunnel',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartGauge</div>
</template>
<script>
export default {
name: 'ChartGauge',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartGeo</div>
</template>
<script>
export default {
name: 'ChartGeo',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartKpi</div>
</template>
<script>
export default {
name: 'ChartKpi',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartLine</div>
</template>
<script>
export default {
name: 'ChartLine',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartLiquidfill</div>
</template>
<script>
export default {
name: 'ChartLiquidfill',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartPie</div>
</template>
<script>
export default {
name: 'ChartPie',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartPolar</div>
</template>
<script>
export default {
name: 'ChartPolar',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartRadar</div>
</template>
<script>
export default {
name: 'ChartRadar',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartSankey</div>
</template>
<script>
export default {
name: 'ChartSankey',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartScatter</div>
</template>
<script>
export default {
name: 'ChartScatter',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartSunburst</div>
</template>
<script>
export default {
name: 'ChartSunburst',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartTable</div>
</template>
<script>
export default {
name: 'ChartTable',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartTree</div>
</template>
<script>
export default {
name: 'ChartTree',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartTreemap</div>
</template>
<script>
export default {
name: 'ChartTreemap',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div ref="chart" :style="chartStyle">ChartWordcloud</div>
</template>
<script>
export default {
name: 'ChartWordcloud',
props: {
data: {
type: Array,
required: true,
default: () => {
return []
}
},
schema: {
type: Object,
required: true,
default: () => {
return {}
}
},
chartStyle: {
type: Object,
require: false,
default: () => {
return {
height: '200px'
}
}
}
},
created() {
console.log(this.data)
}
}
</script>
<style lang="scss" scoped>
</style>
......@@ -54,35 +54,31 @@
<el-row>
<el-divider content-position="left">维度列</el-divider>
<el-col>
<div style="height: 90px; border: 1px dashed #999; margin: 0 10px;">
<draggable group="col" :list="dimensionList">
<div v-for="(item, index) in dimensionList" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</el-tag>
<span v-if="item.input" class="draggable-item-handle">
<el-input v-model="item.alias" size="mini" placeholder="请输入内容" @blur="handleDelTagLabel(index, item)" />
</span>
<span v-else class="draggable-item-handle" @click="handleTagLabel(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleDimensionTagClose(index, item)"><i class="el-icon-delete" /></span>
</div>
</draggable>
</div>
<draggable group="col" :list="dimensionList" class="draggable-wrapper">
<div v-for="(item, index) in dimensionList" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</el-tag>
<span v-if="item.input" class="draggable-item-handle">
<el-input v-model="item.alias" size="mini" placeholder="请输入内容" @blur="handleDelTagLabel(index, item)" />
</span>
<span v-else class="draggable-item-handle" @click="handleTagLabel(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleDimensionTagClose(index, item)"><i class="el-icon-delete" /></span>
</div>
</draggable>
</el-col>
</el-row>
<el-row>
<el-divider content-position="left">指标列</el-divider>
<el-col>
<div style="height: 90px; border: 1px dashed #999; margin: 0 10px;">
<draggable group="col" :list="measureList">
<div v-for="(item, index) in measureList" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</el-tag>
<span v-if="item.input" class="draggable-item-handle">
<el-input v-model="item.alias" size="mini" placeholder="请输入内容" @blur="handleDelTagLabel(index, item)" />
</span>
<span v-else class="draggable-item-handle" @click="handleTagLabel(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleMeasureTagClose(index, item)"><i class="el-icon-delete" /></span>
</div>
</draggable>
</div>
<draggable group="col" :list="measureList" class="draggable-wrapper">
<div v-for="(item, index) in measureList" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</el-tag>
<span v-if="item.input" class="draggable-item-handle">
<el-input v-model="item.alias" size="mini" placeholder="请输入内容" @blur="handleDelTagLabel(index, item)" />
</span>
<span v-else class="draggable-item-handle" @click="handleTagLabel(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleMeasureTagClose(index, item)"><i class="el-icon-delete" /></span>
</div>
</draggable>
</el-col>
</el-row>
</el-col>
......@@ -362,29 +358,36 @@ export default {
margin: 10px;
cursor: move;
}
.draggable-item {
cursor: move;
margin: 5px 5px;
display: inline-block;
border: 1px solid #ebecef;
height: 32px;
line-height: 30px;
border-radius: 4px;
.draggable-item-handle {
background-color: #ecf5ff;
border-color: #d9ecff;
.draggable-wrapper {
height: 90px;
border: 1px dashed #999;
margin: 0 10px;
overflow-x: hidden;
overflow-y: auto;
.draggable-item {
cursor: move;
margin: 5px 5px;
display: inline-block;
border: 1px solid #ebecef;
height: 32px;
padding: 0 10px;
line-height: 30px;
font-size: 12px;
color: #409EFF;
border-width: 1px;
border-style: solid;
box-sizing: border-box;
white-space: nowrap;
cursor: pointer;
margin-left: -5px;
border-radius: 4px;
.draggable-item-handle {
background-color: #ecf5ff;
border-color: #d9ecff;
display: inline-block;
height: 32px;
padding: 0 10px;
line-height: 30px;
font-size: 12px;
color: #409EFF;
border-width: 1px;
border-style: solid;
box-sizing: border-box;
white-space: nowrap;
cursor: pointer;
margin-left: -5px;
}
}
}
</style>
......@@ -47,7 +47,7 @@
<el-row>
<el-divider content-position="left">维度列</el-divider>
<el-col>
<div style="height: 90px; border: 1px dashed #999; margin: 0 10px;">
<div class="draggable-wrapper">
<el-tag v-for="(item, index) in dimensionList" :key="index" class="draggable-item">
{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}
</el-tag>
......@@ -57,7 +57,7 @@
<el-row>
<el-divider content-position="left">指标列</el-divider>
<el-col>
<div style="height: 90px; border: 1px dashed #999; margin: 0 10px;">
<div class="draggable-wrapper">
<el-tag v-for="(item, index) in measureList" :key="index" class="draggable-item">
{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}
</el-tag>
......@@ -266,29 +266,36 @@ export default {
margin: 10px;
cursor: move;
}
.draggable-item {
cursor: move;
margin: 5px 5px;
display: inline-block;
border: 1px solid #ebecef;
height: 32px;
line-height: 30px;
border-radius: 4px;
.draggable-item-handle {
background-color: #ecf5ff;
border-color: #d9ecff;
.draggable-wrapper {
height: 90px;
border: 1px dashed #999;
margin: 0 10px;
overflow-x: hidden;
overflow-y: auto;
.draggable-item {
cursor: move;
margin: 5px 5px;
display: inline-block;
border: 1px solid #ebecef;
height: 32px;
padding: 0 10px;
line-height: 30px;
font-size: 12px;
color: #409EFF;
border-width: 1px;
border-style: solid;
box-sizing: border-box;
white-space: nowrap;
cursor: pointer;
margin-left: -5px;
border-radius: 4px;
.draggable-item-handle {
background-color: #ecf5ff;
border-color: #d9ecff;
display: inline-block;
height: 32px;
padding: 0 10px;
line-height: 30px;
font-size: 12px;
color: #409EFF;
border-width: 1px;
border-style: solid;
box-sizing: border-box;
white-space: nowrap;
cursor: pointer;
margin-left: -5px;
}
}
}
</style>
......@@ -54,35 +54,31 @@
<el-row>
<el-divider content-position="left">维度列</el-divider>
<el-col>
<div style="height: 90px; border: 1px dashed #999; margin: 0 10px;">
<draggable group="col" :list="dimensionList">
<div v-for="(item, index) in dimensionList" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</el-tag>
<span v-if="item.input" class="draggable-item-handle">
<el-input v-model="item.alias" size="mini" placeholder="请输入内容" @blur="handleDelTagLabel(index, item)" />
</span>
<span v-else class="draggable-item-handle" @click="handleTagLabel(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleDimensionTagClose(index, item)"><i class="el-icon-delete" /></span>
</div>
</draggable>
</div>
<draggable group="col" :list="dimensionList" class="draggable-wrapper">
<div v-for="(item, index) in dimensionList" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</el-tag>
<span v-if="item.input" class="draggable-item-handle">
<el-input v-model="item.alias" size="mini" placeholder="请输入内容" @blur="handleDelTagLabel(index, item)" />
</span>
<span v-else class="draggable-item-handle" @click="handleTagLabel(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleDimensionTagClose(index, item)"><i class="el-icon-delete" /></span>
</div>
</draggable>
</el-col>
</el-row>
<el-row>
<el-divider content-position="left">指标列</el-divider>
<el-col>
<div style="height: 90px; border: 1px dashed #999; margin: 0 10px;">
<draggable group="col" :list="measureList">
<div v-for="(item, index) in measureList" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</el-tag>
<span v-if="item.input" class="draggable-item-handle">
<el-input v-model="item.alias" size="mini" placeholder="请输入内容" @blur="handleDelTagLabel(index, item)" />
</span>
<span v-else class="draggable-item-handle" @click="handleTagLabel(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleMeasureTagClose(index, item)"><i class="el-icon-delete" /></span>
</div>
</draggable>
</div>
<draggable group="col" :list="measureList" class="draggable-wrapper">
<div v-for="(item, index) in measureList" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</el-tag>
<span v-if="item.input" class="draggable-item-handle">
<el-input v-model="item.alias" size="mini" placeholder="请输入内容" @blur="handleDelTagLabel(index, item)" />
</span>
<span v-else class="draggable-item-handle" @click="handleTagLabel(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleMeasureTagClose(index, item)"><i class="el-icon-delete" /></span>
</div>
</draggable>
</el-col>
</el-row>
</el-col>
......@@ -381,29 +377,36 @@ export default {
margin: 10px;
cursor: move;
}
.draggable-item {
cursor: move;
margin: 5px 5px;
display: inline-block;
border: 1px solid #ebecef;
height: 32px;
line-height: 30px;
border-radius: 4px;
.draggable-item-handle {
background-color: #ecf5ff;
border-color: #d9ecff;
.draggable-wrapper {
height: 90px;
border: 1px dashed #999;
margin: 0 10px;
overflow-x: hidden;
overflow-y: auto;
.draggable-item {
cursor: move;
margin: 5px 5px;
display: inline-block;
border: 1px solid #ebecef;
height: 32px;
padding: 0 10px;
line-height: 30px;
font-size: 12px;
color: #409EFF;
border-width: 1px;
border-style: solid;
box-sizing: border-box;
white-space: nowrap;
cursor: pointer;
margin-left: -5px;
border-radius: 4px;
.draggable-item-handle {
background-color: #ecf5ff;
border-color: #d9ecff;
display: inline-block;
height: 32px;
padding: 0 10px;
line-height: 30px;
font-size: 12px;
color: #409EFF;
border-width: 1px;
border-style: solid;
box-sizing: border-box;
white-space: nowrap;
cursor: pointer;
margin-left: -5px;
}
}
}
</style>
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