123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- <template>
- <!-- 普通菜单 -->
- <div class="jsmind_layout">
- <div class="noMind" v-if="mindV">
- <img src="../../assets/nominddata.png" alt />
- </div>
- <!-- <div class="jsmind_toolbar" v-if="showBar">
- <el-upload
- class="pad"
- :multiple="false"
- ref="upload"
- action="action"
- :before-upload="beforeUpload"
- :http-request="upload"
- >
- <el-button type="primary" size="medium">导入</el-button>
- </el-upload>
- <el-button @click="save_nodearray_file" size="medium">保存</el-button>
- <el-button @click="screen_shot" size="medium">下载导图</el-button>
- <el-button @click="get_nodearray_data" size="medium">获取数据</el-button>
- <el-button @click="addNode" size="medium">新增节点</el-button>
- <el-button @click="addBrotherNode" size="medium">新增兄弟节点</el-button>
- <el-button @click="editNode" size="medium">编辑节点</el-button>
- <el-button @click="removeNode" size="medium">删除节点</el-button>
- <el-button @click="zoomIn" size="medium" :disabled="isZoomIn">放大</el-button>
- <el-button @click="zoomOut" size="medium" :disabled="isZoomOut" class="pad">缩小</el-button>
- <span>展开:</span>
- <el-select
- v-model="level"
- placeholder="展开节点"
- @change="expand_to_level"
- class="pad pad-left"
- size="medium"
- >
- <el-option
- v-for="item in nodeOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- ></el-option>
- </el-select>
- <span>主题:</span>
- <el-select v-model="localTheme" placeholder="选择主题" @change="set_theme" size="medium">
- <el-option
- v-for="item in themeOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- ></el-option>
- </el-select>
- </div>-->
- <div id="jsmind_container" ref="container"></div>
- <!-- <el-drawer title="编辑节点" :visible.sync="dialogVisible" size="500px">
- <el-form label-width="80px" class="form-con">
- <el-form-item label="字体大小">
- <el-input-number
- controls-position="right"
- v-model.number="nodeOption.fontSize"
- class="ele-width"
- :min="1"
- :max="30"
- maxlength="2"
- ></el-input-number>
- </el-form-item>
- <el-form-item label="字体粗细">
- <el-select v-model="nodeOption.fontWeight" class="ele-width">
- <el-option value="normal" label="常规"></el-option>
- <el-option value="bold" label="粗体"></el-option>
- <el-option value="bolder" label="更粗"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="字体样式">
- <el-select v-model="nodeOption.fontStyle" class="ele-width">
- <el-option value="normal" label="标准"></el-option>
- <el-option value="italic" label="斜体"></el-option>
- <el-option value="oblique" label="倾斜"></el-option>
- </el-select>
- </el-form-item>
- <el-row>
- <el-col :span="12">
- <el-form-item label="背景颜色">
- <el-color-picker v-model="nodeOption.bgColor" show-alpha size="mini"></el-color-picker>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="字体颜色">
- <el-color-picker v-model="nodeOption.fontColor" show-alpha size="mini"></el-color-picker>
- </el-form-item>
- </el-col>
- </el-row>
- <el-form-item label="节点内容">
- <el-input
- type="textarea"
- :rows="2"
- v-model="nodeOption.content"
- class="ele-width"
- maxlength="64"
- ></el-input>
- </el-form-item>
- </el-form>
- <template v-slot:footer>
- <div class="right mr-10">
- <el-button type="primary" class="common-btn" @click="sureEditNode" size="medium">确 定</el-button>
- </div>
- </template>
- </el-drawer>-->
- </div>
- </template>
- <script>
- import "jsmind/style/jsmind.css";
- import jsMind from "jsmind/js/jsmind.js";
- window.jsMind = jsMind;
- require("jsmind/js/jsmind.draggable.js");
- require("jsmind/js/jsmind.screenshot.js");
- export default {
- props: {
- showBar: {
- // 是否显示工具栏,显示启用编辑
- type: Boolean,
- default: true,
- },
- theme: {
- // 主题
- type: String,
- default: "primary",
- },
- lineColor: {
- // 线条颜色
- type: String,
- default: "skyblue",
- },
- mindData: {
- type: Object,
- default: {},
- },
- },
- data() {
- return {
- mindV: false,
- i: 0,
- mind: {},
- jm: null,
- isZoomIn: false,
- isZoomOut: false,
- level: 0,
- nodeOptions: [
- { value: 1, label: "展开到一级节点" },
- { value: 2, label: "展开到二级节点" },
- { value: 3, label: "展开到三级节点" },
- { value: 0, label: "展开全部节点" },
- { value: -1, label: "隐藏全部节点" },
- ],
- themeOptions: [
- { value: "default", label: "default" },
- { value: "primary", label: "primary" },
- { value: "warning", label: "warning" },
- { value: "danger", label: "danger" },
- { value: "success", label: "success" },
- { value: "info", label: "info" },
- { value: "greensea", label: "greensea" },
- { value: "nephrite", label: "nephrite" },
- { value: "belizehole", label: "belizehole" },
- { value: "wisteria", label: "wisteria" },
- { value: "asphalt", label: "asphalt" },
- { value: "orange", label: "orange" },
- { value: "pumpkin", label: "pumpkin" },
- { value: "pomegranate", label: "pomegranate" },
- { value: "clouds", label: "clouds" },
- { value: "asbestos", label: "asbestos" },
- ],
- localTheme: this.theme,
- dialogVisible: false,
- nodeOption: {
- content: "",
- bgColor: "",
- fontColor: "",
- fontSize: "",
- fontWeight: "",
- fontStyle: "",
- },
- };
- },
- watch: {
- mindData: {
- handler: function (cur, old) {
- this.mind = cur;
- if (cur.data.length) {
- if (cur.data[0].topic === "" && cur.data.length === 1) {
- this.mindV = true;
- } else {
- this.mindV = false;
- }
- if (this.jm) {
- this.jm.show(this.mind);
- } else {
- this.open_empty();
- }
- }
- },
- deep: true, //对象内部的属性监听,也叫深度监听
- },
- },
- created() {},
- mounted() {
- this.getData();
- // this.mouseWheel();
- },
- methods: {
- beforeUpload(file) {
- // 上传文件之前钩子
- if (file) {
- jsMind.util.file.read(file, (jsmindData) => {
- const mind = jsMind.util.json.string2json(jsmindData);
- if (mind) {
- this.jm.show(mind);
- this.$message({ type: "success", message: "打开成功" });
- } else {
- this.prompt_info("不能打开mindmap文件");
- }
- });
- } else {
- this.prompt_info("请先选择文件");
- return false;
- }
- },
- upload() {},
- getData() {
- // this.$API({
- // name: "getMind",
- // })
- // .then((res) => {
- // this.mind = res.data;
- // this.open_empty();
- // })
- // .catch((error) => {
- // this.$message.error(error);
- // });
- if (
- !this.mind.data ||
- (this.mind.data[0].topic === "" && this.mind.data.length === 1)
- ) {
- this.mindV = true;
- } else {
- this.mindV = false;
- }
- this.mind = this.mindData;
- this.open_empty();
- },
- open_empty() {
- const options = {
- container: "jsmind_container", // 必选,容器ID
- editable: this.showBar, // 可选,是否启用编辑
- theme: this.localTheme, // 可选,主题
- view: {
- line_width: 2, // 思维导图线条的粗细
- // line_color: this.lineColor, // 思维导图线条的颜色
- },
- shortcut: {
- enable: true, // 禁用快捷键
- },
- layout: {
- hspace: 20, // 节点之间的水平间距
- vspace: 10, // 节点之间的垂直间距
- pspace: 13, // 节点与连接线之间的水平间距(用于容纳节点收缩/展开控制器)
- },
- mode: "side", // 显示模式,子节点只分布在根节点右侧
- };
- this.jm = jsMind.show(options, this.mind);
- // 改变窗口大小重置画布
- window.onresize = () => {
- this.jm.resize();
- };
- this.getDepth(this.jm.mind.root, 1);
- this.$forceUpdate();
- },
- // 获取层级数 i
- getDepth(obj, k) {
- this.i = Math.max(this.i, k);
- if (obj.children) {
- obj.children.forEach((v) => {
- this.getDepth(v, k + 1);
- });
- }
- },
- save_nodearray_file() {
- const mindData = this.jm.get_data("node_array");
- const mindName = mindData.meta.name;
- const mindStr = jsMind.util.json.json2string(mindData);
- jsMind.util.file.save(mindStr, "text/jsmind", mindName + ".jm");
- },
- screen_shot() {
- this.jm.screenshot.shootDownload();
- },
- expand_all() {
- this.jm.expand_all();
- },
- collapse_all() {
- this.jm.collapse_all();
- },
- expand_to_level(num) {
- switch (num) {
- case -1:
- this.collapse_all();
- break;
- case 0:
- this.expand_all();
- break;
- default:
- this.jm.expand_to_depth(num);
- break;
- }
- },
- zoomIn() {
- if (this.jm.view.zoomIn()) {
- this.isZoomOut = false;
- } else {
- this.isZoomIn = true;
- }
- },
- zoomOut() {
- // debugger;
- if (this.jm.view.zoomOut()) {
- this.isZoomIn = false;
- } else {
- this.isZoomOut = true;
- }
- },
- prompt_info(msg) {
- this.$message({ type: "warning", message: msg });
- },
- get_nodearray_data() {
- const mindData = this.jm.get_data("node_array");
- const mindString = jsMind.util.json.json2string(mindData);
- this.$message({ type: "info", message: mindString });
- },
- set_theme(themeName) {
- this.jm.set_theme(themeName);
- },
- scrollFunc(e) {
- e = e || window.event;
- if (e.wheelDelta) {
- if (e.wheelDelta > 0) {
- this.zoomIn();
- } else {
- this.zoomOut();
- }
- } else if (e.detail) {
- if (e.detail > 0) {
- this.zoomIn();
- } else {
- this.zoomOut();
- }
- }
- this.jm.resize();
- },
- // 鼠标滚轮放大缩小
- mouseWheel() {
- if (document.addEventListener) {
- document.addEventListener("domMouseScroll", this.scrollFunc, false);
- }
- this.$refs.container.onmousewheel = this.scrollFunc;
- },
- // 新增节点
- addNode() {
- let selectedNode = this.jm.get_selected_node();
- if (!selectedNode) {
- this.$message({ type: "warning", message: "请先选择一个节点!" });
- return;
- }
- let nodeid = jsMind.util.uuid.newid();
- let topic = "new Node";
- let newNode = this.jm.add_node(selectedNode, nodeid, topic);
- if (newNode) {
- this.jm.select_node(nodeid);
- this.jm.begin_edit(nodeid);
- this.getDepth(this.jm.mind.root, 1);
- }
- },
- // 新增兄弟节点
- addBrotherNode() {
- let selectedNode = this.jm.get_selected_node();
- if (!selectedNode) {
- this.$message({ type: "warning", message: "请先选择一个节点!" });
- return;
- } else if (selectedNode.isroot) {
- this.$message({
- type: "warning",
- message: "不能在根节点添加,请重新选择节点!",
- });
- return;
- }
- let nodeid = jsMind.util.uuid.newid();
- let topic = "new Node";
- let newNode = this.jm.insert_node_after(selectedNode, nodeid, topic);
- if (newNode) {
- this.jm.select_node(nodeid);
- this.jm.begin_edit(nodeid);
- }
- },
- // 获取选中标签的 ID
- get_selected_nodeid() {
- let selectedNode = this.jm.get_selected_node();
- if (selectedNode) {
- return selectedNode.id;
- } else {
- return null;
- }
- },
- // 删除节点
- removeNode() {
- let selectedId = this.get_selected_nodeid();
- if (!selectedId) {
- this.$message({
- type: "warning",
- message: "请先选择一个节点!",
- });
- return;
- }
- this.jm.remove_node(selectedId);
- this.i = 0;
- this.getDepth(this.jm.mind.root, 1);
- },
- // 编辑节点
- editNode() {
- let selectedId = this.get_selected_nodeid();
- if (!selectedId) {
- this.$message({ type: "warning", message: "请先选择一个节点!" });
- return;
- }
- let nodeObj = this.jm.get_node(selectedId);
- this.nodeOption.content = nodeObj.topic;
- this.nodeOption.bgColor = nodeObj.data["background-color"];
- this.nodeOption.fontColor = nodeObj.data["foreground-color"];
- this.nodeOption.fontSize = nodeObj.data["font-size"];
- this.nodeOption.fontWeight = nodeObj.data["font-weight"];
- this.nodeOption.fontStyle = nodeObj.data["font-style"];
- this.dialogVisible = true;
- },
- sureEditNode() {
- let selectedId = this.get_selected_nodeid();
- this.jm.update_node(selectedId, this.nodeOption.content);
- this.jm.set_node_font_style(
- selectedId,
- this.nodeOption.fontSize,
- this.nodeOption.fontWeight,
- this.nodeOption.fontStyle
- );
- this.jm.set_node_color(
- selectedId,
- this.nodeOption.bgColor,
- this.nodeOption.fontColor
- );
- this.nodeOption = {
- content: "",
- bgColor: "",
- fontColor: "",
- fontSize: "",
- fontWeight: "",
- fontStyle: "",
- };
- this.dialogVisible = false;
- },
- },
- beforeDestroy() {
- // document.removeEventListener("domMouseScroll", this.scrollFunc, false);
- },
- };
- </script>
- <style scoped>
- .jsmind_layout {
- display: flex;
- flex-direction: column;
- width: 100%;
- height: calc(100%);
- /* height: 500px; */
- /* margin: 15px 5px 0 0; */
- background: #fff;
- overflow: hidden;
- flex-shrink: 0;
- position: relative;
- }
- .jsmind_title {
- position: absolute;
- top: 20px;
- left: 20px;
- font-size: 20px;
- color: #8d8d8d;
- }
- .noMind {
- position: absolute;
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100%;
- height: 100%;
- z-index: 999;
- background: #fff;
- }
- .jsmind_layout .jsmind_toolbar {
- width: 100%;
- padding: 0 10px 10px 10px;
- height: auto;
- flex-shrink: 0;
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- background-color: #f8f9fa;
- box-shadow: 0 0 4px #b8b8b8;
- }
- .jsmind_layout >>> .el-button--medium,
- .jsmind_layout >>> .el-input--medium {
- margin-top: 10px;
- }
- .jsmind_layout #jsmind_container {
- /* flex: 1 1 auto; */
- height: 100%;
- }
- .jsmind_layout >>> .jsmind-inner {
- /* overflow: hidden auto !important; */
- /* height: auto; */
- }
- .jsmind_layout >>> .el-upload-list {
- display: none !important;
- }
- /* 隐藏滚动条 */
- .jsmind_layout .jsmind-inner::-webkit-scrollbar {
- display: none;
- }
- .jsmind_layout .pad {
- margin-right: 10px;
- }
- .jsmind_layout .pad-left {
- margin-left: 10px;
- }
- .jsmind_layout >>> jmnode.selected {
- background-color: #b9b9b9;
- color: #fff;
- box-shadow: 2px 2px 8px #777;
- }
- .jsmind_layout >>> jmnode:hover {
- box-shadow: 2px 2px 8px #777;
- }
- .jsmind_layout .form-con {
- padding-top: 20px;
- }
- .jsmind_layout .ele-width {
- width: 96%;
- }
- </style>
|