Merge branch 'dev-v2' into pr@dev-v2@feat_plugin_view

This commit is contained in:
fit2cloud-chenyw 2024-06-13 16:28:20 +08:00 committed by GitHub
commit e27ce1b9a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 1529 additions and 257 deletions

View File

@ -114,12 +114,26 @@ public class ChartDataManage {
List<ChartViewFieldDTO> allFields = getAllChartFields(view);
ChartViewDTO chartViewDTO = null;
if (StringUtils.equalsIgnoreCase(view.getType(), "chart-mix")) {
if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix")) {
// 需要排除掉除类别轴以外所有的排序
view.getXAxisExt().forEach(dto -> dto.setSort("none"));
view.getExtBubble().forEach(dto -> dto.setSort("none"));
view.getExtStack().forEach(dto -> dto.setSort("none"));
view.getYAxis().forEach(dto -> dto.setSort("none"));
view.getYAxisExt().forEach(dto -> dto.setSort("none"));
//左轴右轴需要分别调用一次查询
String viewJson = (String) JsonUtil.toJSONString(view);
Map<String, Object> data = new HashMap<>();
//针对左轴删除yAxisExt
ChartViewDTO view1 = JsonUtil.parseObject(viewJson, ChartViewDTO.class);
if (!StringUtils.equalsIgnoreCase(view.getType(), "chart-mix-group")) {
view1.setXAxisExt(new ArrayList<>());
}
if (!StringUtils.equalsIgnoreCase(view.getType(), "chart-mix-stack")) {
view1.setExtStack(new ArrayList<>());
}
view1.setExtBubble(new ArrayList<>());
view1.setYAxisExt(new ArrayList<>());
if (view1.getSenior() != null) {
ChartSeniorAssistCfgDTO assistLineCfg1 = JsonUtil.parseObject((String) JsonUtil.toJSONString(view1.getSenior().get("assistLineCfg")), ChartSeniorAssistCfgDTO.class);
@ -145,13 +159,17 @@ public class ChartDataManage {
}
}
view2.setXAxisExt(view2.getExtBubble());
view2.setExtStack(new ArrayList<>());
view2.setExtBubble(new ArrayList<>());
ChartViewDTO right = calcData(view2, chartExtRequest, allFields, viewFields);
data.put("right", right.getData());
//重新组装
chartViewDTO = BeanUtils.copyBean(new ChartViewDTO(), left);
chartViewDTO.setXAxisExt(view.getXAxisExt());
chartViewDTO.setExtStack(view.getExtStack());
chartViewDTO.setYAxisExt(view.getYAxisExt());
chartViewDTO.setExtBubble(view.getExtBubble());
chartViewDTO.setData(data);
chartViewDTO.setSenior(view.getSenior());
} else {
@ -866,8 +884,15 @@ public class ChartDataManage {
} else if (StringUtils.containsIgnoreCase(view.getType(), "bidirectional-bar")
|| StringUtils.containsIgnoreCase(view.getType(), "progress-bar")) {
mapChart = ChartDataBuild.transMixChartDataAntV(xAxisBase, xAxis, new ArrayList<>(), yAxis, view, data, isDrill);
} else if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix")) {
} else if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix") && !StringUtils.containsIgnoreCase(view.getType(), "stack")) {
mapChart = ChartDataBuild.transMixChartDataAntV(xAxisBase, xAxis, xAxisExt, yAxis, view, data, isDrill);
} else if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix") && StringUtils.containsIgnoreCase(view.getType(), "stack")) {
if (CollectionUtils.isNotEmpty(extStack)) {
mapChart = ChartDataBuild.transMixChartStackDataAntV(xAxisBase, xAxis, extStack, yAxis, view, data, isDrill);
} else {
//右轴还是走原逻辑
mapChart = ChartDataBuild.transMixChartDataAntV(xAxisBase, xAxis, xAxisExt, yAxis, view, data, isDrill);
}
} else if (StringUtils.containsIgnoreCase(view.getType(), "label")) {
mapChart = ChartDataBuild.transLabelChartData(xAxis, yAxis, view, data, isDrill);
} else if (StringUtils.containsIgnoreCase(view.getType(), "quadrant")) {
@ -1351,7 +1376,7 @@ public class ChartDataManage {
xAxis.addAll(xAxisExt);
}
List<ChartViewFieldDTO> yAxis = new ArrayList<>(view.getYAxis());
if (StringUtils.equalsIgnoreCase(view.getType(), "chart-mix")) {
if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix")) {
List<ChartViewFieldDTO> yAxisExt = new ArrayList<>(view.getYAxisExt());
yAxis.addAll(yAxisExt);
}

View File

@ -8,6 +8,7 @@ import io.dataease.i18n.Lang;
import io.dataease.i18n.Translator;
import io.dataease.utils.IDUtils;
import io.dataease.utils.JsonUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
@ -175,7 +176,7 @@ public class ChartDataBuild {
axisChartDataDTO.setCategory(StringUtils.defaultIfBlank(yAxis.get(j).getChartShowName(), yAxis.get(j).getName()));
buildDynamicValue(view, axisChartDataDTO, row, size, extSize);
Map<String, Object> object = JsonUtil.parse((String) JsonUtil.toJSONString(axisChartDataDTO) , HashMap.class);
Map<String, Object> object = JsonUtil.parse((String) JsonUtil.toJSONString(axisChartDataDTO), HashMap.class);
object.put("x", new BigDecimal(row[0]));
object.put("y", new BigDecimal(row[1]));
@ -518,7 +519,7 @@ public class ChartDataBuild {
}
// antV组合图形
public static Map<String, Object> transMixChartDataAntV(List<ChartViewFieldDTO> xAxisBase, List<ChartViewFieldDTO> xAxis,List<ChartViewFieldDTO> xAxisExt, List<ChartViewFieldDTO> yAxis, ChartViewDTO view, List<String[]> data, boolean isDrill) {
public static Map<String, Object> transMixChartDataAntV(List<ChartViewFieldDTO> xAxisBase, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> xAxisExt, List<ChartViewFieldDTO> yAxis, ChartViewDTO view, List<String[]> data, boolean isDrill) {
Map<String, Object> map = new HashMap<>();
List<Series> series = new ArrayList<>();
@ -529,6 +530,8 @@ public class ChartDataBuild {
series1.setData(new ArrayList<>());
series.add(series1);
}
Set<String> categories = new HashSet<>();
for (int i1 = 0; i1 < data.size(); i1++) {
String[] d = data.get(i1);
@ -584,13 +587,107 @@ public class ChartDataBuild {
} catch (Exception e) {
axisChartDataDTO.setValue(new BigDecimal(0));
}
axisChartDataDTO.setCategory(
StringUtils.defaultIfBlank(b.toString(),
StringUtils.defaultIfBlank(yAxis.get(j).getChartShowName(), yAxis.get(j).getName())));
String category = StringUtils.defaultIfBlank(b.toString(),
StringUtils.defaultIfBlank(yAxis.get(j).getChartShowName(), yAxis.get(j).getName()));
axisChartDataDTO.setCategory(category);
categories.add(category);
buildDynamicValue(view, axisChartDataDTO, d, size, extSize);
series.get(j).getData().add(axisChartDataDTO);
}
}
series.get(0).setCategories(categories);
map.put("data", series);
return map;
}
public static Map<String, Object> transMixChartStackDataAntV(List<ChartViewFieldDTO> xAxisBase, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> extStack, List<ChartViewFieldDTO> yAxis, ChartViewDTO view, List<String[]> data, boolean isDrill) {
if (CollectionUtils.isEmpty(extStack)) {
return transMixChartDataAntV(xAxisBase, xAxis, new ArrayList<>(), yAxis, view, data, isDrill);
}
Map<String, Object> map = new HashMap<>();
List<Series> series = new ArrayList<>();
for (ChartViewFieldDTO y : yAxis) {
Series series1 = new Series();
series1.setName(y.getName());
series1.setType(y.getChartType());
series1.setData(new ArrayList<>());
series.add(series1);
}
Set<String> categories = new HashSet<>();
for (int i1 = 0; i1 < data.size(); i1++) {
String[] row = data.get(i1);
StringBuilder a = new StringBuilder();
if (isDrill) {
a.append(row[xAxis.size() - 1]);
} else {
for (int i = 0; i < xAxis.size(); i++) {
if (i == xAxis.size() - 1) {
a.append(row[i]);
} else {
a.append(row[i]).append("\n");
}
}
}
// yAxis最后的数据对应extLabel和extTooltip将他们从yAxis中去掉同时转换成动态值
int size = xAxis.size() + extStack.size() + yAxis.size();
int extSize = view.getExtLabel().size() + view.getExtTooltip().size();
int i = xAxis.size();
AxisChartDataAntVDTO axisChartDataDTO = new AxisChartDataAntVDTO();
axisChartDataDTO.setField(a.toString());
axisChartDataDTO.setName(a.toString());
String category = row[xAxis.size()];
axisChartDataDTO.setCategory(category);
if (category != null) {
categories.add(category);
}
List<ChartDimensionDTO> dimensionList = new ArrayList<>();
List<ChartQuotaDTO> quotaList = new ArrayList<>();
for (int k = 0; k < xAxis.size(); k++) {
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
chartDimensionDTO.setId(xAxis.get(k).getId());
chartDimensionDTO.setValue(row[k]);
dimensionList.add(chartDimensionDTO);
}
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
chartDimensionDTO.setId(extStack.get(0).getId());
chartDimensionDTO.setValue(row[xAxis.size()]);
dimensionList.add(chartDimensionDTO);
axisChartDataDTO.setDimensionList(dimensionList);
int j = i - xAxis.size();
int valueIndex = xAxis.size() + extStack.size();
if (ObjectUtils.isNotEmpty(yAxis)) {
ChartQuotaDTO chartQuotaDTO = new ChartQuotaDTO();
chartQuotaDTO.setId(yAxis.get(j).getId());
quotaList.add(chartQuotaDTO);
axisChartDataDTO.setQuotaList(quotaList);
try {
axisChartDataDTO.setValue(StringUtils.isEmpty(row[valueIndex]) ? null : new BigDecimal(row[valueIndex]));
} catch (Exception e) {
axisChartDataDTO.setValue(new BigDecimal(0));
}
buildDynamicValue(view, axisChartDataDTO, row, size, extSize);
} else {
axisChartDataDTO.setQuotaList(quotaList);
axisChartDataDTO.setValue(new BigDecimal(0));
}
series.get(j).getData().add(axisChartDataDTO);
}
series.get(0).setCategories(categories);
map.put("data", series);
return map;

View File

@ -27,7 +27,7 @@
"axios": "^1.3.3",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.9",
"element-plus-secondary": "^0.5.9",
"element-plus-secondary": "^0.5.11",
"element-resize-detector": "^1.2.4",
"file-saver": "^2.0.5",
"flv.js": "^1.6.2",

View File

@ -0,0 +1,8 @@
<svg width="80" height="56" viewBox="0 0 80 56" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 2.00391V51.0016L76 51.0016L76 54.0016H4V2.00391H7Z" fill="#434343"/>
<path d="M25 4.5C25 4.22386 25.2239 4 25.5 4H34.5C34.7761 4 35 4.22386 35 4.5V48.5C35 48.7761 34.7761 49 34.5 49H25.5C25.2239 49 25 48.7761 25 48.5V4.5Z" fill="#1F4399"/>
<path d="M12 29.5C12 29.2239 12.2239 29 12.5 29H21.5C21.7761 29 22 29.2239 22 29.5V48.5C22 48.7761 21.7761 49 21.5 49H12.5C12.2239 49 12 48.7761 12 48.5V29.5Z" fill="#3370FF"/>
<path d="M47 19.5C47 19.2239 47.2239 19 47.5 19H56.5C56.7761 19 57 19.2239 57 19.5V48.5C57 48.7761 56.7761 49 56.5 49H47.5C47.2239 49 47 48.7761 47 48.5V19.5Z" fill="#3370FF"/>
<path d="M60 36.5C60 36.2239 60.2239 36 60.5 36H69.5C69.7761 36 70 36.2239 70 36.5V48.5C70 48.7761 69.7761 49 69.5 49H60.5C60.2239 49 60 48.7761 60 48.5V36.5Z" fill="#1F4399"/>
<path d="M37.686 5.23115C37.2792 4.8243 36.6138 4.84386 36.2315 5.27389L34.8455 6.83278C34.1868 7.57357 33.2442 8.63334 32.1089 9.90925C29.8382 12.4611 26.7969 15.8774 23.714 19.3352C17.5164 26.2866 11.2327 33.3131 10.6063 33.9395C10.0205 34.5252 10.0205 35.475 10.6063 36.0608C11.1921 36.6466 12.1419 36.6466 12.7277 36.0608C13.4346 35.3538 19.8175 28.2137 25.9533 21.3317C29.0371 17.8728 32.0791 14.4558 34.3501 11.9035C35.4725 10.6421 36.4066 9.59185 37.0644 8.85216L49.5834 21.3711C49.9141 21.7019 50.43 21.7592 50.8253 21.509L72.851 7.56895L72.8605 7.56229C73.5392 7.08722 73.7043 6.15192 73.2292 5.47325C72.7567 4.7983 71.8291 4.63135 71.1513 5.09682L50.5191 18.0642L37.686 5.23115Z" fill="#00D6B9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,8 @@
<svg width="80" height="56" viewBox="0 0 80 56" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 2.00391V51.0016L76 51.0016L76 54.0016H4V2.00391H7Z" fill="#DEE0E3"/>
<path d="M25 4.5C25 4.22386 25.2239 4 25.5 4H34.5C34.7761 4 35 4.22386 35 4.5V48.5C35 48.7761 34.7761 49 34.5 49H25.5C25.2239 49 25 48.7761 25 48.5V4.5Z" fill="#ADC6FF"/>
<path d="M12 29.5C12 29.2239 12.2239 29 12.5 29H21.5C21.7761 29 22 29.2239 22 29.5V48.5C22 48.7761 21.7761 49 21.5 49H12.5C12.2239 49 12 48.7761 12 48.5V29.5Z" fill="#3370FF"/>
<path d="M47 19.5C47 19.2239 47.2239 19 47.5 19H56.5C56.7761 19 57 19.2239 57 19.5V48.5C57 48.7761 56.7761 49 56.5 49H47.5C47.2239 49 47 48.7761 47 48.5V19.5Z" fill="#3370FF"/>
<path d="M60 36.5C60 36.2239 60.2239 36 60.5 36H69.5C69.7761 36 70 36.2239 70 36.5V48.5C70 48.7761 69.7761 49 69.5 49H60.5C60.2239 49 60 48.7761 60 48.5V36.5Z" fill="#ADC6FF"/>
<path d="M37.686 5.23115C37.2792 4.8243 36.6138 4.84386 36.2315 5.27389L34.8455 6.83278C34.1868 7.57357 33.2442 8.63334 32.1089 9.90925C29.8382 12.4611 26.7969 15.8774 23.714 19.3352C17.5164 26.2866 11.2327 33.3131 10.6063 33.9395C10.0205 34.5252 10.0205 35.475 10.6063 36.0608C11.1921 36.6466 12.1419 36.6466 12.7277 36.0608C13.4346 35.3538 19.8175 28.2137 25.9533 21.3317C29.0371 17.8728 32.0791 14.4558 34.3501 11.9035C35.4725 10.6421 36.4066 9.59185 37.0644 8.85216L49.5834 21.3711C49.9141 21.7019 50.43 21.7592 50.8253 21.509L72.851 7.56895L72.8605 7.56229C73.5392 7.08722 73.7043 6.15192 73.2292 5.47325C72.7567 4.7983 71.8291 4.63135 71.1513 5.09682L50.5191 18.0642L37.686 5.23115Z" fill="#00D6B9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,12 @@
<svg width="80" height="56" viewBox="0 0 80 56" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 2.00391V51.0016L76 51.0016L76 54.0016H4V2.00391H7Z" fill="#434343"/>
<path d="M12 30.5C12 30.2239 12.2239 30 12.5 30H21.5C21.7761 30 22 30.2239 22 30.5V37H12V30.5Z" fill="#1F4399"/>
<path d="M12 38H22V48.5C22 48.7761 21.7761 49 21.5 49H12.5C12.2239 49 12 48.7761 12 48.5V38Z" fill="#3370FF"/>
<path d="M28 4.5C28 4.22386 28.2239 4 28.5 4H37.5C37.7761 4 38 4.22386 38 4.5V16H28V4.5Z" fill="#1F4399"/>
<path d="M28 17H38V48.5C38 48.7761 37.7761 49 37.5 49H28.5C28.2239 49 28 48.7761 28 48.5V17Z" fill="#3370FF"/>
<path d="M44 19.5C44 19.2239 44.2239 19 44.5 19H53.5C53.7761 19 54 19.2239 54 19.5V31H44V19.5Z" fill="#1F4399"/>
<path d="M44 32H54V48.5C54 48.7761 53.7761 49 53.5 49H44.5C44.2239 49 44 48.7761 44 48.5V32Z" fill="#3370FF"/>
<path d="M60 36.5C60 36.2239 60.2239 36 60.5 36H69.5C69.7761 36 70 36.2239 70 36.5V41H60V36.5Z" fill="#1F4399"/>
<path d="M60 42H70V48.5C70 48.7761 69.7761 49 69.5 49H60.5C60.2239 49 60 48.7761 60 48.5V42Z" fill="#3370FF"/>
<path d="M37.686 5.23115C37.2792 4.8243 36.6138 4.84386 36.2315 5.27389L34.8455 6.83278C34.1868 7.57357 33.2442 8.63334 32.1089 9.90925C29.8382 12.4611 26.7969 15.8774 23.714 19.3352C17.5164 26.2866 11.2327 33.3131 10.6063 33.9395C10.0205 34.5252 10.0205 35.475 10.6063 36.0608C11.1921 36.6466 12.1419 36.6466 12.7277 36.0608C13.4346 35.3538 19.8175 28.2137 25.9533 21.3317C29.0371 17.8728 32.0791 14.4558 34.3501 11.9035C35.4725 10.6421 36.4066 9.59185 37.0644 8.85216L49.5834 21.3711C49.9141 21.7019 50.43 21.7592 50.8253 21.509L72.851 7.56895L72.8605 7.56229C73.5392 7.08722 73.7043 6.15192 73.2292 5.47325C72.7567 4.7983 71.8291 4.63135 71.1513 5.09682L50.5191 18.0642L37.686 5.23115Z" fill="#00D6B9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,12 @@
<svg width="80" height="56" viewBox="0 0 80 56" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 2.00391V51.0016L76 51.0016L76 54.0016H4V2.00391H7Z" fill="#DEE0E3"/>
<path d="M12 30.5C12 30.2239 12.2239 30 12.5 30H21.5C21.7761 30 22 30.2239 22 30.5V37H12V30.5Z" fill="#ADC6FF"/>
<path d="M12 38H22V48.5C22 48.7761 21.7761 49 21.5 49H12.5C12.2239 49 12 48.7761 12 48.5V38Z" fill="#3370FF"/>
<path d="M28 4.5C28 4.22386 28.2239 4 28.5 4H37.5C37.7761 4 38 4.22386 38 4.5V16H28V4.5Z" fill="#ADC6FF"/>
<path d="M28 17H38V48.5C38 48.7761 37.7761 49 37.5 49H28.5C28.2239 49 28 48.7761 28 48.5V17Z" fill="#3370FF"/>
<path d="M44 19.5C44 19.2239 44.2239 19 44.5 19H53.5C53.7761 19 54 19.2239 54 19.5V31H44V19.5Z" fill="#ADC6FF"/>
<path d="M44 32H54V48.5C54 48.7761 53.7761 49 53.5 49H44.5C44.2239 49 44 48.7761 44 48.5V32Z" fill="#3370FF"/>
<path d="M60 36.5C60 36.2239 60.2239 36 60.5 36H69.5C69.7761 36 70 36.2239 70 36.5V41H60V36.5Z" fill="#ADC6FF"/>
<path d="M60 42H70V48.5C70 48.7761 69.7761 49 69.5 49H60.5C60.2239 49 60 48.7761 60 48.5V42Z" fill="#3370FF"/>
<path d="M37.686 5.23115C37.2792 4.8243 36.6138 4.84386 36.2315 5.27389L34.8455 6.83278C34.1868 7.57357 33.2442 8.63334 32.1089 9.90925C29.8382 12.4611 26.7969 15.8774 23.714 19.3352C17.5164 26.2866 11.2327 33.3131 10.6063 33.9395C10.0205 34.5252 10.0205 35.475 10.6063 36.0608C11.1921 36.6466 12.1419 36.6466 12.7277 36.0608C13.4346 35.3538 19.8175 28.2137 25.9533 21.3317C29.0371 17.8728 32.0791 14.4558 34.3501 11.9035C35.4725 10.6421 36.4066 9.59185 37.0644 8.85216L49.5834 21.3711C49.9141 21.7019 50.43 21.7592 50.8253 21.509L72.851 7.56895L72.8605 7.56229C73.5392 7.08722 73.7043 6.15192 73.2292 5.47325C72.7567 4.7983 71.8291 4.63135 71.1513 5.09682L50.5191 18.0642L37.686 5.23115Z" fill="#00D6B9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 744 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 744 KiB

View File

@ -1 +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="1682495427436" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3689" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M672 288H352c-9.6 0-16 3.2-22.4 9.6-6.4 6.4-9.6 12.8-9.6 22.4v64c0 19.2 12.8 32 32 32s32-16 32-32v-32h96v320h-32c-16 0-32 12.8-32 32s12.8 32 32 32h128c16 0 32-12.8 32-32s-12.8-32-32-32h-32V352h96v32c0 19.2 12.8 32 32 32s32-16 32-32v-64c0-9.6-3.2-16-9.6-22.4-6.4-6.4-12.8-9.6-22.4-9.6z" fill="#F2F2F2" p-id="3690" data-spm-anchor-id="a313x.7781069.0.i4" class=""></path><path d="M896 128H128c-35.2 0-64 28.8-64 64v640c0 35.2 28.8 64 64 64h768c35.2 0 64-28.8 64-64V192c0-35.2-28.8-64-64-64z m0 672c0 16-12.8 32-32 32H160c-19.2 0-32-16-32-32V224c0-16 12.8-32 32-32h704c19.2 0 32 16 32 32v576z" fill="#F2F2F2" p-id="3691" data-spm-anchor-id="a313x.7781069.0.i1" class=""></path></svg>
<?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="1682495427436" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3689" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M672 288H352c-9.6 0-16 3.2-22.4 9.6-6.4 6.4-9.6 12.8-9.6 22.4v64c0 19.2 12.8 32 32 32s32-16 32-32v-32h96v320h-32c-16 0-32 12.8-32 32s12.8 32 32 32h128c16 0 32-12.8 32-32s-12.8-32-32-32h-32V352h96v32c0 19.2 12.8 32 32 32s32-16 32-32v-64c0-9.6-3.2-16-9.6-22.4-6.4-6.4-12.8-9.6-22.4-9.6z" p-id="3690" data-spm-anchor-id="a313x.7781069.0.i4" class=""></path><path d="M896 128H128c-35.2 0-64 28.8-64 64v640c0 35.2 28.8 64 64 64h768c35.2 0 64-28.8 64-64V192c0-35.2-28.8-64-64-64z m0 672c0 16-12.8 32-32 32H160c-19.2 0-32-16-32-32V224c0-16 12.8-32 32-32h704c19.2 0 32 16 32 32v576z" p-id="3691" data-spm-anchor-id="a313x.7781069.0.i1" class=""></path></svg>

Before

Width:  |  Height:  |  Size: 1013 B

After

Width:  |  Height:  |  Size: 984 B

View File

@ -21,6 +21,8 @@ import { useCache } from '@/hooks/web/useCache'
import QueryGroup from '@/custom-component/component-group/QueryGroup.vue'
import ComponentButton from '@/components/visualization/ComponentButton.vue'
import OuterParamsSet from '@/components/visualization/OuterParamsSet.vue'
import MultiplexingCanvas from '@/views/common/MultiplexingCanvas.vue'
import ComponentButtonLabel from '@/components/visualization/ComponentButtonLabel.vue'
let nameEdit = ref(false)
let inputName = ref('')
let nameInput = ref(null)
@ -166,6 +168,7 @@ const getFullScale = () => {
}
const appStore = useAppStoreWithOut()
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
const multiplexingRef = ref(null)
eventBus.on('preview', preview)
eventBus.on('save', saveCanvasWithCheck)
@ -182,6 +185,10 @@ const openOuterParamsSet = () => {
}
outerParamsSetRef.value.optInit()
}
const multiplexingCanvasOpen = () => {
multiplexingRef.value.dialogInit('dataV')
}
</script>
<template>
@ -260,9 +267,21 @@ const openOuterParamsSet = () => {
<component-group is-label :base-width="215" icon-name="dv-more-com" title="更多">
<more-com-group></more-com-group>
</component-group>
<component-group is-label :base-width="410" icon-name="dv-material" title="素材">
<component-group
is-label
:base-width="410"
icon-name="dv-material"
:show-split-line="true"
title="素材"
>
<common-group></common-group>
</component-group>
<component-button-label
icon-name="icon_copy_filled"
title="复用"
is-label
@customClick="multiplexingCanvasOpen"
></component-button-label>
</div>
</template>
<div class="right-area">
@ -316,6 +335,7 @@ const openOuterParamsSet = () => {
ref="resourceGroupOpt"
/>
</div>
<multiplexing-canvas ref="multiplexingRef"></multiplexing-canvas>
<outer-params-set ref="outerParamsSetRef"> </outer-params-set>
<XpackComponent ref="openHandler" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" />
</template>

View File

@ -64,12 +64,12 @@
show-position="viewDialog"
/>
<chart-component-s2
v-if="optType === 'details' && sourceViewType !== 'chart-mix'"
v-if="optType === 'details' && !sourceViewType.includes('chart-mix')"
:view="viewInfo"
show-position="viewDialog"
ref="chartComponentDetails"
/>
<template v-else-if="optType === 'details' && sourceViewType === 'chart-mix'">
<template v-else-if="optType === 'details' && sourceViewType.includes('chart-mix')">
<el-tabs class="tab-header" v-model="activeName" @tab-change="handleClick">
<el-tab-pane :label="t('chart.drag_block_value_axis_left')" name="left"></el-tab-pane>
<el-tab-pane :label="t('chart.drag_block_value_axis_right')" name="right"></el-tab-pane>
@ -214,7 +214,7 @@ const dialogInit = (canvasStyle, view, item, opt) => {
const dataDetailsOpt = () => {
nextTick(() => {
const viewDataInfo = dvMainStore.getViewDataDetails(viewInfo.value.id)
if (sourceViewType.value === 'chart-mix') {
if (sourceViewType.value.includes('chart-mix')) {
chartComponentDetails.value?.renderChartFromDialog(viewInfo.value, viewDataInfo.left)
chartComponentDetails2.value?.renderChartFromDialog(viewInfo.value, viewDataInfo.right)
} else {

View File

@ -69,15 +69,46 @@ const defaultStyle = {
titleShow: false,
titleColor: '',
textColorShow: false,
labelColor: '',
bgColorShow: false,
borderShow: false,
labelColorShow: false,
title: ''
labelShow: true,
title: '',
labelColor: '#1f2329',
fontSize: '14',
fontWeight: '',
fontStyle: '',
fontSizeBtn: '14',
fontWeightBtn: '',
fontStyleBtn: '',
queryConditionWidth: 227,
nameboxSpacing: 8,
queryConditionSpacing: 16,
btnColor: '#3370ff',
labelColorBtn: '#ffffff'
}
const customStyle = reactive({ ...defaultStyle })
const snapshotStore = snapshotStoreWithOut()
const btnStyle = computed(() => {
const style = {
backgroundColor: customStyle.btnColor,
borderColor: customStyle.btnColor,
color: customStyle.labelColorBtn
} as CSSProperties
if (customStyle.fontSizeBtn) {
style.fontSize = customStyle.fontSizeBtn + 'px'
}
if (customStyle.fontWeightBtn) {
style.fontWeight = customStyle.fontWeightBtn
}
if (customStyle.fontStyleBtn) {
style.fontStyle = customStyle.fontStyleBtn
}
return style
})
const curComponentView = computed(() => {
return (canvasViewInfo.value[element.value.id] || {}).customStyle
})
@ -92,14 +123,25 @@ const setCustomStyle = val => {
btnList,
titleLayout,
labelColor,
labelColorShow,
text,
bgColor,
layout,
titleShow,
titleColor,
textColorShow,
title
title,
fontSize,
fontWeight,
fontStyle,
fontSizeBtn,
fontWeightBtn,
fontStyleBtn,
queryConditionWidth,
nameboxSpacing,
queryConditionSpacing,
labelColorBtn,
btnColor,
labelShow
} = val
customStyle.background = bgColorShow ? bgColor || '' : ''
customStyle.border = borderShow ? borderColor || '' : ''
@ -107,10 +149,22 @@ const setCustomStyle = val => {
customStyle.layout = layout
customStyle.titleShow = titleShow
customStyle.titleColor = titleColor
customStyle.labelColor = labelColorShow ? labelColor || '' : ''
customStyle.labelColor = labelShow ? labelColor || '' : ''
customStyle.fontSize = labelShow ? fontSize || '14' : '14'
customStyle.fontWeight = labelShow ? fontWeight || '' : ''
customStyle.fontStyle = labelShow ? fontStyle || '' : ''
customStyle.title = title
customStyle.text = textColorShow ? text || '' : ''
customStyle.titleLayout = titleLayout
customStyle.fontSizeBtn = fontSizeBtn || '14'
customStyle.fontWeightBtn = fontWeightBtn
customStyle.fontStyleBtn = fontStyleBtn
customStyle.queryConditionWidth = queryConditionWidth ?? 227
customStyle.nameboxSpacing = nameboxSpacing ?? 8
customStyle.queryConditionSpacing = queryConditionSpacing ?? 16
customStyle.labelColorBtn = labelColorBtn || '#ffffff'
customStyle.labelShow = labelShow ?? true
customStyle.btnColor = btnColor || '#3370ff'
}
watch(
@ -196,10 +250,14 @@ const queryDataForId = id => {
emitter.emit(`query-data-${ele}`)
})
}
const getQueryConditionWidth = () => {
return customStyle.queryConditionWidth
}
provide('unmount-select', unMountSelect)
provide('release-unmount-select', releaseSelect)
provide('query-data-for-id', queryDataForId)
provide('com-width', getQueryConditionWidth)
onBeforeUnmount(() => {
emitter.off(`addQueryCriteria${element.value.id}`)
emitter.off(`editQueryCriteria${element.value.id}`)
@ -384,9 +442,21 @@ const titleStyle = computed(() => {
})
const labelStyle = computed(() => {
return {
color: customStyle.labelColor || '#1f2329'
const style = {
fontSize: customStyle.fontSize + 'px'
} as CSSProperties
if (customStyle.fontWeight) {
style.fontWeight = customStyle.fontWeight
}
if (customStyle.fontStyle) {
style.fontStyle = customStyle.fontStyle
}
if (customStyle.labelColor) {
style.color = customStyle.labelColor
}
return style
})
const autoStyle = computed(() => {
return {
@ -428,10 +498,15 @@ const autoStyle = computed(() => {
</div>
</div>
<div class="query-fields-container">
<div class="query-item" :key="ele.id" v-for="(ele, index) in listVisible">
<div
class="query-item"
:style="{ marginRight: `${customStyle.queryConditionSpacing}px` }"
:key="ele.id"
v-for="(ele, index) in listVisible"
>
<div class="query-field">
<div class="label">
<div class="label-wrapper">
<div class="label" :style="{ marginRight: `${customStyle.nameboxSpacing}px` }">
<div class="label-wrapper" v-show="customStyle.labelShow">
<div class="label-wrapper-text" :style="labelStyle">
<el-tooltip effect="dark" :content="ele.name" placement="top">
{{ ele.name }}
@ -470,6 +545,7 @@ const autoStyle = computed(() => {
<el-button
@click.stop="queryData"
style="margin-right: 7px"
:style="btnStyle"
v-if="customStyle.btnList.includes('sure')"
type="primary"
>
@ -614,15 +690,10 @@ const autoStyle = computed(() => {
position: relative;
:deep(.ed-date-editor) {
width: 227px;
.ed-input__wrapper {
width: 100%;
}
}
:deep(.ed-select-v2) {
min-width: 170px;
}
}
}
}

View File

@ -69,6 +69,8 @@ const options = shallowRef([])
const unMountSelect: Ref = inject('unmount-select')
const releaseSelect = inject('release-unmount-select', Function, true)
const queryDataForId = inject('query-data-for-id', Function, true)
const queryConditionWidth = inject('com-width', Function, true)
const setDefaultMapValue = arr => {
const { displayId, field } = config.value
if (!displayId) {
@ -444,7 +446,7 @@ const init = () => {
}
const selectStyle = computed(() => {
return props.isConfig ? {} : { width: '227px' }
return props.isConfig ? {} : { width: queryConditionWidth() + 'px' }
})
const mult = ref()

View File

@ -1,5 +1,7 @@
<script lang="ts" setup>
import { toRefs, onBeforeMount, type PropType, inject, type CSSProperties } from 'vue'
import { toRefs, onBeforeMount, type PropType, inject, computed } from 'vue'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
interface SelectConfig {
conditionValueOperatorF: string
conditionValueF: string
@ -22,7 +24,8 @@ const operators = [
value: 'like'
}
]
const dvMainStore = dvMainStoreWithOut()
const { dvInfo } = storeToRefs(dvMainStore)
const props = defineProps({
config: {
type: Object as PropType<SelectConfig>,
@ -57,7 +60,15 @@ const setParams = () => {
onBeforeMount(() => {
setParams()
})
const queryConditionWidth = inject('com-width', Function, true)
const customStyle = inject<{ background: string }>('$custom-style-filter')
const selectStyle = computed(() => {
return { width: queryConditionWidth() + 'px' }
})
const lineWidth = computed(() => {
return { width: queryConditionWidth() - 15 + 'px' }
})
</script>
<template>
@ -65,27 +76,37 @@ const customStyle = inject<{ background: string }>('$custom-style-filter')
<div class="condition-type">
<el-select
class="condition-value-select"
:effect="dvInfo.type === 'dataV' ? 'dark' : ''"
popper-class="condition-value-select-popper"
v-model="config.conditionValueOperatorF"
>
<el-option v-for="ele in operators" :key="ele.value" :label="ele.label" :value="ele.value">
</el-option>
</el-select>
<el-input class="condition-value-input" v-model="config.conditionValueF" />
<div class="bottom-line"></div>
<el-input
:style="selectStyle"
class="condition-value-input"
v-model="config.conditionValueF"
/>
<div :style="lineWidth" class="bottom-line"></div>
</div>
<div class="condition-type" v-if="[1, 2].includes(config.conditionType)">
<sapn class="condition-type-tip">{{ config.conditionType === 1 ? '与' : '或' }}</sapn>
<el-select
class="condition-value-select"
:effect="dvInfo.type === 'dataV' ? 'dark' : ''"
popper-class="condition-value-select-popper"
v-model="config.conditionValueOperatorS"
>
<el-option v-for="ele in operators" :key="ele.value" :label="ele.label" :value="ele.value">
</el-option>
</el-select>
<el-input class="condition-value-input" v-model="config.conditionValueS" />
<div class="bottom-line next-line"></div>
<el-input
:style="selectStyle"
class="condition-value-input"
v-model="config.conditionValueS"
/>
<div :style="lineWidth" class="bottom-line next-line"></div>
</div>
</div>
</template>
@ -145,12 +166,7 @@ const customStyle = inject<{ background: string }>('$custom-style-filter')
position: absolute;
right: 5px;
bottom: 3px;
width: 195px;
z-index: 10;
&.next-line {
width: 195px;
}
}
}
}

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { toRefs, PropType, ref, onBeforeMount, watch, nextTick, computed } from 'vue'
import { toRefs, PropType, ref, onBeforeMount, watch, nextTick, computed, inject } from 'vue'
import { type DatePickType } from 'element-plus-secondary'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import type { ManipulateType } from 'dayjs'
@ -81,101 +81,6 @@ watch(
})
}
)
const isInRange = (ele, startWindowTime, timeStamp) => {
const {
intervalType,
regularOrTrends,
regularOrTrendsValue,
relativeToCurrent,
timeNum,
relativeToCurrentType,
around,
dynamicWindow,
maximumSingleQuery,
timeNumRange,
relativeToCurrentTypeRange,
aroundRange
} = ele.timeRange || {}
let isDynamicWindowTime = false
const noTime = ele.timeGranularityMultiple.split('time').join('').split('range')[0]
const queryTimeType = noTime === 'date' ? 'day' : (noTime as ManipulateType)
if (startWindowTime && dynamicWindow) {
isDynamicWindowTime =
dayjs(startWindowTime)
.add(maximumSingleQuery, queryTimeType)
.startOf(queryTimeType)
.valueOf() -
1000 <
timeStamp
}
if (intervalType === 'none') {
if (dynamicWindow) return isDynamicWindowTime
return false
}
let startTime
if (relativeToCurrent === 'custom') {
startTime = getAround(relativeToCurrentType, around === 'f' ? 'subtract' : 'add', timeNum)
} else {
switch (relativeToCurrent) {
case 'thisYear':
startTime = getThisStart('year')
break
case 'lastYear':
startTime = getLastStart('year')
break
case 'thisMonth':
startTime = getThisStart('month')
break
case 'lastMonth':
startTime = getLastStart('month')
break
case 'today':
startTime = getThisStart('day')
break
case 'yesterday':
startTime = getLastStart('day')
break
case 'monthBeginning':
startTime = getThisStart('month')
break
case 'yearBeginning':
startTime = getThisStart('year')
break
default:
break
}
}
const startValue = regularOrTrends === 'fixed' ? regularOrTrendsValue : startTime
if (intervalType === 'start') {
return startWindowTime < +new Date(startValue) || isDynamicWindowTime
}
if (intervalType === 'end') {
return timeStamp > +new Date(startValue) || isDynamicWindowTime
}
if (intervalType === 'timeInterval') {
const startTime =
regularOrTrends === 'fixed'
? regularOrTrendsValue[0]
: getAround(relativeToCurrentType, around === 'f' ? 'subtract' : 'add', timeNum)
const endTime =
regularOrTrends === 'fixed'
? regularOrTrendsValue[1]
: getAround(
relativeToCurrentTypeRange,
aroundRange === 'f' ? 'subtract' : 'add',
timeNumRange
)
return (
startWindowTime < +new Date(startTime) - 1000 ||
timeStamp > +new Date(endTime) ||
isDynamicWindowTime
)
}
}
const callback = param => {
startWindowTime.value = param[0]
const disabled = param.some(ele => {
@ -243,8 +148,14 @@ const init = () => {
multiple.value = config.value.displayType === '7'
}
const queryConditionWidth = inject('com-width', Function, true)
const selectStyle = computed(() => {
return props.isConfig ? {} : { width: multiple.value ? '470px' : '227px' }
return props.isConfig
? {}
: {
width:
(multiple.value ? queryConditionWidth() * 2 : queryConditionWidth()) + 'px !important'
}
})
const columnsType = computed(() => {

View File

@ -883,6 +883,8 @@ export default {
last_layer: '当前已经是最后一级',
radar_size: '大小',
chart_mix: '柱线组合图',
chart_mix_group_column: '分组柱线组合图',
chart_mix_stack_column: '堆叠柱线组合图',
axis_value: '轴值',
axis_value_min: '最小值',
axis_value_max: '最大值',

View File

@ -409,7 +409,6 @@ export const dvMainStore = defineStore('dataVisualization', {
borderShow: false,
text,
textColorShow: false,
labelColorShow: false,
labelColor,
borderColor,
title: '',
@ -419,7 +418,19 @@ export const dvMainStore = defineStore('dataVisualization', {
titleColor,
titleLayout,
layout,
btnList: ['sure']
btnList: ['sure'],
fontSize: '14',
labelShow: true,
fontWeight: '',
fontStyle: '',
fontSizeBtn: '14',
fontWeightBtn: '',
fontStyleBtn: '',
queryConditionWidth: 227,
nameboxSpacing: 8,
queryConditionSpacing: 16,
labelColorBtn: '#ffffff',
btnColor: '#3370ff'
}
}
}

View File

@ -475,7 +475,7 @@ interface CanvasViewInfo {
}
const colors = ['labelColor', 'borderColor', 'text', 'bgColor']
const colorsSwitch = ['labelColorShow', 'borderShow', 'textColorShow', 'bgColorShow']
const colorsSwitch = ['borderShow', 'textColorShow', 'bgColorShow']
export function adaptCurThemeFilterStyleAllKeyComponent(component) {
if (isFilterComponent(component.type)) {

View File

@ -226,7 +226,13 @@ onMounted(() => {
class="drop-style"
:class="themes === 'dark' ? 'dark-dimension-quota' : ''"
>
<el-dropdown-item @click.prevent>
<el-dropdown-item
@click.prevent
v-if="
!chart.type.includes('chart-mix') ||
(chart.type.includes('chart-mix') && type === 'dimension')
"
>
<el-dropdown
:effect="themes"
popper-class="data-dropdown_popper_mr9"
@ -305,7 +311,14 @@ onMounted(() => {
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item @click.prevent v-if="item.deType === 1" divided>
<el-dropdown-item
@click.prevent
v-if="item.deType === 1"
:divided="
!chart.type.includes('chart-mix') ||
(chart.type.includes('chart-mix') && type === 'dimension')
"
>
<el-dropdown
:effect="themes"
placement="right-start"
@ -495,7 +508,14 @@ onMounted(() => {
</template>
</el-dropdown>
</el-dropdown-item>
<el-dropdown-item class="menu-item-padding" divided :command="beforeClickItem('rename')">
<el-dropdown-item
class="menu-item-padding"
:divided="
!chart.type.includes('chart-mix') ||
(chart.type.includes('chart-mix') && type === 'dimension')
"
:command="beforeClickItem('rename')"
>
<el-icon>
<icon name="icon_edit_outlined"></icon>
</el-icon>

View File

@ -665,7 +665,10 @@ onMounted(() => {
<el-dropdown-item
@click.prevent
v-if="
props.type !== 'extLabel' && props.type !== 'extTooltip' && props.type !== 'extBubble'
props.type !== 'extLabel' &&
props.type !== 'extTooltip' &&
props.type !== 'extBubble' &&
!chart.type.includes('chart-mix')
"
:divided="chart.type !== 'table-info'"
>
@ -739,6 +742,7 @@ onMounted(() => {
"
:icon="Filter"
:command="beforeClickItem('filter')"
:divided="chart.type.includes('chart-mix')"
>
<span>{{ t('chart.filter') }}...</span>
</el-dropdown-item>

View File

@ -21,7 +21,7 @@ const props = defineProps({
(props.view.type.includes('bar') ||
props.view.type.includes('line') ||
props.view.type.includes('scatter') ||
props.view.type === 'chart-mix' ||
props.view.type.includes('chart-mix') ||
props.view.type === 'waterfall' ||
props.view.type === 'area' ||
props.view.type === 'area-stack')

View File

@ -45,7 +45,7 @@ const props = defineProps({
<span v-else-if="props.view.type && props.view.type.includes('tree')">{{
t('chart.drag_block_treemap_size')
}}</span>
<span v-else-if="props.view.type && props.view.type === 'chart-mix'">{{
<span v-else-if="props.view.type && props.view.type.includes('chart-mix')">{{
t('chart.drag_block_value_axis_main')
}}</span>
<span v-else-if="props.view.type && props.view.type === 'liquid'">{{

View File

@ -41,7 +41,7 @@ const quotaExtFields = computed<Array<any>>(() => {
})
const useQuotaExt = computed<boolean>(() => {
return props.chart.type === 'chart-mix'
return props.chart.type.includes('chart-mix')
})
const state = reactive({

View File

@ -124,7 +124,7 @@ const onChangeXAxisForm = (val, prop) => {
}
const onChangeYAxisForm = (val, prop) => {
if (prop === 'show' && chart.value.type === 'chart-mix') {
if (prop === 'show' && chart.value.type.includes('chart-mix')) {
chart.value.customStyle.yAxisExt.show = val.show
onChangeYAxisExtForm(chart.value.customStyle.yAxisExt, 'show')
}

View File

@ -1,11 +1,12 @@
<script lang="tsx" setup>
import { useI18n } from '@/hooks/web/useI18n'
import { PropType, toRefs } from 'vue'
import { PropType, toRefs, computed } from 'vue'
import { COLOR_PANEL } from '@/views/chart/components/editor/util/chart'
const { t } = useI18n()
import CollapseSwitchItem from '@/components/collapse-switch-item/src/CollapseSwitchItem.vue'
const { t } = useI18n()
const state = {
styleActiveNames: ['component']
styleActiveNames: ['basicStyle']
}
const props = defineProps({
@ -26,16 +27,52 @@ const props = defineProps({
default: 'dark'
}
})
const toolTip = computed(() => {
return props.themes === 'dark' ? 'ndark' : 'dark'
})
const predefineColors = COLOR_PANEL
const fontSizeList = []
for (let i = 10; i <= 60; i = i + 2) {
fontSizeList.push({
name: i + '',
value: i + ''
})
}
const { element, chart, commonBackgroundPop } = toRefs(props)
const checkBold = type => {
if (!chart.value.customStyle.component.labelShow) return
chart.value.customStyle.component[type] = chart.value.customStyle.component[type] ? '' : 'bold'
}
const checkItalic = type => {
if (!chart.value.customStyle.component.labelShow) return
chart.value.customStyle.component[type] = chart.value.customStyle.component[type] ? '' : 'italic'
}
const { chart, commonBackgroundPop } = toRefs(props)
if (!chart.value.customStyle.component.hasOwnProperty('labelShow')) {
chart.value.customStyle.component = {
...chart.value.customStyle.component,
labelShow: true,
fontWeight: '',
fontStyle: '',
fontSize: '14',
fontSizeBtn: '14',
fontWeightBtn: '',
fontStyleBtn: '',
queryConditionWidth: 227,
nameboxSpacing: 8,
queryConditionSpacing: 16,
labelColorBtn: '#ffffff',
btnColor: '#3370ff'
}
}
</script>
<template>
<div class="attr-style">
<el-row class="de-collapse-style">
<el-collapse v-model="state.styleActiveNames" class="style-collapse">
<el-collapse-item :effect="themes" name="component" :title="t('visualization.module')">
<el-collapse-item :effect="themes" name="basicStyle" :title="t('chart.basic_style')">
<el-form label-position="top">
<el-form-item class="form-item margin-bottom-8" :class="'form-item-' + themes">
<el-checkbox
@ -95,29 +132,10 @@ const { element, chart, commonBackgroundPop } = toRefs(props)
:predefine="predefineColors"
/>
</el-form-item>
<el-form-item class="form-item margin-bottom-8" :class="'form-item-' + themes">
<el-checkbox
:effect="themes"
size="small"
v-model="chart.customStyle.component.labelColorShow"
>
标签颜色
</el-checkbox>
</el-form-item>
<el-form-item
class="form-item"
style="padding-left: 20px"
:class="'form-item-' + themes"
>
<el-color-picker
:effect="themes"
:trigger-width="108"
is-custom
v-model="chart.customStyle.component.labelColor"
:disabled="!chart.customStyle.component.labelColorShow"
:predefine="predefineColors"
/>
</el-form-item>
</el-form>
</el-collapse-item>
<el-collapse-item :effect="themes" name="addition" title="查询条件">
<el-form label-position="top">
<el-form-item class="form-item margin-bottom-8" :class="'form-item-' + themes">
<el-checkbox
:effect="themes"
@ -187,8 +205,134 @@ const { element, chart, commonBackgroundPop } = toRefs(props)
:predefine="predefineColors"
/>
</el-form-item>
<el-form-item
:effect="themes"
class="form-item"
label="查询条件宽度"
:class="'form-item-' + themes"
>
<el-input-number
v-model="chart.customStyle.component.queryConditionWidth"
:min="0"
controls-position="right"
/>
</el-form-item>
<el-form-item
:effect="themes"
class="form-item"
label="查询条件间距"
:class="'form-item-' + themes"
>
<el-input-number
v-model="chart.customStyle.component.queryConditionSpacing"
:min="0"
controls-position="right"
/>
</el-form-item>
</el-form>
</el-collapse-item>
<collapse-switch-item
:themes="themes"
v-model="chart.customStyle.component.labelShow"
name="legend"
title="查询条件名称"
>
<el-form
:class="!chart.customStyle.component.labelShow && 'is-disabled'"
:disabled="!chart.customStyle.component.labelShow"
label-position="top"
>
<el-form-item
:effect="themes"
class="form-item"
:label="t('visualization.position_adjust')"
:class="'form-item-' + themes"
>
<el-radio-group :effect="themes" v-model="chart.customStyle.component.layout">
<el-radio label="vertical"> 上侧 </el-radio>
<el-radio label="horizontal"> 左侧 </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
:label="t('chart.textColor')"
class="form-item margin-bottom-8"
:class="'form-item-' + themes"
>
<el-color-picker
:effect="themes"
is-custom
v-model="chart.customStyle.component.labelColor"
:predefine="predefineColors"
/><el-tooltip content="" :effect="toolTip" placement="top">
<el-select
style="width: 80px; margin: 0 8px"
:effect="themes"
v-model="chart.customStyle.component.fontSize"
:placeholder="t('chart.text_fontsize')"
size="small"
>
<el-option
v-for="option in fontSizeList"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-tooltip>
<el-tooltip effect="dark" placement="bottom">
<template #content>
{{ t('chart.bolder') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: chart.customStyle.component.fontWeight === 'bold'
}"
style="margin-right: 8px"
@click="checkBold('fontWeight')"
>
<el-icon>
<Icon name="icon_bold_outlined" />
</el-icon>
</div>
</el-tooltip>
<el-divider :effect="themes" class="m-divider" />
<el-tooltip effect="dark" placement="bottom">
<template #content>
{{ t('chart.italic') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: chart.customStyle.component.fontStyle === 'italic'
}"
@click="checkItalic('fontStyle')"
>
<el-icon>
<Icon name="icon_italic_outlined" />
</el-icon>
</div>
</el-tooltip>
</el-form-item>
<el-form-item
:effect="themes"
class="form-item"
label="名称与选框间距"
:class="'form-item-' + themes"
>
<el-input-number
v-model="chart.customStyle.component.nameboxSpacing"
:min="0"
:max="50"
controls-position="right"
/>
</el-form-item>
</el-form>
</collapse-switch-item>
<el-collapse-item :effect="themes" name="button" :title="t('commons.button')">
<el-form label-position="top">
<el-form-item
:effect="themes"
class="form-item"
@ -207,55 +351,77 @@ const { element, chart, commonBackgroundPop } = toRefs(props)
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item class="form-item" label="按钮颜色" :class="'form-item-' + themes">
<el-color-picker
:effect="themes"
:trigger-width="108"
is-custom
v-model="chart.customStyle.component.btnColor"
:predefine="predefineColors"
/>
</el-form-item>
<el-form-item
:effect="themes"
class="form-item"
:label="t('chart.label_position')"
label="按钮文字"
class="form-item margin-bottom-8"
:class="'form-item-' + themes"
>
<el-radio-group
<el-color-picker
:effect="themes"
class="icon-radio-group"
v-model="chart.customStyle.component.layout"
>
<el-radio :effect="themes" label="vertical">
<el-tooltip effect="dark" placement="top">
<template #content>
{{ t('chart.text_pos_top') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: chart.customStyle.component.layout === 'vertical'
}"
>
<el-icon>
<Icon name="icon_title-top-align_outlined" />
</el-icon>
</div>
</el-tooltip>
</el-radio>
is-custom
v-model="chart.customStyle.component.labelColorBtn"
:predefine="predefineColors"
/><el-tooltip content="" :effect="toolTip" placement="top">
<el-select
style="width: 80px; margin: 0 8px"
:effect="themes"
v-model="chart.customStyle.component.fontSizeBtn"
:placeholder="t('chart.text_fontsize')"
size="small"
>
<el-option
v-for="option in fontSizeList"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-tooltip>
<el-tooltip effect="dark" placement="bottom">
<template #content>
{{ t('chart.bolder') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: chart.customStyle.component.fontWeightBtn === 'bold'
}"
style="margin-right: 8px"
@click="checkBold('fontWeightBtn')"
>
<el-icon>
<Icon name="icon_bold_outlined" />
</el-icon>
</div>
</el-tooltip>
<el-radio label="horizontal">
<el-tooltip effect="dark" placement="top">
<template #content>
{{ t('chart.text_pos_left') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: chart.customStyle.component.layout === 'horizontal'
}"
>
<el-icon>
<Icon name="icon_title-left-align_outlined" />
</el-icon>
</div>
</el-tooltip>
</el-radio>
</el-radio-group>
<el-tooltip effect="dark" placement="bottom">
<template #content>
{{ t('chart.italic') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: chart.customStyle.component.fontStyleBtn === 'italic'
}"
@click="checkItalic('fontStyleBtn')"
>
<el-icon>
<Icon name="icon_italic_outlined" />
</el-icon>
</div>
</el-tooltip>
</el-form-item>
</el-form>
</el-collapse-item>

View File

@ -634,7 +634,7 @@ const addAxis = (e, axis: AxisType) => {
emitter.emit('removeAxis', { axisType: 'yAxis', axis, editType: 'remove' })
}
}
if (view.value.type === 'chart-mix') {
if (view.value.type.includes('chart-mix')) {
if (axis === 'yAxis') {
if (view.value.yAxisExt.length > 0) {
const chartType = view.value.yAxisExt[0].chartType
@ -1052,7 +1052,6 @@ const saveRename = ref => {
ref.validate(valid => {
if (valid) {
const { renameType, index, chartShowName } = state.itemForm
console.log(renameType)
let axisType, axis
switch (renameType) {
case 'quota':

View File

@ -1374,6 +1374,20 @@ export const CHART_TYPE_CONFIGS = [
value: 'chart-mix',
title: t('chart.chart_mix'),
icon: 'chart-mix'
},
{
render: 'antv',
category: 'dual_axes',
value: 'chart-mix-group',
title: t('chart.chart_mix_group_column'),
icon: 'chart-mix-group'
},
{
render: 'antv',
category: 'dual_axes',
value: 'chart-mix-stack',
title: t('chart.chart_mix_stack_column'),
icon: 'chart-mix-stack'
}
]
},

View File

@ -12,7 +12,7 @@ import {
setGradientColor
} from '../../common/common_antv'
import { flow, hexColorToRGBA, parseJson } from '@/views/chart/components/js/util'
import { cloneDeep, isEmpty, defaultTo, map, filter, union } from 'lodash-es'
import { cloneDeep, isEmpty, defaultTo, map, filter, union, slice } from 'lodash-es'
import { valueFormatter } from '@/views/chart/components/js/formatter'
import {
CHART_MIX_AXIS_TYPE,
@ -61,7 +61,7 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
}
drawChart(drawOptions: G2PlotDrawOptions<DualAxes>): DualAxes {
const { chart, action, container } = drawOptions
if (!chart.data.left.data?.length && !chart.data.right.data?.length) {
if (!chart.data?.left?.data?.length && !chart.data?.right?.data?.length) {
return
}
const left = cloneDeep(chart.data?.left?.data)
@ -72,6 +72,9 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
const data1Type = 'column'
const data2Type = 'line'
const isGroup = this.name === 'chart-mix-group' && chart.xAxisExt?.length > 0
const isStack = this.name === 'chart-mix-stack' && chart.extStack?.length > 0
const seriesField = isGroup ? 'category' : isStack ? 'category' : undefined
const seriesField2 = chart.extBubble?.length > 0 ? 'category' : undefined
const data1 = defaultTo(left[0]?.data, [])
@ -86,6 +89,8 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
const customAttr = parseJson(chart.customAttr)
let color = customAttr.basicStyle.colors
const colorSize = color.length
color = color.map(ele => {
const tmp = hexColorToRGBA(ele, customAttr.basicStyle.alpha)
if (customAttr.basicStyle.gradient) {
@ -95,6 +100,14 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
}
})
const color2StartNum = defaultTo(left[0]?.categories?.length, 1)
const color2StartIndex = color2StartNum % colorSize
const color2 =
color2StartIndex === 0
? cloneDeep(color)
: union(slice(color, color2StartIndex), slice(color, 0, color2StartIndex))
// options
const initOptions: DualAxesOptions = {
data: [data1, data2],
@ -104,11 +117,15 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
geometryOptions: [
{
geometry: data1Type,
color: color[0]
color: isGroup || isStack ? color : color[0],
isGroup: isGroup,
isStack: isStack,
seriesField: seriesField
},
{
geometry: data2Type,
color: seriesField2 ? color : color[1],
color: seriesField2 ? color2 : color2[0],
seriesField: seriesField2
}
],
@ -398,11 +415,12 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
o.legend.itemName = {
formatter: (text: string, item: any, index: number) => {
let name = undefined
if (index === 0 && text === 'value') {
if (item.viewId === 'left-axes-view' && text === 'value') {
name = left[0]?.name
} else if (index === 1 && text === 'valueExt') {
} else if (item.viewId === 'right-axes-view' && text === 'valueExt') {
name = right[0]?.name
}
item.id = item.id + '__' + index //防止重复的图例出现问题但是左右轴如果有相同的怎么办
if (name === undefined) {
return text
} else {
@ -447,3 +465,32 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
super(name, DEFAULT_DATA)
}
}
export class GroupColumnLineMix extends ColumnLineMix {
axis: AxisType[] = [...this['axis'], 'xAxisExt']
axisConfig = {
...this['axisConfig'],
yAxis: {
name: `${t('chart.drag_block_value_axis_left')} / ${t('chart.column_quota')}`,
limit: 1,
type: 'q'
}
}
constructor(name = 'chart-mix-group') {
super(name)
}
}
export class StackColumnLineMix extends ColumnLineMix {
axis: AxisType[] = [...this['axis'], 'extStack']
axisConfig = {
...this['axisConfig'],
yAxis: {
name: `${t('chart.drag_block_value_axis_left')} / ${t('chart.column_quota')}`,
limit: 1,
type: 'q'
}
}
constructor(name = 'chart-mix-stack') {
super(name)
}
}

View File

@ -676,7 +676,8 @@ export function getAnalyse(chart: Chart) {
return (
dynamicLineFields?.includes(item.fieldId) &&
(!!_.find(quotaFields, d => d.id === item.fieldId) ||
(!!_.find(quotaExtFields, d => d.id === item.fieldId) && chart.type === 'chart-mix'))
(!!_.find(quotaExtFields, d => d.id === item.fieldId) &&
chart.type.includes('chart-mix')))
)
})
const lines = fixedLines.concat(dynamicLines)

View File

@ -467,7 +467,7 @@ export const exportExcelDownload = (chart, callBack?) => {
viewInfo: chart,
viewName: excelName
}
if (chart.type === 'chart-mix') {
if (chart.type.includes('chart-mix')) {
const req1 = getExcelDownloadRequest(chart.data.left)
const req2 = getExcelDownloadRequest(chart.data.right)
request = {

View File

@ -330,11 +330,24 @@ const trackClick = trackAction => {
const curFiled = curView.drillFields[curView.drillFilters.length]
fieldIds.push(curFiled.id)
}
chartData.value?.fields.forEach(field => {
if (!fieldIds.includes(field.id)) {
fieldIds.push(field.id)
}
})
if (curView.type.includes('chart-mix')) {
chartData.value?.left?.fields?.forEach(field => {
if (!fieldIds.includes(field.id)) {
fieldIds.push(field.id)
}
})
chartData.value?.right?.fields?.forEach(field => {
if (!fieldIds.includes(field.id)) {
fieldIds.push(field.id)
}
})
} else {
chartData.value?.fields?.forEach(field => {
if (!fieldIds.includes(field.id)) {
fieldIds.push(field.id)
}
})
}
for (let i = 0; i < fieldIds.length; i++) {
const id = fieldIds[i]
const sourceInfo = view.value.id + '#' + id

View File

@ -200,8 +200,8 @@ const setupPage = (chart: ChartObj, resetPageInfo?: boolean) => {
const initScroll = () => {
// *toptop<*
const customAttr = actualChart.customAttr
const senior = actualChart.senior
const customAttr = actualChart?.customAttr
const senior = actualChart?.senior
if (
senior?.scrollCfg?.open &&
chartData.value.tableRow?.length &&

View File

@ -8,12 +8,19 @@
custom-class="custom-drawer"
>
<dashboard-preview-show
v-if="dialogShow"
v-if="dialogShow && curDvType === 'dashboard'"
ref="multiplexingPreviewShowRef"
class="multiplexing-area"
no-close
show-position="multiplexing"
></dashboard-preview-show>
<preview-show
v-if="dialogShow && curDvType === 'dataV'"
ref="multiplexingPreviewShowRef"
class="multiplexing-area"
no-close
show-position="multiplexing"
></preview-show>
<template #footer>
<el-row class="multiplexing-footer">
<el-col class="adapt-count">
@ -55,6 +62,7 @@ import { copyStoreWithOut } from '@/store/modules/data-visualization/copy'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import PreviewShow from '@/views/data-visualization/PreviewShow.vue'
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const dialogShow = ref(false)
@ -67,10 +75,12 @@ const state = reactive({
{ label: '保持源样式', value: false }
]
})
const curDvType = ref('dashboard')
const selectComponentCount = computed(() => Object.keys(curMultiplexingComponents.value).length)
const dialogInit = () => {
const dialogInit = (dvType = 'dashboard') => {
curDvType.value = dvType
dialogShow.value = true
dvMainStore.initCurMultiplexingComponents()
}

View File

@ -0,0 +1,527 @@
<script lang="ts" setup>
import { nextTick, onBeforeMount, reactive, ref, toRefs, watch } from 'vue'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
const dvMainStore = dvMainStoreWithOut()
const viewShow = ref(true)
const props = defineProps({
canvasStyleData: {
type: Object,
required: true
},
componentData: {
type: Object,
required: true
},
canvasViewInfo: {
type: Object,
required: true
},
dvInfo: {
type: Object,
required: true
}
})
const { canvasStyleData, componentData, canvasViewInfo, dvInfo } = toRefs(props)
const filterNodeMethod = (value, data) => {
return !value || data.multiplexActive
}
const nodeClick = data => {
const components = componentData.value.filter(ele => ele.id === data.id)
state.multiplexInfo = components[0]
viewShow.value = false
nextTick(() => {
viewShow.value = true
})
}
const multiplexInfoTree = ref(null)
const state = reactive({
sourceMultiplexInfo: {},
showSelected: false,
curMultiplexViewInfo: {},
curDatasetInfo: {},
initState: false,
viewId: null,
treeProp: {
id: 'id',
label: 'label',
name: 'name'
},
multiplexInfo: null
})
const curMultiplexTargetComponentsInfo = ref([])
const targetViewCheckedChange = (val, data) => {
nextTick(() => {
multiplexingCheck(val, data)
multiplexInfoTree.value.setCurrentKey(data.id)
nodeClick(data)
})
}
const getIconName = item => {
if (item.component === 'UserView') {
const viewInfo = canvasViewInfo.value[item.id]
return `${viewInfo.type}`
} else {
return item.icon
}
}
watch(
() => dvInfo.value,
() => {
if (dvInfo.value) {
init()
}
}
)
const init = () => {
dvMainStore.initCurMultiplexingComponents()
curMultiplexTargetComponentsInfo.value = []
componentData.value.forEach(item => {
curMultiplexTargetComponentsInfo.value.push({
id: item.id,
label: item.label,
icon: item.icon,
multiplexActive: false,
component: item.component
})
})
}
const multiplexingCheck = (val, data) => {
if (val) {
const components = componentData.value.filter(ele => ele.id === data.id)
// push
dvMainStore.addCurMultiplexingComponent({
component: components[0],
componentId: data.id
})
} else {
// remove
dvMainStore.removeCurMultiplexingComponentWithId(data)
}
}
onBeforeMount(() => {
init()
})
</script>
<template>
<el-row class="preview">
<el-col :span="6" style="height: 100%; overflow-y: auto">
<el-row class="tree-head">
<span class="head-text">选择组件</span>
<span class="head-filter"
>仅看已选 <el-switch size="small" v-model="state.showSelected" />
</span>
</el-row>
<el-tree
class="custom-tree"
menu
ref="multiplexInfoTree"
:empty-text="'暂无可用图表'"
:filter-node-method="filterNodeMethod"
:data="curMultiplexTargetComponentsInfo"
node-key="targetViewId"
highlight-current
@node-click="nodeClick"
>
<template #default="{ data }">
<span class="custom-tree-node">
<span>
<div @click.stop>
<span class="auth-span">
<el-checkbox
v-model="data.multiplexActive"
@change="targetViewCheckedChange($event, data)"
/>
</span>
</div>
</span>
<span>
<span class="tree-select-field">
<Icon
class-name="view-type-icon"
style="margin-right: 4px"
:name="getIconName(data)"
/>
{{ data.label }}
</span>
</span>
</span>
</template>
</el-tree>
</el-col>
<el-col :span="18" class="preview-show">
<div class="view-show-content">
<ComponentWrapper
v-if="viewShow && state.multiplexInfo && state.multiplexInfo.id"
class="wrapper-content"
:view-info="canvasViewInfo[state.multiplexInfo.id]"
:config="state.multiplexInfo"
:canvas-style-data="canvasStyleData"
:dv-info="dvInfo"
:canvas-view-info="canvasViewInfo"
/>
</div>
</el-col>
</el-row>
</template>
<style scoped lang="less">
.root-class {
margin: 15px 0px 5px;
justify-content: right;
}
.preview {
border-radius: 4px;
width: 100%;
height: 100% !important;
overflow: hidden;
background-size: 100% 100% !important;
}
.preview-show {
height: 100%;
padding-left: 12px;
background-size: 100% 100% !important;
}
.slot-class {
color: white;
}
.bottom {
margin-top: 10px;
justify-content: center;
}
.ellip {
margin-left: 10px;
margin-right: 10px;
overflow: hidden; /*超出部分隐藏*/
white-space: nowrap; /*不换行*/
text-overflow: ellipsis; /*超出部分文字以...显示*/
text-align: center;
background-color: #f7f8fa;
color: #3d4d66;
font-size: 12px;
line-height: 24px;
height: 24px;
border-radius: 3px;
}
.select-filed {
overflow: hidden; /*超出部分隐藏*/
white-space: nowrap; /*不换行*/
text-overflow: ellipsis; /*超出部分文字以...显示*/
color: #3d4d66;
font-size: 12px;
border-radius: 3px;
}
.custom-position {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
flex-flow: row nowrap;
color: #9ea6b2;
flex-direction: column;
span {
line-height: 22px;
color: #646a73;
}
}
.tree-style {
padding: 10px 15px;
height: 100%;
overflow-y: auto;
}
.custom-tree-node {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
}
.auth-span {
float: left;
width: 30px;
margin-left: -8px;
}
.tree-head {
height: 40px;
line-height: 40px;
font-size: 12px;
color: #3d4d66;
background-color: white;
.head-text {
margin-left: 16px;
font-weight: 500;
font-size: 14px;
color: #1f2329;
}
.head-filter {
flex: 1;
display: flex;
align-items: center;
justify-content: end;
margin-right: 16px;
font-weight: 400;
font-size: 12px;
color: #646a73;
.ed-switch {
margin-left: 8px;
}
}
}
.padding-lr {
padding: 0 4px;
}
.field-height {
height: calc(100% - 25px);
margin-top: 12px;
}
.drag-list {
height: calc(100% - 26px);
overflow: auto;
}
.item-dimension {
display: flex !important;
align-items: center;
padding: 2px 10px;
margin: 2px 2px 0 2px;
border: solid 1px #eee;
text-align: left;
color: #606266;
font-size: 14px;
background-color: white;
display: block;
word-break: break-all;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-dimension + .item-dimension {
margin-top: 2px;
}
.item-dimension:hover {
color: #1890ff;
background: #e8f4ff;
border-color: #a3d3ff;
cursor: pointer;
}
.item-quota {
padding: 2px 10px;
margin: 2px 2px 0 2px;
border: solid 1px #eee;
text-align: left;
color: #606266;
background-color: white;
display: block;
word-break: break-all;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-quota + .item-quota {
margin-top: 2px;
}
.item-quota:hover {
color: #67c23a;
background: #f0f9eb;
border-color: #b2d3a3;
cursor: pointer;
}
.blackTheme .item-quota:hover {
}
span {
font-size: 12px;
}
.set-name-area {
font-weight: 600;
margin-right: 20px;
}
:deep(.ed-row) {
width: 100%;
}
.dv-selector {
width: 100%;
}
.top-area {
float: left;
line-height: 33px;
display: flex;
flex-direction: row;
align-items: center;
}
.top-area-text {
font-weight: 400;
font-size: 14px;
color: #646a73;
margin-left: 24px;
}
.top-area-value {
font-weight: 400;
font-size: 14px;
color: #1f2329;
display: flex;
flex-direction: row;
align-items: center;
}
.view-type-icon {
color: var(--ed-color-primary);
width: 22px;
height: 16px;
}
.content-head {
height: 22px;
margin-top: 10px;
margin-left: 16px;
font-weight: 500;
font-size: 14px;
color: #1f2329;
line-height: 32px;
margin-right: 16px;
}
.link-icon-join {
font-size: 20px;
margin-top: 7px;
margin-left: 8px;
margin-right: 8px;
}
.inner-content {
width: 100%;
padding: 16px 16px 8px 16px;
font-size: 14px !important;
}
.outer-content {
height: 340px;
border-radius: 4px;
}
.padding-lr {
height: 500px;
border: 1px solid var(--deCardStrokeColor, #dee0e3);
border-radius: 4px;
padding: 12px;
box-sizing: border-box;
margin-left: 12px;
width: 214px;
overflow-y: hidden;
}
.mb8 {
margin-bottom: 8px;
display: inline-flex;
align-items: center;
i {
margin-left: 4.67px;
}
}
.field-height {
height: calc(50% - 41px);
margin-top: 4px;
overflow-y: auto;
}
.class-na {
margin-top: 8px;
text-align: center;
font-size: 14px;
color: var(--deTextDisable);
}
.outer-content-mirror {
border: 1px solid #bbbfc4;
border-radius: 4px;
height: 100%;
overflow: hidden;
}
.url-text {
width: 100%;
line-height: 14px;
margin-bottom: 8px;
}
.tree-select-field {
font-size: 14px;
display: flex;
align-items: center;
}
.custom-tree {
height: 100%;
overflow-y: auto;
}
.m-del-icon-btn {
color: #646a73;
margin-top: 4px;
margin-left: 4px;
&:hover {
background: rgba(31, 35, 41, 0.1) !important;
}
&:focus {
background: rgba(31, 35, 41, 0.1) !important;
}
&:active {
background: rgba(31, 35, 41, 0.2) !important;
}
}
.custom-option {
font-size: 14px;
display: flex;
align-items: center;
}
.enlarge-inner {
position: relative;
width: 100%;
height: 100%;
}
.view-show-content {
position: relative;
width: 100%;
height: 100%;
background: #ffffff;
.wrapper-content {
width: 100%;
height: 100%;
}
}
</style>

View File

@ -13,7 +13,8 @@ import { useRequestStoreWithOut } from '@/store/modules/request'
import { usePermissionStoreWithOut } from '@/store/modules/permission'
import { useMoveLine } from '@/hooks/web/useMoveLine'
import { Icon } from '@/components/icon-custom'
import { download2AppTemplate, downloadCanvas, downloadCanvas2 } from '@/utils/imgUtils'
import { download2AppTemplate, downloadCanvas2 } from '@/utils/imgUtils'
import MultiplexPreviewShow from '@/views/data-visualization/MultiplexPreviewShow.vue'
const dvMainStore = dvMainStoreWithOut()
const { dvInfo } = storeToRefs(dvMainStore)
@ -31,6 +32,11 @@ defineProps({
required: false,
type: String,
default: 'preview'
},
noClose: {
required: false,
type: Boolean,
default: false
}
})
@ -76,7 +82,7 @@ const loadCanvasData = (dvId, weight?) => {
dvMainStore.updateCurDvInfo(dvInfo)
dataInitState.value = true
nextTick(() => {
dvPreview.value.restore()
dvPreview.value?.restore()
})
}
)
@ -143,6 +149,7 @@ onBeforeMount(() => {
<template>
<div class="dv-preview">
<ArrowSide
v-if="!noClose"
:style="{ left: (sideTreeStatus ? width - 12 : 0) + 'px' }"
@change-side-tree-status="changeSideTreeStatus"
:isInside="!sideTreeStatus"
@ -156,6 +163,7 @@ onBeforeMount(() => {
:style="{ width: width + 'px' }"
>
<ArrowSide
v-if="!noClose"
:isInside="!sideTreeStatus"
:style="{ left: (sideTreeStatus ? width - 12 : 0) + 'px' }"
@change-side-tree-status="changeSideTreeStatus"
@ -179,12 +187,20 @@ onBeforeMount(() => {
</div>
<template v-if="dvInfo.name">
<preview-head
v-show="showPosition === 'preview'"
v-if="showPosition === 'preview'"
@reload="reload"
@download="download"
@downloadAsAppTemplate="downloadAsAppTemplate"
/>
<div ref="previewCanvasContainer" class="content">
<div v-if="showPosition === 'multiplexing'" class="content multiplexing-content">
<multiplex-preview-show
:component-data="state.canvasDataPreview"
:canvas-style-data="state.canvasStylePreview"
:canvas-view-info="state.canvasViewInfoPreview"
:dv-info="state.dvInfo"
></multiplex-preview-show>
</div>
<div v-if="showPosition === 'preview'" ref="previewCanvasContainer" class="content">
<div class="content-outer">
<div class="content-inner">
<de-preview
@ -300,4 +316,9 @@ onBeforeMount(() => {
border-right: 1px solid #d7d7d7;
border-bottom: 1px solid #d7d7d7;
}
.multiplexing-content {
padding: 12px;
background-color: rgb(245, 246, 247);
}
</style>

View File

@ -167,9 +167,13 @@ const showApiData = () => {
const data = Base64.encode(JSON.stringify(apiItem))
loading.value = true
cancelMap['/datasource/checkApiDatasource']?.()
checkApiItem({ data: data, type: 'apiStructure' }).then(response => {
originFieldItem.jsonFields = response.data.jsonFields
})
checkApiItem({ data: data, type: 'apiStructure' })
.then(response => {
originFieldItem.jsonFields = response.data.jsonFields
})
.catch(error => {
console.log(error?.message)
})
loading.value = false
} else {
return false
@ -232,13 +236,18 @@ const next = () => {
}
}
cancelMap['/datasource/checkApiDatasource']?.()
checkApiItem({ data: Base64.encode(JSON.stringify(apiItem)) }).then(response => {
apiItem.jsonFields = response.data.jsonFields
apiItem.fields = []
handleFiledChange(apiItem)
previewData()
active.value += 1
})
checkApiItem({ data: Base64.encode(JSON.stringify(apiItem)) })
.then(response => {
apiItem.jsonFields = response.data.jsonFields
apiItem.fields = []
handleFiledChange(apiItem)
previewData()
active.value += 1
})
.catch(error => {
console.log(error?.message)
})
}
})
}

View File

@ -4,6 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Set;
/**
* @Author gin
@ -14,4 +15,5 @@ public class Series {
private String name;
private String type;
private List<Object> data;
private Set<String> categories;
}