美文网首页
XMIND 思维导图

XMIND 思维导图

作者: 潜心之力 | 来源:发表于2020-08-12 15:12 被阅读0次

一、简介

思维导图是表达发散性思维的有效图形思维工具,运用图文并重的技巧,把各级主题的关系用相互隶属与相关的层级图表现出来,把主题关键词与图像、颜色等建立记忆链接。充分运用左右脑的机能,利用记忆、阅读、思维的规律,协助人们在科学与艺术、逻辑与想象之间平衡发展,开启大脑的无限潜能。

二、后端实现

MAVEN引入思维导图的依赖包

<dependency>
    <groupId>com.github.eljah</groupId>
    <artifactId>xmindjbehaveplugin</artifactId>
    <version>0.8</version>
</dependency>

项目需求思维导图的表和思维导图节点的表,省略GETTER和SETTER方法

public class ProjectRequirementMind extends Model<ProjectRequirementMind> { -> 主表
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    private Integer projectId; -> 项目ID
    @TableField(exist = false)
    private String projectName;
    @TableField(exist = false)
    private ProjectRequirementMindNode node; -> 从表节点
    @TableField(exist = false)
    private String json; -> 接收前端传过来的JSON节点
}

public class ProjectRequirementMindNode extends Model<ProjectRequirementMindNode> { -> 从表
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    private Integer parentId;
    private Integer mindId; -> 主表ID
    private String name; -> 节点名称
    private String direction; -> 节点方向
    @TableField(exist = false)
    private List<ProjectRequirementMindNode> node;
}

新增思维导图

@Override
@Transactional
public boolean insert(ProjectRequirementMind entity) {
    boolean success = super.insert(entity);
    if(!StringUtils.isEmpty(entity.getJson())){
        ProjectRequirementMind mind = JSONObject.parseObject(
                entity.getBuildUserName(),ProjectRequirementMind.class);
        node(mind.getNode(),entity.getId(),0);
    }
    return success;
}

private void node(ProjectRequirementMindNode node,Integer mindId,Integer parentId){
    node.setMindId(mindId);
    node.setParentId(parentId);
    mProjectRequirementMindNodeDao.insert(node);
    List<ProjectRequirementMindNode> list = node.getNode();
    for (ProjectRequirementMindNode projectRequirementMindNode : list) {
        node(projectRequirementMindNode,mindId,node.getId());
    }
}

修改思维导图

@Override
@Transactional
public boolean updateById(ProjectRequirementMind entity) {
    if (!StringUtils.isEmpty(entity.getJson())) {
        EntityWrapper<ProjectRequirementMindNode> wrapper = new EntityWrapper<>();
        wrapper.eq("mind_id", entity.getId());
        mProjectRequirementMindNodeDao.delete(wrapper);
        ProjectRequirementMind mind = JSONObject.parseObject(entity.getJson(), ProjectRequirementMind.class);
        node(mind.getNode(), entity.getId(), 0);
    }
    return super.updateById(entity);
}

private void node(ProjectRequirementMindNode node,Integer mindId,Integer parentId){
    node.setMindId(mindId);
    node.setParentId(parentId);
    mProjectRequirementMindNodeDao.insert(node);
    List<ProjectRequirementMindNode> list = node.getNode();
    for (ProjectRequirementMindNode projectRequirementMindNode : list) {
        node(projectRequirementMindNode,mindId,node.getId());
    }
}

导入思维导图

@Override
@Transactional
public boolean important(MultipartFile multipartFile) throws Exception {
    String[] sew = multipartFile.getOriginalFilename().split("\\.");
    File file = File.createTempFile(sew[0], sew[1]);
    multipartFile.transferTo(file);

    DevelopmentProject project = new DevelopmentProject();
    project.setName(sew[0]);
    project = mDevelopmentProjectDao.selectOne(project);
    if (project == null) return Boolean.FALSE;

    ProjectRequirementMind mind = new ProjectRequirementMind();
    mind.setProjectId(project.getId());
    mProjectRequirementMindDao.insert(mind);

    IWorkbookBuilder builder = Core.getWorkbookBuilder();
    IEncryptionHandler iEncryptionHandler = () -> "privet";
    IWorkbook workbook = builder.loadFromFile(file, new ByteArrayStorage(), iEncryptionHandler);
    ISheet sheet = workbook.getPrimarySheet();
    ITopic topic = sheet.getRootTopic();
    node(topic, mind.getId(), 0);

    file.deleteOnExit();
    return true;
}

private void node(ITopic topic, Integer mindId, Integer parentId) {
    ProjectRequirementMindNode node = new ProjectRequirementMindNode();
    node.setParentId(parentId);
    node.setMindId(mindId);
    node.setName(topic.getTitleText());
    node.setDirection("right");
    mProjectRequirementMindNodeDao.insert(node);

    List<ITopic> topics = topic.getAllChildren();
    for (int i = 0; i < topics.size(); i++) {
        node(topics.get(i), mindId, node.getId());
    }
}

导出思维导图

public boolean export(HttpServletResponse response, ProjectRequirementMind mind) throws Exception {
    if (StringUtils.isEmpty(mind.getId())) return false;
    mind = mProjectRequirementMindService.select(mind).get(0);

    ProjectRequirementMindNode node = mind.getNode();
    if (node == null) return false;

    String folder = mind.getProjectName() + ".xmind";
    IWorkbookBuilder builder = Core.getWorkbookBuilder();
    IWorkbook workbook = builder.createWorkbook();

    ISheet sheet = workbook.getPrimarySheet();
    sheet.setTitleText("sheet");

    ITopic topic = sheet.getRootTopic();
    topic.setTitleText(mind.getNode().getName());
    topic.setFolded(true);
    IBoundary boundary = workbook.createBoundary();
    boundary.setTitleText("boundary");
    topic.addBoundary(boundary);
    node(workbook, topic, node.getNode());

    response.setHeader("Content-type", "text/html;charset=UTF-8");
    response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(folder, "UTF-8"));
    workbook.save(response.getOutputStream());
    return true;
}

private void node(IWorkbook workbook, ITopic root, List<ProjectRequirementMindNode> nodes) {
    for (ProjectRequirementMindNode node : nodes) {
        ITopic topic = workbook.createTopic();
        topic.setTitleText(node.getName());
        topic.setFolded(true);
        if (node.getNode().size() > 0) {
            node(workbook, topic, node.getNode());
        }
        root.add(topic);
    }
}

查询思维导图

@Override
public List<ProjectRequirementMind> select(ProjectRequirementMind mind) {
    List<ProjectRequirementMind> list = mProjectRequirementMindDao.select(mind); -> 查单表
    for (int i = 0; i < list.size(); i++) {
        ProjectRequirementMind projectRequirementMind = list.get(i);
        ProjectRequirementMindNode node = new ProjectRequirementMind();
        node.setParentId(0);
        node.setMindId(projectRequirementMind.getId());
        node = mProjectRequirementMindNodeDao.selectOne(node);
        if (node != null) {
            node.setNode(node(node));
        }
        projectRequirementMind.setNode(node);
        list.set(i, projectRequirementMind);
    }
    return list;
}

private List<ProjectRequirementMindNode> node(ProjectRequirementMindNode node) {
    EntityWrapper<ProjectRequirementMindNode> wrapper = new EntityWrapper<>();
    wrapper.eq("parent_id", node.getId());
    wrapper.eq("mind_id", node.getMindId());
    List<ProjectRequirementMindNode> list = mProjectRequirementMindNodeDao.selectList(wrapper);
    for (ProjectRequirementMindNode projectRequirementMindNode : list) {
        projectRequirementMindNode.setNode(node(projectRequirementMind));
    }
    return list;
}

三、前端实现

jsmind官网:http://hizzgdev.github.io/jsmind/developer.html

<link href="/css/jsmind.css" rel="stylesheet" type="text/css"/>
<script src="/js/jquery.min.js" type="text/javascript"></script>
<script src="/js/jsmind.js" type="text/javascript"></script>
<script src="/js/jsmind.draggable.js" type="text/javascript"></script>

<div id="mind"></div> -> 定义思维导图容器

let options = {
    container: 'mind',
    editable: true,
    theme: 'primary'
}
let mind = {
    meta: {
        name: "mind",
        author: "wjx",
        version: "1.0.0"
    },
    format: "node_tree",
    data: {"id": +new Date(), "topic": "New Node", "children": []}
}
let jm = new jsMind(options); -> 初始化思维导图对象
jm.show(mind); -> 初始化思维导图数据

思维导图新增节点

function addNode() {
    let node = jm.get_selected_node();
    if (node == null) {
        layer.alert("请选中需要操作的节点", {
            icon: 0
        });
    } else {
        jm.add_node(node, +new Date(), "New Node", {});
    }
}

思维导图删除节点

function delNode() {
    let node = jm.get_selected_node();
    if (node == null) {
        layer.alert("请选中需要操作的节点", {
            icon: 0
        });
    } else {
        layer.confirm('确定要删除这个节点吗?', {
            btn: ['确定', '取消'],
            success: function (lay) {
                var btn = lay[0].getElementsByClassName('layui-layer-btn')[0].getElementsByTagName('A')[0];
                btn.href = 'javascript:void(0)';
                btn.focus();
            }
        }, function () {
            jm.remove_node(node);
            layer.close(layer.index);
        });
    }
}

思维导图获取所有节点

function getNode(node) {
    let object = {name: '', node: []};
    object.name = node.topic;
    object.direction = getNodeDirection(node.direction);
    for (let i = 0; i < node.children.length; i++) {
        object.node.push(getNode(node.children[i]));
    }
    return object;
}

function getNodeDirection(direction) {
    switch (direction) {
        case 1:
            return "right";
        case -1:
            return "left";
        default:
            return "right";
    }
}

$.ajax({ -> 思维导图的节点发送到后端
    type: 'get',
    url: '/ProjectRequirementMind/insert',
    data: {
        projectId: $("input[name=projectId]").val(),
        json: JSON.stringify({node: getNode(jm.get_root())})
    },
    dataType: 'json',
    success: function (res) {}
});

$.ajax({ -> 思维导图的节点从后端获取渲染
    type: 'get',
    url: '/ProjectRequirementMind/select',
    data: {
        id: $("input[name=id]").val()
    },
    dataType: 'json',
    success: function (res) {
        if(res.length>0){
            mind.data = jQuery.parseJSON(JSON.stringify(data[0].node)
            .replace(/"name"/g, "\"topic\"").replace(/"node"/g, "\"children\""));
            jm.show(mind);
        }
    }
});

相关文章

网友评论

      本文标题:XMIND 思维导图

      本文链接:https://www.haomeiwen.com/subject/bhgpdktx.html