Merge branch 'main' of https://github.com/dataease/dataease into main

This commit is contained in:
TaoJinlong 2021-03-18 18:00:23 +08:00
commit d171a6ccfa
44 changed files with 1476 additions and 140 deletions

View File

@ -352,6 +352,10 @@
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
</exclusion>
</exclusions>
<scope>provided</scope>
</dependency>

View File

@ -9,9 +9,11 @@ public class PanelShare implements Serializable {
private String panelGroupId;
private Long userId;
private Long targetId;
private Long createTime;
private Integer type;
private static final long serialVersionUID = 1L;
}

View File

@ -234,63 +234,63 @@ public class PanelShareExample {
return (Criteria) this;
}
public Criteria andUserIdIsNull() {
addCriterion("user_id is null");
public Criteria andTargetIdIsNull() {
addCriterion("target_id is null");
return (Criteria) this;
}
public Criteria andUserIdIsNotNull() {
addCriterion("user_id is not null");
public Criteria andTargetIdIsNotNull() {
addCriterion("target_id is not null");
return (Criteria) this;
}
public Criteria andUserIdEqualTo(Long value) {
addCriterion("user_id =", value, "userId");
public Criteria andTargetIdEqualTo(Long value) {
addCriterion("target_id =", value, "targetId");
return (Criteria) this;
}
public Criteria andUserIdNotEqualTo(Long value) {
addCriterion("user_id <>", value, "userId");
public Criteria andTargetIdNotEqualTo(Long value) {
addCriterion("target_id <>", value, "targetId");
return (Criteria) this;
}
public Criteria andUserIdGreaterThan(Long value) {
addCriterion("user_id >", value, "userId");
public Criteria andTargetIdGreaterThan(Long value) {
addCriterion("target_id >", value, "targetId");
return (Criteria) this;
}
public Criteria andUserIdGreaterThanOrEqualTo(Long value) {
addCriterion("user_id >=", value, "userId");
public Criteria andTargetIdGreaterThanOrEqualTo(Long value) {
addCriterion("target_id >=", value, "targetId");
return (Criteria) this;
}
public Criteria andUserIdLessThan(Long value) {
addCriterion("user_id <", value, "userId");
public Criteria andTargetIdLessThan(Long value) {
addCriterion("target_id <", value, "targetId");
return (Criteria) this;
}
public Criteria andUserIdLessThanOrEqualTo(Long value) {
addCriterion("user_id <=", value, "userId");
public Criteria andTargetIdLessThanOrEqualTo(Long value) {
addCriterion("target_id <=", value, "targetId");
return (Criteria) this;
}
public Criteria andUserIdIn(List<Long> values) {
addCriterion("user_id in", values, "userId");
public Criteria andTargetIdIn(List<Long> values) {
addCriterion("target_id in", values, "targetId");
return (Criteria) this;
}
public Criteria andUserIdNotIn(List<Long> values) {
addCriterion("user_id not in", values, "userId");
public Criteria andTargetIdNotIn(List<Long> values) {
addCriterion("target_id not in", values, "targetId");
return (Criteria) this;
}
public Criteria andUserIdBetween(Long value1, Long value2) {
addCriterion("user_id between", value1, value2, "userId");
public Criteria andTargetIdBetween(Long value1, Long value2) {
addCriterion("target_id between", value1, value2, "targetId");
return (Criteria) this;
}
public Criteria andUserIdNotBetween(Long value1, Long value2) {
addCriterion("user_id not between", value1, value2, "userId");
public Criteria andTargetIdNotBetween(Long value1, Long value2) {
addCriterion("target_id not between", value1, value2, "targetId");
return (Criteria) this;
}
@ -353,6 +353,66 @@ public class PanelShareExample {
addCriterion("create_time not between", value1, value2, "createTime");
return (Criteria) this;
}
public Criteria andTypeIsNull() {
addCriterion("`type` is null");
return (Criteria) this;
}
public Criteria andTypeIsNotNull() {
addCriterion("`type` is not null");
return (Criteria) this;
}
public Criteria andTypeEqualTo(Integer value) {
addCriterion("`type` =", value, "type");
return (Criteria) this;
}
public Criteria andTypeNotEqualTo(Integer value) {
addCriterion("`type` <>", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThan(Integer value) {
addCriterion("`type` >", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThanOrEqualTo(Integer value) {
addCriterion("`type` >=", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThan(Integer value) {
addCriterion("`type` <", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThanOrEqualTo(Integer value) {
addCriterion("`type` <=", value, "type");
return (Criteria) this;
}
public Criteria andTypeIn(List<Integer> values) {
addCriterion("`type` in", values, "type");
return (Criteria) this;
}
public Criteria andTypeNotIn(List<Integer> values) {
addCriterion("`type` not in", values, "type");
return (Criteria) this;
}
public Criteria andTypeBetween(Integer value1, Integer value2) {
addCriterion("`type` between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andTypeNotBetween(Integer value1, Integer value2) {
addCriterion("`type` not between", value1, value2, "type");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -4,8 +4,9 @@
<resultMap id="BaseResultMap" type="io.dataease.base.domain.PanelShare">
<id column="share_id" jdbcType="BIGINT" property="shareId" />
<result column="panel_group_id" jdbcType="VARCHAR" property="panelGroupId" />
<result column="user_id" jdbcType="BIGINT" property="userId" />
<result column="target_id" jdbcType="BIGINT" property="targetId" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="type" jdbcType="INTEGER" property="type" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -66,7 +67,7 @@
</where>
</sql>
<sql id="Base_Column_List">
share_id, panel_group_id, user_id, create_time
share_id, panel_group_id, target_id, create_time, `type`
</sql>
<select id="selectByExample" parameterType="io.dataease.base.domain.PanelShareExample" resultMap="BaseResultMap">
select
@ -99,10 +100,10 @@
</if>
</delete>
<insert id="insert" parameterType="io.dataease.base.domain.PanelShare">
insert into panel_share (share_id, panel_group_id, user_id,
create_time)
values (#{shareId,jdbcType=BIGINT}, #{panelGroupId,jdbcType=VARCHAR}, #{userId,jdbcType=BIGINT},
#{createTime,jdbcType=BIGINT})
insert into panel_share (share_id, panel_group_id, target_id,
create_time, `type`)
values (#{shareId,jdbcType=BIGINT}, #{panelGroupId,jdbcType=VARCHAR}, #{targetId,jdbcType=BIGINT},
#{createTime,jdbcType=BIGINT}, #{type,jdbcType=INTEGER})
</insert>
<insert id="insertSelective" parameterType="io.dataease.base.domain.PanelShare">
insert into panel_share
@ -113,12 +114,15 @@
<if test="panelGroupId != null">
panel_group_id,
</if>
<if test="userId != null">
user_id,
<if test="targetId != null">
target_id,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="type != null">
`type`,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="shareId != null">
@ -127,12 +131,15 @@
<if test="panelGroupId != null">
#{panelGroupId,jdbcType=VARCHAR},
</if>
<if test="userId != null">
#{userId,jdbcType=BIGINT},
<if test="targetId != null">
#{targetId,jdbcType=BIGINT},
</if>
<if test="createTime != null">
#{createTime,jdbcType=BIGINT},
</if>
<if test="type != null">
#{type,jdbcType=INTEGER},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.dataease.base.domain.PanelShareExample" resultType="java.lang.Long">
@ -150,12 +157,15 @@
<if test="record.panelGroupId != null">
panel_group_id = #{record.panelGroupId,jdbcType=VARCHAR},
</if>
<if test="record.userId != null">
user_id = #{record.userId,jdbcType=BIGINT},
<if test="record.targetId != null">
target_id = #{record.targetId,jdbcType=BIGINT},
</if>
<if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT},
</if>
<if test="record.type != null">
`type` = #{record.type,jdbcType=INTEGER},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -165,8 +175,9 @@
update panel_share
set share_id = #{record.shareId,jdbcType=BIGINT},
panel_group_id = #{record.panelGroupId,jdbcType=VARCHAR},
user_id = #{record.userId,jdbcType=BIGINT},
create_time = #{record.createTime,jdbcType=BIGINT}
target_id = #{record.targetId,jdbcType=BIGINT},
create_time = #{record.createTime,jdbcType=BIGINT},
`type` = #{record.type,jdbcType=INTEGER}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -177,20 +188,24 @@
<if test="panelGroupId != null">
panel_group_id = #{panelGroupId,jdbcType=VARCHAR},
</if>
<if test="userId != null">
user_id = #{userId,jdbcType=BIGINT},
<if test="targetId != null">
target_id = #{targetId,jdbcType=BIGINT},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT},
</if>
<if test="type != null">
`type` = #{type,jdbcType=INTEGER},
</if>
</set>
where share_id = #{shareId,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="io.dataease.base.domain.PanelShare">
update panel_share
set panel_group_id = #{panelGroupId,jdbcType=VARCHAR},
user_id = #{userId,jdbcType=BIGINT},
create_time = #{createTime,jdbcType=BIGINT}
target_id = #{targetId,jdbcType=BIGINT},
create_time = #{createTime,jdbcType=BIGINT},
`type` = #{type,jdbcType=INTEGER}
where share_id = #{shareId,jdbcType=BIGINT}
</update>
</mapper>

View File

@ -3,12 +3,15 @@ package io.dataease.base.mapper.ext;
import io.dataease.base.domain.PanelShare;
import io.dataease.base.mapper.ext.query.GridExample;
import io.dataease.dto.panel.PanelShareDto;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtPanelShareMapper {
int batchInsert(List<PanelShare> shares);
int batchInsert(@Param("shares") List<PanelShare> shares);
List<PanelShareDto> query(GridExample example);
List<PanelShare> queryWithResource(GridExample example);
}

View File

@ -6,13 +6,14 @@
<id column="id" property="id" />
<result column="name" property="name" />
<result column="pid" property="pid" />
<result column="creator" property="create_by" />
</resultMap>
<insert id="batchInsert" parameterType="io.dataease.base.domain.PanelStore">
INSERT INTO panel_store (panel_group_id,user_id,create_time)
<insert id="batchInsert" parameterType="io.dataease.base.domain.PanelShare">
INSERT INTO panel_share (panel_group_id,target_id,create_time,type)
VALUES
<foreach collection="list" item="store" separator=",">
(#{store.panelGroupId}, #{store.userId}, #{store.createTime})
<foreach collection="shares" item="share" separator=",">
(#{share.panelGroupId}, #{share.targetId}, #{share.createTime}, #{share.type})
</foreach>
</insert>
@ -32,6 +33,18 @@
</select>
<select id="queryWithResource" parameterType="io.dataease.base.mapper.ext.query.GridExample" resultMap="io.dataease.base.mapper.PanelShareMapper.BaseResultMap">
select * from panel_share
<if test="_parameter != null">
<include refid="io.dataease.base.mapper.ext.query.GridSql.gridCondition" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>

View File

@ -1,5 +1,6 @@
package io.dataease.controller.panel.api;
import io.dataease.base.domain.PanelShare;
import io.dataease.controller.request.panel.PanelShareRequest;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.dto.panel.PanelShareDto;
@ -25,5 +26,10 @@ public interface ShareApi {
@PostMapping("/treeList")
List<PanelShareDto> treeList(BaseGridRequest request);
@ApiOperation("根据资源查询分享")
@PostMapping("/queryWithResourceId")
List<PanelShare> queryWithResourceId(BaseGridRequest request);
}

View File

@ -1,15 +1,19 @@
package io.dataease.controller.panel.server;
import io.dataease.base.domain.PanelShare;
import io.dataease.controller.panel.api.ShareApi;
import io.dataease.controller.request.panel.PanelShareRequest;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.dto.panel.PanelShareDto;
import io.dataease.service.panel.ShareService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
public class ShareServer implements ShareApi {
@Resource
@ -23,4 +27,10 @@ public class ShareServer implements ShareApi {
public List<PanelShareDto> treeList(@RequestBody BaseGridRequest request) {
return shareService.queryTree(request);
}
@Override
public List<PanelShare> queryWithResourceId(@RequestBody BaseGridRequest request) {
return shareService.queryWithResource(request);
}
}

View File

@ -8,9 +8,10 @@ import java.util.List;
@Data
public class PanelShareRequest implements Serializable {
@ApiModelProperty("分享目标用户集合")
private List<Long> userIds;
@ApiModelProperty(value = "分享目标类型", allowableValues = "0:user,1:role,2:dept")
private Integer type;
@ApiModelProperty("分享目标集合")
private List<Long> targetIds;
@ApiModelProperty("分享仪表板集合")
private List<String> panelIds;
}

View File

@ -2,6 +2,7 @@ package io.dataease.service.panel;
import io.dataease.base.domain.PanelShare;
import io.dataease.base.domain.PanelShareExample;
import io.dataease.base.domain.SysUser;
import io.dataease.base.mapper.PanelShareMapper;
import io.dataease.base.mapper.ext.ExtPanelShareMapper;
import io.dataease.base.mapper.ext.query.GridExample;
@ -36,21 +37,26 @@ public class ShareService {
public void save(PanelShareRequest request){
//1.先根据仪表板删除所有已经分享的
Integer type = request.getType();
List<String> panelIds = request.getPanelIds();
List<Long> userIds = request.getUserIds();
List<Long> targetIds = request.getTargetIds();
// 使用原生对象会导致事物失效 所以这里需要使用spring代理对象
if (CollectionUtils.isNotEmpty(panelIds)){
ShareService proxy = CommonBeanFactory.getBean(ShareService.class);
panelIds.forEach(proxy::delete);
panelIds.forEach(panelId -> {
proxy.delete(panelId, type);
});
}
if (CollectionUtils.isEmpty(userIds)) return;
if (CollectionUtils.isEmpty(targetIds)) return;
long now = System.currentTimeMillis();
List<PanelShare> shares = panelIds.stream().flatMap(panelId ->
userIds.stream().map(userId -> {
targetIds.stream().map(targetId -> {
PanelShare share = new PanelShare();
share.setCreateTime(now);
share.setPanelGroupId(panelId);
share.setUserId(userId);
share.setTargetId(targetId);
share.setType(type);
return share;
})
).collect(Collectors.toList());
@ -64,20 +70,31 @@ public class ShareService {
* @param panel_group_id
*/
@Transactional
public void delete(String panel_group_id){
public void delete(String panel_group_id, Integer type){
PanelShareExample example = new PanelShareExample();
example.createCriteria().andPanelGroupIdEqualTo(panel_group_id);
example.createCriteria().andPanelGroupIdEqualTo(panel_group_id).andTypeEqualTo(type);
mapper.deleteByExample(example);
}
public List<PanelShareDto> queryTree(BaseGridRequest request){
Long userId = AuthUtils.getUser().getUserId();
SysUser user = AuthUtils.getUser();
Long userId = user.getUserId();
Long deptId = user.getDeptId();
List<Long> roleIds = new ArrayList<>();
List<Long> targetIds = new ArrayList<>();
targetIds.add(userId);
targetIds.add(deptId);
targetIds.addAll(roleIds);
ConditionEntity condition = new ConditionEntity();
condition.setField("s.user_id");
condition.setOperator("eq");
condition.setValue(userId);
condition.setField("s.target_id");
condition.setOperator("in");
condition.setValue(targetIds);
request.setConditions(new ArrayList<ConditionEntity>(){{add(condition);}});
GridExample example = request.convertExample();
List<PanelShareDto> datas = extPanelShareMapper.query(example);
return convertTree(datas);
@ -86,9 +103,13 @@ public class ShareService {
//List构建Tree
private List<PanelShareDto> convertTree(List<PanelShareDto> datas){
Map<String, List<PanelShareDto>> map = datas.stream().collect(Collectors.groupingBy(PanelShareDto::getCreator));
List<PanelShareDto> roots = new ArrayList<>();
return map.entrySet().stream().map(entry -> PanelShareDto.builder().name(entry.getKey()).children(entry.getValue()).build()).collect(Collectors.toList());
}
public List<PanelShare> queryWithResource(BaseGridRequest request){
GridExample example = request.convertExample();
return extPanelShareMapper.queryWithResource(example);
}
}

View File

@ -14,6 +14,7 @@ import io.dataease.controller.sys.request.DeptDeleteRequest;
import io.dataease.controller.sys.request.DeptStatusRequest;
import io.dataease.controller.sys.request.SimpleTreeNode;
import io.dataease.controller.sys.response.DeptTreeNode;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -134,8 +135,10 @@ public class DeptService {
List<SimpleTreeNode> targetNodes = nodeByCondition(request);
List<Long> ids = upTree(allNodes, targetNodes);
SysDeptExample example = new SysDeptExample();
SysDeptExample.Criteria criteria = example.createCriteria();
criteria.andDeptIdIn(ids);
if (CollectionUtils.isNotEmpty(ids)){
SysDeptExample.Criteria criteria = example.createCriteria();
criteria.andDeptIdIn(ids);
}
example.setOrderByClause("dept_sort");
List<SysDept> sysDepts = sysDeptMapper.selectByExample(example);
return sysDepts;

View File

@ -58,6 +58,8 @@ spring.cache.ehcache.config=classpath:/ehcache/ehcache.xml
logging.level.org.springframework.web=trace
logging.level.org.springframework.boot.web=trace
spring.mvc.log-request-details=true
pagehelper.PageRowBounds=true

View File

@ -67,7 +67,7 @@ CREATE TABLE `panel_store` (
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`create_time` bigint(13) DEFAULT NULL COMMENT '创建日期',
PRIMARY KEY (`store_id`) USING BTREE,
UNIQUE KEY `UK_store_user_id` (`user_id`) USING BTREE
KEY `UK_store_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='仪表板收藏';
@ -86,11 +86,14 @@ DROP TABLE IF EXISTS `panel_share`;
CREATE TABLE `panel_share` (
`share_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分享ID',
`panel_group_id` varchar(50) DEFAULT NULL COMMENT '仪表板ID',
`user_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
`target_id` bigint(20) DEFAULT NULL COMMENT '目标ID',
`create_time` bigint(13) DEFAULT NULL COMMENT '创建日期',
`type` int(8) DEFAULT NULL COMMENT '类型0:user,1:role,2dept',
PRIMARY KEY (`share_id`) USING BTREE,
UNIQUE KEY `UK_share_user_id` (`user_id`) USING BTREE,
UNIQUE KEY `UK_share_panel_group_id` (`panel_group_id`) USING BTREE
KEY `UK_share_arget_id` (`target_id`) ,
KEY `UK_share_panel_group_id` (`panel_group_id`) ,
KEY `UK_share_type` (`type`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='仪表板分享';

View File

@ -0,0 +1,20 @@
import request from '@/utils/request'
export function saveShare(data) {
return request({
url: '/api/share/',
method: 'post',
loading: true,
data
})
}
export function loadShares(data) {
return request({
url: '/api/share/queryWithResourceId',
method: 'post',
loading: true,
data
})
}

View File

@ -69,6 +69,10 @@ export default {
replace: true,
name: 'VueDragResizeRotate',
props: {
viewId: {
type: String,
default: ''
},
className: {
type: String,
default: 'vdr'
@ -596,6 +600,11 @@ export default {
},
methods: {
removeView() {
debugger
console.log(this.viewId)
this.$emit('removeView', this.viewId)
},
//
resetBoundsAndMouseState() {
this.mouseClickPosition = { mouseX: 0, mouseY: 0, x: 0, y: 0, w: 0, h: 0 }

View 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="1616054957891" class="icon" viewBox="0 0 1072 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1374" xmlns:xlink="http://www.w3.org/1999/xlink" width="209.375" height="200"><defs><style type="text/css"></style></defs><path d="M150.528 77.482667v207.286857H623.177143l2.998857-207.286857zM1023.853714 380.830476H150.528v207.286857h867.791238zM820.711619 684.178286H150.528v207.286857h665.916952z" p-id="1375"></path><path d="M115.151238 943.079619V0.146286h-41.203809v994.377143h996.10819v-51.44381H115.151238z" fill="#8a8a8a" p-id="1376"></path></svg>

After

Width:  |  Height:  |  Size: 707 B

View 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="1616055514308" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4523" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1004.202667 396.168533H19.677867c-8.97024 0-16.264533 7.294293-16.264534 16.145067v199.48544c0 8.973653 7.294293 16.145067 16.264534 16.145067h984.64768c8.97024 0 16.264533-7.294293 16.264533-16.145067v-199.48544a16.366933 16.366933 0 0 0-16.387413-16.145067z m-81.926827 150.21056H369.261227c-19.131733 0-34.679467-15.547733-34.679467-34.679466s15.547733-34.686293 34.679467-34.686294h553.018026c19.131733 0 34.679467 15.55456 34.679467 34.686294 0 19.135147-15.54432 34.679467-34.68288 34.679466zM1004.202667 94.306987H19.677867A16.2816 16.2816 0 0 0 3.413333 110.574933v199.48544c0 8.97024 7.294293 16.145067 16.264534 16.145067h984.64768c8.97024 0 16.264533-7.30112 16.264533-16.145067V110.452053c-0.12288-8.850773-7.417173-16.145067-16.387413-16.145066z m-81.926827 150.575786h-205.71136c-19.12832 0-34.68288-15.55456-34.68288-34.686293s15.55456-34.679467 34.68288-34.679467h205.71136c19.131733 0 34.679467 15.547733 34.679467 34.679467s-15.540907 34.686293-34.679467 34.686293zM1004.202667 697.914027H19.677867c-8.97024 0-16.264533 7.181653-16.264534 16.145066v199.48544c0 8.966827 7.294293 16.145067 16.264534 16.145067h984.64768c8.97024 0 16.264533-7.30112 16.264533-16.145067v-199.365973c-0.12288-8.97024-7.417173-16.264533-16.387413-16.264533z m-81.926827 150.572373H547.9424c-19.135147 0-34.686293-15.547733-34.686293-34.679467s15.547733-34.686293 34.686293-34.686293h374.336853c19.131733 0 34.679467 15.55456 34.679467 34.686293 0 19.254613-15.54432 34.679467-34.68288 34.679467z" p-id="4524"></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View 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="1616054999656" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2027" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M268.04419 302.762667H59.879619c-19.114667 0-34.694095 15.579429-34.694095 34.694095v624.469333c0 19.041524 15.60381 34.694095 34.694095 34.694095h208.164571c19.114667 0 34.694095-15.652571 34.694096-34.694095V337.456762c0-19.114667-15.60381-34.694095-34.694096-34.694095z m0 624.469333H59.879619V649.679238h208.164571v277.552762zM614.985143 163.986286h-208.164572c-19.114667 0-34.694095 15.579429-34.694095 34.694095v763.245714c0 19.041524 15.60381 34.694095 34.694095 34.694095h208.164572c19.114667 0 34.694095-15.652571 34.694095-34.694095V198.704762c0-19.114667-15.579429-34.694095-34.694095-34.694095z m0 763.245714h-208.164572v-346.940952h208.164572v346.940952zM961.950476 25.209905h-208.164571c-19.114667 0-34.718476 15.579429-34.718476 34.694095v902.022095c0 19.041524 15.60381 34.694095 34.718476 34.694095h208.164571c19.114667 0 34.694095-15.652571 34.694095-34.694095V59.904c0-19.114667-15.60381-34.694095-34.694095-34.694095z m0 902.022095h-208.164571V510.902857h208.164571v416.329143z" p-id="2028"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View 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="1616054813530" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="853" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M95.743954 952.636499h914.090232a14.360374 14.360374 0 0 1 14.165326 13.775231v43.812551a14.019041 14.019041 0 0 1-14.140945 13.775231H38.521886a14.238469 14.238469 0 0 1-14.140945-14.140945V38.521886A14.360374 14.360374 0 0 1 38.156172 24.380941h43.812551c7.631234 0 13.775232 6.436568 13.775231 14.140945v914.114613zM163.839922 402.529332c0-20.284943 14.969898-36.79084 35.206078-36.790839h69.071206c19.455991 0 35.206078 16.993516 35.206078 36.81522v438.369315c0.097524 9.801138-3.535236 19.309705-10.215614 26.209511a33.840746 33.840746 0 0 1-24.990464 10.60571H199.070381c-19.382848-0.219428-35.011031-16.505897-35.206078-36.815221V402.529332z m209.212853-269.482538c0-19.6998 14.994279-35.49865 35.206078-35.49865h69.071205a35.596174 35.596174 0 0 1 35.206079 35.49865v709.192805c0.097524 9.508567-3.63276 18.627039-10.215614 25.307416A34.303984 34.303984 0 0 1 477.37882 877.713868h-69.071205c-19.358467 0-35.108555-15.920754-35.206078-35.596174V133.022413z m232.594175 415.378088c0-20.089895 14.945517-36.400745 35.157316-36.400745h69.022444c19.455991 0 35.181698 15.701326 35.181697 36.400745v292.912622c0.097524 9.801138-3.63276 19.1878-10.288757 25.990083A33.621317 33.621317 0 0 1 709.729186 877.713868h-68.998063a33.645698 33.645698 0 0 1-24.89294-10.410662 37.205316 37.205316 0 0 1-10.313138-25.990083V548.400501h0.097524z m209.115329-196.388478c0-19.334086 14.969898-35.059793 35.206078-35.059793h69.071205c19.455991 0 35.206078 16.091421 35.206079 35.059793v490.642052c0 19.334086-14.994279 35.059793-35.206079 35.059793h-69.071205a35.376745 35.376745 0 0 1-35.206078-35.059793V352.012023z" p-id="854"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View 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="1616055024589" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2204" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M904.97219 357.595429L786.041905 690.785524H262.363429L143.36 357.595429h761.58781z m29.769143-83.309715L1024 24.380952H24.380952l89.234286 249.904762h821.150476z m-178.492952 499.809524L667.014095 1024H381.366857l-89.234286-249.904762h464.091429z" p-id="2205"></path></svg>

After

Width:  |  Height:  |  Size: 652 B

View 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="1616054974287" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1552" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M176.664381 916.309333H1024V999.619048H24.380952V0h83.309715v869.571048l271.286857-380.781715L646.826667 616.838095 903.972571 136.533333l73.435429 39.326477-294.716952 550.521904-276.48-132.242285z" p-id="1553"></path></svg>

After

Width:  |  Height:  |  Size: 603 B

View 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="1616054982578" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1729" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M549.254095 0.219429v469.430857h469.430857C1018.684952 214.211048 804.693333 0.219429 549.254095 0.219429z" p-id="1730"></path><path d="M494.031238 517.973333V48.542476c-262.339048 0-469.430857 214.016-469.430857 469.430857 0 255.439238 213.991619 469.430857 469.430857 469.430857 262.339048 0 469.430857-213.991619 469.430857-469.430857H494.031238z" fill="#8a8a8a" p-id="1731"></path></svg>

After

Width:  |  Height:  |  Size: 769 B

View File

@ -602,7 +602,20 @@ export default {
std: '标准差',
var_samp: '方差',
quick_calc: '快速计算',
show_name_set: '显示名设置'
show_name_set: '显示名设置',
color: '颜色',
color_case: '配色方案',
pls_slc_color_case: '请选择配色方案',
color_default: '默认',
color_retro: '复古',
color_future: '未来',
color_gradual: '渐变',
color_business: '商务',
color_gentle: '柔和',
color_elegant: '淡雅',
color_technology: '科技',
color_simple: '简洁',
not_alpha: '不透明度'
},
dataset: {
datalist: '数据集',

View File

@ -8,15 +8,13 @@ import i18n from './lang' // internationalization
import App from './App'
import store from './store'
import router from './router'
import message from './utils/message'
import '@/icons' // icon
import '@/permission' // permission control
import api from '@/api/index.js'
import filter from '@/filter/filter'
import directives from './directive'
import './styles/vdrr/common-temp.scss'
import vdrr from './components/vue-drag-resize-rotate'
Vue.component('vdrr', vdrr)
@ -27,7 +25,7 @@ import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts
import UmyUi from 'umy-ui'
import 'umy-ui/lib/theme-chalk/index.css'// 引入样式
Vue.use(UmyUi)
/**
@ -55,6 +53,7 @@ Vue.use(Fit2CloudUI, {
})
Vue.use(filter)
Vue.use(directives)
Vue.use(message)
Vue.config.productionTip = false
new Vue({

View File

@ -1,7 +1,10 @@
const getDefaultState = () => {
return {
panelName: ''
panelName: '',
panelInfo: {
name: ''
}
}
}
@ -10,12 +13,20 @@ const state = getDefaultState()
const mutations = {
setPanelName: (state, panelName) => {
state.panelName = panelName
},
setPanelInfo: (state, panelInfo) => {
debugger
state.panelInfo = panelInfo
}
}
const actions = {
setPanelName({ commit }, panelName) {
commit('setPanelName', panelName)
},
setPanelInfo({ commit }, panelInfo) {
debugger
commit('setPanelInfo', panelInfo)
}
}

View File

@ -6,6 +6,8 @@
@import './sidebar.scss';
@import './topbar.scss';
@import "~fit2cloud-ui/src/styles/index.scss";
@import './vdrr/common-temp.scss';
@import '~umy-ui/lib/theme-chalk/index.css';// 引入样式
// @import '../metersphere/common/css/index.css';
@ -69,3 +71,42 @@ div:focus {
.app-container {
padding: 20px;
}
.de-dialog {
width: 30% !important;
.el-dialog__header{
background-color: #f4f4f5;
padding: 10px 20px !important;
}
.el-dialog__body{
padding: 1px 20px !important;
}
}
.de-search-header {
.el-tabs__header{
display: none !important;;
}
}
.de-input{
margin-bottom: 14px;
margin-top: 10px;
.el-input{
.el-input__inner {
line-height: 30px !important;
height: 30px !important;
border-right: none;
}
}
.el-input__inner:focus{
border-color: #E6E6E6 !important;
}
.el-input-group__append {
background-color: #ffffff;
}
}

View File

@ -14,7 +14,7 @@ const RefreshTokenKey = Config.RefreshTokenKey
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
timeout: 10000 // request timeout
})
// request interceptor

View File

@ -0,0 +1,81 @@
import { hexColorToRGBA } from '../util.js'
export function baseBarOption(chart_option, chart) {
// 处理shape attr
let customAttr = {}
if (chart.customAttr) {
customAttr = JSON.parse(chart.customAttr)
if (customAttr.color) {
chart_option.color = customAttr.color.colors
}
}
// 处理data
if (chart.data) {
chart_option.title.text = chart.title
chart_option.xAxis.data = chart.data.x
for (let i = 0; i < chart.data.series.length; i++) {
const y = chart.data.series[i]
y.itemStyle = {
color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha)
}
y.type = 'bar'
chart_option.legend.data.push(y.name)
chart_option.series.push(y)
}
}
// console.log(chart_option);
return chart_option
}
export function stackBarOption(chart_option, chart) {
baseBarOption(chart_option, chart)
// ext
chart_option.series.forEach(function(s) {
s.stack = 'stack'
s.emphasis = {
focus: 'series'
}
})
return chart_option
}
export function horizontalBarOption(chart_option, chart) {
// 处理shape attr
let customAttr = {}
if (chart.customAttr) {
customAttr = JSON.parse(chart.customAttr)
if (customAttr.color) {
chart_option.color = customAttr.color.colors
}
}
// 处理data
if (chart.data) {
chart_option.title.text = chart.title
chart_option.yAxis.data = chart.data.x
for (let i = 0; i < chart.data.series.length; i++) {
const y = chart.data.series[i]
y.itemStyle = {
color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha)
}
y.type = 'bar'
chart_option.legend.data.push(y.name)
chart_option.series.push(y)
}
}
// console.log(chart_option);
return chart_option
}
export function horizontalStackBarOption(chart_option, chart) {
horizontalBarOption(chart_option, chart)
// ext
chart_option.series.forEach(function(s) {
s.stack = 'stack'
s.emphasis = {
focus: 'series'
}
})
return chart_option
}

View File

@ -1,3 +1,8 @@
export const DEFAULT_COLOR_CASE = {
value: 'default',
colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
alpha: 100
}
export const BASE_BAR = {
title: {
text: ''
@ -14,6 +19,22 @@ export const BASE_BAR = {
},
series: []
}
export const HORIZONTAL_BAR = {
title: {
text: ''
},
tooltip: {},
legend: {
data: []
},
xAxis: {
type: 'value'
},
yAxis: {
data: []
},
series: []
}
export const BASE_LINE = {
title: {
@ -32,6 +53,78 @@ export const BASE_LINE = {
series: []
}
export default {
BASE_BAR, BASE_LINE
export const BASE_PIE = {
title: {
text: ''
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {},
series: [
{
name: '',
type: 'pie',
radius: ['0%', '60%'],
avoidLabelOverlap: false,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
data: []
}
]
}
export const BASE_FUNNEL = {
title: {
text: ''
},
tooltip: {
trigger: 'item'
},
legend: {
// data: []
},
series: [
{
name: '',
type: 'funnel',
left: 'center',
top: 60,
bottom: 60,
width: '80%',
min: 0,
max: 100,
minSize: '0%',
maxSize: '100%',
sort: 'descending',
gap: 1,
// label: {
// show: true,
// position: 'inside'
// },
labelLine: {
length: 10,
lineStyle: {
width: 1,
type: 'solid'
}
},
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
emphasis: {
label: {
fontSize: 20
}
},
data: []
}
]
}

View File

@ -0,0 +1,35 @@
import { hexColorToRGBA } from '@/views/chart/chart/util'
export function baseFunnelOption(chart_option, chart) {
// 处理shape attr
let customAttr = {}
if (chart.customAttr) {
customAttr = JSON.parse(chart.customAttr)
if (customAttr.color) {
chart_option.color = customAttr.color.colors
}
}
// 处理data
if (chart.data) {
chart_option.title.text = chart.title
if (chart.data.series.length > 0) {
chart_option.series[0].name = chart.data.series[0].name
const valueArr = chart.data.series[0].data
chart_option.series[0].max = Math.max.apply(Math, valueArr)
for (let i = 0; i < valueArr.length; i++) {
const y = {
name: chart.data.x[i],
value: valueArr[i]
}
y.itemStyle = {
color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha)
}
y.type = 'funnel'
chart_option.series[0].data.push(y)
}
}
}
// console.log(chart_option);
return chart_option
}

View File

@ -0,0 +1,29 @@
import { hexColorToRGBA } from '@/views/chart/chart/util'
export function baseLineOption(chart_option, chart) {
// 处理shape attr
let customAttr = {}
if (chart.customAttr) {
customAttr = JSON.parse(chart.customAttr)
if (customAttr.color) {
chart_option.color = customAttr.color.colors
}
}
// 处理data
if (chart.data) {
chart_option.title.text = chart.title
chart_option.xAxis.data = chart.data.x
for (let i = 0; i < chart.data.series.length; i++) {
const y = chart.data.series[i]
y.itemStyle = {
color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha)
}
y.type = 'line'
chart_option.legend.data.push(y.name)
chart_option.series.push(y)
}
}
// console.log(chart_option);
return chart_option
}

View File

@ -0,0 +1,34 @@
import { hexColorToRGBA } from '@/views/chart/chart/util'
export function basePieOption(chart_option, chart) {
// 处理shape attr
let customAttr = {}
if (chart.customAttr) {
customAttr = JSON.parse(chart.customAttr)
if (customAttr.color) {
chart_option.color = customAttr.color.colors
}
}
// 处理data
if (chart.data) {
chart_option.title.text = chart.title
if (chart.data.series.length > 0) {
chart_option.series[0].name = chart.data.series[0].name
const valueArr = chart.data.series[0].data
for (let i = 0; i < valueArr.length; i++) {
const y = {
name: chart.data.x[i],
value: valueArr[i]
}
y.itemStyle = {
color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha)
}
y.type = 'pie'
chart_option.series[0].data.push(y)
}
}
}
// console.log(chart_option);
return chart_option
}

View File

@ -0,0 +1,19 @@
export function hexColorToRGBA(hex, alpha) {
const rgb = [] // 定义rgb数组
if (/^\#[0-9A-F]{3}$/i.test(hex)) { // 判断传入是否为#三位十六进制数
let sixHex = '#'
hex.replace(/[0-9A-F]/ig, function(kw) {
sixHex += kw + kw // 把三位16进制数转化为六位
})
hex = sixHex // 保存回hex
}
if (/^#[0-9A-F]{6}$/i.test(hex)) { // 判断传入是否为#六位十六进制数
hex.replace(/[0-9A-F]{2}/ig, function(kw) {
rgb.push(eval('0x' + kw)) // 十六进制转化为十进制并存如数组
})
return `rgba(${rgb.join(',')},${alpha / 100})` // 输出RGB格式颜色
} else {
console.log(`Input ${hex} is wrong!`)
return 'rgb(0,0,0)'
}
}

View File

@ -5,7 +5,11 @@
</template>
<script>
import { BASE_BAR, BASE_LINE } from '../chart/chart'
import { BASE_BAR, BASE_LINE, HORIZONTAL_BAR, BASE_PIE, BASE_FUNNEL } from '../chart/chart'
import { baseBarOption, stackBarOption, horizontalBarOption, horizontalStackBarOption } from '../chart/bar/bar'
import { baseLineOption } from '../chart/line/line'
import { basePieOption } from '../chart/pie/pie'
import { baseFunnelOption } from '../chart/funnel/funnel'
export default {
name: 'ChartComponent',
@ -35,20 +39,21 @@ export default {
let chart_option = {}
// todo type
if (chart.type === 'bar') {
chart_option = JSON.parse(JSON.stringify(BASE_BAR))
chart_option = baseBarOption(JSON.parse(JSON.stringify(BASE_BAR)), chart)
} else if (chart.type === 'bar-stack') {
chart_option = stackBarOption(JSON.parse(JSON.stringify(BASE_BAR)), chart)
} else if (chart.type === 'bar-horizontal') {
chart_option = horizontalBarOption(JSON.parse(JSON.stringify(HORIZONTAL_BAR)), chart)
} else if (chart.type === 'bar-horizontal-stack') {
chart_option = horizontalStackBarOption(JSON.parse(JSON.stringify(HORIZONTAL_BAR)), chart)
} else if (chart.type === 'line') {
chart_option = JSON.parse(JSON.stringify(BASE_LINE))
chart_option = baseLineOption(JSON.parse(JSON.stringify(BASE_LINE)), chart)
} else if (chart.type === 'pie') {
chart_option = basePieOption(JSON.parse(JSON.stringify(BASE_PIE)), chart)
} else if (chart.type === 'funnel') {
chart_option = baseFunnelOption(JSON.parse(JSON.stringify(BASE_FUNNEL)), chart)
}
// console.log(chart_option);
if (chart.data) {
chart_option.title.text = chart.title
chart_option.xAxis.data = chart.data.x
chart.data.series.forEach(function(y) {
chart_option.legend.data.push(y.name)
chart_option.series.push(y)
})
}
// console.log(chart_option);
console.log(chart_option)
this.myEcharts(chart_option)
},
myEcharts(option) {

View File

@ -0,0 +1,141 @@
<template>
<div>
<div style="width:100%;height: 32px;margin:0;padding:0 4px;border-radius: 4px;border: 1px solid #DCDFE6;display: flex;align-items: center;">
<el-popover
placement="right"
width="400"
trigger="click"
>
<el-col>
<el-form ref="colorForm" :model="colorForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.color_case')" class="form-item">
<el-select v-model="colorForm.colorCase" :placeholder="$t('chart.pls_slc_color_case')" size="mini" @change="changeColorCase">
<el-option v-for="option in colorCases" :key="option.value" :label="option.name" :value="option.value" style="display: flex;align-items: center;">
<div style="float: left">
<span v-for="(c,index) in option.colors" :key="index" :style="{width: '20px',height: '20px',float: 'left',backgroundColor: c}" />
</div>
<span style="margin-left: 4px;">{{ option.name }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('chart.not_alpha')" class="form-item">
<el-slider v-model="colorForm.alpha" show-input :show-input-controls="false" input-size="mini" @change="changeColorCase" />
</el-form-item>
</el-form>
</el-col>
<el-button slot="reference" size="mini" class="shape-item">{{ $t('chart.color') }}<i class="el-icon-setting el-icon--right" /></el-button>
</el-popover>
<!--todo other color attr-->
</div>
</div>
</template>
<script>
export default {
name: 'ColorSelector',
props: {
chart: {
type: Object,
required: true
}
},
data() {
return {
colorCases: [
{
name: this.$t('chart.color_default'),
value: 'default',
colors: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc']
},
{
name: this.$t('chart.color_retro'),
value: 'retro',
colors: ['#0780cf', '#765005', '#fa6d1d', '#0e2c82', '#b6b51f', '#da1f18', '#701866', '#f47a75', '#009db2']
},
{
name: this.$t('chart.color_elegant'),
value: 'elegant',
colors: ['#95a2ff', '#fa8080', '#ffc076', '#fae768', '#87e885', '#3cb9fc', '#73abf5', '#cb9bff', '#434348']
},
{
name: this.$t('chart.color_future'),
value: 'future',
colors: ['#63b2ee', '#76da91', '#f8cb7f', '#f89588', '#7cd6cf', '#9192ab', '#7898e1', '#efa666', '#eddd86']
},
{
name: this.$t('chart.color_gradual'),
value: 'gradual',
colors: ['#71ae46', '#96b744', '#c4cc38', '#ebe12a', '#eab026', '#e3852b', '#d85d2a', '#ce2626', '#ac2026']
},
{
name: this.$t('chart.color_simple'),
value: 'simple',
colors: ['#929fff', '#9de0ff', '#ffa897', '#af87fe', '#7dc3fe', '#bb60b2', '#433e7c', '#f47a75', '#009db2']
},
{
name: this.$t('chart.color_business'),
value: 'business',
colors: ['#194f97', '#555555', '#bd6b08', '#00686b', '#c82d31', '#625ba1', '#898989', '#9c9800', '#007f54']
},
{
name: this.$t('chart.color_gentle'),
value: 'gentle',
colors: ['#5b9bd5', '#ed7d31', '#70ad47', '#ffc000', '#4472c4', '#91d024', '#b235e6', '#02ae75', '#5b9bd5']
},
{
name: this.$t('chart.color_technology'),
value: 'technology',
colors: ['#05f8d6', '#0082fc', '#fdd845', '#22ed7c', '#09b0d3', '#1d27c9', '#f9e264', '#f47a75', '#009db2']
}
],
colorForm: {
colorCase: 'default',
alpha: 100
}
}
},
watch: {
'chart': {
handler: function() {
const chart = JSON.parse(JSON.stringify(this.chart))
if (chart.customAttr) {
const customAttr = JSON.parse(chart.customAttr)
if (customAttr.color) {
this.colorForm.colorCase = customAttr.color.value
this.colorForm.alpha = customAttr.color.alpha
}
}
}
}
},
mounted() {
},
methods: {
changeColorCase() {
const that = this
const items = this.colorCases.filter(ele => {
return ele.value === that.colorForm.colorCase
})
this.$emit('onColorChange', {
value: items[0].value,
colors: items[0].colors,
alpha: this.colorForm.alpha
})
}
}
}
</script>
<style scoped lang="scss">
.shape-item{
padding: 6px;
border: none;
}
.form-item>>>.el-form-item__label{
font-size: 12px;
}
.el-select-dropdown__item{
padding: 0 20px;
}
span{font-size: 12px}
</style>

View File

@ -24,10 +24,10 @@
<el-dropdown-item icon="el-icon-s-grid">
<el-dropdown placement="right-start" size="mini" @command="quickCalc">
<span class="el-dropdown-link">
{{ $t('chart.quick_calc') }}<span class="summary-span">(test)</span><i class="el-icon-arrow-right el-icon--right" />
{{ $t('chart.quick_calc') }}<span class="summary-span">()</span><i class="el-icon-arrow-right el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="beforeQuickCalc('none')">test</el-dropdown-item>
<el-dropdown-item :command="beforeQuickCalc('none')"></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown-item>

View File

@ -211,6 +211,7 @@
<script>
import { post } from '@/api/chart/chart'
import TableSelector from '../view/TableSelector'
import { DEFAULT_COLOR_CASE } from '../chart/chart'
export default {
name: 'Group',
@ -503,6 +504,10 @@ export default {
view.name = this.table.name
view.sceneId = this.currGroup.id
view.tableId = this.table.id
view.type = 'bar'
view.customAttr = JSON.stringify({
color: DEFAULT_COLOR_CASE
})
post('/chart/view/save', view).then(response => {
this.selectTableFlag = false
this.$store.dispatch('chart/setTableId', null)

View File

@ -79,14 +79,21 @@
<el-row>
<div class="chart-type">
<!--TODO 这里要替换好看点的图标-->
<el-radio v-model="view.type" label="bar"><i class="el-icon-platform-eleme" style="font-size: 20px"/></el-radio>
<el-radio v-model="view.type" label="line">折线图</el-radio>
<el-radio v-model="view.type" label="bar"><svg-icon icon-class="bar" class="chart-icon" /></el-radio>
<el-radio v-model="view.type" label="bar-stack"><svg-icon icon-class="bar-stack" class="chart-icon" /></el-radio>
<el-radio v-model="view.type" label="bar-horizontal"><svg-icon icon-class="bar-horizontal" class="chart-icon" /></el-radio>
<el-radio v-model="view.type" label="bar-horizontal-stack"><svg-icon icon-class="bar-stack-horizontal" class="chart-icon" /></el-radio>
<el-radio v-model="view.type" label="line"><svg-icon icon-class="line" class="chart-icon" /></el-radio>
<el-radio v-model="view.type" label="pie"><svg-icon icon-class="pie" class="chart-icon" /></el-radio>
<el-radio v-model="view.type" label="funnel"><svg-icon icon-class="funnel" class="chart-icon" /></el-radio>
</div>
</el-row>
</div>
<div style="height: 45%;overflow:auto;border-top: 1px solid #e6e6e6">
<el-tabs type="card" :stretch="true" class="tab-header">
<el-tab-pane :label="$t('chart.shape_attr')" class="padding-lr">TODO</el-tab-pane>
<el-tab-pane :label="$t('chart.shape_attr')" class="padding-lr">
<color-selector :chart="chart" @onColorChange="onColorChange" />
</el-tab-pane>
<el-tab-pane :label="$t('chart.module_style')" class="padding-lr">TODO</el-tab-pane>
</el-tabs>
</div>
@ -144,10 +151,13 @@ import draggable from 'vuedraggable'
import DimensionItem from '../components/DimensionItem'
import QuotaItem from '../components/QuotaItem'
import ChartComponent from '../components/ChartComponent'
// shape attr
import { DEFAULT_COLOR_CASE } from '../chart/chart'
import ColorSelector from '../components/ColorSelector'
export default {
name: 'ChartEdit',
components: { ChartComponent, QuotaItem, DimensionItem, draggable },
components: { ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
data() {
return {
table: {},
@ -158,7 +168,10 @@ export default {
yaxis: [],
show: true,
type: 'bar',
title: ''
title: '',
customAttr: {
color: DEFAULT_COLOR_CASE
}
},
//
arr1: [
@ -224,17 +237,6 @@ export default {
this.quota = response.data.quota
})
},
get(id) {
if (id) {
post('/chart/view/get/' + id, null).then(response => {
this.view = response.data
this.view.xaxis = this.view.xaxis ? JSON.parse(this.view.xaxis) : []
this.view.yaxis = this.view.yaxis ? JSON.parse(this.view.yaxis) : []
})
} else {
this.view = {}
}
},
save() {
const view = JSON.parse(JSON.stringify(this.view))
view.id = this.view.id
@ -251,8 +253,14 @@ export default {
ele.summary = 'sum'
}
})
if (view.type.startsWith('pie') || view.type.startsWith('funnel')) {
if (view.yaxis.length > 1) {
view.yaxis.splice(1, view.yaxis.length)
}
}
view.xaxis = JSON.stringify(view.xaxis)
view.yaxis = JSON.stringify(view.yaxis)
view.customAttr = JSON.stringify(view.customAttr)
post('/chart/view/save', view).then(response => {
// this.get(response.data.id);
this.getData(response.data.id)
@ -266,9 +274,10 @@ export default {
getData(id) {
if (id) {
post('/chart/view/getData/' + id, null).then(response => {
this.view = response.data
this.view = JSON.parse(JSON.stringify(response.data))
this.view.xaxis = this.view.xaxis ? JSON.parse(this.view.xaxis) : []
this.view.yaxis = this.view.yaxis ? JSON.parse(this.view.yaxis) : []
this.view.customAttr = this.view.customAttr ? JSON.parse(this.view.customAttr) : {}
// echart
this.chart = response.data
})
@ -365,12 +374,17 @@ export default {
// }
// })
this.save()
},
onColorChange(val) {
this.view.customAttr.color = val
this.save()
}
}
}
</script>
<style scoped>
<style scoped lang="scss">
.padding-lr {
padding: 0 6px;
}
@ -399,6 +413,7 @@ export default {
border: solid 1px #eee;
text-align: left;
color: #606266;
background-color: rgba(35,46,64,.05);
display: block;
}
@ -408,6 +423,7 @@ export default {
border: solid 1px #eee;
text-align: left;
color: #606266;
background-color: rgba(35,46,64,.05);
}
.item + .item {
@ -439,7 +455,27 @@ export default {
height: calc(100% - 6px);
}
.chart-type{
padding: 4px;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.chart-icon{
width: 20px;
height: 20px;
}
.chart-type>>>.el-radio__input{
display: none;
}
.el-radio{
margin:6px;
}
.el-radio>>>.el-radio__label{
padding-left: 0;
}
</style>

View File

@ -0,0 +1,235 @@
<template>
<div class="my_table">
<el-table
ref="table"
:data="data"
lazy
:show-header="true"
:load="loadExpandDatas"
style="width: 100%"
:row-style="{height: '35px'}"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
row-key="deptId"
>
<el-table-column label="所有组织" prop="name" />
<el-table-column type="selection" fixd />
<!-- <el-table-column label="分享给" prop="deptId" width="80" fixed="right">
<template slot-scope="scope">
<el-checkbox :v-model="scope.row.deptId===0" />
</template>
</el-table-column> -->
</el-table>
</div>
</template>
<script>
import { getDeptTree, loadTable } from '@/api/system/dept'
import { saveShare, loadShares } from '@/api/panel/share'
export default {
name: 'GrantDept',
props: {
resourceId: {
type: String,
default: null
},
keyWord: {
type: String,
default: ''
}
},
data() {
return {
data: [],
defaultCondition: {
field: 'pid',
operator: 'eq',
value: 0
},
type: 2, // 2
shares: [],
changeIndex: 0,
timeMachine: null
}
},
watch: {
keyWord(v, o) {
this.destryTimeMachine()
this.changeIndex++
this.searchWithKey(this.changeIndex)
}
},
created() {
this.search()
},
methods: {
//
// 1500ms key
searchWithKey(index) {
this.timeMachine = setTimeout(() => {
if (index === this.changeIndex) {
const condition = {
field: 'name',
operator: 'like',
value: this.keyWord
}
this.search(condition)
console.log('start execute search')
}
this.destryTimeMachine()
}, 1500)
},
destryTimeMachine() {
this.timeMachine && clearTimeout(this.timeMachine)
this.timeMachine = null
},
//
loadExpandDatas(row, treeNode, resolve) {
getDeptTree(row.deptId).then(res => {
let data = res.data
data = data.map(obj => {
if (obj.subCount > 0) {
obj.hasChildren = true
}
return obj
})
// this.maps.set(row.deptId, { row, treeNode, resolve })
resolve && resolve(data)
this.$nextTick(() => {
this.setCheckExpandNodes(data)
})
})
},
//
search(condition) {
// this.setTableAttr()
this.data = []
let param = {}
if (condition && condition.value) {
param = { conditions: [condition] }
} else {
param = { conditions: [this.defaultCondition] }
}
loadTable(param).then(res => {
let data = res.data
data = data.map(obj => {
if (obj.subCount > 0) {
obj.hasChildren = true
}
return obj
})
if (condition && condition.value) {
data = data.map(node => {
delete (node.hasChildren)
return node
})
this.data = this.buildTree(data)
this.$nextTick(() => {
data.forEach(node => {
this.$refs.table.toggleRowExpansion(node, true)
})
})
} else {
this.data = data
}
this.queryShareNodeIds()
})
},
buildTree(arrs) {
const idMapping = arrs.reduce((acc, el, i) => {
acc[el.deptId] = i
return acc
}, {})
const roots = []
arrs.forEach(el => {
//
if (el.pid === null || el.pid === 0) {
roots.push(el)
return
}
//
const parentEl = arrs[idMapping[el.pid]]
// `children`
parentEl.children = [...(parentEl.children || []), el]
})
return roots
},
save() {
const rows = this.$refs.table.store.states.selection
const request = this.buildRequest(rows)
saveShare(request).then(res => {
this.$success('保存成功')
return true
}).catch(err => {
this.$error(err.message)
return false
})
console.log('dept save')
},
cancel() {
console.log('dept cancel')
},
buildRequest(rows) {
const targetIds = rows.map(row => row.deptId)
const panelIds = [this.resourceId]
return {
targetIds: targetIds,
panelIds: panelIds,
type: this.type
}
},
queryShareNodeIds(callBack) {
const conditionResourceId = { field: 'panel_group_id', operator: 'eq', value: this.resourceId }
const conditionType = { field: 'type', operator: 'eq', value: this.type }
const param = { conditions: [conditionResourceId, conditionType] }
loadShares(param).then(res => {
const shares = res.data
const nodeIds = shares.map(share => share.targetId)
this.shares = nodeIds
this.$nextTick(() => {
this.setCheckNodes()
})
callBack && callBack()
})
},
setCheckNodes() {
this.data.forEach(node => {
const nodeId = node.deptId
this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true)
})
},
setCheckExpandNodes(rows) {
rows.forEach(node => {
const nodeId = node.deptId
this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true)
})
}
}
}
</script>
<style scoped>
.my_table >>> .el-table__row>td{
/* 去除表格线 */
border: none;
padding: 0 0;
}
.my_table >>> .el-table th.is-leaf {
/* 去除上边框 */
border: none;
}
.my_table >>> .el-table::before{
/* 去除下边框 */
height: 0;
}
</style>

View File

@ -0,0 +1,101 @@
<template>
<div>
<el-button v-show="!showSearchInput" class="de-icon" icon="el-icon-search" circle size="mini" @click="showSearchWidget" />
<div v-show="showSearchInput" class="de-input">
<el-input v-model="key">
<el-button slot="append" icon="el-icon-close" @click="closeSearchWidget" />
</el-input>
</div>
<el-tabs v-model="activeName" :class="{'de-search-header': showSearchInput}" @tab-click="handleClick">
<el-tab-pane :lazy="true" class="de-tab" label="部门" :name="tabNames[0]"><grant-dept :ref="tabNames[0]" :resource-id="resourceId" :key-word="key" /></el-tab-pane>
<el-tab-pane :lazy="true" class="de-tab" label="角色" :name="tabNames[1]"><grant-role :ref="tabNames[1]" :resource-id="resourceId" :key-word="key" /></el-tab-pane>
<el-tab-pane :lazy="true" class="de-tab" label="用户" :name="tabNames[2]"><grant-user :ref="tabNames[2]" :resource-id="resourceId" :key-word="key" /></el-tab-pane>
</el-tabs>
<div class="auth-root-class">
<span slot="footer">
<el-button @click="cancel"> </el-button>
<el-button type="primary" @click="save"> </el-button>
</span>
</div>
</div>
</template>
<script>
import GrantDept from './dept'
import GrantRole from './role'
import GrantUser from './user'
export default {
name: 'GrantAuth',
components: { GrantDept, GrantRole, GrantUser },
props: {
resourceId: {
type: String,
default: null
}
},
data() {
return {
tabNames: ['grantDept', 'grantRole', 'grantUser'],
activeName: null,
showSearchInput: false,
key: ''
}
},
created() {
this.activeName = this.tabNames[0]
},
methods: {
handleClick(tab, event) {
console.log(tab, event)
},
showSearchWidget() {
this.showSearchInput = true
},
closeSearchWidget() {
this.key = ''
this.showSearchInput = false
},
save() {
this.$refs[this.activeName].save()
this.$emit('close-grant', 0)
},
cancel() {
this.$refs[this.activeName].cancel()
this.$emit('close-grant', 0)
}
}
}
</script>
<style lang="scss" scoped>
.de-tab {
border:1px solid #E6E6E6;
min-height:200px !important;
max-height:300px !important;
overflow:auto;
}
.de-icon {
position: absolute;
right: 20px;
top: 50px;
z-index: 99;
}
.el-input-group__append{
background-color: #ffffff;
}
.el-input__inner{
border-right: none;
}
.auth-root-class {
margin: 15px 0px 5px;
text-align: right;
}
// ::-webkit-scrollbar {
// }
</style>

View File

@ -0,0 +1,144 @@
<template>
<div class="my_table">
<el-table
ref="table"
:data="data.filter(node => !keyWord || node[fieldName].toLowerCase().includes(keyWord.toLowerCase()))"
:show-header="true"
style="width: 100%"
:row-style="{height: '35px'}"
@filter-change="filterChange"
>
<el-table-column :column-key="fieldName" :label="columnLabel" :prop="fieldName" filter-placement="right-start" :filters="filter_options" :filter-multiple="false" :filter-method="filterHandler" />
<el-table-column type="selection" fixd />
</el-table>
</div>
</template>
<script>
import { roleGrid } from '@/api/system/role'
import { formatCondition } from '@/utils/index'
import { saveShare, loadShares } from '@/api/panel/share'
export default {
name: 'GrantRole',
props: {
resourceId: {
type: String,
default: null
},
keyWord: {
type: String,
default: ''
}
},
data() {
return {
data: [],
defaultHeadName: '全部',
columnLabel: null,
filter_options: [{ text: '未分享角色', value: 0 }, { text: '已分享角色', value: 1 }],
fieldName: 'name',
type: 1, // 1
shares: []
}
},
created() {
this.initColumnLabel()
this.search()
},
methods: {
initColumnLabel() {
this.columnLabel = this.defaultHeadName
},
search(condition) {
const temp = formatCondition(condition)
const param = temp || {}
roleGrid(1, 0, param).then(response => {
const data = response.data
// this.total = data.itemCount
this.data = data.listObject
this.queryShareNodeIds()
})
},
filterHandler(value, row, column) {
// const property = column['property']
// return row[property] === value
const roleId = row['roleId']
return !(value ^ this.shares.includes(roleId))
},
filterChange(obj) {
const arr = obj[this.fieldName]
if (arr.length === 0) {
this.initColumnLabel()
return
}
this.columnLabel = this.filter_options[arr[0]].text
},
save() {
const rows = this.$refs.table.store.states.selection
const request = this.buildRequest(rows)
saveShare(request).then(res => {
this.$success('保存成功')
return true
}).catch(err => {
this.$error(err.message)
return false
})
},
cancel() {
console.log('role cancel')
},
buildRequest(rows) {
const targetIds = rows.map(row => row.roleId)
const panelIds = [this.resourceId]
return {
targetIds: targetIds,
panelIds: panelIds,
type: this.type
}
},
queryShareNodeIds(callBack) {
const conditionResourceId = { field: 'panel_group_id', operator: 'eq', value: this.resourceId }
const conditionType = { field: 'type', operator: 'eq', value: this.type }
const param = { conditions: [conditionResourceId, conditionType] }
loadShares(param).then(res => {
const shares = res.data
const nodeIds = shares.map(share => share.targetId)
this.shares = nodeIds
this.$nextTick(() => {
this.setCheckNodes()
})
callBack && callBack()
})
},
setCheckNodes() {
this.data.forEach(node => {
const nodeId = node.roleId
this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true)
})
}
}
}
</script>
<style scoped>
.my_table >>> .el-table__row>td{
/* 去除表格线 */
border: none;
padding: 0 0;
}
.my_table >>> .el-table th.is-leaf {
/* 去除上边框 */
border: none;
}
.my_table >>> .el-table::before{
/* 去除下边框 */
height: 0;
}
</style>

View File

@ -0,0 +1,144 @@
<template>
<div class="my_table">
<el-table
ref="table"
:data="data.filter(node => !keyWord || node[fieldName].toLowerCase().includes(keyWord.toLowerCase()))"
:show-header="true"
style="width: 100%"
:row-style="{height: '35px'}"
@filter-change="filterChange"
>
<el-table-column :column-key="fieldName" :label="columnLabel" :prop="fieldName" filter-placement="right-start" :filters="filter_options" :filter-multiple="false" :filter-method="filterHandler" />
<el-table-column type="selection" fixd />
</el-table>
</div>
</template>
<script>
import { userLists } from '@/api/system/user'
import { formatCondition } from '@/utils/index'
import { saveShare, loadShares } from '@/api/panel/share'
export default {
name: 'GrantUser',
props: {
resourceId: {
type: String,
default: null
},
keyWord: {
type: String,
default: ''
}
},
data() {
return {
data: [],
defaultHeadName: '全部',
columnLabel: null,
filter_options: [{ text: '未分享人员', value: 0 }, { text: '已分享人员', value: 1 }],
fieldName: 'nickName',
type: 0, // 0
shares: []
}
},
created() {
this.initColumnLabel()
this.search()
},
methods: {
initColumnLabel() {
this.columnLabel = this.defaultHeadName
},
search(condition) {
const temp = formatCondition(condition)
const param = temp || {}
userLists(1, 0, param).then(response => {
const data = response.data
// this.total = data.itemCount
this.data = data.listObject
this.queryShareNodeIds()
})
},
filterHandler(value, row, column) {
// const property = column['property']
// return row[property] === value
const userId = row['userId']
return !(value ^ this.shares.includes(userId))
},
filterChange(obj) {
const arr = obj[this.fieldName]
if (arr.length === 0) {
this.initColumnLabel()
return
}
this.columnLabel = this.filter_options[arr[0]].text
},
save() {
const rows = this.$refs.table.store.states.selection
const request = this.buildRequest(rows)
saveShare(request).then(res => {
this.$success('保存成功')
return true
}).catch(err => {
this.$error(err.message)
return false
})
},
cancel() {
console.log('user cancel')
},
buildRequest(rows) {
const targetIds = rows.map(row => row.userId)
const panelIds = [this.resourceId]
return {
targetIds: targetIds,
panelIds: panelIds,
type: this.type
}
},
queryShareNodeIds(callBack) {
const conditionResourceId = { field: 'panel_group_id', operator: 'eq', value: this.resourceId }
const conditionType = { field: 'type', operator: 'eq', value: this.type }
const param = { conditions: [conditionResourceId, conditionType] }
loadShares(param).then(res => {
const shares = res.data
const nodeIds = shares.map(share => share.targetId)
this.shares = nodeIds
this.$nextTick(() => {
this.setCheckNodes()
})
callBack && callBack()
})
},
setCheckNodes() {
this.data.forEach(node => {
const nodeId = node.userId
this.shares.includes(nodeId) && this.$refs.table.toggleRowSelection(node, true)
})
}
}
}
</script>
<style scoped>
.my_table >>> .el-table__row>td{
/* 去除表格线 */
border: none;
padding: 0 0;
}
.my_table >>> .el-table th.is-leaf {
/* 去除上边框 */
border: none;
}
.my_table >>> .el-table::before{
/* 去除下边框 */
height: 0;
}
</style>

View File

@ -111,30 +111,31 @@
</el-dialog>
<el-dialog
:title="$t('panel.share')"
:title="authTitle"
:visible.sync="authVisible"
:show-close="false"
top="10vh"
width="30%"
:before-close="handleClose"
custom-class="de-dialog"
>
<span>分享授权</span>
<span slot="footer" class="dialog-footer">
<grant-auth v-if="authVisible" :resource-id="authResourceId" @close-grant="closeGrant" />
<!-- <span slot="footer" class="dialog-footer">
<el-button @click="authVisible = false"> </el-button>
<el-button type="primary" @click="authVisible = false"> </el-button>
</span>
</span> -->
</el-dialog>
</el-col>
</el-col>
</template>
<script>
import GrantAuth from '../GrantAuth'
import { loadTable, getScene, addGroup, delGroup, addTable, delTable, groupTree, defaultTree } from '@/api/panel/panel'
export default {
name: 'PanelList',
components: { GrantAuth },
data() {
return {
authTitle: null,
authResourceId: null,
authVisible: false,
defaultData: [],
dialogTitle: '',
@ -389,12 +390,9 @@ export default {
},
nodeClick(data, node) {
// console.log(data);
// console.log(node);
if (data.nodeType === 'panel') {
this.sceneMode = true
this.currGroup = data
this.$store.dispatch('dataset/setSceneData', this.currGroup.id)
this.$store.dispatch('panel/setPanelInfo', data)
}
if (node.expanded) {
this.expandedArray.push(data.id)
@ -477,16 +475,18 @@ export default {
panelDefaultClick(data, node) {
console.log(data)
console.log(node)
this.$store.dispatch('panel/setPanelName', data.name)
this.$store.dispatch('panel/setPanelInfo', data)
// view
this.$emit('switchComponent', { name: 'PanelView' })
},
share(data) {
console.log(data)
this.authResourceId = data.id
this.authTitle = '把[' + data.label + ']分享给'
this.authVisible = true
},
handleClose(done) {
this.handleClose = false
closeGrant() {
this.authResourceId = null
this.authVisible = false
}
}
}
@ -537,4 +537,5 @@ export default {
.title-text {
line-height: 26px;
}
</style>

View File

@ -34,6 +34,7 @@
<el-col class="panel-design">
<!--TODO 仪表盘设计公共设置区域-->
<el-row class="panel-design-head">
<span style="float: left;line-height: 40px; color: gray">名称{{ panelInfo.name }}</span>
<span style="float: right;line-height: 40px;">
<el-button size="mini">
背景图
@ -126,19 +127,8 @@ export default {
}
},
computed: {
tableId() {
// console.log(this.$store.state.chart.tableId);
this.initTableData(this.$store.state.chart.tableId)
return this.$store.state.chart.tableId
},
sceneId() {
// console.log(this.$store.state.chart.sceneId);
return this.$store.state.chart.sceneId
},
vId() {
// console.log(this.$store.state.chart.viewId);
this.getData(this.$store.state.chart.viewId)
return this.$store.state.chart.viewId
panelInfo() {
return this.$store.state.panel.panelInfo
}
},