forked from github/dataease
Merge branch 'dev-v2' into heatmap
This commit is contained in:
commit
4b492d29ca
@ -1,6 +1,6 @@
|
|||||||
FROM registry.cn-qingdao.aliyuncs.com/dataease/alpine-openjdk17-jre
|
FROM registry.cn-qingdao.aliyuncs.com/dataease/alpine-openjdk21-jre
|
||||||
|
|
||||||
RUN mkdir -p /opt/apps/config /opt/dataease2.0/drivers/ /opt/dataease2.0/cache/ /opt/dataease2.0/data/map /opt/dataease2.0/data/static-resource/ /opt/dataease2.0/data/appearance/
|
RUN mkdir -p /opt/apps/config /opt/dataease2.0/drivers/ /opt/dataease2.0/cache/ /opt/dataease2.0/data/map /opt/dataease2.0/data/static-resource/ /opt/dataease2.0/data/appearance/ /opt/dataease2.0/data/exportData/
|
||||||
|
|
||||||
ADD drivers/* /opt/dataease2.0/drivers/
|
ADD drivers/* /opt/dataease2.0/drivers/
|
||||||
ADD mapFiles/ /opt/dataease2.0/data/map/
|
ADD mapFiles/ /opt/dataease2.0/data/map/
|
||||||
@ -11,8 +11,9 @@ WORKDIR /opt/apps
|
|||||||
ADD core/core-backend/target/CoreApplication.jar /opt/apps/app.jar
|
ADD core/core-backend/target/CoreApplication.jar /opt/apps/app.jar
|
||||||
|
|
||||||
ENV JAVA_APP_JAR=/opt/apps/app.jar
|
ENV JAVA_APP_JAR=/opt/apps/app.jar
|
||||||
|
ENV RUNNING_PORT=8100
|
||||||
ENV JAVA_OPTIONS="-Dfile.encoding=utf-8 -Dloader.path=/opt/apps -Dspring.config.additional-location=/opt/apps/config/"
|
ENV JAVA_OPTIONS="-Dfile.encoding=utf-8 -Dloader.path=/opt/apps -Dspring.config.additional-location=/opt/apps/config/"
|
||||||
|
|
||||||
HEALTHCHECK --interval=15s --timeout=5s --retries=20 --start-period=30s CMD nc -zv 127.0.0.1 8100
|
HEALTHCHECK --interval=15s --timeout=5s --retries=20 --start-period=30s CMD nc -zv 127.0.0.1 $RUNNING_PORT
|
||||||
|
|
||||||
CMD ["/deployments/run-java.sh"]
|
CMD ["/deployments/run-java.sh"]
|
||||||
|
@ -48,6 +48,10 @@
|
|||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
<classifier>de</classifier>
|
<classifier>de</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
@ -83,6 +87,10 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fit2cloud</groupId>
|
<groupId>com.fit2cloud</groupId>
|
||||||
<artifactId>quartz-spring-boot-starter</artifactId>
|
<artifactId>quartz-spring-boot-starter</artifactId>
|
||||||
|
@ -5,13 +5,16 @@ import io.dataease.api.chart.dto.ChartViewDTO;
|
|||||||
import io.dataease.api.chart.dto.ViewDetailField;
|
import io.dataease.api.chart.dto.ViewDetailField;
|
||||||
import io.dataease.api.chart.request.ChartExcelRequest;
|
import io.dataease.api.chart.request.ChartExcelRequest;
|
||||||
import io.dataease.chart.manage.ChartDataManage;
|
import io.dataease.chart.manage.ChartDataManage;
|
||||||
|
import io.dataease.constant.AuthConstant;
|
||||||
import io.dataease.constant.CommonConstants;
|
import io.dataease.constant.CommonConstants;
|
||||||
import io.dataease.engine.constant.DeTypeConstants;
|
import io.dataease.engine.constant.DeTypeConstants;
|
||||||
import io.dataease.exception.DEException;
|
import io.dataease.exception.DEException;
|
||||||
|
import io.dataease.exportCenter.manage.ExportCenterManage;
|
||||||
import io.dataease.result.ResultCode;
|
import io.dataease.result.ResultCode;
|
||||||
import io.dataease.utils.LogUtil;
|
import io.dataease.utils.LogUtil;
|
||||||
import io.dataease.visualization.manage.VisualizationTemplateExtendDataManage;
|
import io.dataease.visualization.manage.VisualizationTemplateExtendDataManage;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
@ -22,12 +25,13 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,10 +42,11 @@ import java.util.stream.Collectors;
|
|||||||
public class ChartDataServer implements ChartDataApi {
|
public class ChartDataServer implements ChartDataApi {
|
||||||
@Resource
|
@Resource
|
||||||
private ChartDataManage chartDataManage;
|
private ChartDataManage chartDataManage;
|
||||||
|
@Resource
|
||||||
|
private ExportCenterManage exportCenterManage;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private VisualizationTemplateExtendDataManage extendDataManage;
|
private VisualizationTemplateExtendDataManage extendDataManage;
|
||||||
|
|
||||||
@Value("${export.views.limit:500000}")
|
@Value("${export.views.limit:500000}")
|
||||||
private Integer limit;
|
private Integer limit;
|
||||||
|
|
||||||
@ -76,6 +81,12 @@ public class ChartDataServer implements ChartDataApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void innerExportDetails(ChartExcelRequest request, HttpServletResponse response) throws Exception {
|
public void innerExportDetails(ChartExcelRequest request, HttpServletResponse response) throws Exception {
|
||||||
|
HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||||
|
String linkToken = httpServletRequest.getHeader(AuthConstant.LINK_TOKEN_KEY);
|
||||||
|
if (StringUtils.isEmpty(linkToken)) {
|
||||||
|
exportCenterManage.addTask(request.getViewId(), "chart", request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
OutputStream outputStream = response.getOutputStream();
|
OutputStream outputStream = response.getOutputStream();
|
||||||
try {
|
try {
|
||||||
findExcelData(request);
|
findExcelData(request);
|
||||||
|
@ -207,7 +207,7 @@ public class DatasetDataManage {
|
|||||||
Order2SQLObj.getOrders(sqlMeta, fields, datasetGroupInfoDTO.getSortFields(), crossDs, dsMap);
|
Order2SQLObj.getOrders(sqlMeta, fields, datasetGroupInfoDTO.getSortFields(), crossDs, dsMap);
|
||||||
String querySQL;
|
String querySQL;
|
||||||
if (start == null || count == null) {
|
if (start == null || count == null) {
|
||||||
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, false, needOrder);
|
querySQL = SQLProvider.createQuerySQL(sqlMeta, false, needOrder, false);
|
||||||
} else {
|
} else {
|
||||||
querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, false, start, count);
|
querySQL = SQLProvider.createQuerySQLWithLimit(sqlMeta, false, needOrder, false, start, count);
|
||||||
}
|
}
|
||||||
@ -231,7 +231,7 @@ public class DatasetDataManage {
|
|||||||
map.put("allFields", fieldList);
|
map.put("allFields", fieldList);
|
||||||
}
|
}
|
||||||
map.put("sql", Base64.getEncoder().encodeToString(querySQL.getBytes()));
|
map.put("sql", Base64.getEncoder().encodeToString(querySQL.getBytes()));
|
||||||
String replaceSql = SqlUtils.rebuildSQL(SQLProvider.createQuerySQL(sqlMeta, false, false, needOrder), sqlMeta, crossDs, dsMap);
|
String replaceSql = SqlUtils.rebuildSQL(SQLProvider.createQuerySQL(sqlMeta, false, false, false), sqlMeta, crossDs, dsMap);
|
||||||
map.put("total", getDatasetTotal(datasetGroupInfoDTO, replaceSql, null));
|
map.put("total", getDatasetTotal(datasetGroupInfoDTO, replaceSql, null));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
@ -220,11 +220,12 @@ public class PermissionManage {
|
|||||||
|
|
||||||
private String handleSysVariable(UserFormVO userEntity, String sysVariable) {
|
private String handleSysVariable(UserFormVO userEntity, String sysVariable) {
|
||||||
String value = null;
|
String value = null;
|
||||||
System.out.println(sysVariable);
|
|
||||||
System.out.println(JsonUtil.toJSONString(userEntity));
|
|
||||||
if (StringUtils.isNotBlank(sysVariable) && sysVariable.startsWith("${") && sysVariable.endsWith("}")) {
|
if (StringUtils.isNotBlank(sysVariable) && sysVariable.startsWith("${") && sysVariable.endsWith("}")) {
|
||||||
String variableId = sysVariable.substring(2, sysVariable.length() - 1);
|
String variableId = sysVariable.substring(2, sysVariable.length() - 1);
|
||||||
for (SysVariableValueItem variable : userEntity.getVariables()) {
|
for (SysVariableValueItem variable : userEntity.getVariables()) {
|
||||||
|
if (!variable.isValid()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (variableId.equalsIgnoreCase(variable.getVariableId().toString())) {
|
if (variableId.equalsIgnoreCase(variable.getVariableId().toString())) {
|
||||||
if (variable.getSysVariableDto().getType().equalsIgnoreCase("text")) {
|
if (variable.getSysVariableDto().getType().equalsIgnoreCase("text")) {
|
||||||
for (SysVariableValueDto sysVariableValueDto : variable.getValueList()) {
|
for (SysVariableValueDto sysVariableValueDto : variable.getValueList()) {
|
||||||
|
@ -932,9 +932,9 @@ public class CalciteProvider {
|
|||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
if (StringUtils.isNotBlank(configuration.getUsername())) {
|
||||||
props.setProperty("user", configuration.getUsername());
|
props.setProperty("user", configuration.getUsername());
|
||||||
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
}
|
||||||
props.setProperty("password", configuration.getPassword());
|
if (StringUtils.isNotBlank(configuration.getPassword())) {
|
||||||
}
|
props.setProperty("password", configuration.getPassword());
|
||||||
}
|
}
|
||||||
String driverClassName = configuration.getDriver();
|
String driverClassName = configuration.getDriver();
|
||||||
ExtendedJdbcClassLoader jdbcClassLoader = extendedJdbcClassLoader;
|
ExtendedJdbcClassLoader jdbcClassLoader = extendedJdbcClassLoader;
|
||||||
|
@ -7,7 +7,7 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public class SQLUtils {
|
public class SQLUtils {
|
||||||
public static String transKeyword(String value) {
|
public static String transKeyword(String value) {
|
||||||
return Optional.ofNullable(value).orElse("").replaceAll("'", "\\\\'");
|
return Optional.ofNullable(value).orElse("").replaceAll("'", "''");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String buildOriginPreviewSql(String sql, int limit, int offset) {
|
public static String buildOriginPreviewSql(String sql, int limit, int offset) {
|
||||||
|
@ -68,7 +68,8 @@ public class Utils {
|
|||||||
String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), ele.getDataeaseName()));
|
String.format(SQLConstants.FIELD_NAME, tableObj.getTableAlias(), ele.getDataeaseName()));
|
||||||
} else {
|
} else {
|
||||||
originField = originField.replaceAll("\\[" + ele.getId() + "]",
|
originField = originField.replaceAll("\\[" + ele.getId() + "]",
|
||||||
tableObj.getTableAlias() + "." + datasourceType.getPrefix() + ele.getDataeaseName() + datasourceType.getSuffix());
|
datasourceType.getPrefix() + tableObj.getTableAlias() + datasourceType.getSuffix() +
|
||||||
|
"." + datasourceType.getPrefix() + ele.getDataeaseName() + datasourceType.getSuffix());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
originField = originField.replaceAll("\\[" + ele.getId() + "]", "(" + ele.getOriginName() + ")");
|
originField = originField.replaceAll("\\[" + ele.getId() + "]", "(" + ele.getOriginName() + ")");
|
||||||
|
BIN
core/core-backend/src/main/java/io/dataease/exportCenter/.DS_Store
vendored
Normal file
BIN
core/core-backend/src/main/java/io/dataease/exportCenter/.DS_Store
vendored
Normal file
Binary file not shown.
@ -0,0 +1,159 @@
|
|||||||
|
package io.dataease.exportCenter.dao.auto.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 导出任务表
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author fit2cloud
|
||||||
|
* @since 2024-05-23
|
||||||
|
*/
|
||||||
|
@TableName("core_export_task")
|
||||||
|
public class CoreExportTask implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
private Double fileSize;
|
||||||
|
|
||||||
|
private String fileSizeUnit;
|
||||||
|
|
||||||
|
private String exportFrom;
|
||||||
|
|
||||||
|
private String exportStatus;
|
||||||
|
|
||||||
|
private String exportFromType;
|
||||||
|
|
||||||
|
private Long exportTime;
|
||||||
|
|
||||||
|
private String exportProgress;
|
||||||
|
|
||||||
|
private String exportMachineName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤参数
|
||||||
|
*/
|
||||||
|
private String params;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(Long userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileSize(Double fileSize) {
|
||||||
|
this.fileSize = fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileSizeUnit() {
|
||||||
|
return fileSizeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileSizeUnit(String fileSizeUnit) {
|
||||||
|
this.fileSizeUnit = fileSizeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExportFrom() {
|
||||||
|
return exportFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportFrom(String exportFrom) {
|
||||||
|
this.exportFrom = exportFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExportStatus() {
|
||||||
|
return exportStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportStatus(String exportStatus) {
|
||||||
|
this.exportStatus = exportStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExportFromType() {
|
||||||
|
return exportFromType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportFromType(String exportFromType) {
|
||||||
|
this.exportFromType = exportFromType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getExportTime() {
|
||||||
|
return exportTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportTime(Long exportTime) {
|
||||||
|
this.exportTime = exportTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExportProgress() {
|
||||||
|
return exportProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportProgress(String exportProgress) {
|
||||||
|
this.exportProgress = exportProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExportMachineName() {
|
||||||
|
return exportMachineName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportMachineName(String exportMachineName) {
|
||||||
|
this.exportMachineName = exportMachineName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParams() {
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParams(String params) {
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CoreExportTask{" +
|
||||||
|
"id = " + id +
|
||||||
|
", userId = " + userId +
|
||||||
|
", fileName = " + fileName +
|
||||||
|
", fileSize = " + fileSize +
|
||||||
|
", fileSizeUnit = " + fileSizeUnit +
|
||||||
|
", exportFrom = " + exportFrom +
|
||||||
|
", exportStatus = " + exportStatus +
|
||||||
|
", exportFromType = " + exportFromType +
|
||||||
|
", exportTime = " + exportTime +
|
||||||
|
", exportProgress = " + exportProgress +
|
||||||
|
", exportMachineName = " + exportMachineName +
|
||||||
|
", params = " + params +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package io.dataease.exportCenter.dao.auto.mapper;
|
||||||
|
|
||||||
|
import io.dataease.exportCenter.dao.auto.entity.CoreExportTask;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 导出任务表 Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author fit2cloud
|
||||||
|
* @since 2024-05-23
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CoreExportTaskMapper extends BaseMapper<CoreExportTask> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,413 @@
|
|||||||
|
package io.dataease.exportCenter.manage;
|
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import io.dataease.api.chart.dto.ViewDetailField;
|
||||||
|
import io.dataease.api.chart.request.ChartExcelRequest;
|
||||||
|
import io.dataease.api.exportCenter.vo.ExportTaskDTO;
|
||||||
|
import io.dataease.auth.bo.TokenUserBO;
|
||||||
|
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
|
||||||
|
import io.dataease.chart.server.ChartDataServer;
|
||||||
|
import io.dataease.engine.constant.DeTypeConstants;
|
||||||
|
import io.dataease.exception.DEException;
|
||||||
|
import io.dataease.exportCenter.dao.auto.entity.CoreExportTask;
|
||||||
|
import io.dataease.exportCenter.dao.auto.mapper.CoreExportTaskMapper;
|
||||||
|
import io.dataease.utils.*;
|
||||||
|
import io.dataease.visualization.server.DataVisualizationServer;
|
||||||
|
import io.dataease.websocket.WsMessage;
|
||||||
|
import io.dataease.websocket.WsService;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class ExportCenterManage {
|
||||||
|
@Resource
|
||||||
|
private CoreExportTaskMapper exportTaskMapper;
|
||||||
|
@Resource
|
||||||
|
DataVisualizationServer dataVisualizationServer;
|
||||||
|
@Resource
|
||||||
|
private CoreChartViewMapper coreChartViewMapper;
|
||||||
|
@Autowired
|
||||||
|
private WsService wsService;
|
||||||
|
|
||||||
|
@Value("${export.dataset.limit:100000}")
|
||||||
|
private int limit;
|
||||||
|
private final static String DATA_URL_TITLE = "data:image/jpeg;base64,";
|
||||||
|
private static final String exportData_path = "/opt/dataease2.0/data/exportData/";
|
||||||
|
@Value("${extract.page.size:50000}")
|
||||||
|
private Integer extractPageSize;
|
||||||
|
static private List<String> STATUS = Arrays.asList("SUCCESS", "FAILED", "PENDING", "IN_PROGRESS", "ALL");
|
||||||
|
private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
|
||||||
|
private int corePoolSize = 10;
|
||||||
|
private int keepAliveSeconds = 600;
|
||||||
|
private Map<String, Future> Running_Task = new HashMap<>();
|
||||||
|
@Resource
|
||||||
|
private ChartDataServer chartDataServer;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(corePoolSize);
|
||||||
|
scheduledThreadPoolExecutor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(fixedRate = 5000)
|
||||||
|
public void checkRunningTask() {
|
||||||
|
Iterator<Map.Entry<String, Future>> iterator = Running_Task.entrySet().iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry<String, Future> entry = iterator.next();
|
||||||
|
if (entry.getValue().isDone()) {
|
||||||
|
iterator.remove();
|
||||||
|
try {
|
||||||
|
CoreExportTask exportTask = exportTaskMapper.selectById(entry.getKey());
|
||||||
|
ExportTaskDTO exportTaskDTO = new ExportTaskDTO();
|
||||||
|
BeanUtils.copyBean(exportTaskDTO, exportTask);
|
||||||
|
setExportFromName(exportTaskDTO);
|
||||||
|
WsMessage message = new WsMessage(exportTask.getUserId(), "/task-export-topic", exportTaskDTO);
|
||||||
|
wsService.releaseMessage(message);
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void download(String id, HttpServletResponse response) throws Exception {
|
||||||
|
CoreExportTask exportTask = exportTaskMapper.selectById(id);
|
||||||
|
OutputStream outputStream = response.getOutputStream();
|
||||||
|
response.setContentType("application/vnd.ms-excel");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename=" + exportTask.getFileName());
|
||||||
|
InputStream fileInputStream = new FileInputStream(exportData_path + id + "/" + exportTask.getFileName());
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
fileInputStream.close();
|
||||||
|
response.flushBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(String id) {
|
||||||
|
Iterator<Map.Entry<String, Future>> iterator = Running_Task.entrySet().iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry<String, Future> entry = iterator.next();
|
||||||
|
if (entry.getKey().equalsIgnoreCase(id)) {
|
||||||
|
entry.getValue().cancel(true);
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FileUtils.deleteDirectoryRecursively(exportData_path + id);
|
||||||
|
exportTaskMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAll(String type) {
|
||||||
|
if (!STATUS.contains(type)) {
|
||||||
|
DEException.throwException("无效的状态");
|
||||||
|
}
|
||||||
|
QueryWrapper<CoreExportTask> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("user_id", AuthUtils.getUser().getUserId());
|
||||||
|
if (!type.equalsIgnoreCase("ALL")) {
|
||||||
|
queryWrapper.eq("export_status", type);
|
||||||
|
}
|
||||||
|
List<CoreExportTask> exportTasks = exportTaskMapper.selectList(queryWrapper);
|
||||||
|
exportTasks.parallelStream().forEach(exportTask -> {
|
||||||
|
Iterator<Map.Entry<String, Future>> iterator = Running_Task.entrySet().iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry<String, Future> entry = iterator.next();
|
||||||
|
if (entry.getKey().equalsIgnoreCase(exportTask.getId())) {
|
||||||
|
entry.getValue().cancel(true);
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FileUtils.deleteDirectoryRecursively(exportData_path + exportTask.getId());
|
||||||
|
exportTaskMapper.deleteById(exportTask.getId());
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(List<String> ids) {
|
||||||
|
ids.forEach(this::delete);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void retry(String id) {
|
||||||
|
CoreExportTask exportTask = exportTaskMapper.selectById(id);
|
||||||
|
exportTask.setExportStatus("PENDING");
|
||||||
|
exportTask.setExportProgress("0");
|
||||||
|
exportTask.setExportMachineName(hostName());
|
||||||
|
exportTask.setExportTime(System.currentTimeMillis());
|
||||||
|
exportTaskMapper.updateById(exportTask);
|
||||||
|
FileUtils.deleteDirectoryRecursively(exportData_path + id);
|
||||||
|
if (exportTask.getExportFromType().equalsIgnoreCase("chart")) {
|
||||||
|
ChartExcelRequest request = JsonUtil.parse(exportTask.getParams(), ChartExcelRequest.class);
|
||||||
|
startViewTask(exportTask, request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ExportTaskDTO> exportTasks(String status) {
|
||||||
|
if (!STATUS.contains(status)) {
|
||||||
|
DEException.throwException("Invalid status: " + status);
|
||||||
|
}
|
||||||
|
QueryWrapper<CoreExportTask> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("user_id", AuthUtils.getUser().getUserId());
|
||||||
|
queryWrapper.orderByDesc("export_time");
|
||||||
|
List<CoreExportTask> exportTasks = exportTaskMapper.selectList(queryWrapper);
|
||||||
|
List<ExportTaskDTO> result = new ArrayList<>();
|
||||||
|
exportTasks.forEach(exportTask -> {
|
||||||
|
ExportTaskDTO exportTaskDTO = new ExportTaskDTO();
|
||||||
|
BeanUtils.copyBean(exportTaskDTO, exportTask);
|
||||||
|
if (status.equalsIgnoreCase("ALL")) {
|
||||||
|
setExportFromAbsName(exportTaskDTO);
|
||||||
|
}
|
||||||
|
if (status.equalsIgnoreCase(exportTaskDTO.getExportStatus())) {
|
||||||
|
setExportFromAbsName(exportTaskDTO);
|
||||||
|
}
|
||||||
|
result.add(exportTaskDTO);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setExportFromAbsName(ExportTaskDTO exportTaskDTO) {
|
||||||
|
if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) {
|
||||||
|
exportTaskDTO.setExportFromName(dataVisualizationServer.getAbsPath(exportTaskDTO.getExportFrom()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setExportFromName(ExportTaskDTO exportTaskDTO) {
|
||||||
|
if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) {
|
||||||
|
exportTaskDTO.setExportFromName(coreChartViewMapper.selectById(exportTaskDTO.getExportFrom()).getTitle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String hostName() {
|
||||||
|
String hostname = null;
|
||||||
|
try {
|
||||||
|
InetAddress localMachine = InetAddress.getLocalHost();
|
||||||
|
hostname = localMachine.getHostName();
|
||||||
|
} catch (Exception e) {
|
||||||
|
DEException.throwException("请设置主机名!");
|
||||||
|
}
|
||||||
|
return hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTask(String exportFrom, String exportFromType, ChartExcelRequest request) {
|
||||||
|
CoreExportTask exportTask = new CoreExportTask();
|
||||||
|
exportTask.setId(UUID.randomUUID().toString());
|
||||||
|
exportTask.setUserId(AuthUtils.getUser().getUserId());
|
||||||
|
exportTask.setExportFrom(exportFrom);
|
||||||
|
exportTask.setExportFromType(exportFromType);
|
||||||
|
exportTask.setExportStatus("PENDING");
|
||||||
|
exportTask.setFileName(request.getViewName() + ".xlsx");
|
||||||
|
exportTask.setExportProgress("0");
|
||||||
|
exportTask.setExportTime(System.currentTimeMillis());
|
||||||
|
exportTask.setParams(JsonUtil.toJSONString(request).toString());
|
||||||
|
exportTask.setExportMachineName(hostName());
|
||||||
|
exportTaskMapper.insert(exportTask);
|
||||||
|
startViewTask(exportTask, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startViewTask(CoreExportTask exportTask, ChartExcelRequest request) {
|
||||||
|
String dataPath = exportData_path + exportTask.getId();
|
||||||
|
File directory = new File(dataPath);
|
||||||
|
boolean isCreated = directory.mkdir();
|
||||||
|
TokenUserBO tokenUserBO = AuthUtils.getUser();
|
||||||
|
Future future = scheduledThreadPoolExecutor.submit(() -> {
|
||||||
|
AuthUtils.setUser(tokenUserBO);
|
||||||
|
try {
|
||||||
|
exportTask.setExportStatus("IN_PROGRESS");
|
||||||
|
exportTaskMapper.updateById(exportTask);
|
||||||
|
chartDataServer.findExcelData(request);
|
||||||
|
List<Object[]> details = request.getDetails();
|
||||||
|
Integer[] excelTypes = request.getExcelTypes();
|
||||||
|
details.add(0, request.getHeader());
|
||||||
|
Workbook wb = new SXSSFWorkbook();
|
||||||
|
//明细sheet
|
||||||
|
Sheet detailsSheet = wb.createSheet("数据");
|
||||||
|
//给单元格设置样式
|
||||||
|
CellStyle cellStyle = wb.createCellStyle();
|
||||||
|
Font font = wb.createFont();
|
||||||
|
//设置字体大小
|
||||||
|
font.setFontHeightInPoints((short) 12);
|
||||||
|
//设置字体加粗
|
||||||
|
font.setBold(true);
|
||||||
|
//给字体设置样式
|
||||||
|
cellStyle.setFont(font);
|
||||||
|
//设置单元格背景颜色
|
||||||
|
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
|
||||||
|
//设置单元格填充样式(使用纯色背景颜色填充)
|
||||||
|
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
|
||||||
|
|
||||||
|
Boolean mergeHead = false;
|
||||||
|
ViewDetailField[] detailFields = request.getDetailFields();
|
||||||
|
if (ArrayUtils.isNotEmpty(detailFields)) {
|
||||||
|
cellStyle.setBorderTop(BorderStyle.THIN);
|
||||||
|
cellStyle.setBorderRight(BorderStyle.THIN);
|
||||||
|
cellStyle.setBorderBottom(BorderStyle.THIN);
|
||||||
|
cellStyle.setBorderLeft(BorderStyle.THIN);
|
||||||
|
String[] detailField = Arrays.stream(detailFields).map(field -> field.getName()).collect(Collectors.toList()).toArray(new String[detailFields.length]);
|
||||||
|
Object[] header = request.getHeader();
|
||||||
|
Row row = detailsSheet.createRow(0);
|
||||||
|
int headLen = header.length;
|
||||||
|
int detailFieldLen = detailField.length;
|
||||||
|
for (int i = 0; i < headLen; i++) {
|
||||||
|
Cell cell = row.createCell(i);
|
||||||
|
cell.setCellValue(header[i].toString());
|
||||||
|
if (i < headLen - 1) {
|
||||||
|
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 1, i, i);
|
||||||
|
detailsSheet.addMergedRegion(cellRangeAddress);
|
||||||
|
} else {
|
||||||
|
for (int j = i + 1; j < detailFieldLen + i; j++) {
|
||||||
|
row.createCell(j).setCellStyle(cellStyle);
|
||||||
|
}
|
||||||
|
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, i, i + detailFieldLen - 1);
|
||||||
|
detailsSheet.addMergedRegion(cellRangeAddress);
|
||||||
|
}
|
||||||
|
cell.setCellStyle(cellStyle);
|
||||||
|
detailsSheet.setColumnWidth(i, 255 * 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
Row detailRow = detailsSheet.createRow(1);
|
||||||
|
for (int i = 0; i < headLen - 1; i++) {
|
||||||
|
Cell cell = detailRow.createCell(i);
|
||||||
|
cell.setCellStyle(cellStyle);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < detailFieldLen; i++) {
|
||||||
|
int colIndex = headLen - 1 + i;
|
||||||
|
Cell cell = detailRow.createCell(colIndex);
|
||||||
|
cell.setCellValue(detailField[i]);
|
||||||
|
cell.setCellStyle(cellStyle);
|
||||||
|
detailsSheet.setColumnWidth(colIndex, 255 * 20);
|
||||||
|
}
|
||||||
|
details.add(1, detailField);
|
||||||
|
mergeHead = true;
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(details) && (!mergeHead || details.size() > 2)) {
|
||||||
|
int realDetailRowIndex = 2;
|
||||||
|
for (int i = (mergeHead ? 2 : 0); i < details.size(); i++) {
|
||||||
|
Row row = detailsSheet.createRow(realDetailRowIndex > 2 ? realDetailRowIndex : i);
|
||||||
|
Object[] rowData = details.get(i);
|
||||||
|
if (rowData != null) {
|
||||||
|
for (int j = 0; j < rowData.length; j++) {
|
||||||
|
Object cellValObj = rowData[j];
|
||||||
|
if (mergeHead && j == rowData.length - 1 && (cellValObj.getClass().isArray() || cellValObj instanceof ArrayList)) {
|
||||||
|
Object[] detailRowArray = ((List<Object>) cellValObj).toArray(new Object[((List<?>) cellValObj).size()]);
|
||||||
|
int detailRowArrayLen = detailRowArray.length;
|
||||||
|
int temlJ = j;
|
||||||
|
while (detailRowArrayLen > 1 && temlJ-- > 0) {
|
||||||
|
CellRangeAddress cellRangeAddress = new CellRangeAddress(realDetailRowIndex, realDetailRowIndex + detailRowArrayLen - 1, temlJ, temlJ);
|
||||||
|
detailsSheet.addMergedRegion(cellRangeAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < detailRowArrayLen; k++) {
|
||||||
|
List<Object> detailRows = (List<Object>) detailRowArray[k];
|
||||||
|
Row curRow = row;
|
||||||
|
if (k > 0) {
|
||||||
|
curRow = detailsSheet.createRow(realDetailRowIndex + k);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int l = 0; l < detailRows.size(); l++) {
|
||||||
|
Object col = detailRows.get(l);
|
||||||
|
Cell cell = curRow.createCell(j + l);
|
||||||
|
cell.setCellValue(col.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
realDetailRowIndex += detailRowArrayLen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cell cell = row.createCell(j);
|
||||||
|
if (i == 0) {// 头部
|
||||||
|
cell.setCellValue(cellValObj.toString());
|
||||||
|
cell.setCellStyle(cellStyle);
|
||||||
|
//设置列的宽度
|
||||||
|
detailsSheet.setColumnWidth(j, 255 * 20);
|
||||||
|
} else if (cellValObj != null) {
|
||||||
|
try {
|
||||||
|
// with DataType
|
||||||
|
if ((excelTypes[j].equals(DeTypeConstants.DE_INT) || excelTypes[j].equals(DeTypeConstants.DE_FLOAT)) && StringUtils.isNotEmpty(cellValObj.toString())) {
|
||||||
|
cell.setCellValue(Double.valueOf(cellValObj.toString()));
|
||||||
|
} else {
|
||||||
|
cell.setCellValue(cellValObj.toString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.warn("export excel data transform error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try (FileOutputStream outputStream = new FileOutputStream(dataPath + "/" + request.getViewName() + ".xlsx")) {
|
||||||
|
wb.write(outputStream);
|
||||||
|
outputStream.flush();
|
||||||
|
}
|
||||||
|
wb.close();
|
||||||
|
|
||||||
|
exportTask.setExportProgress("100");
|
||||||
|
exportTask.setExportStatus("SUCCESS");
|
||||||
|
setFileSize(dataPath + "/" + request.getViewName() + ".xlsx", exportTask);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
LogUtil.error("Failed to export data", e);
|
||||||
|
exportTask.setExportStatus("FAILED");
|
||||||
|
} finally {
|
||||||
|
exportTaskMapper.updateById(exportTask);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Running_Task.put(exportTask.getId(), future);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void setFileSize(String filePath, CoreExportTask exportTask) {
|
||||||
|
File file = new File(filePath);
|
||||||
|
long length = file.length();
|
||||||
|
String unit = "Mb";
|
||||||
|
Double size = 0.0;
|
||||||
|
if ((double) length / 1024 / 1024 > 1) {
|
||||||
|
if ((double) length / 1024 / 1024 / 1024 > 1) {
|
||||||
|
unit = "Gb";
|
||||||
|
size = Double.valueOf(String.format("%.2f", (double) length / 1024 / 1024 / 1024));
|
||||||
|
} else {
|
||||||
|
size = Double.valueOf(String.format("%.2f", (double) length / 1024 / 1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
unit = "Kb";
|
||||||
|
size = Double.valueOf(String.format("%.2f", (double) length / 1024));
|
||||||
|
}
|
||||||
|
exportTask.setFileSize(size);
|
||||||
|
exportTask.setFileSizeUnit(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final String LOG_RETENTION = "30";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
package io.dataease.exportCenter.server;
|
||||||
|
|
||||||
|
import io.dataease.api.exportCenter.ExportCenterApi;
|
||||||
|
import io.dataease.api.exportCenter.vo.ExportTaskDTO;
|
||||||
|
import io.dataease.exportCenter.manage.ExportCenterManage;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/exportCenter")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class ExportCenterServer implements ExportCenterApi {
|
||||||
|
@Resource
|
||||||
|
private ExportCenterManage exportCenterManage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ExportTaskDTO> exportTasks(String status) {
|
||||||
|
return exportCenterManage.exportTasks(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(String id) {
|
||||||
|
exportCenterManage.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(List<String> ids) {
|
||||||
|
exportCenterManage.delete(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAll(String type) {
|
||||||
|
exportCenterManage.deleteAll(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void download(String id, HttpServletResponse response) throws Exception {
|
||||||
|
exportCenterManage.download(id, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retry(String id) {
|
||||||
|
exportCenterManage.retry(id);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package io.dataease.home;
|
|||||||
|
|
||||||
import io.dataease.utils.ModelUtils;
|
import io.dataease.utils.ModelUtils;
|
||||||
import io.dataease.utils.RsaUtils;
|
import io.dataease.utils.RsaUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
@ -11,6 +12,9 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RequestMapping
|
@RequestMapping
|
||||||
public class RestIndexController {
|
public class RestIndexController {
|
||||||
|
|
||||||
|
@Value("${dataease.xpack-front-distributed:false}")
|
||||||
|
private boolean xpackFrontDistributed;
|
||||||
|
|
||||||
@GetMapping("/dekey")
|
@GetMapping("/dekey")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String dekey() {
|
public String dekey() {
|
||||||
@ -23,4 +27,11 @@ public class RestIndexController {
|
|||||||
return ModelUtils.isDesktop();
|
return ModelUtils.isDesktop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/xpackModel")
|
||||||
|
@ResponseBody
|
||||||
|
public boolean xpackModel() {
|
||||||
|
return xpackFrontDistributed;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ public class XpackShareManage {
|
|||||||
return pos.stream().map(po ->
|
return pos.stream().map(po ->
|
||||||
new XpackShareGridVO(
|
new XpackShareGridVO(
|
||||||
po.getShareId(), po.getResourceId(), po.getName(), po.getCreator().toString(),
|
po.getShareId(), po.getResourceId(), po.getName(), po.getCreator().toString(),
|
||||||
po.getTime(), po.getExp(), 9,po.getExtFlag())).toList();
|
po.getTime(), po.getExp(), 9,po.getExtFlag(),po.getType())).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private XpackShareManage proxy() {
|
private XpackShareManage proxy() {
|
||||||
|
@ -13,6 +13,7 @@ import io.dataease.api.visualization.vo.DataVisualizationVO;
|
|||||||
import io.dataease.api.visualization.vo.VisualizationResourceVO;
|
import io.dataease.api.visualization.vo.VisualizationResourceVO;
|
||||||
import io.dataease.api.visualization.vo.VisualizationWatermarkVO;
|
import io.dataease.api.visualization.vo.VisualizationWatermarkVO;
|
||||||
import io.dataease.chart.dao.auto.entity.CoreChartView;
|
import io.dataease.chart.dao.auto.entity.CoreChartView;
|
||||||
|
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
|
||||||
import io.dataease.chart.manage.ChartDataManage;
|
import io.dataease.chart.manage.ChartDataManage;
|
||||||
import io.dataease.chart.manage.ChartViewManege;
|
import io.dataease.chart.manage.ChartViewManege;
|
||||||
import io.dataease.commons.constants.DataVisualizationConstants;
|
import io.dataease.commons.constants.DataVisualizationConstants;
|
||||||
@ -30,10 +31,7 @@ import io.dataease.template.dao.auto.entity.VisualizationTemplateExtendData;
|
|||||||
import io.dataease.template.dao.auto.mapper.VisualizationTemplateExtendDataMapper;
|
import io.dataease.template.dao.auto.mapper.VisualizationTemplateExtendDataMapper;
|
||||||
import io.dataease.template.dao.auto.mapper.VisualizationTemplateMapper;
|
import io.dataease.template.dao.auto.mapper.VisualizationTemplateMapper;
|
||||||
import io.dataease.template.manage.TemplateCenterManage;
|
import io.dataease.template.manage.TemplateCenterManage;
|
||||||
import io.dataease.utils.AuthUtils;
|
import io.dataease.utils.*;
|
||||||
import io.dataease.utils.BeanUtils;
|
|
||||||
import io.dataease.utils.IDUtils;
|
|
||||||
import io.dataease.utils.JsonUtil;
|
|
||||||
import io.dataease.visualization.dao.auto.entity.DataVisualizationInfo;
|
import io.dataease.visualization.dao.auto.entity.DataVisualizationInfo;
|
||||||
import io.dataease.visualization.dao.auto.entity.VisualizationWatermark;
|
import io.dataease.visualization.dao.auto.entity.VisualizationWatermark;
|
||||||
import io.dataease.visualization.dao.auto.mapper.DataVisualizationInfoMapper;
|
import io.dataease.visualization.dao.auto.mapper.DataVisualizationInfoMapper;
|
||||||
@ -41,6 +39,7 @@ import io.dataease.visualization.dao.auto.mapper.VisualizationWatermarkMapper;
|
|||||||
import io.dataease.visualization.dao.ext.mapper.ExtDataVisualizationMapper;
|
import io.dataease.visualization.dao.ext.mapper.ExtDataVisualizationMapper;
|
||||||
import io.dataease.visualization.manage.CoreVisualizationManage;
|
import io.dataease.visualization.manage.CoreVisualizationManage;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
@ -48,10 +47,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@ -64,6 +60,8 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ChartViewManege chartViewManege;
|
private ChartViewManege chartViewManege;
|
||||||
|
@Resource
|
||||||
|
private CoreChartViewMapper coreChartViewMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ExtDataVisualizationMapper extDataVisualizationMapper;
|
private ExtDataVisualizationMapper extDataVisualizationMapper;
|
||||||
@ -327,6 +325,15 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
|||||||
Map<Long, VisualizationTemplateExtendDataDTO> extendDataInfo = new HashMap<>();
|
Map<Long, VisualizationTemplateExtendDataDTO> extendDataInfo = new HashMap<>();
|
||||||
for (Map.Entry<String, String> entry : dynamicDataMap.entrySet()) {
|
for (Map.Entry<String, String> entry : dynamicDataMap.entrySet()) {
|
||||||
String originViewId = entry.getKey();
|
String originViewId = entry.getKey();
|
||||||
|
Object viewInfo = entry.getValue();
|
||||||
|
try{
|
||||||
|
// 旧模板图表过滤器适配
|
||||||
|
if(viewInfo instanceof Map && ((Map)viewInfo).get("customFilter") instanceof ArrayList){
|
||||||
|
((Map)viewInfo).put("customFilter",new HashMap<>());
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
LogUtil.error("History Adaptor Error",e);
|
||||||
|
}
|
||||||
String originViewData = JsonUtil.toJSONString(entry.getValue()).toString();
|
String originViewData = JsonUtil.toJSONString(entry.getValue()).toString();
|
||||||
ChartViewDTO chartView = JsonUtil.parseObject(originViewData, ChartViewDTO.class);
|
ChartViewDTO chartView = JsonUtil.parseObject(originViewData, ChartViewDTO.class);
|
||||||
if (chartView == null) {
|
if (chartView == null) {
|
||||||
@ -391,4 +398,42 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAbsPath(String id) {
|
||||||
|
CoreChartView coreChartView = coreChartViewMapper.selectById(id);
|
||||||
|
if (coreChartView == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (coreChartView.getSceneId() == null) {
|
||||||
|
return coreChartView.getTitle();
|
||||||
|
}
|
||||||
|
List<DataVisualizationInfo> parents = getParents(coreChartView.getSceneId());
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
parents.forEach(ele -> {
|
||||||
|
if (ObjectUtils.isNotEmpty(ele)) {
|
||||||
|
stringBuilder.append(ele.getName()).append("/");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
stringBuilder.append(coreChartView.getTitle());
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DataVisualizationInfo> getParents(Long id) {
|
||||||
|
List<DataVisualizationInfo> list = new ArrayList<>();
|
||||||
|
DataVisualizationInfo dataVisualizationInfo = visualizationInfoMapper.selectById(id);
|
||||||
|
list.add(dataVisualizationInfo);
|
||||||
|
getParent(list, dataVisualizationInfo);
|
||||||
|
Collections.reverse(list);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getParent(List<DataVisualizationInfo> list, DataVisualizationInfo dataVisualizationInfo) {
|
||||||
|
if (ObjectUtils.isNotEmpty(dataVisualizationInfo)) {
|
||||||
|
if (dataVisualizationInfo.getPid() != null) {
|
||||||
|
DataVisualizationInfo d = visualizationInfoMapper.selectById(dataVisualizationInfo.getPid());
|
||||||
|
list.add(d);
|
||||||
|
getParent(list, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
BIN
core/core-backend/src/main/java/io/dataease/websocket/.DS_Store
vendored
Normal file
BIN
core/core-backend/src/main/java/io/dataease/websocket/.DS_Store
vendored
Normal file
Binary file not shown.
@ -0,0 +1,33 @@
|
|||||||
|
package io.dataease.websocket.aop;
|
||||||
|
|
||||||
|
import io.dataease.websocket.WsMessage;
|
||||||
|
import io.dataease.websocket.WsService;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.AfterReturning;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class WSTrigger {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WsService wsService;
|
||||||
|
|
||||||
|
@AfterReturning(value = "execution(* io.dataease.service.message.service.strategy.SendStation.sendMsg(..))")
|
||||||
|
public void after(JoinPoint point) {
|
||||||
|
Object[] args = point.getArgs();
|
||||||
|
Optional.ofNullable(args).ifPresent(objs -> {
|
||||||
|
if (ArrayUtils.isEmpty(objs)) return;
|
||||||
|
Object arg = args[0];
|
||||||
|
Long userId = (Long) arg;
|
||||||
|
WsMessage message = new WsMessage(userId, "/web-msg-topic", "refresh");
|
||||||
|
wsService.releaseMessage(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package io.dataease.websocket.config;
|
||||||
|
|
||||||
|
import io.dataease.websocket.factory.DeWsHandlerFactory;
|
||||||
|
import io.dataease.websocket.handler.PrincipalHandshakeHandler;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
|
||||||
|
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
|
||||||
|
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||||
|
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
|
||||||
|
import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSocketMessageBroker
|
||||||
|
public class WsConfig implements WebSocketMessageBrokerConfigurer {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||||
|
registry.addEndpoint("/websocket")
|
||||||
|
.setAllowedOriginPatterns("*")
|
||||||
|
.setHandshakeHandler(new PrincipalHandshakeHandler())
|
||||||
|
.withSockJS();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||||
|
registry.enableSimpleBroker("/topic", "/user");
|
||||||
|
registry.setUserDestinationPrefix("/user");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
|
||||||
|
registry.addDecoratorFactory(new DeWsHandlerFactory());
|
||||||
|
registry.setMessageSizeLimit(8192) //设置消息字节数大小
|
||||||
|
.setSendBufferSizeLimit(8192)//设置消息缓存大小
|
||||||
|
.setSendTimeLimit(10000); //设置消息发送时间限制毫秒
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.dataease.websocket.entity;
|
||||||
|
|
||||||
|
import java.security.Principal;
|
||||||
|
|
||||||
|
public class DePrincipal implements Principal {
|
||||||
|
|
||||||
|
public DePrincipal(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package io.dataease.websocket.factory;
|
||||||
|
|
||||||
|
import io.dataease.websocket.util.WsUtil;
|
||||||
|
import org.springframework.web.socket.CloseStatus;
|
||||||
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class DeWebSocketHandlerDecorator extends WebSocketHandlerDecorator {
|
||||||
|
|
||||||
|
|
||||||
|
public DeWebSocketHandlerDecorator(WebSocketHandler delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||||
|
Optional.ofNullable(session.getPrincipal()).ifPresent(principal -> {
|
||||||
|
String name = principal.getName();
|
||||||
|
Long userId = Long.parseLong(name);
|
||||||
|
WsUtil.onLine(userId);
|
||||||
|
});
|
||||||
|
super.afterConnectionEstablished(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
||||||
|
Optional.ofNullable(session.getPrincipal()).ifPresent(principal -> {
|
||||||
|
String name = principal.getName();
|
||||||
|
Long userId = Long.parseLong(name);
|
||||||
|
WsUtil.offLine(userId);
|
||||||
|
});
|
||||||
|
|
||||||
|
super.afterConnectionClosed(session, closeStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package io.dataease.websocket.factory;
|
||||||
|
|
||||||
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
|
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
|
||||||
|
|
||||||
|
public class DeWsHandlerFactory implements WebSocketHandlerDecoratorFactory {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WebSocketHandler decorate(WebSocketHandler webSocketHandler) {
|
||||||
|
return new DeWebSocketHandlerDecorator(webSocketHandler);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package io.dataease.websocket.handler;
|
||||||
|
|
||||||
|
import io.dataease.websocket.entity.DePrincipal;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.ServletServerHttpRequest;
|
||||||
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
|
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
|
||||||
|
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PrincipalHandshakeHandler extends DefaultHandshakeHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
|
||||||
|
if (request instanceof ServletServerHttpRequest) {
|
||||||
|
ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) request;
|
||||||
|
HttpServletRequest httpRequest = servletServerHttpRequest.getServletRequest();
|
||||||
|
final String userId = httpRequest.getParameter("userId");
|
||||||
|
if (StringUtils.isEmpty(userId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new DePrincipal(userId);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package io.dataease.websocket.service.impl;
|
||||||
|
|
||||||
|
import io.dataease.websocket.WsMessage;
|
||||||
|
import io.dataease.websocket.WsService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class StandaloneWsService implements WsService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SimpMessagingTemplate messagingTemplate;
|
||||||
|
|
||||||
|
public void releaseMessage(WsMessage wsMessage){
|
||||||
|
if(ObjectUtils.isEmpty(wsMessage) || ObjectUtils.isEmpty(wsMessage.getUserId()) || ObjectUtils.isEmpty(wsMessage.getTopic())) return;
|
||||||
|
messagingTemplate.convertAndSendToUser(String.valueOf(wsMessage.getUserId()), wsMessage.getTopic(),wsMessage.getData());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package io.dataease.websocket.util;
|
||||||
|
|
||||||
|
|
||||||
|
import io.dataease.auth.bo.TokenUserBO;
|
||||||
|
import io.dataease.utils.AuthUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
|
public class WsUtil {
|
||||||
|
|
||||||
|
private static final CopyOnWriteArraySet<Long> ONLINE_USERS = new CopyOnWriteArraySet();
|
||||||
|
|
||||||
|
public static boolean onLine() {
|
||||||
|
TokenUserBO user = AuthUtils.getUser();
|
||||||
|
if (ObjectUtils.isNotEmpty(user) && ObjectUtils.isNotEmpty(user.getUserId()))
|
||||||
|
return onLine(user.getUserId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean onLine(Long userId) {
|
||||||
|
return ONLINE_USERS.add(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean offLine() {
|
||||||
|
TokenUserBO user = AuthUtils.getUser();
|
||||||
|
if (ObjectUtils.isNotEmpty(user) && ObjectUtils.isNotEmpty(user.getUserId()))
|
||||||
|
return offLine(user.getUserId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean offLine(Long userId) {
|
||||||
|
return ONLINE_USERS.remove(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isOnLine(Long userId) {
|
||||||
|
return ONLINE_USERS.contains(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,10 @@ spring:
|
|||||||
url: jdbc:mysql://localhost:3306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
|
url: jdbc:mysql://localhost:3306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
|
||||||
username: root
|
username: root
|
||||||
password: 123456
|
password: 123456
|
||||||
|
# datasource:
|
||||||
|
# url: jdbc:mysql://39.98.78.97:13306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
|
||||||
|
# username: root
|
||||||
|
# password: Password123@mysql
|
||||||
messages:
|
messages:
|
||||||
basename: i18n/lic,i18n/core,i18n/permissions,i18n/xpack
|
basename: i18n/lic,i18n/core,i18n/permissions,i18n/xpack
|
||||||
flyway:
|
flyway:
|
||||||
|
@ -24,6 +24,24 @@ ALTER TABLE `xpack_setting_authentication`
|
|||||||
ADD COLUMN `valid` tinyint(1) NOT NULL DEFAULT 0 COMMENT '有效' AFTER `synced`;
|
ADD COLUMN `valid` tinyint(1) NOT NULL DEFAULT 0 COMMENT '有效' AFTER `synced`;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `core_export_task`;
|
||||||
|
CREATE TABLE `core_export_task`
|
||||||
|
(
|
||||||
|
`id` varchar(255) NOT NULL,
|
||||||
|
`user_id` bigint(20) NOT NULL,
|
||||||
|
`file_name` varchar(2048) DEFAULT NULL,
|
||||||
|
`file_size` DOUBLE DEFAULT NULL,
|
||||||
|
`file_size_unit` varchar(255) DEFAULT NULL,
|
||||||
|
`export_from` varchar(255) DEFAULT NULL,
|
||||||
|
`export_status` varchar(255) DEFAULT NULL,
|
||||||
|
`export_from_type` varchar(255) DEFAULT NULL,
|
||||||
|
`export_time` bigint(20) DEFAULT NULL,
|
||||||
|
`export_progress` varchar(255) DEFAULT NULL,
|
||||||
|
`export_machine_name` varchar(512) DEFAULT NULL,
|
||||||
|
`params` longtext NOT NULL COMMENT '过滤参数',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) COMMENT='导出任务表';
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `xpack_platform_token`;
|
DROP TABLE IF EXISTS `xpack_platform_token`;
|
||||||
CREATE TABLE `xpack_platform_token`
|
CREATE TABLE `xpack_platform_token`
|
||||||
(
|
(
|
||||||
@ -33,3 +51,4 @@ CREATE TABLE `xpack_platform_token`
|
|||||||
`exp_time` bigint NOT NULL,
|
`exp_time` bigint NOT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mathjs": "^11.6.0",
|
"mathjs": "^11.6.0",
|
||||||
"mitt": "^3.0.0",
|
"mitt": "^3.0.0",
|
||||||
|
"net": "^1.0.2",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.0.32",
|
"pinia": "^2.0.32",
|
||||||
@ -63,6 +64,8 @@
|
|||||||
"@types/element-resize-detector": "^1.1.3",
|
"@types/element-resize-detector": "^1.1.3",
|
||||||
"@types/jquery": "^3.5.16",
|
"@types/jquery": "^3.5.16",
|
||||||
"@types/lodash-es": "^4.17.6",
|
"@types/lodash-es": "^4.17.6",
|
||||||
|
"@types/sockjs-client": "^1.5.4",
|
||||||
|
"@types/stompjs": "^2.3.9",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.53.0",
|
"@typescript-eslint/eslint-plugin": "^5.53.0",
|
||||||
"@typescript-eslint/parser": "^5.53.0",
|
"@typescript-eslint/parser": "^5.53.0",
|
||||||
"@vitejs/plugin-vue": "^4.0.0",
|
"@vitejs/plugin-vue": "^4.0.0",
|
||||||
@ -80,6 +83,8 @@
|
|||||||
"postcss-scss": "^4.0.6",
|
"postcss-scss": "^4.0.6",
|
||||||
"prettier": "^2.8.4",
|
"prettier": "^2.8.4",
|
||||||
"rimraf": "^4.1.2",
|
"rimraf": "^4.1.2",
|
||||||
|
"sockjs-client": "^1.6.1",
|
||||||
|
"stompjs": "^2.3.3",
|
||||||
"stylelint": "^15.2.0",
|
"stylelint": "^15.2.0",
|
||||||
"stylelint-config-html": "^1.1.0",
|
"stylelint-config-html": "^1.1.0",
|
||||||
"stylelint-config-recommended": "^10.0.1",
|
"stylelint-config-recommended": "^10.0.1",
|
||||||
@ -96,6 +101,7 @@
|
|||||||
"vite-plugin-style-import-secondary": "^2.0.0",
|
"vite-plugin-style-import-secondary": "^2.0.0",
|
||||||
"vite-plugin-stylelint": "^4.2.0",
|
"vite-plugin-stylelint": "^4.2.0",
|
||||||
"vite-plugin-svg-icons": "^2.0.1",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"vue-tsc": "^1.0.24"
|
"vue-tsc": "^1.0.24",
|
||||||
|
"xss": "^1.0.14"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,10 @@ export interface DatasetDetail {
|
|||||||
fields: {
|
fields: {
|
||||||
dimensionList: Array<Field>
|
dimensionList: Array<Field>
|
||||||
quotaList: Array<Field>
|
quotaList: Array<Field>
|
||||||
|
parameterList?: Array<Field>
|
||||||
}
|
}
|
||||||
|
activelist?: string
|
||||||
|
hasParameter?: boolean
|
||||||
checkList: string[]
|
checkList: string[]
|
||||||
list: Array<Field>
|
list: Array<Field>
|
||||||
}
|
}
|
||||||
@ -247,3 +250,39 @@ export const getFunction = async (): Promise<DatasetDetail[]> => {
|
|||||||
return res?.data
|
return res?.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const exportTasks = async (type): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/exportCenter/exportTasks/' + type, data: {} }).then(res => {
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const exportRetry = async (id): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/exportCenter/retry/' + id, data: {} }).then(res => {
|
||||||
|
return res?.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const downloadFile = async (id): Promise<Blob> => {
|
||||||
|
return request.get({ url: 'exportCenter/download/' + id, responseType: 'blob' }).then(res => {
|
||||||
|
return res?.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const exportDelete = async (id): Promise<IResponse> => {
|
||||||
|
return request.get({ url: '/exportCenter/delete/' + id }).then(res => {
|
||||||
|
return res?.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const exportDeleteAll = async (type, data): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/exportCenter/deleteAll/' + type, data }).then(res => {
|
||||||
|
return res?.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const exportDeletePost = async (data): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/exportCenter/delete', data }).then(res => {
|
||||||
|
return res?.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export const load = (key: string) => request.get({ url: `/xpackComponent/content/${key}` })
|
export const load = (key: string) => request.get({ url: `/xpackComponent/content/${key}` })
|
||||||
|
|
||||||
|
export const loadDistributed = () => request.get({ url: '/DEXPack.umd.js' })
|
||||||
|
|
||||||
|
export const xpackModelApi = () => request.get({ url: '/xpackModel' })
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1716798774711" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3450" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M474.3168 450.56H369.3568l66.4576-73.3184 13.7216-6.144h40.96L549.4784 79.1552c-57.6512 3.584-104.448 20.992-141.312 52.224-40.6528 34.5088-60.8256 79.1552-60.8256 134.2464l1.024 24.1664-143.9744 67.9936 2.8672-32.768c9.6256-111.7184 54.6816-194.9696 134.8608-247.808C420.7616 25.6 537.3952 0 692.224 0H1024l-60.0064 184.832h-73.4208l8.192-25.088c4.096-11.8784 6.0416-23.552 6.0416-34.816C904.8064 96.256 840.3968 76.1856 706.56 76.1856h-7.5776l-59.6992 294.8096H892.928l-84.5824 85.2992-15.6672 5.4272a1191.424 1191.424 0 0 0-158.72-11.264h-10.6496l-27.648 136.9088c-26.624 131.3792-78.1312 236.9536-154.8288 316.2112C363.52 983.6544 272.4864 1024 169.1648 1024 111.3088 1024 59.392 1002.5984 14.336 960.3072L0 946.7904l110.1824-110.08 11.4688 23.3472c24.7808 50.3808 63.1808 74.6496 117.9648 74.6496 50.176 0 88.7808-21.7088 117.76-66.4576 30.72-47.5136 59.0848-134.144 84.48-258.8672L474.3168 450.56z" p-id="3451"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
1
core/core-frontend/src/assets/svg/variable.svg
Normal file
1
core/core-frontend/src/assets/svg/variable.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1716884731544" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3731" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M872 561.7V93.4c0-17.3-15.1-31.4-33.8-31.4-18.6 0-33.8 14.1-33.8 31.4v468.3c-51.9 14.7-90 62.4-90 119.1s38.1 104.4 90 119.1v130.8c0 17.3 15.1 31.4 33.8 31.4 18.6 0 33.8-14.1 33.8-31.4V799.8c51.9-14.7 90-62.4 90-119.1s-38.1-104.3-90-119z m6 158.8c-11 11-24.2 16.5-39.8 16.5s-28.8-5.5-39.8-16.5c-11-11-16.5-24.2-16.5-39.8 0-15.5 5.5-28.8 16.5-39.8 11-11 24.2-16.5 39.8-16.5S867 630 878 641c11 11 16.5 24.2 16.5 39.8 0 15.5-5.5 28.7-16.5 39.7zM557 201.7V93.4c0-17.3-15.1-31.4-33.8-31.4-18.6 0-33.8 14.1-33.8 31.4v108.3c-51.9 14.7-90 62.4-90 119.1 0 56.6 38.1 104.4 90 119.1v490.8c0 17.3 15.1 31.4 33.8 31.4 18.6 0 33.8-14.1 33.8-31.4V439.8c51.9-14.7 90-62.4 90-119.1 0-56.6-38.1-104.4-90-119z m6 158.8c-11 11-24.2 16.5-39.8 16.5s-28.8-5.5-39.8-16.5c-11-11-16.5-24.2-16.5-39.8s5.5-28.8 16.5-39.8c11-11 24.2-16.5 39.8-16.5S552 270 563 281c11 11 16.5 24.2 16.5 39.8s-5.5 28.7-16.5 39.7zM219.5 561.7V93.4c0-17.3-15.1-31.4-33.8-31.4-18.6 0-33.7 14.1-33.7 31.4v468.3c-51.9 14.7-90 62.4-90 119.1s38.1 104.4 90 119.1v130.8c0 17.3 15.1 31.4 33.8 31.4 18.6 0 33.8-14.1 33.8-31.4V799.8c51.9-14.7 90-62.4 90-119.1s-38.2-104.3-90.1-119z m6 158.8c-11 11-24.2 16.5-39.8 16.5s-28.8-5.5-39.8-16.5c-11-11-16.5-24.2-16.5-39.8 0-15.5 5.5-28.8 16.5-39.8 11-11 24.2-16.5 39.8-16.5s28.8 5.5 39.8 16.5c11 11 16.5 24.2 16.5 39.8 0 15.6-5.5 28.8-16.5 39.8z" p-id="3732"></path></svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -13,6 +13,11 @@ const props = defineProps({
|
|||||||
themes: {
|
themes: {
|
||||||
type: String as PropType<EditorTheme>,
|
type: String as PropType<EditorTheme>,
|
||||||
default: 'dark'
|
default: 'dark'
|
||||||
|
},
|
||||||
|
showSwitch: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:modelValue', 'modelChange'])
|
const emit = defineEmits(['update:modelValue', 'modelChange'])
|
||||||
@ -45,12 +50,15 @@ const switchValue = computed({
|
|||||||
<span>
|
<span>
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</span>
|
</span>
|
||||||
<el-switch
|
<div>
|
||||||
:effect="themes"
|
<el-switch
|
||||||
size="small"
|
v-show="showSwitch"
|
||||||
v-model="switchValue"
|
v-model="switchValue"
|
||||||
@click.stop="onSwitchChange"
|
:effect="themes"
|
||||||
/>
|
size="small"
|
||||||
|
@click.stop="onSwitchChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<slot />
|
<slot />
|
||||||
|
@ -285,6 +285,14 @@ const batchOptStatusChange = value => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const openOuterParamsSet = () => {
|
const openOuterParamsSet = () => {
|
||||||
|
if (componentData.value.length === 0) {
|
||||||
|
ElMessage.warning('当前仪表板为空,请先添加组件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!dvInfo.value.id) {
|
||||||
|
ElMessage.warning('请先保存当前页面')
|
||||||
|
return
|
||||||
|
}
|
||||||
outerParamsSetRef.value.optInit()
|
outerParamsSetRef.value.optInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1391,6 +1391,7 @@ onMounted(() => {
|
|||||||
if (isMainCanvas(canvasId.value)) {
|
if (isMainCanvas(canvasId.value)) {
|
||||||
initSnapshotTimer()
|
initSnapshotTimer()
|
||||||
initWatermark()
|
initWatermark()
|
||||||
|
dvMainStore.setEditMode('edit')
|
||||||
}
|
}
|
||||||
// 获取编辑器元素
|
// 获取编辑器元素
|
||||||
composeStore.getEditor(canvasId.value)
|
composeStore.getEditor(canvasId.value)
|
||||||
|
@ -83,7 +83,7 @@ const { config, showPosition, index, canvasStyleData, canvasViewInfo, dvInfo, se
|
|||||||
toRefs(props)
|
toRefs(props)
|
||||||
let currentInstance
|
let currentInstance
|
||||||
const component = ref(null)
|
const component = ref(null)
|
||||||
const emits = defineEmits(['userViewEnlargeOpen'])
|
const emits = defineEmits(['userViewEnlargeOpen', 'onPointClick'])
|
||||||
|
|
||||||
const htmlToImage = () => {
|
const htmlToImage = () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -180,6 +180,10 @@ const commonBackgroundSvgInner = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const onPointClick = param => {
|
||||||
|
emits('onPointClick', param)
|
||||||
|
}
|
||||||
|
|
||||||
const deepScale = computed(() => scale.value / 100)
|
const deepScale = computed(() => scale.value / 100)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -234,6 +238,7 @@ const deepScale = computed(() => scale.value / 100)
|
|||||||
:scale="deepScale"
|
:scale="deepScale"
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
:is-edit="false"
|
:is-edit="false"
|
||||||
|
@onPointClick="onPointClick"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,7 +90,7 @@ const paste = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const deleteComponent = () => {
|
const deleteComponent = () => {
|
||||||
if (curComponent.value) {
|
if (curComponent.value && !isGroupArea.value) {
|
||||||
const curInfo = getCurInfo()
|
const curInfo = getCurInfo()
|
||||||
dvMainStore.deleteComponentById(curComponent.value?.id, curInfo.componentData)
|
dvMainStore.deleteComponentById(curComponent.value?.id, curInfo.componentData)
|
||||||
} else if (areaData.value.components.length) {
|
} else if (areaData.value.components.length) {
|
||||||
@ -153,6 +153,10 @@ const handleComposeMouseDown = e => {
|
|||||||
const composeDivider = computed(() => {
|
const composeDivider = computed(() => {
|
||||||
return !(!curComponent || curComponent['isLock'] || curComponent['component'] != 'Group')
|
return !(!curComponent || curComponent['isLock'] || curComponent['component'] != 'Group')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isGroupArea = computed(() => {
|
||||||
|
return curComponent.value?.component === 'GroupArea'
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -201,7 +205,7 @@ const composeDivider = computed(() => {
|
|||||||
取消组合
|
取消组合
|
||||||
</li>
|
</li>
|
||||||
<el-divider class="custom-divider" v-show="composeDivider" />
|
<el-divider class="custom-divider" v-show="composeDivider" />
|
||||||
<template v-if="curComponent">
|
<template v-if="curComponent && !isGroupArea">
|
||||||
<template v-if="!curComponent['isLock']">
|
<template v-if="!curComponent['isLock']">
|
||||||
<li @click="upComponent">上移一层</li>
|
<li @click="upComponent">上移一层</li>
|
||||||
<li @click="downComponent">下移一层</li>
|
<li @click="downComponent">下移一层</li>
|
||||||
|
@ -13,9 +13,10 @@ import { isMainCanvas } from '@/utils/canvasUtils'
|
|||||||
import { activeWatermark } from '@/components/watermark/watermark'
|
import { activeWatermark } from '@/components/watermark/watermark'
|
||||||
import { personInfoApi } from '@/api/user'
|
import { personInfoApi } from '@/api/user'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
import { XpackComponent } from '@/components/plugin'
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
const { pcMatrixCount, curComponent, mobileInPc } = storeToRefs(dvMainStore)
|
const { pcMatrixCount, curComponent, mobileInPc } = storeToRefs(dvMainStore)
|
||||||
|
const openHandler = ref(null)
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
canvasStyleData: {
|
canvasStyleData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -238,7 +239,6 @@ const initWatermark = (waterDomId = 'preview-canvas-main') => {
|
|||||||
|
|
||||||
// 目标校验: 需要校验targetSourceId 是否是当前可视化资源ID
|
// 目标校验: 需要校验targetSourceId 是否是当前可视化资源ID
|
||||||
const winMsgHandle = event => {
|
const winMsgHandle = event => {
|
||||||
console.info('PostMessage Params Received')
|
|
||||||
const msgInfo = event.data
|
const msgInfo = event.data
|
||||||
// 校验targetSourceId
|
// 校验targetSourceId
|
||||||
if (
|
if (
|
||||||
@ -246,9 +246,9 @@ const winMsgHandle = event => {
|
|||||||
msgInfo.type === 'attachParams' &&
|
msgInfo.type === 'attachParams' &&
|
||||||
msgInfo.targetSourceId === dvInfo.value.id + ''
|
msgInfo.targetSourceId === dvInfo.value.id + ''
|
||||||
) {
|
) {
|
||||||
const attachParam = msgInfo.params
|
const attachParams = msgInfo.params
|
||||||
if (attachParam) {
|
if (attachParams) {
|
||||||
dvMainStore.addOuterParamsFilter(attachParam, componentData.value, 'outer')
|
dvMainStore.addOuterParamsFilter(attachParams, componentData.value, 'outer')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,6 +281,32 @@ const userViewEnlargeOpen = (opt, item) => {
|
|||||||
const handleMouseDown = () => {
|
const handleMouseDown = () => {
|
||||||
dvMainStore.setCurComponent({ component: null, index: null })
|
dvMainStore.setCurComponent({ component: null, index: null })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onPointClick = param => {
|
||||||
|
try {
|
||||||
|
console.info('de_inner_params send')
|
||||||
|
if (window['dataease-embedded-host'] && openHandler?.value) {
|
||||||
|
const pm = {
|
||||||
|
methodName: 'embeddedInteractive',
|
||||||
|
args: {
|
||||||
|
eventName: 'de_inner_params',
|
||||||
|
args: param
|
||||||
|
}
|
||||||
|
}
|
||||||
|
openHandler.value.invokeMethod(pm)
|
||||||
|
} else {
|
||||||
|
console.info('de_inner_params send to host')
|
||||||
|
const targetPm = {
|
||||||
|
type: 'dataease-embedded-interactive',
|
||||||
|
eventName: 'de_inner_params',
|
||||||
|
args: param
|
||||||
|
}
|
||||||
|
window.parent.postMessage(targetPm, '*')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('de_inner_params send error')
|
||||||
|
}
|
||||||
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
restore
|
restore
|
||||||
})
|
})
|
||||||
@ -316,17 +342,14 @@ defineExpose({
|
|||||||
:scale="mobileInPc ? 100 : scaleWidth"
|
:scale="mobileInPc ? 100 : scaleWidth"
|
||||||
:is-selector="props.isSelector"
|
:is-selector="props.isSelector"
|
||||||
@userViewEnlargeOpen="userViewEnlargeOpen($event, item)"
|
@userViewEnlargeOpen="userViewEnlargeOpen($event, item)"
|
||||||
|
@onPointClick="onPointClick"
|
||||||
/>
|
/>
|
||||||
<user-view-enlarge ref="userViewEnlargeRef"></user-view-enlarge>
|
<user-view-enlarge ref="userViewEnlargeRef"></user-view-enlarge>
|
||||||
</div>
|
</div>
|
||||||
|
<XpackComponent ref="openHandler" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 0px !important;
|
|
||||||
height: 0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvas-container {
|
.canvas-container {
|
||||||
background-size: 100% 100% !important;
|
background-size: 100% 100% !important;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -334,6 +357,10 @@ defineExpose({
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0px !important;
|
||||||
|
height: 0px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fix-button {
|
.fix-button {
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import noLic from './nolic.vue'
|
import noLic from './nolic.vue'
|
||||||
import { ref, useAttrs } from 'vue'
|
import { ref, useAttrs, onMounted } from 'vue'
|
||||||
import { execute, randomKey, formatArray } from './convert'
|
import { execute, randomKey, formatArray } from './convert'
|
||||||
import { load } from '@/api/plugin'
|
import { load, loadDistributed, xpackModelApi } from '@/api/plugin'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
import { useCache } from '@/hooks/web/useCache'
|
||||||
|
import { i18n } from '@/plugins/vue-i18n'
|
||||||
|
import * as Vue from 'vue'
|
||||||
|
import axios from 'axios'
|
||||||
|
import * as Pinia from 'pinia'
|
||||||
|
import * as vueI18n from 'vue-i18n'
|
||||||
|
import * as vueRouter from 'vue-router'
|
||||||
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
|
|
||||||
@ -73,11 +80,44 @@ const storeCacheProxy = byteArray => {
|
|||||||
})
|
})
|
||||||
wsCache.set(`de-plugin-proxy`, JSON.stringify(result))
|
wsCache.set(`de-plugin-proxy`, JSON.stringify(result))
|
||||||
}
|
}
|
||||||
loadComponent()
|
|
||||||
const pluginProxy = ref(null)
|
const pluginProxy = ref(null)
|
||||||
const invokeMethod = param => {
|
const invokeMethod = param => {
|
||||||
pluginProxy.value['invokeMethod'](param)
|
pluginProxy.value['invokeMethod'](param)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const key = 'xpack-model-distributed'
|
||||||
|
let distributed = false
|
||||||
|
if (wsCache.get(key) === null) {
|
||||||
|
const res = await xpackModelApi()
|
||||||
|
wsCache.set('xpack-model-distributed', res.data)
|
||||||
|
distributed = res.data
|
||||||
|
} else {
|
||||||
|
distributed = wsCache.get(key)
|
||||||
|
}
|
||||||
|
if (distributed) {
|
||||||
|
window['Vue'] = Vue
|
||||||
|
window['Axios'] = axios
|
||||||
|
window['Pinia'] = Pinia
|
||||||
|
window['vueI18n'] = vueI18n
|
||||||
|
window['vueRouter'] = vueRouter
|
||||||
|
window['MittAll'] = useEmitt().emitter.all
|
||||||
|
window['i18n'] = i18n
|
||||||
|
if (window['DEXPack']) {
|
||||||
|
const xpack = await window['DEXPack'].mapping[attrs.jsname]
|
||||||
|
plugin.value = xpack.default
|
||||||
|
} else {
|
||||||
|
loadDistributed().then(async res => {
|
||||||
|
new Function(res.data)()
|
||||||
|
const xpack = await window['DEXPack'].mapping[attrs.jsname]
|
||||||
|
plugin.value = xpack.default
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loadComponent()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const emits = defineEmits(['loadFail'])
|
const emits = defineEmits(['loadFail'])
|
||||||
defineExpose({
|
defineExpose({
|
||||||
invokeMethod
|
invokeMethod
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
:append-to-body="true"
|
:append-to-body="true"
|
||||||
v-model="dialogShow"
|
v-model="dialogShow"
|
||||||
width="340px"
|
width="340px"
|
||||||
|
:show-close="false"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
>
|
>
|
||||||
<el-row style="height: 20px">
|
<el-row style="height: 20px">
|
||||||
|
@ -146,7 +146,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onBeforeUnmount, onMounted, reactive, toRefs, watch } from 'vue'
|
import { computed, h, onBeforeUnmount, onMounted, reactive, toRefs, watch } from 'vue'
|
||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
@ -156,7 +156,8 @@ import { useEmitt } from '@/hooks/web/useEmitt'
|
|||||||
import { copyStoreWithOut } from '@/store/modules/data-visualization/copy'
|
import { copyStoreWithOut } from '@/store/modules/data-visualization/copy'
|
||||||
import { exportExcelDownload } from '@/views/chart/components/js/util'
|
import { exportExcelDownload } from '@/views/chart/components/js/util'
|
||||||
import FieldsList from '@/custom-component/rich-text/FieldsList.vue'
|
import FieldsList from '@/custom-component/rich-text/FieldsList.vue'
|
||||||
import { ElTooltip } from 'element-plus-secondary'
|
import { RefreshLeft } from '@element-plus/icons-vue'
|
||||||
|
import { ElMessage, ElTooltip, ElButton } from 'element-plus-secondary'
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
const snapshotStore = snapshotStoreWithOut()
|
const snapshotStore = snapshotStoreWithOut()
|
||||||
const copyStore = copyStoreWithOut()
|
const copyStore = copyStoreWithOut()
|
||||||
@ -312,12 +313,45 @@ const showBarTooltipPosition = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const openMessageLoading = cb => {
|
||||||
|
const iconClass = `el-icon-loading`
|
||||||
|
const customClass = `de-message-loading de-message-export`
|
||||||
|
ElMessage({
|
||||||
|
message: h('p', null, [
|
||||||
|
'后台导出中,可前往',
|
||||||
|
h(
|
||||||
|
ElButton,
|
||||||
|
{
|
||||||
|
text: true,
|
||||||
|
size: 'small',
|
||||||
|
class: 'btn-text',
|
||||||
|
onClick: () => {
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
t('data_export.export_center')
|
||||||
|
),
|
||||||
|
'查看进度,进行下载'
|
||||||
|
]),
|
||||||
|
iconClass,
|
||||||
|
icon: h(RefreshLeft),
|
||||||
|
showClose: true,
|
||||||
|
customClass
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const callbackExport = () => {
|
||||||
|
useEmitt().emitter.emit('data-export-center')
|
||||||
|
}
|
||||||
|
|
||||||
const exportAsExcel = () => {
|
const exportAsExcel = () => {
|
||||||
const viewDataInfo = dvMainStore.getViewDataDetails(element.value.id)
|
const viewDataInfo = dvMainStore.getViewDataDetails(element.value.id)
|
||||||
const chartExtRequest = dvMainStore.getLastViewRequestInfo(element.value.id)
|
const chartExtRequest = dvMainStore.getLastViewRequestInfo(element.value.id)
|
||||||
const viewInfo = dvMainStore.getViewDetails(element.value.id)
|
const viewInfo = dvMainStore.getViewDetails(element.value.id)
|
||||||
const chart = { ...viewInfo, chartExtRequest, data: viewDataInfo }
|
const chart = { ...viewInfo, chartExtRequest, data: viewDataInfo }
|
||||||
exportExcelDownload(chart)
|
exportExcelDownload(chart, () => {
|
||||||
|
openMessageLoading(callbackExport)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const exportAsImage = () => {
|
const exportAsImage = () => {
|
||||||
// do export
|
// do export
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ComponentWrapper from '@/components/data-visualization/canvas/ComponentWrapper.vue'
|
import ComponentWrapper from '@/components/data-visualization/canvas/ComponentWrapper.vue'
|
||||||
import { computed, nextTick, ref } from 'vue'
|
import { computed, h, nextTick, ref } from 'vue'
|
||||||
import { toPng } from 'html-to-image'
|
import { toPng } from 'html-to-image'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { deepCopy } from '@/utils/utils'
|
import { deepCopy } from '@/utils/utils'
|
||||||
@ -79,8 +79,10 @@ import ChartComponentS2 from '@/views/chart/components/views/components/ChartCom
|
|||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
import { exportExcelDownload } from '@/views/chart/components/js/util'
|
import { exportExcelDownload } from '@/views/chart/components/js/util'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { RefreshLeft } from '@element-plus/icons-vue'
|
||||||
import { assign } from 'lodash-es'
|
import { assign } from 'lodash-es'
|
||||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
|
import { ElMessage, ElButton } from 'element-plus-secondary'
|
||||||
const downLoading = ref(false)
|
const downLoading = ref(false)
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
const dialogShow = ref(false)
|
const dialogShow = ref(false)
|
||||||
@ -201,10 +203,41 @@ const downloadViewDetails = () => {
|
|||||||
}
|
}
|
||||||
exportLoading.value = true
|
exportLoading.value = true
|
||||||
exportExcelDownload(chart, () => {
|
exportExcelDownload(chart, () => {
|
||||||
|
openMessageLoading(exportData)
|
||||||
exportLoading.value = false
|
exportLoading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const exportData = () => {
|
||||||
|
useEmitt().emitter.emit('data-export-center')
|
||||||
|
}
|
||||||
|
|
||||||
|
const openMessageLoading = cb => {
|
||||||
|
const iconClass = `el-icon-loading`
|
||||||
|
const customClass = `de-message-loading de-message-export`
|
||||||
|
ElMessage({
|
||||||
|
message: h('p', null, [
|
||||||
|
'后台导出中,可前往',
|
||||||
|
h(
|
||||||
|
ElButton,
|
||||||
|
{
|
||||||
|
text: true,
|
||||||
|
size: 'small',
|
||||||
|
class: 'btn-text',
|
||||||
|
onClick: () => {
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
t('data_export.export_center')
|
||||||
|
),
|
||||||
|
'查看进度,进行下载'
|
||||||
|
]),
|
||||||
|
iconClass,
|
||||||
|
icon: h(RefreshLeft),
|
||||||
|
showClose: true,
|
||||||
|
customClass
|
||||||
|
})
|
||||||
|
}
|
||||||
const htmlToImage = () => {
|
const htmlToImage = () => {
|
||||||
downLoading.value = true
|
downLoading.value = true
|
||||||
useEmitt().emitter.emit('renderChart-' + viewInfo.value.id)
|
useEmitt().emitter.emit('renderChart-' + viewInfo.value.id)
|
||||||
|
@ -171,6 +171,8 @@ service.interceptors.response.use(
|
|||||||
} else if (response.config.url.match(/^\/map|geo\/\d{3}\/\d+\.json$/)) {
|
} else if (response.config.url.match(/^\/map|geo\/\d{3}\/\d+\.json$/)) {
|
||||||
// TODO 处理静态文件
|
// TODO 处理静态文件
|
||||||
return response
|
return response
|
||||||
|
} else if (response.config.url.includes('DEXPack.umd.js')) {
|
||||||
|
return response
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
!response?.config?.url.startsWith('/xpackComponent/content') &&
|
!response?.config?.url.startsWith('/xpackComponent/content') &&
|
||||||
|
@ -2,6 +2,39 @@
|
|||||||
<el-row class="custom-row">
|
<el-row class="custom-row">
|
||||||
<el-row class="custom-row-inner">
|
<el-row class="custom-row-inner">
|
||||||
<el-space wrap>
|
<el-space wrap>
|
||||||
|
<template v-for="styleOptionKey in styleOptionKeyArrayPre">
|
||||||
|
<el-tooltip
|
||||||
|
:key="styleOptionKey.value"
|
||||||
|
v-if="styleForm[styleOptionKey.value] !== undefined"
|
||||||
|
:effect="themes"
|
||||||
|
placement="bottom"
|
||||||
|
>
|
||||||
|
<template #content> {{ styleOptionKey.label }} </template>
|
||||||
|
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
|
||||||
|
<el-select
|
||||||
|
:style="{ width: styleOptionKey.width }"
|
||||||
|
:effect="themes"
|
||||||
|
v-model="styleForm[styleOptionKey.value]"
|
||||||
|
size="small"
|
||||||
|
@change="changeStyle"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<el-icon :class="{ 'dark-icon': themes === 'dark' }">
|
||||||
|
<Icon :name="styleOptionKey.icon" />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
<el-option
|
||||||
|
class="custom-style-option"
|
||||||
|
v-for="option in styleOptionKey.customOption"
|
||||||
|
:key="option.value"
|
||||||
|
:label="option.name"
|
||||||
|
:value="option.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-for="styleColorKey in styleColorKeyArray">
|
<template v-for="styleColorKey in styleColorKeyArray">
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
:key="styleColorKey.value"
|
:key="styleColorKey.value"
|
||||||
@ -274,18 +307,25 @@ const styleMounted = ref({
|
|||||||
color: '#000000'
|
color: '#000000'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const fontFamilyList = [
|
||||||
|
{ name: '微软雅黑', value: 'Microsoft YaHei' },
|
||||||
|
{ name: '宋体', value: 'SimSun, "Songti SC", STSong' },
|
||||||
|
{ name: '黑体', value: 'SimHei, Helvetica' },
|
||||||
|
{ name: '楷体', value: 'KaiTi, "Kaiti SC", STKaiti' }
|
||||||
|
]
|
||||||
|
|
||||||
const scrollSpeedList = [
|
const scrollSpeedList = [
|
||||||
{ name: '停止', value: 0 },
|
{ name: '停止', value: 0 },
|
||||||
{ name: '1', value: 20 },
|
{ name: '1', value: 80 },
|
||||||
{ name: '2', value: 18 },
|
{ name: '2', value: 60 },
|
||||||
{ name: '3', value: 16 },
|
{ name: '3', value: 40 },
|
||||||
{ name: '4', value: 14 },
|
{ name: '4', value: 30 },
|
||||||
{ name: '5', value: 12 },
|
{ name: '5', value: 20 },
|
||||||
{ name: '6', value: 10 },
|
{ name: '6', value: 15 },
|
||||||
{ name: '7', value: 8 },
|
{ name: '7', value: 10 },
|
||||||
{ name: '8', value: 6 },
|
{ name: '8', value: 8 },
|
||||||
{ name: '9', value: 4 },
|
{ name: '9', value: 6 },
|
||||||
{ name: '10', value: 2 }
|
{ name: '10', value: 3 }
|
||||||
]
|
]
|
||||||
|
|
||||||
const opacitySizeList = [
|
const opacitySizeList = [
|
||||||
@ -376,6 +416,16 @@ const borderStyleList = [
|
|||||||
{ name: '点线', value: 'dotted' }
|
{ name: '点线', value: 'dotted' }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const styleOptionKeyArrayPre = [
|
||||||
|
{
|
||||||
|
value: 'fontFamily',
|
||||||
|
label: '字体',
|
||||||
|
customOption: fontFamilyList,
|
||||||
|
width: '188px',
|
||||||
|
icon: 'dv-style-fontFamily'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
//大小随画布缩放动态变化
|
//大小随画布缩放动态变化
|
||||||
const styleOptionMountedKeyArray = [
|
const styleOptionMountedKeyArray = [
|
||||||
{
|
{
|
||||||
|
@ -498,7 +498,8 @@ const list = [
|
|||||||
color: '',
|
color: '',
|
||||||
padding: 4,
|
padding: 4,
|
||||||
verticalAlign: 'middle',
|
verticalAlign: 'middle',
|
||||||
scrollSpeed: 0
|
scrollSpeed: 0,
|
||||||
|
fontFamily: 'Microsoft YaHei'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -117,7 +117,6 @@ const destroyPlayer = () => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: rgba(245, 245, 220, 0.1);
|
background-color: rgba(245, 245, 220, 0.1);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #000000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.move-bg {
|
.move-bg {
|
||||||
|
@ -88,7 +88,6 @@ watch(
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #9ea6b2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.player {
|
.player {
|
||||||
|
@ -467,11 +467,10 @@ defineExpose({
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto !important;
|
overflow-y: auto !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
::-webkit-scrollbar {
|
||||||
|
width: 0px !important;
|
||||||
::-webkit-scrollbar {
|
height: 0px !important;
|
||||||
width: 0px !important;
|
}
|
||||||
height: 0px !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.ol) {
|
:deep(.ol) {
|
||||||
|
@ -78,8 +78,6 @@ const clearStyle = e => {
|
|||||||
if (text !== '') {
|
if (text !== '') {
|
||||||
document.execCommand('insertText', false, text)
|
document.execCommand('insertText', false, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('input', element.value, e.target.innerHTML)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBlur = e => {
|
const handleBlur = e => {
|
||||||
@ -141,11 +139,12 @@ const textStyle = computed(() => {
|
|||||||
@mousedown="handleMousedown"
|
@mousedown="handleMousedown"
|
||||||
@blur="handleBlur"
|
@blur="handleBlur"
|
||||||
@input="handleInput"
|
@input="handleInput"
|
||||||
v-html="element['propValue']"
|
>
|
||||||
></div>
|
{{ element['propValue'] }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="v-text preview">
|
<div v-else class="v-text preview" :style="varStyle">
|
||||||
<div class="marquee-txt" :style="textStyle" v-html="element['propValue']"></div>
|
<div class="marquee-txt" :style="textStyle">{{ element['propValue'] }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -71,6 +71,11 @@ const autoStyle = computed(() => {
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const emits = defineEmits(['onPointClick'])
|
||||||
|
|
||||||
|
const onPointClick = param => {
|
||||||
|
emits('onPointClick', param)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -83,6 +88,7 @@ const autoStyle = computed(() => {
|
|||||||
:show-position="showPosition"
|
:show-position="showPosition"
|
||||||
:search-count="searchCount"
|
:search-count="searchCount"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
|
@onPointClick="onPointClick"
|
||||||
></chart>
|
></chart>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -107,7 +107,6 @@ const activeCondition = ref('')
|
|||||||
const isIndeterminate = ref(false)
|
const isIndeterminate = ref(false)
|
||||||
const datasetTree = shallowRef([])
|
const datasetTree = shallowRef([])
|
||||||
const fields = ref<DatasetDetail[]>()
|
const fields = ref<DatasetDetail[]>()
|
||||||
const parameters = ref([])
|
|
||||||
|
|
||||||
const { queryElement } = toRefs(props)
|
const { queryElement } = toRefs(props)
|
||||||
|
|
||||||
@ -191,6 +190,9 @@ const setParameters = () => {
|
|||||||
|
|
||||||
if (!!curComponent.value.parameters.length) {
|
if (!!curComponent.value.parameters.length) {
|
||||||
curComponent.value.conditionType = 0
|
curComponent.value.conditionType = 0
|
||||||
|
if (curComponent.value.optionValueSource === 0) {
|
||||||
|
curComponent.value.optionValueSource = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setType()
|
setType()
|
||||||
@ -1386,7 +1388,9 @@ defineExpose({
|
|||||||
@change="handleValueSourceChange"
|
@change="handleValueSourceChange"
|
||||||
v-model="curComponent.optionValueSource"
|
v-model="curComponent.optionValueSource"
|
||||||
>
|
>
|
||||||
<el-radio :label="0">{{ t('chart.margin_model_auto') }}</el-radio>
|
<el-radio :disabled="!!curComponent.parameters.length" :label="0">{{
|
||||||
|
t('chart.margin_model_auto')
|
||||||
|
}}</el-radio>
|
||||||
<el-radio :label="1">{{ t('chart.select_dataset') }}</el-radio>
|
<el-radio :label="1">{{ t('chart.select_dataset') }}</el-radio>
|
||||||
<el-radio :label="2">手动输入</el-radio>
|
<el-radio :label="2">手动输入</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
@ -4,6 +4,7 @@ import { usePermissionStore } from '@/store/modules/permission'
|
|||||||
import { isExternal } from '@/utils/validate'
|
import { isExternal } from '@/utils/validate'
|
||||||
import { formatRoute } from '@/router/establish'
|
import { formatRoute } from '@/router/establish'
|
||||||
import HeaderMenuItem from './HeaderMenuItem.vue'
|
import HeaderMenuItem from './HeaderMenuItem.vue'
|
||||||
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
import { Icon } from '@/components/icon-custom'
|
import { Icon } from '@/components/icon-custom'
|
||||||
import { ElHeader, ElMenu } from 'element-plus-secondary'
|
import { ElHeader, ElMenu } from 'element-plus-secondary'
|
||||||
import SystemCfg from './SystemCfg.vue'
|
import SystemCfg from './SystemCfg.vue'
|
||||||
@ -15,8 +16,8 @@ import { isDesktop } from '@/utils/ModelUtil'
|
|||||||
import { XpackComponent } from '@/components/plugin'
|
import { XpackComponent } from '@/components/plugin'
|
||||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||||
import AiComponent from '@/layout/components/AiComponent.vue'
|
import AiComponent from '@/layout/components/AiComponent.vue'
|
||||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
|
||||||
import { findBaseParams } from '@/api/aiComponent'
|
import { findBaseParams } from '@/api/aiComponent'
|
||||||
|
import ExportExcel from '@/views/visualized/data/dataset/ExportExcel.vue'
|
||||||
import AiTips from '@/layout/components/AiTips.vue'
|
import AiTips from '@/layout/components/AiTips.vue'
|
||||||
|
|
||||||
const appearanceStore = useAppearanceStoreWithOut()
|
const appearanceStore = useAppearanceStoreWithOut()
|
||||||
@ -42,7 +43,10 @@ const activeIndex = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const permissionStore = usePermissionStore()
|
||||||
|
const ExportExcelRef = ref()
|
||||||
|
const downloadClick = () => {
|
||||||
|
ExportExcelRef.value.init()
|
||||||
|
}
|
||||||
const routers: any[] = formatRoute(permissionStore.getRoutersNotHidden as AppCustomRouteRecordRaw[])
|
const routers: any[] = formatRoute(permissionStore.getRoutersNotHidden as AppCustomRouteRecordRaw[])
|
||||||
const showSystem = ref(false)
|
const showSystem = ref(false)
|
||||||
const showToolbox = ref(false)
|
const showToolbox = ref(false)
|
||||||
@ -87,6 +91,10 @@ onMounted(() => {
|
|||||||
initShowSystem()
|
initShowSystem()
|
||||||
initShowToolbox()
|
initShowToolbox()
|
||||||
initAiBase()
|
initAiBase()
|
||||||
|
useEmitt({
|
||||||
|
name: 'data-export-center',
|
||||||
|
callback: downloadClick
|
||||||
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -118,6 +126,9 @@ onMounted(() => {
|
|||||||
>
|
>
|
||||||
<Icon name="dv-ai" @click="handleAiClick" />
|
<Icon name="dv-ai" @click="handleAiClick" />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
<el-icon style="margin: 0 10px">
|
||||||
|
<Icon name="dv-preview-download" @click="downloadClick" />
|
||||||
|
</el-icon>
|
||||||
<ai-tips
|
<ai-tips
|
||||||
@confirm="aiTipsConfirm"
|
@confirm="aiTipsConfirm"
|
||||||
v-if="showOverlay && appearanceStore.getShowAi"
|
v-if="showOverlay && appearanceStore.getShowAi"
|
||||||
@ -134,6 +145,7 @@ onMounted(() => {
|
|||||||
<div v-if="showOverlay && appearanceStore.getShowAi" class="overlay"></div>
|
<div v-if="showOverlay && appearanceStore.getShowAi" class="overlay"></div>
|
||||||
</div>
|
</div>
|
||||||
</el-header>
|
</el-header>
|
||||||
|
<ExportExcel ref="ExportExcelRef"></ExportExcel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
@ -50,6 +50,37 @@ export default {
|
|||||||
filter_condition: '筛选条件',
|
filter_condition: '筛选条件',
|
||||||
no_auth_tips: '缺少菜单权限,请联系管理员'
|
no_auth_tips: '缺少菜单权限,请联系管理员'
|
||||||
},
|
},
|
||||||
|
data_export: {
|
||||||
|
export_center: '数据导出中心',
|
||||||
|
export_info: '查看进度,进行下载',
|
||||||
|
exporting: '后台导出中,可前往',
|
||||||
|
del_all: '全部删除',
|
||||||
|
export_failed: '导出失败',
|
||||||
|
export_from: '导出来源',
|
||||||
|
export_obj: '导出对象',
|
||||||
|
export_time: '导出时间',
|
||||||
|
sure_del_all: '确定删除全部导出记录吗?',
|
||||||
|
sure_del: '确定删除该导出记录吗?',
|
||||||
|
no_failed_file: '暂无失败文件',
|
||||||
|
no_file: '暂无文件',
|
||||||
|
no_task: '暂无任务',
|
||||||
|
download_all: '下载全部',
|
||||||
|
download: '下载'
|
||||||
|
},
|
||||||
|
driver: {
|
||||||
|
driver: '驱动',
|
||||||
|
please_choose_driver: '请选择驱动',
|
||||||
|
mgm: '驱动管理',
|
||||||
|
exit_mgm: '退出驱动管理',
|
||||||
|
add: '添加驱动',
|
||||||
|
modify: '修改',
|
||||||
|
show_info: '驱动信息',
|
||||||
|
file_name: '文件名',
|
||||||
|
version: '版本',
|
||||||
|
please_set_driverClass: '请指定驱动类',
|
||||||
|
please_set_surpportVersions: '请输入支持的数据库大版本',
|
||||||
|
surpportVersions: '支持版本'
|
||||||
|
},
|
||||||
login: {
|
login: {
|
||||||
welcome: '欢迎使用',
|
welcome: '欢迎使用',
|
||||||
btn: '登录',
|
btn: '登录',
|
||||||
@ -291,6 +322,7 @@ export default {
|
|||||||
please_input_host: '请输入主机',
|
please_input_host: '请输入主机',
|
||||||
please_input_url: '请输入URL地址',
|
please_input_url: '请输入URL地址',
|
||||||
please_input_port: '请输入端口',
|
please_input_port: '请输入端口',
|
||||||
|
please_input_be_port: '请输入BE端口',
|
||||||
modify: '编辑数据源',
|
modify: '编辑数据源',
|
||||||
copy: '复制数据源',
|
copy: '复制数据源',
|
||||||
validate_success: '校验成功',
|
validate_success: '校验成功',
|
||||||
@ -656,6 +688,7 @@ export default {
|
|||||||
table_show_row_tooltip: '开启行头提示',
|
table_show_row_tooltip: '开启行头提示',
|
||||||
table_show_col_tooltip: '开启列头提示',
|
table_show_col_tooltip: '开启列头提示',
|
||||||
table_show_cell_tooltip: '开启单元格提示',
|
table_show_cell_tooltip: '开启单元格提示',
|
||||||
|
table_show_header_tooltip: '开启表头提示',
|
||||||
stripe: '斑马纹',
|
stripe: '斑马纹',
|
||||||
start_angle: '起始角度',
|
start_angle: '起始角度',
|
||||||
end_angle: '结束角度',
|
end_angle: '结束角度',
|
||||||
@ -680,11 +713,11 @@ export default {
|
|||||||
chart_bar: '基础柱状图',
|
chart_bar: '基础柱状图',
|
||||||
chart_bar_stack: '堆叠柱状图',
|
chart_bar_stack: '堆叠柱状图',
|
||||||
chart_percentage_bar_stack: '百分比柱状图',
|
chart_percentage_bar_stack: '百分比柱状图',
|
||||||
chart_bar_horizontal: '横向柱状图',
|
chart_bar_horizontal: '基础条形图',
|
||||||
chart_bar_stack_horizontal: '横向堆叠柱状图',
|
chart_bar_stack_horizontal: '堆叠条形图',
|
||||||
chart_percentage_bar_stack_horizontal: '横向百分比柱状图',
|
chart_percentage_bar_stack_horizontal: '百分比条形图',
|
||||||
chart_bar_range: '区间条形图',
|
chart_bar_range: '区间条形图',
|
||||||
chart_bidirectional_bar: '对称柱状图',
|
chart_bidirectional_bar: '对称条形图',
|
||||||
chart_progress_bar: '进度条',
|
chart_progress_bar: '进度条',
|
||||||
chart_line: '基础折线图',
|
chart_line: '基础折线图',
|
||||||
chart_area_stack: '堆叠折线图',
|
chart_area_stack: '堆叠折线图',
|
||||||
@ -851,7 +884,7 @@ export default {
|
|||||||
chart_type_table: '表格',
|
chart_type_table: '表格',
|
||||||
chart_type_quota: '指标',
|
chart_type_quota: '指标',
|
||||||
chart_type_trend: '线/面图',
|
chart_type_trend: '线/面图',
|
||||||
chart_type_compare: '柱状图',
|
chart_type_compare: '柱/条图',
|
||||||
chart_type_distribute: '分布图',
|
chart_type_distribute: '分布图',
|
||||||
chart_type_relation: '关系图',
|
chart_type_relation: '关系图',
|
||||||
chart_type_dual_axes: '双轴图',
|
chart_type_dual_axes: '双轴图',
|
||||||
@ -1141,7 +1174,10 @@ export default {
|
|||||||
top_n_input_2: ', 其余合并至其他',
|
top_n_input_2: ', 其余合并至其他',
|
||||||
top_n_label: '其他项名称',
|
top_n_label: '其他项名称',
|
||||||
progress_target: '目标值',
|
progress_target: '目标值',
|
||||||
progress_current: '实际值'
|
progress_current: '实际值',
|
||||||
|
gauge_axis_label: '显示刻度',
|
||||||
|
gauge_percentage_tick: '百分比刻度',
|
||||||
|
add_style: '添加样式'
|
||||||
},
|
},
|
||||||
dataset: {
|
dataset: {
|
||||||
scope_edit: '仅编辑时生效',
|
scope_edit: '仅编辑时生效',
|
||||||
@ -1412,6 +1448,7 @@ export default {
|
|||||||
pls_input_filename: '请输入文件名称',
|
pls_input_filename: '请输入文件名称',
|
||||||
calc_tips: {
|
calc_tips: {
|
||||||
tip1: '表达式语法请遵循calcite语法。',
|
tip1: '表达式语法请遵循calcite语法。',
|
||||||
|
tip1_1: '表达式语法请遵循该数据源对应的数据库语法。',
|
||||||
tip2: '聚合运算仅能在图表中生效。',
|
tip2: '聚合运算仅能在图表中生效。',
|
||||||
tip3: '引用字段以 "[" 开始, "]" 结束',
|
tip3: '引用字段以 "[" 开始, "]" 结束',
|
||||||
tip4: '请勿修改引用内容,否则将引用失败',
|
tip4: '请勿修改引用内容,否则将引用失败',
|
||||||
@ -1904,7 +1941,7 @@ export default {
|
|||||||
yes: '是',
|
yes: '是',
|
||||||
no: '否',
|
no: '否',
|
||||||
live_tips: '优先HTTPS链接',
|
live_tips: '优先HTTPS链接',
|
||||||
stream_media_add_tips: '请在右侧添加流媒体信息...',
|
stream_media_add_tips: '请添加流媒体信息...',
|
||||||
stream_mobile_tips: 'IOS终端可能无法显示',
|
stream_mobile_tips: 'IOS终端可能无法显示',
|
||||||
json_params_error: '第三方参数解析失败,请检查参数格式是否正确',
|
json_params_error: '第三方参数解析失败,请检查参数格式是否正确',
|
||||||
inner_padding: '内边距',
|
inner_padding: '内边距',
|
||||||
@ -2142,8 +2179,8 @@ export default {
|
|||||||
play_circle: '循环播放',
|
play_circle: '循环播放',
|
||||||
video_links: '视频链接',
|
video_links: '视频链接',
|
||||||
web_url: '网页地址',
|
web_url: '网页地址',
|
||||||
video_add_tips: '请在右侧添加视频信息...',
|
video_add_tips: '请配置视频信息...',
|
||||||
link_add_tips_pre: '请在右侧配置网页信息..',
|
link_add_tips_pre: '请配置网页信息..',
|
||||||
web_add_tips_suf: '添加网页信息...',
|
web_add_tips_suf: '添加网页信息...',
|
||||||
panel_view_result_show: '图表结果',
|
panel_view_result_show: '图表结果',
|
||||||
panel_view_result_tips: '选择{0}会覆盖图表的结果展示数量,取值范围1~10000',
|
panel_view_result_tips: '选择{0}会覆盖图表的结果展示数量,取值范围1~10000',
|
||||||
|
@ -104,6 +104,14 @@ declare interface ChartBasicStyle {
|
|||||||
* 仪表盘样式
|
* 仪表盘样式
|
||||||
*/
|
*/
|
||||||
gaugeStyle: string
|
gaugeStyle: string
|
||||||
|
/**
|
||||||
|
* 仪表盘刻度显示
|
||||||
|
*/
|
||||||
|
gaugeAxisLine: boolean
|
||||||
|
/**
|
||||||
|
* 仪表盘百分比刻度
|
||||||
|
*/
|
||||||
|
gaugePercentLabel: boolean
|
||||||
/**
|
/**
|
||||||
* 配色方案
|
* 配色方案
|
||||||
*/
|
*/
|
||||||
@ -274,13 +282,19 @@ declare interface ChartTableHeaderAttr {
|
|||||||
*/
|
*/
|
||||||
tableHeaderSort: boolean
|
tableHeaderSort: boolean
|
||||||
/**
|
/**
|
||||||
|
* @deprecated since version 2.7.0 由提示统一控制
|
||||||
* 行头鼠标悬浮提示开关
|
* 行头鼠标悬浮提示开关
|
||||||
*/
|
*/
|
||||||
showRowTooltip: boolean
|
showRowTooltip: boolean
|
||||||
/**
|
/**
|
||||||
|
* @deprecated since version 2.7.0 由提示统一控制
|
||||||
* 列头鼠标悬浮提示开关
|
* 列头鼠标悬浮提示开关
|
||||||
*/
|
*/
|
||||||
showColTooltip: boolean
|
showColTooltip: boolean
|
||||||
|
/**
|
||||||
|
* 表头显示开关
|
||||||
|
*/
|
||||||
|
showTableHeader: boolean
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 单元格属性
|
* 单元格属性
|
||||||
@ -315,6 +329,7 @@ declare interface ChartTableCellAttr {
|
|||||||
*/
|
*/
|
||||||
tableItemSubBgColor: string
|
tableItemSubBgColor: string
|
||||||
/**
|
/**
|
||||||
|
* @deprecated since version 2.7.0 由提示统一控制
|
||||||
* 鼠标悬浮提示
|
* 鼠标悬浮提示
|
||||||
*/
|
*/
|
||||||
showTooltip: boolean
|
showTooltip: boolean
|
||||||
|
@ -14,6 +14,7 @@ import { setupCustomComponent } from '@/custom-component'
|
|||||||
import { installDirective } from '@/directive'
|
import { installDirective } from '@/directive'
|
||||||
import '@/utils/DateUtil'
|
import '@/utils/DateUtil'
|
||||||
import '@/permission'
|
import '@/permission'
|
||||||
|
import WebSocketPlugin from '../../websocket'
|
||||||
const setupAll = async () => {
|
const setupAll = async () => {
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
installDirective(app)
|
installDirective(app)
|
||||||
@ -23,6 +24,7 @@ const setupAll = async () => {
|
|||||||
setupElementPlus(app)
|
setupElementPlus(app)
|
||||||
setupCustomComponent(app)
|
setupCustomComponent(app)
|
||||||
setupElementPlusIcons(app)
|
setupElementPlusIcons(app)
|
||||||
|
app.use(WebSocketPlugin)
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ const DashboardEditor = defineAsyncComponent(() => import('@/views/dashboard/ind
|
|||||||
|
|
||||||
const Dashboard = defineAsyncComponent(() => import('./DashboardPreview.vue'))
|
const Dashboard = defineAsyncComponent(() => import('./DashboardPreview.vue'))
|
||||||
const ViewWrapper = defineAsyncComponent(() => import('./ViewWrapper.vue'))
|
const ViewWrapper = defineAsyncComponent(() => import('./ViewWrapper.vue'))
|
||||||
|
const Iframe = defineAsyncComponent(() => import('./Iframe.vue'))
|
||||||
const Dataset = defineAsyncComponent(() => import('@/views/visualized/data/dataset/index.vue'))
|
const Dataset = defineAsyncComponent(() => import('@/views/visualized/data/dataset/index.vue'))
|
||||||
const Datasource = defineAsyncComponent(
|
const Datasource = defineAsyncComponent(
|
||||||
() => import('@/views/visualized/data/datasource/index.vue')
|
() => import('@/views/visualized/data/datasource/index.vue')
|
||||||
@ -18,6 +19,9 @@ const ScreenPanel = defineAsyncComponent(() => import('@/views/data-visualizatio
|
|||||||
const DashboardPanel = defineAsyncComponent(
|
const DashboardPanel = defineAsyncComponent(
|
||||||
() => import('@/views/dashboard/DashboardPreviewShow.vue')
|
() => import('@/views/dashboard/DashboardPreviewShow.vue')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const Preview = defineAsyncComponent(() => import('@/views/data-visualization/PreviewCanvas.vue'))
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
componentName: propTypes.string.def('DashboardEditor')
|
componentName: propTypes.string.def('DashboardEditor')
|
||||||
})
|
})
|
||||||
@ -27,8 +31,10 @@ const componentMap = {
|
|||||||
DashboardEditor,
|
DashboardEditor,
|
||||||
VisualizationEditor,
|
VisualizationEditor,
|
||||||
ViewWrapper,
|
ViewWrapper,
|
||||||
|
Preview,
|
||||||
Dashboard,
|
Dashboard,
|
||||||
Dataset,
|
Dataset,
|
||||||
|
Iframe,
|
||||||
Datasource,
|
Datasource,
|
||||||
ScreenPanel,
|
ScreenPanel,
|
||||||
DashboardPanel
|
DashboardPanel
|
||||||
|
@ -39,7 +39,7 @@ onBeforeMount(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 添加外部参数
|
// 添加外部参数
|
||||||
let attachParam
|
let attachParams
|
||||||
await getOuterParamsInfo(embeddedStore.dvId).then(rsp => {
|
await getOuterParamsInfo(embeddedStore.dvId).then(rsp => {
|
||||||
dvMainStore.setNowPanelOuterParamsInfo(rsp.data)
|
dvMainStore.setNowPanelOuterParamsInfo(rsp.data)
|
||||||
})
|
})
|
||||||
@ -48,7 +48,7 @@ onBeforeMount(async () => {
|
|||||||
if (embeddedStore.outerParams) {
|
if (embeddedStore.outerParams) {
|
||||||
try {
|
try {
|
||||||
const outerPramsParse = JSON.parse(embeddedStore.outerParams)
|
const outerPramsParse = JSON.parse(embeddedStore.outerParams)
|
||||||
attachParam = outerPramsParse.attachParam
|
attachParams = outerPramsParse.attachParams
|
||||||
dvMainStore.setEmbeddedCallBack(outerPramsParse.callBackFlag || 'no')
|
dvMainStore.setEmbeddedCallBack(outerPramsParse.callBackFlag || 'no')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
@ -74,8 +74,8 @@ onBeforeMount(async () => {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
dashboardPreview.value.restore()
|
dashboardPreview.value.restore()
|
||||||
})
|
})
|
||||||
if (attachParam) {
|
if (attachParams) {
|
||||||
dvMainStore.addOuterParamsFilter(attachParam, canvasDataResult, 'outer')
|
dvMainStore.addOuterParamsFilter(attachParams, canvasDataResult, 'outer')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
19
core/core-frontend/src/pages/panel/Iframe.vue
Normal file
19
core/core-frontend/src/pages/panel/Iframe.vue
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useEmbedded } from '@/store/modules/embedded'
|
||||||
|
const embeddedStore = useEmbedded()
|
||||||
|
const outerUrl = computed(() => {
|
||||||
|
return embeddedStore.outerUrl
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<iframe class="de-jump_outer_url" :src="outerUrl" frameborder="0"></iframe>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.de-jump_outer_url {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -9,6 +9,7 @@ import { getOuterParamsInfo } from '@/api/visualization/outerParams'
|
|||||||
import { ElMessage } from 'element-plus-secondary'
|
import { ElMessage } from 'element-plus-secondary'
|
||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { XpackComponent } from '@/components/plugin'
|
||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
const interactiveStore = interactiveStoreWithOut()
|
const interactiveStore = interactiveStoreWithOut()
|
||||||
const embeddedStore = useEmbedded()
|
const embeddedStore = useEmbedded()
|
||||||
@ -17,7 +18,7 @@ const viewInfo = ref()
|
|||||||
const userViewEnlargeRef = ref()
|
const userViewEnlargeRef = ref()
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
const openHandler = ref(null)
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
canvasDataPreview: null,
|
canvasDataPreview: null,
|
||||||
canvasStylePreview: null,
|
canvasStylePreview: null,
|
||||||
@ -29,13 +30,12 @@ const state = reactive({
|
|||||||
|
|
||||||
// 目标校验: 需要校验targetSourceId 是否是当前可视化资源ID
|
// 目标校验: 需要校验targetSourceId 是否是当前可视化资源ID
|
||||||
const winMsgHandle = event => {
|
const winMsgHandle = event => {
|
||||||
console.info('PostMessage Params Received')
|
|
||||||
const msgInfo = event.data
|
const msgInfo = event.data
|
||||||
// 校验targetSourceId
|
// 校验targetSourceId
|
||||||
if (msgInfo && msgInfo.type === 'attachParams' && msgInfo.targetSourceId === state.chartId + '') {
|
if (msgInfo && msgInfo.type === 'attachParams' && msgInfo.targetSourceId === state.chartId + '') {
|
||||||
const attachParam = msgInfo.params
|
const attachParams = msgInfo.params
|
||||||
if (attachParam) {
|
if (attachParams) {
|
||||||
dvMainStore.addOuterParamsFilter(attachParam, state.canvasDataPreview, 'outer')
|
dvMainStore.addOuterParamsFilter(attachParams, state.canvasDataPreview, 'outer')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ onBeforeMount(async () => {
|
|||||||
window.addEventListener('message', winMsgHandle)
|
window.addEventListener('message', winMsgHandle)
|
||||||
|
|
||||||
// 添加外部参数
|
// 添加外部参数
|
||||||
let attachParam
|
let attachParams
|
||||||
await getOuterParamsInfo(embeddedStore.dvId).then(rsp => {
|
await getOuterParamsInfo(embeddedStore.dvId).then(rsp => {
|
||||||
dvMainStore.setNowPanelOuterParamsInfo(rsp.data)
|
dvMainStore.setNowPanelOuterParamsInfo(rsp.data)
|
||||||
})
|
})
|
||||||
@ -67,7 +67,7 @@ onBeforeMount(async () => {
|
|||||||
if (embeddedStore.outerParams) {
|
if (embeddedStore.outerParams) {
|
||||||
try {
|
try {
|
||||||
const outerPramsParse = JSON.parse(embeddedStore.outerParams)
|
const outerPramsParse = JSON.parse(embeddedStore.outerParams)
|
||||||
attachParam = outerPramsParse.attachParam
|
attachParams = outerPramsParse.attachParams
|
||||||
dvMainStore.setEmbeddedCallBack(outerPramsParse.callBackFlag || 'no')
|
dvMainStore.setEmbeddedCallBack(outerPramsParse.callBackFlag || 'no')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
@ -90,8 +90,8 @@ onBeforeMount(async () => {
|
|||||||
state.canvasViewInfoPreview = canvasViewInfoPreview
|
state.canvasViewInfoPreview = canvasViewInfoPreview
|
||||||
state.dvInfo = dvInfo
|
state.dvInfo = dvInfo
|
||||||
state.curPreviewGap = curPreviewGap
|
state.curPreviewGap = curPreviewGap
|
||||||
if (attachParam) {
|
if (attachParams) {
|
||||||
dvMainStore.addOuterParamsFilter(attachParam, canvasDataResult)
|
dvMainStore.addOuterParamsFilter(attachParams, canvasDataResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewInfo.value = canvasViewInfoPreview[embeddedStore.chartId]
|
viewInfo.value = canvasViewInfoPreview[embeddedStore.chartId]
|
||||||
@ -124,6 +124,32 @@ onBeforeMount(async () => {
|
|||||||
const userViewEnlargeOpen = () => {
|
const userViewEnlargeOpen = () => {
|
||||||
userViewEnlargeRef.value.dialogInit(state.canvasStylePreview, viewInfo.value, config.value)
|
userViewEnlargeRef.value.dialogInit(state.canvasStylePreview, viewInfo.value, config.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onPointClick = param => {
|
||||||
|
try {
|
||||||
|
console.info('de_inner_params send')
|
||||||
|
if (window['dataease-embedded-host'] && openHandler?.value) {
|
||||||
|
const pm = {
|
||||||
|
methodName: 'embeddedInteractive',
|
||||||
|
args: {
|
||||||
|
eventName: 'de_inner_params',
|
||||||
|
args: param
|
||||||
|
}
|
||||||
|
}
|
||||||
|
openHandler.value.invokeMethod(pm)
|
||||||
|
} else {
|
||||||
|
console.info('de_inner_params send to host')
|
||||||
|
const targetPm = {
|
||||||
|
type: 'dataease-embedded-interactive',
|
||||||
|
eventName: 'de_inner_params',
|
||||||
|
args: param
|
||||||
|
}
|
||||||
|
window.parent.postMessage(targetPm, '*')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('de_inner_params send error')
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -136,9 +162,11 @@ const userViewEnlargeOpen = () => {
|
|||||||
:dv-info="state.dvInfo"
|
:dv-info="state.dvInfo"
|
||||||
:canvas-view-info="state.canvasViewInfoPreview"
|
:canvas-view-info="state.canvasViewInfoPreview"
|
||||||
@userViewEnlargeOpen="userViewEnlargeOpen"
|
@userViewEnlargeOpen="userViewEnlargeOpen"
|
||||||
|
@onPointClick="onPointClick"
|
||||||
/>
|
/>
|
||||||
<user-view-enlarge ref="userViewEnlargeRef"></user-view-enlarge>
|
<user-view-enlarge ref="userViewEnlargeRef"></user-view-enlarge>
|
||||||
</div>
|
</div>
|
||||||
|
<XpackComponent ref="openHandler" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
@ -29,20 +29,24 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
start()
|
start()
|
||||||
loadStart()
|
loadStart()
|
||||||
checkPlatform()
|
checkPlatform()
|
||||||
|
let isDesktop = wsCache.get('app.desktop')
|
||||||
|
if (isDesktop === null) {
|
||||||
|
await appStore.setAppModel()
|
||||||
|
isDesktop = appStore.getDesktop
|
||||||
|
}
|
||||||
if (isMobile()) {
|
if (isMobile()) {
|
||||||
done()
|
done()
|
||||||
loadDone()
|
loadDone()
|
||||||
if (to.name === 'link') {
|
if (to.name === 'link') {
|
||||||
window.location.href = window.origin + '/mobile.html#' + to.path
|
window.location.href = window.origin + '/mobile.html#' + to.path
|
||||||
} else if (!isPlatformClient() && !isLarkPlatform()) {
|
} else if (
|
||||||
|
wsCache.get('user.token') ||
|
||||||
|
isDesktop ||
|
||||||
|
(!isPlatformClient() && !isLarkPlatform())
|
||||||
|
) {
|
||||||
window.location.href = window.origin + '/mobile.html#/index'
|
window.location.href = window.origin + '/mobile.html#/index'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let isDesktop = wsCache.get('app.desktop')
|
|
||||||
if (isDesktop === null) {
|
|
||||||
await appStore.setAppModel()
|
|
||||||
isDesktop = appStore.getDesktop
|
|
||||||
}
|
|
||||||
await appearanceStore.setAppearance()
|
await appearanceStore.setAppearance()
|
||||||
if (wsCache.get('user.token') || isDesktop) {
|
if (wsCache.get('user.token') || isDesktop) {
|
||||||
if (!userStore.getUid) {
|
if (!userStore.getUid) {
|
||||||
|
@ -33,7 +33,7 @@ export const dvMainStore = defineStore('dataVisualization', {
|
|||||||
datasetAreaCollapse: false
|
datasetAreaCollapse: false
|
||||||
},
|
},
|
||||||
embeddedCallBack: 'no', // 嵌入模式是否允许反馈参数
|
embeddedCallBack: 'no', // 嵌入模式是否允许反馈参数
|
||||||
editMode: 'edit', // 编辑器模式 edit preview
|
editMode: 'preview', // 编辑器模式 edit preview
|
||||||
mobileInPc: false,
|
mobileInPc: false,
|
||||||
firstLoadMap: [],
|
firstLoadMap: [],
|
||||||
canvasStyleData: { ...deepCopy(DEFAULT_CANVAS_STYLE_DATA_DARK), backgroundColor: null },
|
canvasStyleData: { ...deepCopy(DEFAULT_CANVAS_STYLE_DATA_DARK), backgroundColor: null },
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { store } from '../index'
|
import { store } from '../index'
|
||||||
import { clear } from '@/api/sync/syncTaskLog'
|
|
||||||
interface AppState {
|
interface AppState {
|
||||||
type: string
|
type: string
|
||||||
token: string
|
token: string
|
||||||
@ -14,6 +13,8 @@ interface AppState {
|
|||||||
opt: string
|
opt: string
|
||||||
createType: string
|
createType: string
|
||||||
templateParams: string
|
templateParams: string
|
||||||
|
jumpInfoParam: string
|
||||||
|
outerUrl: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const userStore = defineStore('embedded', {
|
export const userStore = defineStore('embedded', {
|
||||||
@ -30,13 +31,21 @@ export const userStore = defineStore('embedded', {
|
|||||||
resourceId: '',
|
resourceId: '',
|
||||||
opt: '',
|
opt: '',
|
||||||
createType: '',
|
createType: '',
|
||||||
templateParams: ''
|
templateParams: '',
|
||||||
|
outerUrl: '',
|
||||||
|
jumpInfoParam: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getType(): string {
|
getType(): string {
|
||||||
return this.type
|
return this.type
|
||||||
},
|
},
|
||||||
|
getJumpInfoParam(): string {
|
||||||
|
return this.jumpInfoParam
|
||||||
|
},
|
||||||
|
getOuterUrl(): string {
|
||||||
|
return this.outerUrl
|
||||||
|
},
|
||||||
getCreateType(): string {
|
getCreateType(): string {
|
||||||
return this.createType
|
return this.createType
|
||||||
},
|
},
|
||||||
@ -87,6 +96,12 @@ export const userStore = defineStore('embedded', {
|
|||||||
setType(type: string) {
|
setType(type: string) {
|
||||||
this.type = type
|
this.type = type
|
||||||
},
|
},
|
||||||
|
setOuterUrl(outerUrl: string) {
|
||||||
|
this.outerUrl = outerUrl
|
||||||
|
},
|
||||||
|
setJumpInfoParam(jumpInfoParam: string) {
|
||||||
|
this.jumpInfoParam = jumpInfoParam
|
||||||
|
},
|
||||||
setCreateType(createType: string) {
|
setCreateType(createType: string) {
|
||||||
this.createType = createType
|
this.createType = createType
|
||||||
},
|
},
|
||||||
@ -137,6 +152,8 @@ export const userStore = defineStore('embedded', {
|
|||||||
this.setTemplateParams('')
|
this.setTemplateParams('')
|
||||||
this.setResourceId('')
|
this.setResourceId('')
|
||||||
this.setDvId('')
|
this.setDvId('')
|
||||||
|
this.setJumpInfoParam('')
|
||||||
|
this.setOuterUrl('')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -376,7 +376,7 @@ em {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.color-dataV {
|
.color-dataV {
|
||||||
background: rgb(0, 214, 185);
|
background: rgb(0, 214, 185)!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-dataset {
|
.color-dataset {
|
||||||
@ -392,7 +392,7 @@ em {
|
|||||||
}
|
}
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
font-synthesis: style weight!important;
|
font-synthesis: style weight !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ed-date-editor .ed-range__icon {
|
.ed-date-editor .ed-range__icon {
|
||||||
@ -400,12 +400,94 @@ strong {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ed-picker__popper {
|
.ed-picker__popper {
|
||||||
--ed-datepicker-border-color: #DEE0E3 !important;
|
--ed-datepicker-border-color: #dee0e3 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ed-dialog__headerbtn {
|
.ed-dialog__headerbtn {
|
||||||
top: 21px !important;
|
top: 21px !important;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.de-message-export {
|
||||||
|
min-width: 20px !important;
|
||||||
|
padding: 16px 20px !important;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0px 4px 8px 0px #1f23291a;
|
||||||
|
|
||||||
|
& > p {
|
||||||
|
font-family: AlibabaPuHuiTi;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
text-align: left;
|
||||||
|
color: #1f2329;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-text {
|
||||||
|
padding: 2px 4px;
|
||||||
|
&:hover {
|
||||||
|
background: var(--primary10, #3370ff1a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ed-message__closeBtn {
|
||||||
|
margin-left: 28px;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
position: relative;
|
||||||
|
margin-right: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
transform: translateY(0);
|
||||||
|
color: #646a73;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ed-message__icon {
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.de-message-loading {
|
||||||
|
border: 1px solid var(--primary, #3370ff) !important;
|
||||||
|
background: #f0f4ff !important;
|
||||||
|
@keyframes circle {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ed-message__icon {
|
||||||
|
color: var(--primary, #3370ff);
|
||||||
|
animation: circle infinite 0.75s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.de-message-error {
|
||||||
|
border: 1px solid var(--deDanger, #f54a45) !important;
|
||||||
|
background: var(--deWhitemsgDeDanger, #fef1f1) !important;
|
||||||
|
|
||||||
|
.ed-message__icon {
|
||||||
|
color: var(--deDanger, #f54a45);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.de-message-success {
|
||||||
|
border: 1px solid var(--deSuccess, #34c724) !important;
|
||||||
|
background: var(--deWhitemsgDeSuccess, #f0fbef) !important;
|
||||||
|
|
||||||
|
.ed-message__icon {
|
||||||
|
color: var(--deSuccess, #34c724);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,8 +119,8 @@ export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
|
|||||||
const canvasStyleResult = JSON.parse(canvasInfo.canvasStyleData)
|
const canvasStyleResult = JSON.parse(canvasInfo.canvasStyleData)
|
||||||
const canvasViewInfoPreview = canvasInfo.canvasViewInfo
|
const canvasViewInfoPreview = canvasInfo.canvasViewInfo
|
||||||
//历史字段适配
|
//历史字段适配
|
||||||
canvasStyleResult.component.seniorStyleSetting =
|
canvasStyleResult.component['seniorStyleSetting'] =
|
||||||
canvasStyleResult.component.seniorStyleSetting || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
canvasStyleResult.component['seniorStyleSetting'] || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
||||||
|
|
||||||
canvasDataResult.forEach(componentItem => {
|
canvasDataResult.forEach(componentItem => {
|
||||||
componentItem['canvasActive'] = false
|
componentItem['canvasActive'] = false
|
||||||
@ -420,6 +420,9 @@ export async function decompressionPre(params, callBack) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const sourceCanvasStyle = JSON.parse(deTemplateDataTemp['canvasStyleData'])
|
const sourceCanvasStyle = JSON.parse(deTemplateDataTemp['canvasStyleData'])
|
||||||
|
//历史字段适配
|
||||||
|
sourceCanvasStyle.component['seniorStyleSetting'] =
|
||||||
|
sourceCanvasStyle.component['seniorStyleSetting'] || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
||||||
deTemplateData = {
|
deTemplateData = {
|
||||||
canvasStyleData: sourceCanvasStyle,
|
canvasStyleData: sourceCanvasStyle,
|
||||||
componentData: sourceComponentData,
|
componentData: sourceComponentData,
|
||||||
@ -432,19 +435,28 @@ export async function decompressionPre(params, callBack) {
|
|||||||
callBack(deTemplateData)
|
callBack(deTemplateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function trackBarStyleCheck(element, trackbarStyle, scale) {
|
export function trackBarStyleCheck(element, trackbarStyle, _scale, trackMenuNumber) {
|
||||||
const { width, height } = element.style
|
const { width, height } = element.style
|
||||||
const widthReal = width
|
const widthReal = width
|
||||||
const heightReal = height
|
const heightReal = height
|
||||||
|
// 浮窗高度
|
||||||
|
function calculateTrackHeight(trackMenuNumber) {
|
||||||
|
if (trackMenuNumber === 2) {
|
||||||
|
return 75
|
||||||
|
} else {
|
||||||
|
const increment = Math.floor(trackMenuNumber - 2) * 35
|
||||||
|
return 75 + increment
|
||||||
|
}
|
||||||
|
}
|
||||||
if (trackbarStyle.left < 0) {
|
if (trackbarStyle.left < 0) {
|
||||||
trackbarStyle.left = 0
|
trackbarStyle.left = 0
|
||||||
} else if (widthReal - trackbarStyle.left < 60) {
|
} else if (widthReal - trackbarStyle.left < 60) {
|
||||||
trackbarStyle.left = trackbarStyle.left - 60
|
trackbarStyle.left = trackbarStyle.left - 60
|
||||||
}
|
}
|
||||||
|
const trackMenuHeight = calculateTrackHeight(trackMenuNumber)
|
||||||
if (trackbarStyle.top < 0) {
|
if (trackbarStyle.top < 0) {
|
||||||
trackbarStyle.top = 0
|
trackbarStyle.top = 0
|
||||||
} else if (heightReal - trackbarStyle.top < 100) {
|
} else if (trackbarStyle.top + trackMenuHeight + 60 > heightReal) {
|
||||||
trackbarStyle.top = trackbarStyle.top - 100
|
trackbarStyle.top = trackbarStyle.top - trackMenuHeight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ const canvasInit = (isFistLoad = true) => {
|
|||||||
}
|
}
|
||||||
// afterInit
|
// afterInit
|
||||||
dvMainStore.setDataPrepareState(true)
|
dvMainStore.setDataPrepareState(true)
|
||||||
if (isMainCanvas(canvasId.value.id) && isFistLoad) {
|
if (isMainCanvas(canvasId.value) && isFistLoad) {
|
||||||
snapshotStore.recordSnapshotCache('renderChart')
|
snapshotStore.recordSnapshotCache('renderChart')
|
||||||
}
|
}
|
||||||
}, 500)
|
}, 500)
|
||||||
@ -289,10 +289,9 @@ defineExpose({
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
&::-webkit-scrollbar {
|
}
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.render-active {
|
.render-active {
|
||||||
|
@ -231,7 +231,12 @@ init()
|
|||||||
<div @keydown.stop @keyup.stop style="width: 100%; margin-bottom: 16px">
|
<div @keydown.stop @keyup.stop style="width: 100%; margin-bottom: 16px">
|
||||||
<!--仪表盘-->
|
<!--仪表盘-->
|
||||||
<el-col v-show="showProperty('gaugeThreshold')">
|
<el-col v-show="showProperty('gaugeThreshold')">
|
||||||
<el-form ref="thresholdForm" :model="state.thresholdForm" label-position="top">
|
<el-form
|
||||||
|
:model="state.thresholdForm"
|
||||||
|
ref="thresholdForm"
|
||||||
|
label-position="top"
|
||||||
|
@submit.prevent
|
||||||
|
>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="t('chart.threshold_range') + '(%)'"
|
:label="t('chart.threshold_range') + '(%)'"
|
||||||
class="form-item"
|
class="form-item"
|
||||||
@ -252,7 +257,7 @@ init()
|
|||||||
<el-tooltip effect="dark" placement="bottom">
|
<el-tooltip effect="dark" placement="bottom">
|
||||||
<el-icon style="margin-left: 10px"><InfoFilled /></el-icon>
|
<el-icon style="margin-left: 10px"><InfoFilled /></el-icon>
|
||||||
<template #content>
|
<template #content>
|
||||||
阈值设置,决定仪表盘区间颜色,为空则不开启阈值,范围(0-100),逐级递增
|
条件样式设置,决定仪表盘区间颜色,为空则不开启阈值,范围(0-100),逐级递增
|
||||||
<br />
|
<br />
|
||||||
例如:输入 30,70;表示:分为3段,分别为[0,30],(30,70],(70,100]
|
例如:输入 30,70;表示:分为3段,分别为[0,30],(30,70],(70,100]
|
||||||
</template>
|
</template>
|
||||||
@ -261,7 +266,12 @@ init()
|
|||||||
</el-form>
|
</el-form>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-show="showProperty('liquidThreshold')">
|
<el-col v-show="showProperty('liquidThreshold')">
|
||||||
<el-form ref="thresholdForm" :model="state.thresholdForm" label-position="top">
|
<el-form
|
||||||
|
:model="state.thresholdForm"
|
||||||
|
ref="thresholdForm"
|
||||||
|
label-position="top"
|
||||||
|
@submit.prevent
|
||||||
|
>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="t('chart.threshold_range') + '(%)'"
|
:label="t('chart.threshold_range') + '(%)'"
|
||||||
class="form-item"
|
class="form-item"
|
||||||
@ -282,7 +292,7 @@ init()
|
|||||||
<el-tooltip effect="dark" placement="bottom">
|
<el-tooltip effect="dark" placement="bottom">
|
||||||
<el-icon style="margin-left: 10px"><InfoFilled /></el-icon>
|
<el-icon style="margin-left: 10px"><InfoFilled /></el-icon>
|
||||||
<template #content>
|
<template #content>
|
||||||
阈值设置,决定水波图颜色,为空则不开启阈值,范围(0-100),逐级递增
|
条件样式设置,决定水波图颜色,为空则不开启阈值,范围(0-100),逐级递增
|
||||||
<br />
|
<br />
|
||||||
例如:输入 30,70;表示:分为3段,分别为[0,30],(30,70],(70,100]
|
例如:输入 30,70;表示:分为3段,分别为[0,30],(30,70],(70,100]
|
||||||
</template>
|
</template>
|
||||||
@ -360,7 +370,7 @@ init()
|
|||||||
<el-col v-if="props.chart.type && props.chart.type === 'indicator'">
|
<el-col v-if="props.chart.type && props.chart.type === 'indicator'">
|
||||||
<el-col>
|
<el-col>
|
||||||
<div class="inner-container">
|
<div class="inner-container">
|
||||||
<span class="label" :class="'label-' + props.themes">阈值设置</span>
|
<span class="label" :class="'label-' + props.themes">条件样式设置</span>
|
||||||
<span class="right-btns">
|
<span class="right-btns">
|
||||||
<span
|
<span
|
||||||
class="set-text-info"
|
class="set-text-info"
|
||||||
@ -458,7 +468,7 @@ init()
|
|||||||
<el-col v-show="showProperty('tableThreshold')">
|
<el-col v-show="showProperty('tableThreshold')">
|
||||||
<el-col>
|
<el-col>
|
||||||
<div class="inner-container">
|
<div class="inner-container">
|
||||||
<span class="label" :class="'label-' + props.themes">阈值设置</span>
|
<span class="label" :class="'label-' + props.themes">条件样式设置</span>
|
||||||
<span class="right-btns">
|
<span class="right-btns">
|
||||||
<span
|
<span
|
||||||
class="set-text-info"
|
class="set-text-info"
|
||||||
|
@ -436,7 +436,7 @@ init()
|
|||||||
<template #icon>
|
<template #icon>
|
||||||
<Icon name="icon_add_outlined" />
|
<Icon name="icon_add_outlined" />
|
||||||
</template>
|
</template>
|
||||||
{{ t('chart.add_condition') }}
|
{{ t('chart.add_style') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -451,7 +451,7 @@ init()
|
|||||||
<template #icon>
|
<template #icon>
|
||||||
<Icon name="icon_add_outlined" />
|
<Icon name="icon_add_outlined" />
|
||||||
</template>
|
</template>
|
||||||
{{ t('chart.add_threshold') }}
|
{{ t('chart.add_condition') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</template>
|
</template>
|
||||||
|
@ -354,13 +354,14 @@ watch(
|
|||||||
/>
|
/>
|
||||||
</collapse-switch-item>
|
</collapse-switch-item>
|
||||||
<collapse-switch-item
|
<collapse-switch-item
|
||||||
:themes="themes"
|
|
||||||
v-if="showProperties('tooltip-selector')"
|
v-if="showProperties('tooltip-selector')"
|
||||||
v-model="chart.customAttr.tooltip.show"
|
v-model="chart.customAttr.tooltip.show"
|
||||||
|
:themes="themes"
|
||||||
:change-model="chart.customAttr.tooltip"
|
:change-model="chart.customAttr.tooltip"
|
||||||
@modelChange="val => onTooltipChange({ data: val }, 'show')"
|
|
||||||
name="tooltip"
|
|
||||||
:title="$t('chart.tooltip')"
|
:title="$t('chart.tooltip')"
|
||||||
|
:show-switch="propertyInnerAll['tooltip-selector'].includes('show')"
|
||||||
|
name="tooltip"
|
||||||
|
@modelChange="val => onTooltipChange({ data: val }, 'show')"
|
||||||
>
|
>
|
||||||
<tooltip-selector
|
<tooltip-selector
|
||||||
class="attr-selector"
|
class="attr-selector"
|
||||||
@ -371,11 +372,15 @@ watch(
|
|||||||
@onExtTooltipChange="onExtTooltipChange"
|
@onExtTooltipChange="onExtTooltipChange"
|
||||||
/>
|
/>
|
||||||
</collapse-switch-item>
|
</collapse-switch-item>
|
||||||
<el-collapse-item
|
<collapse-switch-item
|
||||||
:effect="themes"
|
|
||||||
name="tableHeader"
|
|
||||||
:title="t('chart.table_header')"
|
|
||||||
v-if="showProperties('table-header-selector')"
|
v-if="showProperties('table-header-selector')"
|
||||||
|
v-model="chart.customAttr.tableHeader.showTableHeader"
|
||||||
|
:change-model="chart.customAttr.tableHeader"
|
||||||
|
:effect="themes"
|
||||||
|
:title="t('chart.table_header')"
|
||||||
|
:show-switch="propertyInnerAll['table-header-selector'].includes('showTableHeader')"
|
||||||
|
name="tableHeader"
|
||||||
|
@modelChange="val => onTableHeaderChange(val, 'showTableHeader')"
|
||||||
>
|
>
|
||||||
<table-header-selector
|
<table-header-selector
|
||||||
:property-inner="propertyInnerAll['table-header-selector']"
|
:property-inner="propertyInnerAll['table-header-selector']"
|
||||||
@ -383,7 +388,7 @@ watch(
|
|||||||
:chart="chart"
|
:chart="chart"
|
||||||
@onTableHeaderChange="onTableHeaderChange"
|
@onTableHeaderChange="onTableHeaderChange"
|
||||||
/>
|
/>
|
||||||
</el-collapse-item>
|
</collapse-switch-item>
|
||||||
<el-collapse-item
|
<el-collapse-item
|
||||||
:effect="themes"
|
:effect="themes"
|
||||||
name="tableCell"
|
name="tableCell"
|
||||||
@ -434,7 +439,7 @@ watch(
|
|||||||
:change-model="chart.customStyle.xAxis"
|
:change-model="chart.customStyle.xAxis"
|
||||||
@modelChange="val => onChangeXAxisForm(val, 'show')"
|
@modelChange="val => onChangeXAxisForm(val, 'show')"
|
||||||
name="xAxis"
|
name="xAxis"
|
||||||
:title="chart.type === 'bidirectional-bar' ? $t('chart.yAxis') : t('chart.xAxis')"
|
:title="selectorSpec['x-axis-selector']?.title"
|
||||||
>
|
>
|
||||||
<x-axis-selector
|
<x-axis-selector
|
||||||
class="attr-selector"
|
class="attr-selector"
|
||||||
@ -469,7 +474,7 @@ watch(
|
|||||||
:change-model="chart.customStyle.yAxis"
|
:change-model="chart.customStyle.yAxis"
|
||||||
@modelChange="val => onChangeYAxisForm(val, 'show')"
|
@modelChange="val => onChangeYAxisForm(val, 'show')"
|
||||||
name="yAxis"
|
name="yAxis"
|
||||||
:title="chart.type === 'bidirectional-bar' ? $t('chart.xAxis') : $t('chart.yAxis')"
|
:title="selectorSpec['dual-y-axis-selector']?.title"
|
||||||
>
|
>
|
||||||
<dual-y-axis-selector
|
<dual-y-axis-selector
|
||||||
class="attr-selector"
|
class="attr-selector"
|
||||||
|
@ -834,6 +834,34 @@ onMounted(() => {
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
v-if="showProperty('gaugeAxisLine')"
|
||||||
|
class="form-item"
|
||||||
|
:class="'form-item-' + themes"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
v-model="state.basicStyleForm.gaugeAxisLine"
|
||||||
|
:effect="themes"
|
||||||
|
size="small"
|
||||||
|
@change="changeBasicStyle('gaugeAxisLine')"
|
||||||
|
>
|
||||||
|
{{ t('chart.gauge_axis_label') }}</el-checkbox
|
||||||
|
>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
v-if="showProperty('gaugePercentLabel') && state.basicStyleForm.gaugeAxisLine"
|
||||||
|
class="form-item"
|
||||||
|
:class="'form-item-' + themes"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
v-model="state.basicStyleForm.gaugePercentLabel"
|
||||||
|
:effect="themes"
|
||||||
|
size="small"
|
||||||
|
@change="changeBasicStyle('gaugePercentLabel')"
|
||||||
|
>
|
||||||
|
{{ t('chart.gauge_percentage_tick') }}</el-checkbox
|
||||||
|
>
|
||||||
|
</el-form-item>
|
||||||
<!--gauge end-->
|
<!--gauge end-->
|
||||||
<!--bar start-->
|
<!--bar start-->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
@ -7,12 +7,11 @@ import cloneDeep from 'lodash-es/cloneDeep'
|
|||||||
import defaultsDeep from 'lodash-es/defaultsDeep'
|
import defaultsDeep from 'lodash-es/defaultsDeep'
|
||||||
import { formatterType, unitType } from '../../../js/formatter'
|
import { formatterType, unitType } from '../../../js/formatter'
|
||||||
import { fieldType } from '@/utils/attr'
|
import { fieldType } from '@/utils/attr'
|
||||||
import { partition, uniqWith, isEqual } from 'lodash-es'
|
import { partition } from 'lodash-es'
|
||||||
import chartViewManager from '../../../js/panel'
|
import chartViewManager from '../../../js/panel'
|
||||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
import { deepCopy } from '@/utils/utils'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
@ -41,55 +40,54 @@ const quotaData = ref<Axis[]>(inject('quotaData'))
|
|||||||
const showSeriesTooltipFormatter = computed(() => {
|
const showSeriesTooltipFormatter = computed(() => {
|
||||||
return showProperty('seriesTooltipFormatter') && !batchOptStatus.value && props.chart.id
|
return showProperty('seriesTooltipFormatter') && !batchOptStatus.value && props.chart.id
|
||||||
})
|
})
|
||||||
// 初始化系列提示
|
// 切换图表类型直接重置为默认
|
||||||
const initSeriesTooltip = () => {
|
const changeChartType = () => {
|
||||||
if (!showSeriesTooltipFormatter.value) {
|
if (!showSeriesTooltipFormatter.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
curSeriesFormatter.value = {}
|
||||||
const formatter = state.tooltipForm.seriesTooltipFormatter
|
const formatter = state.tooltipForm.seriesTooltipFormatter
|
||||||
const seriesAxisMap = formatter.reduce((pre, next) => {
|
|
||||||
next.seriesId = next.seriesId ?? next.id
|
|
||||||
pre[next.seriesId] = next
|
|
||||||
return pre
|
|
||||||
}, {})
|
|
||||||
// 新增图表
|
|
||||||
if (!quotaAxis.value?.length) {
|
|
||||||
if (!formatter.length) {
|
|
||||||
quotaData.value?.forEach(i => formatter.push({ ...i, seriesId: i.id, show: false }))
|
|
||||||
}
|
|
||||||
curSeriesFormatter.value = {}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
formatter.splice(0, formatter.length)
|
formatter.splice(0, formatter.length)
|
||||||
const axisIds = quotaAxis.value?.map(i => i.id)
|
const axisIds = []
|
||||||
const allQuotaAxis = quotaAxis.value?.concat(
|
quotaAxis.value.forEach(axis => {
|
||||||
quotaData.value?.filter(ele => !axisIds.includes(ele.id))
|
formatter.push({
|
||||||
)
|
...axis,
|
||||||
const axisMap = allQuotaAxis.reduce((pre, next, index) => {
|
show: true
|
||||||
let tmp = {
|
})
|
||||||
...next,
|
axisIds.push(axis.id)
|
||||||
seriesId: next.seriesId ?? next.id,
|
})
|
||||||
show: index <= quotaAxis.value.length - 1,
|
quotaData.value.forEach(quotaAxis => {
|
||||||
summary: COUNT_DE_TYPE.includes(next.deType) ? 'count' : 'sum'
|
if (!axisIds.includes(quotaAxis.id)) {
|
||||||
} as SeriesFormatter
|
formatter.push({
|
||||||
if (seriesAxisMap[tmp.seriesId]) {
|
...quotaAxis,
|
||||||
tmp = {
|
seriesId: quotaAxis.id,
|
||||||
...tmp,
|
show: false
|
||||||
formatterCfg: seriesAxisMap[tmp.seriesId].formatterCfg,
|
})
|
||||||
show: seriesAxisMap[tmp.seriesId].show,
|
}
|
||||||
summary: seriesAxisMap[tmp.seriesId].summary,
|
})
|
||||||
chartShowName: seriesAxisMap[tmp.seriesId].chartShowName
|
emit('onTooltipChange', { data: state.tooltipForm, render: false }, 'seriesTooltipFormatter')
|
||||||
}
|
emit('onExtTooltipChange', extTooltip.value)
|
||||||
|
}
|
||||||
|
// 切换数据集
|
||||||
|
const changeDataset = () => {
|
||||||
|
curSeriesFormatter.value = {}
|
||||||
|
const formatter = state.tooltipForm.seriesTooltipFormatter
|
||||||
|
const quotaIds = quotaData.value.map(i => i.id)
|
||||||
|
for (let i = formatter.length - 1; i >= 0; i--) {
|
||||||
|
if (!quotaIds.includes(formatter[i].id)) {
|
||||||
|
formatter.splice(i, 1)
|
||||||
}
|
}
|
||||||
formatter.push(tmp)
|
|
||||||
pre[tmp.seriesId] = tmp
|
|
||||||
return pre
|
|
||||||
}, {})
|
|
||||||
if (!curSeriesFormatter.value || !axisMap[curSeriesFormatter.value.seriesId]) {
|
|
||||||
curSeriesFormatter.value = axisMap[formatter[0].seriesId]
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
curSeriesFormatter.value = axisMap[curSeriesFormatter.value.seriesId]
|
const formatterIds = formatter.map(i => i.id)
|
||||||
|
quotaData.value.forEach(axis => {
|
||||||
|
if (!formatterIds.includes(axis.id)) {
|
||||||
|
formatter.push({
|
||||||
|
...axis,
|
||||||
|
seriesId: axis.id,
|
||||||
|
show: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const AXIS_PROP: AxisType[] = ['yAxis', 'yAxisExt', 'extBubble']
|
const AXIS_PROP: AxisType[] = ['yAxis', 'yAxisExt', 'extBubble']
|
||||||
const quotaAxis = computed(() => {
|
const quotaAxis = computed(() => {
|
||||||
@ -173,16 +171,6 @@ watch(
|
|||||||
},
|
},
|
||||||
{ deep: false }
|
{ deep: false }
|
||||||
)
|
)
|
||||||
watch(
|
|
||||||
[quotaData, () => props.chart.type],
|
|
||||||
newVal => {
|
|
||||||
if (!newVal?.[0]?.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
initSeriesTooltip()
|
|
||||||
},
|
|
||||||
{ deep: false }
|
|
||||||
)
|
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
tooltipForm: {
|
tooltipForm: {
|
||||||
@ -373,6 +361,8 @@ onMounted(() => {
|
|||||||
useEmitt({ name: 'addAxis', callback: updateSeriesTooltipFormatter })
|
useEmitt({ name: 'addAxis', callback: updateSeriesTooltipFormatter })
|
||||||
useEmitt({ name: 'removeAxis', callback: updateSeriesTooltipFormatter })
|
useEmitt({ name: 'removeAxis', callback: updateSeriesTooltipFormatter })
|
||||||
useEmitt({ name: 'updateAxis', callback: updateSeriesTooltipFormatter })
|
useEmitt({ name: 'updateAxis', callback: updateSeriesTooltipFormatter })
|
||||||
|
useEmitt({ name: 'chart-type-change', callback: changeChartType })
|
||||||
|
useEmitt({ name: 'dataset-change', callback: changeDataset })
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -255,7 +255,11 @@ onMounted(() => {
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<el-divider class="m-divider" :class="'m-divider--' + themes" />
|
<el-divider
|
||||||
|
v-if="showProperty('splitLine') || showProperty('axisLine')"
|
||||||
|
class="m-divider"
|
||||||
|
:class="'m-divider--' + themes"
|
||||||
|
/>
|
||||||
<el-form-item class="form-item" :class="'form-item-' + themes" v-if="showProperty('axisLine')">
|
<el-form-item class="form-item" :class="'form-item-' + themes" v-if="showProperty('axisLine')">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
size="small"
|
size="small"
|
||||||
@ -325,7 +329,11 @@ onMounted(() => {
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<el-divider class="m-divider" :class="'m-divider--' + themes" />
|
<el-divider
|
||||||
|
v-if="showProperty('axisLabel')"
|
||||||
|
class="m-divider"
|
||||||
|
:class="'m-divider--' + themes"
|
||||||
|
/>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
class="form-item form-item-checkbox"
|
class="form-item form-item-checkbox"
|
||||||
:class="{
|
:class="{
|
||||||
|
@ -234,20 +234,6 @@ onMounted(() => {
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-form-item
|
|
||||||
class="form-item"
|
|
||||||
:class="'form-item-' + themes"
|
|
||||||
v-if="showProperty('showTooltip')"
|
|
||||||
>
|
|
||||||
<el-checkbox
|
|
||||||
size="small"
|
|
||||||
:effect="themes"
|
|
||||||
v-model="state.tableCellForm.showTooltip"
|
|
||||||
@change="changeTableCell('showTooltip')"
|
|
||||||
>
|
|
||||||
{{ t('chart.table_show_cell_tooltip') }}
|
|
||||||
</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -66,7 +66,12 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-form ref="tableHeaderForm" :model="state.tableHeaderForm" label-position="top">
|
<el-form
|
||||||
|
:model="state.tableHeaderForm"
|
||||||
|
:disabled="!state.tableHeaderForm.showTableHeader"
|
||||||
|
ref="tableHeaderForm"
|
||||||
|
label-position="top"
|
||||||
|
>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:label="t('chart.backgroundColor')"
|
:label="t('chart.backgroundColor')"
|
||||||
class="form-item"
|
class="form-item"
|
||||||
@ -245,34 +250,6 @@ onMounted(() => {
|
|||||||
{{ t('chart.table_header_sort') }}
|
{{ t('chart.table_header_sort') }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
|
||||||
class="form-item"
|
|
||||||
:class="'form-item-' + themes"
|
|
||||||
v-if="showProperty('showColTooltip')"
|
|
||||||
>
|
|
||||||
<el-checkbox
|
|
||||||
size="small"
|
|
||||||
:effect="themes"
|
|
||||||
v-model="state.tableHeaderForm.showColTooltip"
|
|
||||||
@change="changeTableHeader('showColTooltip')"
|
|
||||||
>
|
|
||||||
{{ t('chart.table_show_col_tooltip') }}
|
|
||||||
</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
class="form-item"
|
|
||||||
:class="'form-item-' + themes"
|
|
||||||
v-if="showProperty('showRowTooltip')"
|
|
||||||
>
|
|
||||||
<el-checkbox
|
|
||||||
size="small"
|
|
||||||
:effect="themes"
|
|
||||||
v-model="state.tableHeaderForm.showRowTooltip"
|
|
||||||
@change="changeTableHeader('showRowTooltip')"
|
|
||||||
>
|
|
||||||
{{ t('chart.table_show_row_tooltip') }}
|
|
||||||
</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ const state = reactive({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const filedList = computed(() => {
|
const filedList = computed(() => {
|
||||||
return [...state.dimension, ...state.quota].filter(ele => ele.id !== 'count')
|
return [...state.dimension, ...state.quota].filter(ele => ele.id !== 'count' && !!ele.summary)
|
||||||
})
|
})
|
||||||
|
|
||||||
provide('filedList', () => filedList.value)
|
provide('filedList', () => filedList.value)
|
||||||
@ -211,6 +211,7 @@ const getFields = (id, chartId) => {
|
|||||||
state.quota = (res.quotaList as unknown as Field[]) || []
|
state.quota = (res.quotaList as unknown as Field[]) || []
|
||||||
state.dimensionData = JSON.parse(JSON.stringify(state.dimension))
|
state.dimensionData = JSON.parse(JSON.stringify(state.dimension))
|
||||||
state.quotaData = JSON.parse(JSON.stringify(state.quota))
|
state.quotaData = JSON.parse(JSON.stringify(state.quota))
|
||||||
|
emitter.emit('dataset-change')
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
state.dimension = []
|
state.dimension = []
|
||||||
@ -739,6 +740,7 @@ const onAreaChange = val => {
|
|||||||
const onTypeChange = (render, type) => {
|
const onTypeChange = (render, type) => {
|
||||||
view.value.render = render
|
view.value.render = render
|
||||||
view.value.type = type
|
view.value.type = type
|
||||||
|
emitter.emit('chart-type-change')
|
||||||
// 处理配置项默认值,不同图表的同一配置项默认值不同
|
// 处理配置项默认值,不同图表的同一配置项默认值不同
|
||||||
const chartViewInstance = chartViewManager.getChartView(view.value.render, view.value.type)
|
const chartViewInstance = chartViewManager.getChartView(view.value.render, view.value.type)
|
||||||
if (chartViewInstance) {
|
if (chartViewInstance) {
|
||||||
@ -3289,7 +3291,7 @@ span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:deep(.ed-tabs__content) {
|
:deep(.ed-tabs__content) {
|
||||||
height: calc(100% - 33px);
|
height: calc(100% - 35px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,8 @@ export const DEFAULT_TABLE_HEADER: ChartTableHeaderAttr = {
|
|||||||
tableTitleHeight: 36,
|
tableTitleHeight: 36,
|
||||||
tableHeaderSort: false,
|
tableHeaderSort: false,
|
||||||
showColTooltip: false,
|
showColTooltip: false,
|
||||||
showRowTooltip: false
|
showRowTooltip: false,
|
||||||
|
showTableHeader: true
|
||||||
}
|
}
|
||||||
export const DEFAULT_TABLE_CELL: ChartTableCellAttr = {
|
export const DEFAULT_TABLE_CELL: ChartTableCellAttr = {
|
||||||
tableFontColor: '#000000',
|
tableFontColor: '#000000',
|
||||||
@ -1445,7 +1446,9 @@ export const DEFAULT_BASIC_STYLE: ChartBasicStyle = {
|
|||||||
tableLayoutMode: 'grid',
|
tableLayoutMode: 'grid',
|
||||||
calcTopN: false,
|
calcTopN: false,
|
||||||
topN: 5,
|
topN: 5,
|
||||||
topNLabel: '其他'
|
topNLabel: '其他',
|
||||||
|
gaugeAxisLine: true,
|
||||||
|
gaugePercentLabel: true
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BASE_VIEW_CONFIG = {
|
export const BASE_VIEW_CONFIG = {
|
||||||
|
@ -26,7 +26,7 @@ export class Bar extends G2PlotChartView<ColumnOptions, Column> {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...BAR_EDITOR_PROPERTY_INNER,
|
...BAR_EDITOR_PROPERTY_INNER,
|
||||||
'label-selector': ['vPosition', 'seriesLabelFormatter'],
|
'label-selector': ['vPosition', 'seriesLabelFormatter'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'y-axis-selector': [...BAR_EDITOR_PROPERTY_INNER['y-axis-selector'], 'axisLabelFormatter']
|
'y-axis-selector': [...BAR_EDITOR_PROPERTY_INNER['y-axis-selector'], 'axisLabelFormatter']
|
||||||
}
|
}
|
||||||
protected baseOptions: ColumnOptions = {
|
protected baseOptions: ColumnOptions = {
|
||||||
@ -236,7 +236,7 @@ export class StackBar extends Bar {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...this['propertyInner'],
|
...this['propertyInner'],
|
||||||
'label-selector': [...BAR_EDITOR_PROPERTY_INNER['label-selector'], 'vPosition'],
|
'label-selector': [...BAR_EDITOR_PROPERTY_INNER['label-selector'], 'vPosition'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter']
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter', 'show']
|
||||||
}
|
}
|
||||||
protected configLabel(chart: Chart, options: ColumnOptions): ColumnOptions {
|
protected configLabel(chart: Chart, options: ColumnOptions): ColumnOptions {
|
||||||
const baseOptions = super.configLabel(chart, options)
|
const baseOptions = super.configLabel(chart, options)
|
||||||
@ -372,7 +372,7 @@ export class PercentageStackBar extends GroupStackBar {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...this['propertyInner'],
|
...this['propertyInner'],
|
||||||
'label-selector': ['color', 'fontSize', 'vPosition', 'reserveDecimalCount'],
|
'label-selector': ['color', 'fontSize', 'vPosition', 'reserveDecimalCount'],
|
||||||
'tooltip-selector': ['color', 'fontSize']
|
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'show']
|
||||||
}
|
}
|
||||||
protected configLabel(chart: Chart, options: ColumnOptions): ColumnOptions {
|
protected configLabel(chart: Chart, options: ColumnOptions): ColumnOptions {
|
||||||
const baseOptions = super.configLabel(chart, options)
|
const baseOptions = super.configLabel(chart, options)
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
import { flow, hexColorToRGBA, parseJson } from '@/views/chart/components/js/util'
|
import { flow, hexColorToRGBA, parseJson } from '@/views/chart/components/js/util'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
||||||
|
import { Options } from '@antv/g2plot/esm'
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
/**
|
/**
|
||||||
* 对称柱状图
|
* 对称柱状图
|
||||||
@ -87,7 +88,17 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
|||||||
'legend-selector': ['icon', 'orient', 'fontSize', 'color', 'hPosition', 'vPosition'],
|
'legend-selector': ['icon', 'orient', 'fontSize', 'color', 'hPosition', 'vPosition'],
|
||||||
'function-cfg': ['emptyDataStrategy'],
|
'function-cfg': ['emptyDataStrategy'],
|
||||||
'label-selector': ['hPosition', 'seriesLabelFormatter'],
|
'label-selector': ['hPosition', 'seriesLabelFormatter'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter']
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show']
|
||||||
|
}
|
||||||
|
|
||||||
|
selectorSpec: EditorSelectorSpec = {
|
||||||
|
...this['selectorSpec'],
|
||||||
|
'dual-y-axis-selector': {
|
||||||
|
title: `${t('chart.xAxis')}`
|
||||||
|
},
|
||||||
|
'x-axis-selector': {
|
||||||
|
title: `${t('chart.yAxis')}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawChart(drawOptions: G2PlotDrawOptions<G2BidirectionalBar>): G2BidirectionalBar {
|
drawChart(drawOptions: G2PlotDrawOptions<G2BidirectionalBar>): G2BidirectionalBar {
|
||||||
@ -118,11 +129,27 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
|||||||
},
|
},
|
||||||
interactions: [{ type: 'active-region' }],
|
interactions: [{ type: 'active-region' }],
|
||||||
yField: ['value', 'valueExt'],
|
yField: ['value', 'valueExt'],
|
||||||
appendPadding: getPadding(chart)
|
appendPadding: getPadding(chart),
|
||||||
|
meta: {
|
||||||
|
field: {
|
||||||
|
type: 'cat'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const customOptions = this.setupOptions(chart, initOptions)
|
||||||
|
const options = {
|
||||||
|
...customOptions
|
||||||
|
}
|
||||||
|
const xAxis = chart.xAxis
|
||||||
|
if (xAxis?.length === 1 && xAxis[0].deType === 1) {
|
||||||
|
const values = data2.map(item => item.field)
|
||||||
|
options.meta = {
|
||||||
|
field: {
|
||||||
|
type: 'cat',
|
||||||
|
values: values.reverse()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = this.setupOptions(chart, initOptions)
|
|
||||||
|
|
||||||
// 开始渲染
|
// 开始渲染
|
||||||
const newChart = new G2BidirectionalBar(container, options)
|
const newChart = new G2BidirectionalBar(container, options)
|
||||||
|
|
||||||
@ -418,6 +445,45 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
|||||||
return { ...options, label }
|
return { ...options, label }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected configEmptyDataStrategy(
|
||||||
|
chart: Chart,
|
||||||
|
options: BidirectionalBarOptions
|
||||||
|
): BidirectionalBarOptions {
|
||||||
|
const { data } = options as unknown as Options
|
||||||
|
if (!data?.length) {
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
const strategy = parseJson(chart.senior).functionCfg.emptyDataStrategy
|
||||||
|
if (strategy === 'ignoreData') {
|
||||||
|
const emptyFields = data
|
||||||
|
.filter(obj => obj['value'] === null || obj['valueExt'] === null)
|
||||||
|
.map(obj => obj['field'])
|
||||||
|
return {
|
||||||
|
...options,
|
||||||
|
data: data.filter(obj => {
|
||||||
|
if (emptyFields.includes(obj['field'])) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const updateValues = (strategy: 'breakLine' | 'setZero', data: any[]) => {
|
||||||
|
data.forEach(obj => {
|
||||||
|
if (obj['value'] === null) {
|
||||||
|
obj['value'] = strategy === 'breakLine' ? null : 0
|
||||||
|
}
|
||||||
|
if (obj['valueExt'] === null) {
|
||||||
|
obj['valueExt'] = strategy === 'breakLine' ? null : 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (strategy === 'breakLine' || strategy === 'setZero') {
|
||||||
|
updateValues(strategy, data)
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
protected setupOptions(chart: Chart, options: BidirectionalBarOptions) {
|
protected setupOptions(chart: Chart, options: BidirectionalBarOptions) {
|
||||||
return flow(
|
return flow(
|
||||||
this.configTheme,
|
this.configTheme,
|
||||||
|
@ -30,7 +30,7 @@ export const BAR_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
|||||||
'background-overall-component': ['all'],
|
'background-overall-component': ['all'],
|
||||||
'basic-style-selector': ['colors', 'alpha', 'gradient'],
|
'basic-style-selector': ['colors', 'alpha', 'gradient'],
|
||||||
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'tooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'tooltipFormatter', 'show'],
|
||||||
'x-axis-selector': [
|
'x-axis-selector': [
|
||||||
'name',
|
'name',
|
||||||
'color',
|
'color',
|
||||||
|
@ -34,7 +34,7 @@ export class HorizontalBar extends G2PlotChartView<BarOptions, Bar> {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...BAR_EDITOR_PROPERTY_INNER,
|
...BAR_EDITOR_PROPERTY_INNER,
|
||||||
'label-selector': ['hPosition', 'seriesLabelFormatter'],
|
'label-selector': ['hPosition', 'seriesLabelFormatter'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'x-axis-selector': [...BAR_EDITOR_PROPERTY_INNER['x-axis-selector'], 'axisLabelFormatter']
|
'x-axis-selector': [...BAR_EDITOR_PROPERTY_INNER['x-axis-selector'], 'axisLabelFormatter']
|
||||||
}
|
}
|
||||||
axis: AxisType[] = [...BAR_AXIS_TYPE]
|
axis: AxisType[] = [...BAR_AXIS_TYPE]
|
||||||
@ -267,7 +267,7 @@ export class HorizontalStackBar extends HorizontalBar {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...this['propertyInner'],
|
...this['propertyInner'],
|
||||||
'label-selector': ['color', 'fontSize', 'hPosition', 'labelFormatter'],
|
'label-selector': ['color', 'fontSize', 'hPosition', 'labelFormatter'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter']
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter', 'show']
|
||||||
}
|
}
|
||||||
protected configLabel(chart: Chart, options: BarOptions): BarOptions {
|
protected configLabel(chart: Chart, options: BarOptions): BarOptions {
|
||||||
const baseOptions = super.configLabel(chart, options)
|
const baseOptions = super.configLabel(chart, options)
|
||||||
@ -328,7 +328,7 @@ export class HorizontalPercentageStackBar extends HorizontalStackBar {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...this['propertyInner'],
|
...this['propertyInner'],
|
||||||
'label-selector': ['color', 'fontSize', 'hPosition', 'reserveDecimalCount'],
|
'label-selector': ['color', 'fontSize', 'hPosition', 'reserveDecimalCount'],
|
||||||
'tooltip-selector': ['color', 'fontSize']
|
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'show']
|
||||||
}
|
}
|
||||||
protected configLabel(chart: Chart, options: BarOptions): BarOptions {
|
protected configLabel(chart: Chart, options: BarOptions): BarOptions {
|
||||||
const baseOptions = super.configLabel(chart, options)
|
const baseOptions = super.configLabel(chart, options)
|
||||||
|
@ -49,7 +49,7 @@ export class ProgressBar extends G2PlotChartView<BarOptions, G2Progress> {
|
|||||||
'background-overall-component': ['all'],
|
'background-overall-component': ['all'],
|
||||||
'basic-style-selector': ['colors', 'alpha', 'gradient'],
|
'basic-style-selector': ['colors', 'alpha', 'gradient'],
|
||||||
'label-selector': ['hPosition', 'color', 'fontSize'],
|
'label-selector': ['hPosition', 'color', 'fontSize'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter', 'show'],
|
||||||
'y-axis-selector': ['name', 'color', 'fontSize', 'axisForm', 'axisLabel', 'position'],
|
'y-axis-selector': ['name', 'color', 'fontSize', 'axisForm', 'axisLabel', 'position'],
|
||||||
'function-cfg': ['emptyDataStrategy']
|
'function-cfg': ['emptyDataStrategy']
|
||||||
}
|
}
|
||||||
@ -62,7 +62,8 @@ export class ProgressBar extends G2PlotChartView<BarOptions, G2Progress> {
|
|||||||
isGroup: false,
|
isGroup: false,
|
||||||
isPercent: true,
|
isPercent: true,
|
||||||
isStack: true,
|
isStack: true,
|
||||||
xAxis: false
|
xAxis: false,
|
||||||
|
appendPadding: [0, 0, 10, 0]
|
||||||
}
|
}
|
||||||
|
|
||||||
drawChart(drawOptions: G2PlotDrawOptions<G2Progress>): G2Progress {
|
drawChart(drawOptions: G2PlotDrawOptions<G2Progress>): G2Progress {
|
||||||
@ -98,13 +99,15 @@ export class ProgressBar extends G2PlotChartView<BarOptions, G2Progress> {
|
|||||||
const data1 = defaultTo(sourceData[0]?.data, [])
|
const data1 = defaultTo(sourceData[0]?.data, [])
|
||||||
const data2 = defaultTo(sourceData[1]?.data, [])
|
const data2 = defaultTo(sourceData[1]?.data, [])
|
||||||
const currentData = data2.map(item => {
|
const currentData = data2.map(item => {
|
||||||
|
const progress = getCompletionRate(data1.find(i => i.field === item.field)?.value, item.value)
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
type: 'current',
|
type: 'current',
|
||||||
title: item.field,
|
title: item.field,
|
||||||
id: item.quotaList[0].id,
|
id: item.quotaList[0].id,
|
||||||
originalValue: item.value,
|
originalValue: item.value,
|
||||||
progress: getCompletionRate(data1.find(i => i.field === item.field)?.value, item.value)
|
originalProgress: progress,
|
||||||
|
progress: progress >= 100 ? 100 : progress
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const targetData = data1.map(item => {
|
const targetData = data1.map(item => {
|
||||||
@ -223,7 +226,7 @@ export class ProgressBar extends G2PlotChartView<BarOptions, G2Progress> {
|
|||||||
if (item.type === 'target') {
|
if (item.type === 'target') {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
return (item.progress * 100).toFixed(2) + '%'
|
return item.originalProgress.toFixed(2) + '%'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (label.position === 'top') {
|
if (label.position === 'top') {
|
||||||
|
@ -39,7 +39,14 @@ export class RangeBar extends G2PlotChartView<BarOptions, Bar> {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...BAR_EDITOR_PROPERTY_INNER,
|
...BAR_EDITOR_PROPERTY_INNER,
|
||||||
'label-selector': ['hPosition', 'color', 'fontSize', 'labelFormatter', 'showGap'],
|
'label-selector': ['hPosition', 'color', 'fontSize', 'labelFormatter', 'showGap'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter', 'showGap'],
|
'tooltip-selector': [
|
||||||
|
'fontSize',
|
||||||
|
'color',
|
||||||
|
'backgroundColor',
|
||||||
|
'tooltipFormatter',
|
||||||
|
'showGap',
|
||||||
|
'show'
|
||||||
|
],
|
||||||
'x-axis-selector': [...BAR_EDITOR_PROPERTY_INNER['x-axis-selector'], 'axisLabelFormatter']
|
'x-axis-selector': [...BAR_EDITOR_PROPERTY_INNER['x-axis-selector'], 'axisLabelFormatter']
|
||||||
}
|
}
|
||||||
axis: AxisType[] = [...BAR_AXIS_TYPE, 'yAxisExt']
|
axis: AxisType[] = [...BAR_AXIS_TYPE, 'yAxisExt']
|
||||||
@ -47,7 +54,7 @@ export class RangeBar extends G2PlotChartView<BarOptions, Bar> {
|
|||||||
data: [],
|
data: [],
|
||||||
xField: 'values',
|
xField: 'values',
|
||||||
yField: 'field',
|
yField: 'field',
|
||||||
colorFiled: 'category',
|
colorField: 'category',
|
||||||
isGroup: true,
|
isGroup: true,
|
||||||
interactions: [
|
interactions: [
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@ export class Waterfall extends G2PlotChartView<WaterfallOptions, G2Waterfall> {
|
|||||||
'background-overall-component': ['all'],
|
'background-overall-component': ['all'],
|
||||||
'basic-style-selector': ['colors', 'alpha', 'gradient'],
|
'basic-style-selector': ['colors', 'alpha', 'gradient'],
|
||||||
'label-selector': ['fontSize', 'color', 'vPosition', 'labelFormatter'],
|
'label-selector': ['fontSize', 'color', 'vPosition', 'labelFormatter'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'title-selector': [
|
'title-selector': [
|
||||||
'title',
|
'title',
|
||||||
'fontSize',
|
'fontSize',
|
||||||
@ -187,7 +187,7 @@ export class Waterfall extends G2PlotChartView<WaterfallOptions, G2Waterfall> {
|
|||||||
let tmpValue = totalMap[id]
|
let tmpValue = totalMap[id]
|
||||||
let color = 'grey'
|
let color = 'grey'
|
||||||
if (id === yAxis[0].id) {
|
if (id === yAxis[0].id) {
|
||||||
tmpValue = parseFloat(head.value as unknown as string)
|
tmpValue = head.data.value
|
||||||
color = head.color
|
color = head.color
|
||||||
}
|
}
|
||||||
const value = valueFormatter(tmpValue, formatter.formatterCfg)
|
const value = valueFormatter(tmpValue, formatter.formatterCfg)
|
||||||
|
@ -261,7 +261,7 @@ export class StackArea extends Area {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...this['propertyInner'],
|
...this['propertyInner'],
|
||||||
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'tooltipFormatter']
|
'tooltip-selector': ['fontSize', 'color', 'tooltipFormatter', 'show']
|
||||||
}
|
}
|
||||||
protected configLabel(chart: Chart, options: AreaOptions): AreaOptions {
|
protected configLabel(chart: Chart, options: AreaOptions): AreaOptions {
|
||||||
const customAttr = parseJson(chart.customAttr)
|
const customAttr = parseJson(chart.customAttr)
|
||||||
|
@ -15,7 +15,7 @@ export const LINE_EDITOR_PROPERTY: EditorProperty[] = [
|
|||||||
export const LINE_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
export const LINE_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
||||||
'background-overall-component': ['all'],
|
'background-overall-component': ['all'],
|
||||||
'label-selector': ['fontSize', 'color'],
|
'label-selector': ['fontSize', 'color'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'show'],
|
||||||
'basic-style-selector': [
|
'basic-style-selector': [
|
||||||
'colors',
|
'colors',
|
||||||
'alpha',
|
'alpha',
|
||||||
|
@ -95,7 +95,8 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
// 禁用线上地图数据
|
// 禁用线上地图数据
|
||||||
customFetchGeoData: () => null
|
customFetchGeoData: () => null
|
||||||
}
|
}
|
||||||
options = this.setupOptions(chart, options, drawOption, geoJson)
|
const context = { drawOption, geoJson }
|
||||||
|
options = this.setupOptions(chart, options, context)
|
||||||
const view = new Choropleth(container, options)
|
const view = new Choropleth(container, options)
|
||||||
const dotLayer = this.getDotLayer(chart, geoJson, drawOption)
|
const dotLayer = this.getDotLayer(chart, geoJson, drawOption)
|
||||||
this.configZoomButton(chart, view)
|
this.configZoomButton(chart, view)
|
||||||
@ -170,10 +171,10 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
private configBasicStyle(
|
private configBasicStyle(
|
||||||
chart: Chart,
|
chart: Chart,
|
||||||
options: ChoroplethOptions,
|
options: ChoroplethOptions,
|
||||||
extra: any[]
|
context: Record<string, any>
|
||||||
): ChoroplethOptions {
|
): ChoroplethOptions {
|
||||||
const { areaId }: L7PlotDrawOptions<any> = extra[0]
|
const { areaId }: L7PlotDrawOptions<any> = context.drawOption
|
||||||
const geoJson: FeatureCollection = extra[1]
|
const geoJson: FeatureCollection = context.geoJson
|
||||||
const { basicStyle, label } = parseJson(chart.customAttr)
|
const { basicStyle, label } = parseJson(chart.customAttr)
|
||||||
const senior = parseJson(chart.senior)
|
const senior = parseJson(chart.senior)
|
||||||
const curAreaNameMapping = senior.areaMapping?.[areaId]
|
const curAreaNameMapping = senior.areaMapping?.[areaId]
|
||||||
@ -208,7 +209,7 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
protected setupOptions(
|
protected setupOptions(
|
||||||
chart: Chart,
|
chart: Chart,
|
||||||
options: ChoroplethOptions,
|
options: ChoroplethOptions,
|
||||||
...extra: any[]
|
context: Record<string, any>
|
||||||
): ChoroplethOptions {
|
): ChoroplethOptions {
|
||||||
return flow(
|
return flow(
|
||||||
this.configEmptyDataStrategy,
|
this.configEmptyDataStrategy,
|
||||||
@ -216,6 +217,6 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
this.configStyle,
|
this.configStyle,
|
||||||
this.configTooltip,
|
this.configTooltip,
|
||||||
this.configBasicStyle
|
this.configBasicStyle
|
||||||
)(chart, options, extra)
|
)(chart, options, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ export const MAP_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
|||||||
'showDimension',
|
'showDimension',
|
||||||
'showQuota'
|
'showQuota'
|
||||||
],
|
],
|
||||||
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'tooltipFormatter'],
|
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'tooltipFormatter', 'show'],
|
||||||
'function-cfg': ['emptyDataStrategy'],
|
'function-cfg': ['emptyDataStrategy'],
|
||||||
'map-mapping': ['']
|
'map-mapping': ['']
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,8 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
// 禁用线上地图数据
|
// 禁用线上地图数据
|
||||||
customFetchGeoData: () => null
|
customFetchGeoData: () => null
|
||||||
}
|
}
|
||||||
options = this.setupOptions(chart, options, drawOption, geoJson)
|
const context = { drawOption, geoJson }
|
||||||
|
options = this.setupOptions(chart, options, context)
|
||||||
const view = new Choropleth(container, options)
|
const view = new Choropleth(container, options)
|
||||||
this.configZoomButton(chart, view)
|
this.configZoomButton(chart, view)
|
||||||
view.once('loaded', () => {
|
view.once('loaded', () => {
|
||||||
@ -120,10 +121,10 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
private configBasicStyle(
|
private configBasicStyle(
|
||||||
chart: Chart,
|
chart: Chart,
|
||||||
options: ChoroplethOptions,
|
options: ChoroplethOptions,
|
||||||
extra: any[]
|
context: Record<string, any>
|
||||||
): ChoroplethOptions {
|
): ChoroplethOptions {
|
||||||
const { areaId }: L7PlotDrawOptions<any> = extra[0]
|
const { areaId }: L7PlotDrawOptions<any> = context.drawOption
|
||||||
const geoJson: FeatureCollection = extra[1]
|
const geoJson: FeatureCollection = context.geoJson
|
||||||
const { basicStyle, label } = parseJson(chart.customAttr)
|
const { basicStyle, label } = parseJson(chart.customAttr)
|
||||||
const senior = parseJson(chart.senior)
|
const senior = parseJson(chart.senior)
|
||||||
const curAreaNameMapping = senior.areaMapping?.[areaId]
|
const curAreaNameMapping = senior.areaMapping?.[areaId]
|
||||||
@ -176,7 +177,7 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
protected setupOptions(
|
protected setupOptions(
|
||||||
chart: Chart,
|
chart: Chart,
|
||||||
options: ChoroplethOptions,
|
options: ChoroplethOptions,
|
||||||
...extra: any[]
|
context: Record<string, any>
|
||||||
): ChoroplethOptions {
|
): ChoroplethOptions {
|
||||||
return flow(
|
return flow(
|
||||||
this.configEmptyDataStrategy,
|
this.configEmptyDataStrategy,
|
||||||
@ -185,6 +186,6 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
|||||||
this.configTooltip,
|
this.configTooltip,
|
||||||
this.configBasicStyle,
|
this.configBasicStyle,
|
||||||
this.configLegend
|
this.configLegend
|
||||||
)(chart, options, extra)
|
)(chart, options, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export const CHART_MIX_EDITOR_PROPERTY: EditorProperty[] = [
|
|||||||
export const CHART_MIX_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
export const CHART_MIX_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
||||||
'background-overall-component': ['all'],
|
'background-overall-component': ['all'],
|
||||||
'label-selector': ['fontSize', 'color'],
|
'label-selector': ['fontSize', 'color'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'show'],
|
||||||
'basic-style-selector': [
|
'basic-style-selector': [
|
||||||
'colors',
|
'colors',
|
||||||
'alpha',
|
'alpha',
|
||||||
|
@ -24,7 +24,7 @@ export class Funnel extends G2PlotChartView<FunnelOptions, G2Funnel> {
|
|||||||
'background-overall-component': ['all'],
|
'background-overall-component': ['all'],
|
||||||
'basic-style-selector': ['colors', 'alpha'],
|
'basic-style-selector': ['colors', 'alpha'],
|
||||||
'label-selector': ['fontSize', 'color', 'hPosition', 'labelFormatter'],
|
'label-selector': ['fontSize', 'color', 'hPosition', 'labelFormatter'],
|
||||||
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'title-selector': [
|
'title-selector': [
|
||||||
'show',
|
'show',
|
||||||
'title',
|
'title',
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
||||||
import { getPadding, setGradientColor } from '@/views/chart/components/js/panel/common/common_antv'
|
import { getPadding, setGradientColor } from '@/views/chart/components/js/panel/common/common_antv'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { merge } from 'lodash-es'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
]
|
]
|
||||||
propertyInner: EditorPropertyInner = {
|
propertyInner: EditorPropertyInner = {
|
||||||
'background-overall-component': ['all'],
|
'background-overall-component': ['all'],
|
||||||
'basic-style-selector': ['colors', 'alpha', 'gaugeStyle', 'gradient'],
|
'basic-style-selector': ['colors', 'alpha', 'gradient', 'gaugeAxisLine', 'gaugePercentLabel'],
|
||||||
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
||||||
'title-selector': [
|
'title-selector': [
|
||||||
'title',
|
'title',
|
||||||
@ -77,10 +78,6 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
label: {
|
label: {
|
||||||
style: {
|
style: {
|
||||||
fontSize: getScaleValue(12, scale) // 刻度值字体大小
|
fontSize: getScaleValue(12, scale) // 刻度值字体大小
|
||||||
},
|
|
||||||
formatter: function (v) {
|
|
||||||
const r = parseFloat(v)
|
|
||||||
return v === '0' || !r ? v : r * 100 + '%'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tickLine: {
|
tickLine: {
|
||||||
@ -98,11 +95,15 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const options = this.setupOptions(chart, initOptions, scale)
|
const options = this.setupOptions(chart, initOptions, { scale })
|
||||||
return new G2Gauge(container, options)
|
return new G2Gauge(container, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected configMisc(chart: Chart, options: GaugeOptions): GaugeOptions {
|
protected configMisc(
|
||||||
|
chart: Chart,
|
||||||
|
options: GaugeOptions,
|
||||||
|
context: Record<string, any>
|
||||||
|
): GaugeOptions {
|
||||||
const customAttr = parseJson(chart.customAttr)
|
const customAttr = parseJson(chart.customAttr)
|
||||||
const data = chart.data.series[0].data[0]
|
const data = chart.data.series[0].data[0]
|
||||||
let min, max, startAngle, endAngle
|
let min, max, startAngle, endAngle
|
||||||
@ -123,6 +124,8 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
}
|
}
|
||||||
startAngle = (misc.gaugeStartAngle * Math.PI) / 180
|
startAngle = (misc.gaugeStartAngle * Math.PI) / 180
|
||||||
endAngle = (misc.gaugeEndAngle * Math.PI) / 180
|
endAngle = (misc.gaugeEndAngle * Math.PI) / 180
|
||||||
|
context.min = min
|
||||||
|
context.max = max
|
||||||
}
|
}
|
||||||
const percent = (parseFloat(data) - parseFloat(min)) / (parseFloat(max) - parseFloat(min))
|
const percent = (parseFloat(data) - parseFloat(min)) / (parseFloat(max) - parseFloat(min))
|
||||||
const tmp = {
|
const tmp = {
|
||||||
@ -133,8 +136,12 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
return { ...options, ...tmp }
|
return { ...options, ...tmp }
|
||||||
}
|
}
|
||||||
|
|
||||||
private configRange(chart: Chart, options: GaugeOptions, extra: any[]): GaugeOptions {
|
private configRange(
|
||||||
const [scale] = extra
|
chart: Chart,
|
||||||
|
options: GaugeOptions,
|
||||||
|
context: Record<string, any>
|
||||||
|
): GaugeOptions {
|
||||||
|
const { scale } = context
|
||||||
const range = [0]
|
const range = [0]
|
||||||
let index = 0
|
let index = 0
|
||||||
let flag = false
|
let flag = false
|
||||||
@ -216,36 +223,55 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
return { ...options, ...rangOptions }
|
return { ...options, ...rangOptions }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected configLabel(chart: Chart, options: GaugeOptions): GaugeOptions {
|
protected configLabel(
|
||||||
|
chart: Chart,
|
||||||
|
options: GaugeOptions,
|
||||||
|
context?: Record<string, any>
|
||||||
|
): GaugeOptions {
|
||||||
const customAttr = parseJson(chart.customAttr)
|
const customAttr = parseJson(chart.customAttr)
|
||||||
const data = chart.data.series[0].data[0]
|
const data = chart.data.series[0].data[0]
|
||||||
let labelContent
|
let labelContent: GaugeOptions['statistic']['content'] = false
|
||||||
if (customAttr.label) {
|
const label = customAttr.label
|
||||||
const label = customAttr.label
|
const labelFormatter = label.labelFormatter ?? DEFAULT_LABEL.labelFormatter
|
||||||
const labelFormatter = label.labelFormatter ?? DEFAULT_LABEL.labelFormatter
|
if (label.show) {
|
||||||
if (label.show) {
|
labelContent = {
|
||||||
labelContent = {
|
style: {
|
||||||
style: () => ({
|
fontSize: `${label.fontSize}`,
|
||||||
fontSize: label.fontSize,
|
color: label.color
|
||||||
color: label.color
|
},
|
||||||
}),
|
formatter: function () {
|
||||||
formatter: function () {
|
let value
|
||||||
let value
|
if (labelFormatter.type === 'percent') {
|
||||||
if (labelFormatter.type === 'percent') {
|
value = options.percent
|
||||||
value = options.percent
|
} else {
|
||||||
} else {
|
value = data
|
||||||
value = data
|
|
||||||
}
|
|
||||||
return valueFormatter(value, labelFormatter)
|
|
||||||
}
|
}
|
||||||
|
return valueFormatter(value, labelFormatter)
|
||||||
}
|
}
|
||||||
} else {
|
} as GaugeOptions['statistic']['content']
|
||||||
labelContent = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const statistic = {
|
const statistic = {
|
||||||
content: labelContent
|
content: labelContent
|
||||||
}
|
}
|
||||||
|
const { gaugeAxisLine, gaugePercentLabel } = customAttr.basicStyle
|
||||||
|
const { min, max } = context
|
||||||
|
const tmp = {
|
||||||
|
axis: {
|
||||||
|
label: {
|
||||||
|
formatter: v => {
|
||||||
|
if (gaugeAxisLine === false) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
if (gaugePercentLabel === false) {
|
||||||
|
const val = v === '0' ? min : v === '1' ? max : min + (max - min) * v
|
||||||
|
return valueFormatter(val, labelFormatter)
|
||||||
|
}
|
||||||
|
return v === '0' ? v : v * 100 + '%'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options = merge(options, tmp)
|
||||||
return { ...options, statistic }
|
return { ...options, statistic }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,13 +289,17 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
|
|||||||
return chart
|
return chart
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setupOptions(chart: Chart, options: GaugeOptions, ...extra: any[]): GaugeOptions {
|
protected setupOptions(
|
||||||
|
chart: Chart,
|
||||||
|
options: GaugeOptions,
|
||||||
|
context: Record<string, any>
|
||||||
|
): GaugeOptions {
|
||||||
return flow(
|
return flow(
|
||||||
this.configTheme,
|
this.configTheme,
|
||||||
this.configMisc,
|
this.configMisc,
|
||||||
this.configLabel,
|
this.configLabel,
|
||||||
this.configRange
|
this.configRange
|
||||||
)(chart, options, extra)
|
)(chart, options, context)
|
||||||
}
|
}
|
||||||
constructor() {
|
constructor() {
|
||||||
super('gauge', DEFAULT_DATA)
|
super('gauge', DEFAULT_DATA)
|
||||||
|
@ -30,7 +30,7 @@ export class Quadrant extends G2PlotChartView<ScatterOptions, G2Scatter> {
|
|||||||
propertyInner: EditorPropertyInner = {
|
propertyInner: EditorPropertyInner = {
|
||||||
'basic-style-selector': ['colors', 'alpha', 'scatterSymbol', 'scatterSymbolSize'],
|
'basic-style-selector': ['colors', 'alpha', 'scatterSymbol', 'scatterSymbolSize'],
|
||||||
'label-selector': ['fontSize', 'color'],
|
'label-selector': ['fontSize', 'color'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'x-axis-selector': [
|
'x-axis-selector': [
|
||||||
'position',
|
'position',
|
||||||
'name',
|
'name',
|
||||||
|
@ -24,7 +24,7 @@ export class Radar extends G2PlotChartView<RadarOptions, G2Radar> {
|
|||||||
propertyInner: EditorPropertyInner = {
|
propertyInner: EditorPropertyInner = {
|
||||||
'basic-style-selector': ['colors', 'alpha', 'radarShape'],
|
'basic-style-selector': ['colors', 'alpha', 'radarShape'],
|
||||||
'label-selector': ['seriesLabelFormatter'],
|
'label-selector': ['seriesLabelFormatter'],
|
||||||
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'misc-style-selector': ['showName', 'color', 'fontSize', 'axisColor'],
|
'misc-style-selector': ['showName', 'color', 'fontSize', 'axisColor'],
|
||||||
'title-selector': [
|
'title-selector': [
|
||||||
'show',
|
'show',
|
||||||
@ -42,6 +42,7 @@ export class Radar extends G2PlotChartView<RadarOptions, G2Radar> {
|
|||||||
'legend-selector': ['icon', 'orient', 'color', 'fontSize', 'hPosition', 'vPosition']
|
'legend-selector': ['icon', 'orient', 'color', 'fontSize', 'hPosition', 'vPosition']
|
||||||
}
|
}
|
||||||
selectorSpec: EditorSelectorSpec = {
|
selectorSpec: EditorSelectorSpec = {
|
||||||
|
...this['selectorSpec'],
|
||||||
'misc-style-selector': {
|
'misc-style-selector': {
|
||||||
title: `${t('chart.tooltip_axis')}`
|
title: `${t('chart.tooltip_axis')}`
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ export class RangeBar extends G2PlotChartView<SankeyOptions, Sankey> {
|
|||||||
propertyInner = {
|
propertyInner = {
|
||||||
...SANKEY_EDITOR_PROPERTY_INNER,
|
...SANKEY_EDITOR_PROPERTY_INNER,
|
||||||
'label-selector': ['color', 'fontSize'],
|
'label-selector': ['color', 'fontSize'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter']
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter', 'show']
|
||||||
}
|
}
|
||||||
axis: AxisType[] = [...SANKEY_AXIS_TYPE]
|
axis: AxisType[] = [...SANKEY_AXIS_TYPE]
|
||||||
protected baseOptions: SankeyOptions = {
|
protected baseOptions: SankeyOptions = {
|
||||||
|
@ -29,7 +29,7 @@ export class Scatter extends G2PlotChartView<ScatterOptions, G2Scatter> {
|
|||||||
propertyInner: EditorPropertyInner = {
|
propertyInner: EditorPropertyInner = {
|
||||||
'basic-style-selector': ['colors', 'alpha', 'scatterSymbol', 'scatterSymbolSize'],
|
'basic-style-selector': ['colors', 'alpha', 'scatterSymbol', 'scatterSymbolSize'],
|
||||||
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
'label-selector': ['fontSize', 'color', 'labelFormatter'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'x-axis-selector': [
|
'x-axis-selector': [
|
||||||
'position',
|
'position',
|
||||||
'name',
|
'name',
|
||||||
|
@ -29,7 +29,7 @@ export class Treemap extends G2PlotChartView<TreemapOptions, G2Treemap> {
|
|||||||
'basic-style-selector': ['colors', 'alpha'],
|
'basic-style-selector': ['colors', 'alpha'],
|
||||||
'label-selector': ['fontSize', 'color', 'showDimension', 'showQuota', 'showProportion'],
|
'label-selector': ['fontSize', 'color', 'showDimension', 'showQuota', 'showProportion'],
|
||||||
'legend-selector': ['icon', 'orient', 'fontSize', 'color', 'hPosition', 'vPosition'],
|
'legend-selector': ['icon', 'orient', 'fontSize', 'color', 'hPosition', 'vPosition'],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'title-selector': [
|
'title-selector': [
|
||||||
'title',
|
'title',
|
||||||
'fontSize',
|
'fontSize',
|
||||||
|
@ -41,7 +41,7 @@ export class WordCloud extends G2PlotChartView<WordCloudOptions, G2WordCloud> {
|
|||||||
'fontShadow'
|
'fontShadow'
|
||||||
],
|
],
|
||||||
'misc-selector': ['wordSizeRange', 'wordSpacing'],
|
'misc-selector': ['wordSizeRange', 'wordSpacing'],
|
||||||
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter']
|
'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'seriesTooltipFormatter', 'show']
|
||||||
}
|
}
|
||||||
axis: AxisType[] = ['xAxis', 'yAxis', 'filter']
|
axis: AxisType[] = ['xAxis', 'yAxis', 'filter']
|
||||||
axisConfig: AxisConfig = {
|
axisConfig: AxisConfig = {
|
||||||
|
@ -22,7 +22,7 @@ export const PIE_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
|||||||
'showQuota',
|
'showQuota',
|
||||||
'showProportion'
|
'showProportion'
|
||||||
],
|
],
|
||||||
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter'],
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'seriesTooltipFormatter', 'show'],
|
||||||
'basic-style-selector': ['colors', 'alpha', 'radius'],
|
'basic-style-selector': ['colors', 'alpha', 'radius'],
|
||||||
'title-selector': [
|
'title-selector': [
|
||||||
'title',
|
'title',
|
||||||
|
@ -4,6 +4,7 @@ export const TABLE_EDITOR_PROPERTY: EditorProperty[] = [
|
|||||||
'table-header-selector',
|
'table-header-selector',
|
||||||
'table-cell-selector',
|
'table-cell-selector',
|
||||||
'title-selector',
|
'title-selector',
|
||||||
|
'tooltip-selector',
|
||||||
'function-cfg',
|
'function-cfg',
|
||||||
'threshold',
|
'threshold',
|
||||||
'scroll-cfg',
|
'scroll-cfg',
|
||||||
@ -45,6 +46,7 @@ export const TABLE_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
|||||||
'letterSpace',
|
'letterSpace',
|
||||||
'fontShadow'
|
'fontShadow'
|
||||||
],
|
],
|
||||||
|
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'show'],
|
||||||
'function-cfg': ['emptyDataStrategy'],
|
'function-cfg': ['emptyDataStrategy'],
|
||||||
threshold: ['tableThreshold']
|
threshold: ['tableThreshold']
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { S2ChartView, S2DrawOptions } from '../../types/impl/s2'
|
|||||||
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
|
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { isNumber } from 'lodash-es'
|
import { isNumber } from 'lodash-es'
|
||||||
import { copyContent } from '@/views/chart/components/js/panel/common/common_table'
|
import { copyContent, SortTooltip } from '@/views/chart/components/js/panel/common/common_table'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
@ -18,7 +18,8 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
|||||||
...TABLE_EDITOR_PROPERTY_INNER,
|
...TABLE_EDITOR_PROPERTY_INNER,
|
||||||
'table-header-selector': [
|
'table-header-selector': [
|
||||||
...TABLE_EDITOR_PROPERTY_INNER['table-header-selector'],
|
...TABLE_EDITOR_PROPERTY_INNER['table-header-selector'],
|
||||||
'tableHeaderSort'
|
'tableHeaderSort',
|
||||||
|
'showTableHeader'
|
||||||
],
|
],
|
||||||
'basic-style-selector': [
|
'basic-style-selector': [
|
||||||
'tableColumnMode',
|
'tableColumnMode',
|
||||||
@ -107,7 +108,8 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
|||||||
style: this.configStyle(chart),
|
style: this.configStyle(chart),
|
||||||
conditions: this.configConditions(chart),
|
conditions: this.configConditions(chart),
|
||||||
tooltip: {
|
tooltip: {
|
||||||
getContainer: () => containerDom
|
getContainer: () => containerDom,
|
||||||
|
renderTooltip: sheet => new SortTooltip(sheet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 开启序号之后,第一列就是序号列,修改 label 即可
|
// 开启序号之后,第一列就是序号列,修改 label 即可
|
||||||
@ -134,9 +136,23 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tooltip
|
// tooltip
|
||||||
this.configTooltip(s2Options)
|
this.configTooltip(chart, s2Options)
|
||||||
// header interaction
|
// 隐藏表头,保留顶部的分割线, 禁用表头横向 resize
|
||||||
this.configHeaderInteraction(chart, s2Options)
|
if (customAttr.tableHeader.showTableHeader === false) {
|
||||||
|
s2Options.style.colCfg.height = 1
|
||||||
|
s2Options.interaction = {
|
||||||
|
resize: {
|
||||||
|
colCellVertical: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s2Options.colCell = (node, sheet, config) => {
|
||||||
|
node.label = ' '
|
||||||
|
return new TableColCell(node, sheet, config)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// header interaction
|
||||||
|
this.configHeaderInteraction(chart, s2Options)
|
||||||
|
}
|
||||||
// 开始渲染
|
// 开始渲染
|
||||||
const newChart = new TableSheet(containerDom, s2DataConfig, s2Options)
|
const newChart = new TableSheet(containerDom, s2DataConfig, s2Options)
|
||||||
|
|
||||||
@ -168,14 +184,10 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
|||||||
}
|
}
|
||||||
action(param)
|
action(param)
|
||||||
})
|
})
|
||||||
|
// tooltip
|
||||||
// hover
|
const { show } = customAttr.tooltip
|
||||||
const { showColTooltip } = customAttr.tableHeader
|
if (show) {
|
||||||
if (showColTooltip) {
|
|
||||||
newChart.on(S2Event.COL_CELL_HOVER, event => this.showTooltip(newChart, event, meta))
|
newChart.on(S2Event.COL_CELL_HOVER, event => this.showTooltip(newChart, event, meta))
|
||||||
}
|
|
||||||
const { showTooltip } = customAttr.tableCell
|
|
||||||
if (showTooltip) {
|
|
||||||
newChart.on(S2Event.DATA_CELL_HOVER, event => this.showTooltip(newChart, event, meta))
|
newChart.on(S2Event.DATA_CELL_HOVER, event => this.showTooltip(newChart, event, meta))
|
||||||
}
|
}
|
||||||
// header resize
|
// header resize
|
||||||
|
@ -2,7 +2,11 @@ import { S2ChartView, S2DrawOptions } from '@/views/chart/components/js/panel/ty
|
|||||||
import { S2Event, S2Options, TableSheet, TableColCell, ViewMeta, TableDataCell } from '@antv/s2'
|
import { S2Event, S2Options, TableSheet, TableColCell, ViewMeta, TableDataCell } from '@antv/s2'
|
||||||
import { parseJson } from '@/views/chart/components/js/util'
|
import { parseJson } from '@/views/chart/components/js/util'
|
||||||
import { formatterItem, valueFormatter } from '@/views/chart/components/js/formatter'
|
import { formatterItem, valueFormatter } from '@/views/chart/components/js/formatter'
|
||||||
import { copyContent, getCurrentField } from '@/views/chart/components/js/panel/common/common_table'
|
import {
|
||||||
|
copyContent,
|
||||||
|
getCurrentField,
|
||||||
|
SortTooltip
|
||||||
|
} from '@/views/chart/components/js/panel/common/common_table'
|
||||||
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
|
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { isNumber } from 'lodash-es'
|
import { isNumber } from 'lodash-es'
|
||||||
@ -17,7 +21,8 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
|||||||
...TABLE_EDITOR_PROPERTY_INNER,
|
...TABLE_EDITOR_PROPERTY_INNER,
|
||||||
'table-header-selector': [
|
'table-header-selector': [
|
||||||
...TABLE_EDITOR_PROPERTY_INNER['table-header-selector'],
|
...TABLE_EDITOR_PROPERTY_INNER['table-header-selector'],
|
||||||
'tableHeaderSort'
|
'tableHeaderSort',
|
||||||
|
'showTableHeader'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
axis: AxisType[] = ['xAxis', 'yAxis', 'drill', 'filter']
|
axis: AxisType[] = ['xAxis', 'yAxis', 'drill', 'filter']
|
||||||
@ -110,7 +115,8 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
|||||||
style: this.configStyle(chart),
|
style: this.configStyle(chart),
|
||||||
conditions: this.configConditions(chart),
|
conditions: this.configConditions(chart),
|
||||||
tooltip: {
|
tooltip: {
|
||||||
getContainer: () => containerDom
|
getContainer: () => containerDom,
|
||||||
|
renderTooltip: sheet => new SortTooltip(sheet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 开启序号之后,第一列就是序号列,修改 label 即可
|
// 开启序号之后,第一列就是序号列,修改 label 即可
|
||||||
@ -133,9 +139,23 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tooltip
|
// tooltip
|
||||||
this.configTooltip(s2Options)
|
this.configTooltip(chart, s2Options)
|
||||||
// header interaction
|
// 隐藏表头,保留顶部的分割线, 禁用表头横向 resize
|
||||||
this.configHeaderInteraction(chart, s2Options)
|
if (customAttr.tableHeader.showTableHeader === false) {
|
||||||
|
s2Options.style.colCfg.height = 1
|
||||||
|
s2Options.interaction = {
|
||||||
|
resize: {
|
||||||
|
colCellVertical: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s2Options.colCell = (node, sheet, config) => {
|
||||||
|
node.label = ' '
|
||||||
|
return new TableColCell(node, sheet, config)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// header interaction
|
||||||
|
this.configHeaderInteraction(chart, s2Options)
|
||||||
|
}
|
||||||
// 开始渲染
|
// 开始渲染
|
||||||
const newChart = new TableSheet(containerDom, s2DataConfig, s2Options)
|
const newChart = new TableSheet(containerDom, s2DataConfig, s2Options)
|
||||||
|
|
||||||
@ -167,13 +187,10 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
|||||||
}
|
}
|
||||||
action(param)
|
action(param)
|
||||||
})
|
})
|
||||||
// hover
|
// tooltip
|
||||||
const { showColTooltip } = customAttr.tableHeader
|
const { show } = customAttr.tooltip
|
||||||
if (showColTooltip) {
|
if (show) {
|
||||||
newChart.on(S2Event.COL_CELL_HOVER, event => this.showTooltip(newChart, event, meta))
|
newChart.on(S2Event.COL_CELL_HOVER, event => this.showTooltip(newChart, event, meta))
|
||||||
}
|
|
||||||
const { showTooltip } = customAttr.tableCell
|
|
||||||
if (showTooltip) {
|
|
||||||
newChart.on(S2Event.DATA_CELL_HOVER, event => this.showTooltip(newChart, event, meta))
|
newChart.on(S2Event.DATA_CELL_HOVER, event => this.showTooltip(newChart, event, meta))
|
||||||
}
|
}
|
||||||
// header resize
|
// header resize
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user