| | |
| | | } |
| | | }, |
| | | "@antv/x6": { |
| | | "version": "2.10.1", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6/-/x6-2.10.1.tgz", |
| | | "integrity": "sha512-38Fi9Qgnp+ylTrnRnhrGsc2cxsDosULbN6toVs9GjVpOguzq3oxRUblzO6dcnJhbzXfZxIcB/IuQt3pYpXJBKA==", |
| | | "version": "2.11.1", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6/-/x6-2.11.1.tgz", |
| | | "integrity": "sha512-DwyuT/zuTEhwsnKwCj67cadwLeEbB5jfdCxrkTnEm6pg0+vT3FinbF71IK7SHoY8d4HOHl+sJt7ikJfr61JqLw==", |
| | | "requires": { |
| | | "@antv/x6-common": "^2.0.12", |
| | | "@antv/x6-geometry": "^2.0.5", |
| | |
| | | "version": "2.0.5", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-geometry/-/x6-geometry-2.0.5.tgz", |
| | | "integrity": "sha512-MId6riEQkxphBpVeTcL4ZNXL4lScyvDEPLyIafvWMcWNTGK0jgkK7N20XSzqt8ltJb0mGUso5s56mrk8ysHu2A==" |
| | | }, |
| | | "@antv/x6-plugin-clipboard": { |
| | | "version": "2.1.6", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-plugin-clipboard/-/x6-plugin-clipboard-2.1.6.tgz", |
| | | "integrity": "sha512-roZPLnZx6PK8MBvee0QMo90fz/TXeF0WNe4EGin2NBq5M1I5XTWrYvA6N2XVIiWAAI67gjQeEE8TpkL7f8QdqA==" |
| | | }, |
| | | "@antv/x6-plugin-dnd": { |
| | | "version": "2.0.5", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-plugin-dnd/-/x6-plugin-dnd-2.0.5.tgz", |
| | | "integrity": "sha512-g8GGJS2XmM8C59juOBiFqaR/f8i8y8tqw9sJNwta7s1Phh3hwDd7o4kk36Kk5eTKkfZfnjEyWHMOqp/h+EDibQ==" |
| | | }, |
| | | "@antv/x6-plugin-history": { |
| | | "version": "2.2.3", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-plugin-history/-/x6-plugin-history-2.2.3.tgz", |
| | | "integrity": "sha512-yiv5e7CQKm1HrJe7je4iWjkzDzU+I0WsyL8En2j0UwXJrUNaKYyv4BkRg2tvyi52hydxidMgi3tNnNQHEZwoMg==" |
| | | }, |
| | | "@antv/x6-plugin-keyboard": { |
| | | "version": "2.2.1", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-plugin-keyboard/-/x6-plugin-keyboard-2.2.1.tgz", |
| | | "integrity": "sha512-sqfN0h4txVO211uIeKBd3zQ/IN2zPzDThWNTEhRx7Lecg1fO7uRXWBbOA48j3EgpRFXVexdSzIEVJEx+IWUdYw==", |
| | | "requires": { |
| | | "mousetrap": "^1.6.5" |
| | | } |
| | | }, |
| | | "@antv/x6-plugin-selection": { |
| | | "version": "2.1.7", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-plugin-selection/-/x6-plugin-selection-2.1.7.tgz", |
| | | "integrity": "sha512-ODfYLNwKSaLgIYMYfMW4dYQ9KKFOVBEdH0BzvyG8mfRol+JtZuyrm4BRbAvMryQKHrSxs4JCYXTFd2F7ZTuxLQ==" |
| | | }, |
| | | "@antv/x6-plugin-snapline": { |
| | | "version": "2.1.7", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-plugin-snapline/-/x6-plugin-snapline-2.1.7.tgz", |
| | | "integrity": "sha512-AsysoCb9vES0U2USNhEpYuO/W8I0aYfkhlbee5Kt4NYiMfQfZKQyqW/YjDVaS2pm38C1NKu1LdPVk/BBr4CasA==" |
| | | }, |
| | | "@antv/x6-plugin-stencil": { |
| | | "version": "2.0.3", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-plugin-stencil/-/x6-plugin-stencil-2.0.3.tgz", |
| | | "integrity": "sha512-pQkTIbMCezTqo38fofuFGnI30Rk0j5gHc/+Ndml1RHVEV0p8i1HGRAR5we7SVTcT56AHlP46H+oRFReQmVgvKA==" |
| | | }, |
| | | "@antv/x6-plugin-transform": { |
| | | "version": "2.1.7", |
| | | "resolved": "https://registry.npmjs.org/@antv/x6-plugin-transform/-/x6-plugin-transform-2.1.7.tgz", |
| | | "integrity": "sha512-idzBr8/Bcw8zHQUSNS0Y8VSNMigCWiUuiwqO572Ac/P2tMfP6Ot2SahEYHGUOD2NEMPr95q4JMZc+Evvt4JFTw==" |
| | | }, |
| | | "@antv/x6-react-components": { |
| | | "version": "1.1.15", |
| | |
| | | "insert-css": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz", |
| | | "integrity": "sha1-610Ql7dUL0x56jBg067gfQU4gPQ=" |
| | | "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA==" |
| | | }, |
| | | "internal-ip": { |
| | | "version": "4.3.0", |
| | |
| | | "@antv/g2": "^4.1.34", |
| | | "@antv/g6": "^4.6.4", |
| | | "@antv/util": "^2.0.17", |
| | | "@antv/x6": "^2.10.1", |
| | | "@antv/x6": "^2.11.1", |
| | | "@antv/x6-plugin-clipboard": "^2.1.6", |
| | | "@antv/x6-plugin-dnd": "^2.0.5", |
| | | "@antv/x6-plugin-history": "^2.2.3", |
| | | "@antv/x6-plugin-keyboard": "^2.2.1", |
| | | "@antv/x6-plugin-selection": "^2.1.7", |
| | | "@antv/x6-plugin-snapline": "^2.1.7", |
| | | "@antv/x6-plugin-stencil": "^2.0.3", |
| | | "@antv/x6-plugin-transform": "^2.1.7", |
| | | "@antv/xflow": "^1.0.50", |
| | | "@babel/core": "7.5.5", |
| | | "@svgr/webpack": "4.3.2", |
| | |
| | | "identity-obj-proxy": "3.0.0", |
| | | "immutability-helper": "^3.0.1", |
| | | "immutable": "^4.0.0-rc.12", |
| | | "insert-css": "^2.0.0", |
| | | "is-wsl": "^1.1.0", |
| | | "jest": "24.8.0", |
| | | "jest-environment-jsdom-fourteen": "0.1.0", |
| | |
| | | const { card } = this.state |
| | | |
| | | if (card.plot.subtype === 'mindmap') { |
| | | this.ponitrender() |
| | | this.mindrender() |
| | | } else if (card.plot.subtype === 'indentTree') { |
| | | this.indentrender() |
| | | } else if (card.plot.subtype === 'kapmap') { |
| | |
| | | } |
| | | |
| | | /** |
| | | * @description 散点图 |
| | | * @description 思维导图 |
| | | */ |
| | | ponitrender = () => { |
| | | mindrender = () => { |
| | | const { card } = this.state |
| | | const plot = card.plot |
| | | const data = this.getdata() |
| | |
| | | color: rgba(0, 0, 0, 0.85); |
| | | background: rgba(255, 255, 255, 0.55); |
| | | } |
| | | |
| | | .model-menu-action-list { |
| | | position: absolute; |
| | | right: 0px; |
| | | top: 30px; |
| | | z-index: 4; |
| | | font-size: 16px; |
| | | |
| | | .ant-row .anticon-plus { |
| | | float: right; |
| | | } |
| | | |
| | | .page-card { |
| | | float: right; |
| | | } |
| | | } |
| | | .normal-header + .canvas + .model-menu-action-list { |
| | | top: 45px; |
| | | } |
| | | } |
| | | .menu-scatter-chart-edit-box:hover { |
| | | z-index: 1; |
| | |
| | | type: 'select', |
| | | field: 'subtype', |
| | | label: '类型', |
| | | initval: card.subtype || 'mindmap', |
| | | initval: card.subtype || 'xflow', |
| | | required: true, |
| | | options: [{ |
| | | value: 'mindmap', |
| | | label: '思维导图' |
| | | value: 'xflow', |
| | | label: '流程图' |
| | | }, { |
| | | value: 'indentTree', |
| | | label: '缩进文件树' |
| | | label: '泳道图' |
| | | }, { |
| | | value: 'kapmap', |
| | | label: '知识图谱树' |
| | | }], |
| | | controlFields: [ |
| | | {field: 'dirField', values: ['mindmap']}, |
| | | {field: 'nodeColor', values: ['mindmap']}, |
| | | // {field: 'collapsed', values: ['indentTree', 'kapmap']}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'rootType', |
| | | label: '根节点取值', |
| | | initval: card.rootType || 'fixed', |
| | | tooltip: '选择上级时,请填写根节点的文本和值的字段名', |
| | | required: true, |
| | | options: [{ |
| | | value: 'fixed', |
| | | label: '固定值' |
| | | }, { |
| | | value: 'supvalue', |
| | | label: '上级组件' |
| | | }, { |
| | | value: 'line', |
| | | label: '行' |
| | | }], |
| | | controlFields: [ |
| | | {field: 'rootLabel', values: ['fixed', 'supvalue']}, |
| | | {field: 'rootValue', values: ['fixed', 'supvalue']}, |
| | | {field: 'mark', values: ['line']}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'rootValue', |
| | | label: '根节点值', |
| | | initval: card.rootValue || '', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'rootLabel', |
| | | label: '根节点文本', |
| | | initval: card.rootLabel || '', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'valueField', |
| | | label: '值字段', |
| | | initval: card.valueField || '', |
| | | required: true, |
| | | options: columns |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'labelField', |
| | | label: '文本字段', |
| | | initval: card.labelField || '', |
| | | required: true, |
| | | options: columns |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'parentField', |
| | | label: '上级字段', |
| | | initval: card.parentField || '', |
| | | required: true, |
| | | options: columns |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'mark', |
| | | label: '顶级标识', |
| | | initval: card.mark || '', |
| | | tooltip: '上级字段值与顶级标识相同时,视为根节点。', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'select', |
| | | field: 'dirField', |
| | | label: '方向控制', |
| | | initval: card.dirField || '', |
| | | required: false, |
| | | options: columns, |
| | | controlFields: [ |
| | | {field: 'dirSign', notNull: true}, |
| | | {field: 'leftColor', notNull: true}, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'text', |
| | | field: 'dirSign', |
| | | label: '左向标记', |
| | | initval: card.dirSign || '', |
| | | tooltip: '当节点值与标记相同时节点信息位于节点左侧,多个值请用逗号分隔。', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'color', |
| | | field: 'nodeColor', |
| | | label: '节点颜色', |
| | | initval: card.nodeColor || '#1890ff', |
| | | tooltip: '右侧节点的标记颜色。', |
| | | colorType: 'hex', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'color', |
| | | field: 'leftColor', |
| | | label: '左节点颜色', |
| | | initval: card.leftColor || '#26C281', |
| | | tooltip: '左侧节点的标记颜色。', |
| | | colorType: 'hex', |
| | | required: false |
| | | label: '组织结构图' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | |
| | | {value: 'show', label: '否'}, |
| | | {value: 'hidden', label: '是'}, |
| | | ], |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | field: 'collapsed', |
| | | label: '节点合并', |
| | | initval: card.collapsed || 'false', |
| | | tooltip: '一级节点是否合并。', |
| | | required: false, |
| | | options: [ |
| | | {value: 'false', label: '否'}, |
| | | {value: 'true', label: '是'}, |
| | | ], |
| | | }, |
| | | } |
| | | ] |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Popover, message } from 'antd' |
| | | import { Popover } from 'antd' |
| | | import { ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons' |
| | | import G6 from '@antv/g6' |
| | | import { Graph, Shape } from '@antv/x6' |
| | | import { Stencil } from '@antv/x6-plugin-stencil' |
| | | import { Transform } from '@antv/x6-plugin-transform' |
| | | import { Selection } from '@antv/x6-plugin-selection' |
| | | import { Snapline } from '@antv/x6-plugin-snapline' |
| | | import { Keyboard } from '@antv/x6-plugin-keyboard' |
| | | import { Clipboard } from '@antv/x6-plugin-clipboard' |
| | | import { History } from '@antv/x6-plugin-history' |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import asyncIconComponent from '@/utils/asyncIconComponent' |
| | | import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js' |
| | | import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js' |
| | | import './index.scss' |
| | | |
| | | const { Util } = G6 |
| | | |
| | | const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) |
| | | const ChartCompileForm = asyncIconComponent(() => import('./chartcompile')) |
| | | const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) |
| | | const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) |
| | | const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) |
| | | |
| | | const MindData = [ |
| | | 'Modeling Methods', |
| | | [ |
| | | 'Classification', |
| | | ['Logistic regression', 'Linear discriminant analysis', 'Rules', 'Decision trees', 'Naive Bayes', 'K nearest neighbor', 'Probabilistic neural network', 'Support vector machine'] |
| | | ], |
| | | [ |
| | | 'Consensus', |
| | | [ |
| | | 'Models diversity', |
| | | ['Different initializations', 'Different parameter choices', 'Different architectures', 'Different modeling methods', 'Different training sets', 'Different feature sets'] |
| | | ], |
| | | [ |
| | | 'Methods', |
| | | ['Classifier selection', 'Classifier fusion'] |
| | | ], |
| | | [ |
| | | 'Common', |
| | | ['Bagging', 'Boosting', 'AdaBoost'] |
| | | ] |
| | | ], |
| | | [ |
| | | 'Regression', |
| | | ['Multiple linear regression', 'Partial least squares', 'Multi-layer feedforward neural network', 'General regression neural network', 'Support vector regression'] |
| | | ] |
| | | ] |
| | | |
| | | const styles = { |
| | | blue: '#1890ff', |
| | | red: '#f5222d', |
| | | orange_red: '#fa541c', |
| | | orange: '#fa8c16', |
| | | orange_yellow: '#faad14', |
| | | yellow: '#fadb14', |
| | | yellow_green: '#a0d911', |
| | | green: '#52c41a', |
| | | cyan: '#13c2c2', |
| | | blue_purple: '#2f54eb', |
| | | purple: '#722ed1', |
| | | magenta: '#eb2f96', |
| | | grass_green: '#aeb303', |
| | | deep_red: '#c32539', |
| | | deep_blue: '#1d3661' |
| | | } |
| | | |
| | | let systemColor = '#1890ff' |
| | | if (window.GLOB.style) { |
| | | let type = window.GLOB.style.replace(/bg_black_style_|bg_white_style_/, '') |
| | | systemColor = styles[type] || '#1890ff' |
| | | } |
| | | const COLORS = ['#5B8FF9', '#F6BD16', '#5AD8A6', '#945FB9', '#E86452', '#6DC8EC', '#FF99C3', '#1E9493', '#FF9845', '#5D7092'] |
| | | |
| | | // 思维导图 |
| | | G6.registerNode( |
| | | 'dice-mind-map-root', { |
| | | jsx: (cfg) => { |
| | | const width = Util.getTextSize(cfg.label, 16)[0] + 24 |
| | | |
| | | return ` |
| | | <group> |
| | | <rect style={{width: ${width}, height: 42, stroke: ${systemColor}, radius: 4}} keyshape> |
| | | <text style={{ fontSize: 16, marginLeft: 6, marginTop: 12 }}>${cfg.label}</text> |
| | | </rect> |
| | | </group> |
| | | ` |
| | | }, |
| | | getAnchorPoints() { |
| | | return [ |
| | | [0, 0.5], |
| | | [1, 0.5] |
| | | ] |
| | | } |
| | | }, |
| | | 'single-node', |
| | | ) |
| | | |
| | | G6.registerNode( |
| | | 'dice-mind-map-leaf', { |
| | | jsx: (cfg) => { |
| | | const width = Util.getTextSize(cfg.label, 12)[0] + 24 |
| | | |
| | | return ` |
| | | <group> |
| | | <rect style={{width: ${width}, height: 26, fill: 'transparent', cursor: pointer }}> |
| | | <text style={{ fontSize: 12, fill: ${cfg.selected ? systemColor : '#000000'}, marginLeft: 12, marginTop: 6, cursor: pointer }}>${cfg.label}</text> |
| | | </rect> |
| | | <rect style={{ fill: ${cfg.color}, width: ${width}, height: 2, x: 0, y: 32, cursor: pointer }} /> |
| | | </group> |
| | | ` |
| | | }, |
| | | getAnchorPoints() { |
| | | return [ |
| | | [0, 0.965], |
| | | [1, 0.965] |
| | | ] |
| | | } |
| | | }, |
| | | 'single-node', |
| | | ) |
| | | G6.registerBehavior('dice-mindmap', { |
| | | getEvents() { |
| | | return { |
| | | 'node:click': 'editNode', |
| | | 'canvas:click': 'onCanvasClick' |
| | | } |
| | | }, |
| | | editNode(evt) { |
| | | const item = evt.item |
| | | const model = item.get('model') |
| | | |
| | | this.graph.getNodes().forEach(node => { |
| | | let _model = node.get('model') |
| | | if (_model.selected) { |
| | | _model.selected = false |
| | | this.graph.updateItem(node, _model, false) |
| | | } |
| | | }) |
| | | |
| | | model.selected = true |
| | | this.graph.updateItem(item, model, false) |
| | | }, |
| | | onCanvasClick(e) { |
| | | this.graph.getNodes().forEach(node => { |
| | | let _model = node.get('model') |
| | | if (_model.selected) { |
| | | _model.selected = false |
| | | this.graph.updateItem(node, _model, false) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | G6.registerBehavior('scroll-canvas', { |
| | | getEvents: function getEvents() { |
| | | return { |
| | | wheel: 'onWheel' |
| | | } |
| | | }, |
| | | onWheel: function onWheel(ev) { |
| | | const { graph } = this |
| | | if (!graph) { |
| | | return |
| | | } |
| | | if (ev.ctrlKey) { |
| | | const canvas = graph.get('canvas') |
| | | const point = canvas.getPointByClient(ev.clientX, ev.clientY) |
| | | let ratio = graph.getZoom() |
| | | if (ev.wheelDelta > 0) { |
| | | ratio += ratio * 0.05 |
| | | } else { |
| | | ratio *= ratio * 0.05 |
| | | } |
| | | graph.zoomTo(ratio, { |
| | | x: point.x, |
| | | y: point.y |
| | | }) |
| | | } else { |
| | | const x = ev.deltaX || ev.movementX |
| | | const y = ev.deltaY || ev.movementY || (-ev.wheelDelta * 125) / 3 |
| | | graph.translate(-x, -y) |
| | | } |
| | | ev.preventDefault() |
| | | } |
| | | }) |
| | | |
| | | // 缩进文件树 |
| | | G6.registerNode('indentedRoot', { |
| | | draw(model, group) { |
| | | const keyShape = group.addShape('rect', { |
| | | attrs: { |
| | | x: -46, |
| | | y: -16, |
| | | width: 92, |
| | | height: 32, |
| | | fill: systemColor, |
| | | radius: 2, |
| | | stroke: '#5B8FF9', |
| | | lineWidth: 0 |
| | | }, |
| | | name: 'key-shape' |
| | | }) |
| | | |
| | | const text = group.addShape('text', { |
| | | attrs: { |
| | | text: model.label || 'root', |
| | | fill: "#fff", |
| | | fontSize: 12, |
| | | x: 0, |
| | | y: 0, |
| | | textAlign: 'center', |
| | | textBaseline: 'middle' |
| | | }, |
| | | name: 'root-text-shape' |
| | | }) |
| | | const textBBox = text.getBBox() |
| | | const width = textBBox.width + 24 |
| | | const height = textBBox.height + 12 |
| | | keyShape.attr({ |
| | | x: -width / 2, |
| | | y: -height / 2, |
| | | width, |
| | | height |
| | | }) |
| | | |
| | | return keyShape |
| | | }, |
| | | getAnchorPoints() { |
| | | return [ |
| | | [0.5, 1] |
| | | ] |
| | | }, |
| | | update: undefined |
| | | }) |
| | | |
| | | G6.registerNode('indentedNode', { |
| | | addChildCount(group, tag, props) { |
| | | const { collapsed, branchColor, count } = props |
| | | let clickCircleY = 10 |
| | | // 子类数量 icon,绘制圆点在节点正下方 |
| | | if (tag) { |
| | | const childCountGroup = group.addGroup({ |
| | | name: 'child-count-group' |
| | | }) |
| | | childCountGroup.setMatrix([1, 0, 0, 0, 1, 0, 0, clickCircleY, 1]) |
| | | const countBackWidth = collapsed ? 26 : 12 |
| | | childCountGroup.addShape('rect', { |
| | | attrs: { |
| | | width: countBackWidth, |
| | | height: 12, |
| | | radius: 6, |
| | | stroke: branchColor, |
| | | lineWidth: 2, |
| | | fill: collapsed ? branchColor : '#fff', |
| | | x: -countBackWidth / 2, |
| | | y: -6, |
| | | cursor: 'pointer', |
| | | }, |
| | | name: 'child-count-rect-shape' |
| | | }) |
| | | const childCountText = childCountGroup.addShape('text', { |
| | | attrs: { |
| | | text: count, |
| | | fill: '#fff', |
| | | x: 0, |
| | | y: 0, |
| | | fontSize: 10, |
| | | textAlign: 'center', |
| | | textBaseline: 'middle', |
| | | cursor: 'pointer', |
| | | }, |
| | | name: 'child-count-text-shape' |
| | | }) |
| | | const childHoverIcon = childCountGroup.addShape('path', { |
| | | attrs: { |
| | | stroke: '#fff', |
| | | lineWidth: 1, |
| | | cursor: 'pointer', |
| | | path: [['M', -3, 2], ['L', 0, -2], ['L', 3, 2]] |
| | | }, |
| | | name: 'child-count-expand-icon', |
| | | capture: false |
| | | }) |
| | | childHoverIcon.hide() |
| | | |
| | | // 连接 count 的线段 |
| | | const countLink = group.addShape('path', { |
| | | attrs: { |
| | | path: [['M', 0, 0], ['L', 0, 11]], |
| | | stroke: branchColor, |
| | | lineWidth: 2, |
| | | }, |
| | | name: 'count-link' |
| | | }) |
| | | countLink.toBack() |
| | | |
| | | if (collapsed) { |
| | | childCountGroup.show() |
| | | childCountText.show() |
| | | countLink.show() |
| | | } |
| | | else { |
| | | childCountGroup.hide() |
| | | childCountText.hide() |
| | | countLink.hide() |
| | | } |
| | | |
| | | clickCircleY += 16 |
| | | } |
| | | }, |
| | | addBottomLine(group, props) { |
| | | const { x, width, stroke, lineWidth } = props |
| | | return group.addShape('path', { |
| | | attrs: { |
| | | path: [ |
| | | ['M', x - 1, 0], |
| | | ['L', width, 0], |
| | | ], |
| | | stroke, |
| | | lineWidth, |
| | | }, |
| | | name: 'node-path-shape' |
| | | }) |
| | | }, |
| | | addName(group, props) { |
| | | const { label, x = 0, y, fill } = props |
| | | return group.addShape('text', { |
| | | attrs: { |
| | | text: label, |
| | | x, |
| | | y, |
| | | textAlign: 'start', |
| | | textBaseline: 'top', |
| | | fill, |
| | | fontSize: 14, |
| | | fontFamily: 'PingFangSC-Regular', |
| | | cursor: 'pointer', |
| | | }, |
| | | name: 'not-root-text-shape' |
| | | }) |
| | | }, |
| | | draw(model, group) { |
| | | const { collapsed, depth, label, children, selected } = model |
| | | // 是否为根节点 |
| | | const rootNode = depth === 0 |
| | | // 子节点数量 |
| | | const childCount = children ? children.length : 0 |
| | | |
| | | let width = 0 |
| | | const height = 24 |
| | | const x = 0 |
| | | const y = -height / 2 |
| | | const borderRadius = 4 |
| | | // 名称文本 |
| | | const text = this.addName(group, { label, x, y }) |
| | | |
| | | let textWidth = text.getBBox().width |
| | | width = textWidth + 20 |
| | | |
| | | const keyShapeAttrs = { |
| | | x, |
| | | y, |
| | | width, |
| | | height, |
| | | radius: borderRadius, |
| | | fill: undefined, |
| | | stroke: undefined, |
| | | } |
| | | |
| | | const keyShape = group.addShape('rect', { |
| | | attrs: keyShapeAttrs, |
| | | name: 'root-key-shape-rect-shape' |
| | | }) |
| | | |
| | | // 底部横线 |
| | | const bottomLine = this.addBottomLine(group, { |
| | | stroke: model.branchColor || '#AAB7C4', |
| | | lineWidth: 3, |
| | | x, |
| | | width |
| | | }) |
| | | |
| | | let nameColor = 'rgba(0, 0, 0, 0.85)' |
| | | |
| | | if (selected) { |
| | | nameColor = systemColor |
| | | } |
| | | |
| | | // 名称 |
| | | text.attr({ |
| | | y: y - 12, |
| | | fill: nameColor |
| | | }) |
| | | text.toFront() |
| | | textWidth = text.getBBox().width |
| | | |
| | | if (bottomLine) bottomLine.toFront() |
| | | |
| | | this.addChildCount(group, childCount && !rootNode, { |
| | | collapsed, |
| | | branchColor: model.branchColor, |
| | | count: childCount ? `${childCount}` : undefined |
| | | }) |
| | | |
| | | const bbox = group.getBBox() |
| | | const backContainer = group.addShape('path', { |
| | | attrs: { |
| | | path: childCount ? [ |
| | | ['M', bbox.minX, bbox.minY], |
| | | ['L', bbox.maxX, bbox.minY], |
| | | ['L', bbox.maxX, bbox.maxY], |
| | | ['L', bbox.minX + 20, bbox.maxY], |
| | | ['L', bbox.minX + 20, bbox.maxY + 20], |
| | | ['L', bbox.minX, bbox.maxY + 20], |
| | | ['Z'] |
| | | ] : [ |
| | | ['M', bbox.minX, bbox.minY], |
| | | ['L', bbox.maxX, bbox.minY], |
| | | ['L', bbox.maxX, bbox.maxY], |
| | | ['L', bbox.minX, bbox.maxY], |
| | | ['Z'] |
| | | ], |
| | | fill: '#fff', |
| | | opacity: 0 |
| | | } |
| | | }) |
| | | backContainer.toBack() |
| | | return keyShape |
| | | } |
| | | }) |
| | | |
| | | G6.registerEdge('indentedEdge', { |
| | | afterDraw: (cfg, group) => { |
| | | const sourceNode = cfg.sourceNode && cfg.sourceNode.getModel() |
| | | const targetNode = cfg.targetNode && cfg.targetNode.getModel() |
| | | const color = sourceNode.branchColor || targetNode.branchColor || cfg.color || '#000' |
| | | |
| | | const keyShape = group.get('children')[0] |
| | | keyShape.attr({ |
| | | stroke: color, |
| | | lineWidth: 3 // branchThick |
| | | }) |
| | | group.toBack() |
| | | }, |
| | | getControlPoints: (cfg) => { |
| | | const startPoint = cfg.startPoint |
| | | const endPoint = cfg.endPoint |
| | | return [ |
| | | startPoint, |
| | | { |
| | | x: startPoint.x, |
| | | y: endPoint.y, |
| | | }, |
| | | endPoint |
| | | ] |
| | | }, |
| | | update: undefined |
| | | }, 'polyline') |
| | | |
| | | G6.registerBehavior('wheel-scroll', { |
| | | getDefaultCfg() { |
| | | return { |
| | | direction: 'y', |
| | | zoomKey: 'ctrl', |
| | | sensitivity: 3, |
| | | scalableRange: -64 |
| | | } |
| | | }, |
| | | getEvents() { |
| | | return { |
| | | wheel: 'onWheel' |
| | | } |
| | | }, |
| | | onWheel(ev) { |
| | | const graph = this.graph |
| | | let keyDown = ev[`${this.zoomKey}Key`] |
| | | if (this.zoomKey === 'control') keyDown = ev.ctrlKey |
| | | if (keyDown) { |
| | | const sensitivity = this.get('sensitivity') |
| | | const canvas = graph.get('canvas') |
| | | const point = canvas.getPointByClient(ev.clientX, ev.clientY) |
| | | let ratio = graph.getZoom() |
| | | if (ev.wheelDelta > 0) { |
| | | ratio *= (1 + 0.01 * sensitivity) |
| | | } else { |
| | | ratio *= (1 - 0.01 * sensitivity) |
| | | } |
| | | graph.zoomTo(ratio, { |
| | | x: point.x, |
| | | y: point.y |
| | | }) |
| | | graph.emit('wheelzoom', ev) |
| | | } else { |
| | | let dx = ev.deltaX || ev.movementX |
| | | let dy = ev.deltaY || ev.movementY |
| | | if (!dy && navigator.userAgent.indexOf('Firefox') > -1) dy = (-ev.wheelDelta * 125) / 3 |
| | | |
| | | const width = this.graph.get('width') |
| | | const height = this.graph.get('height') |
| | | const graphCanvasBBox = this.graph.get('group').getCanvasBBox() |
| | | |
| | | let expandWidth = this.scalableRange |
| | | let expandHeight = this.scalableRange |
| | | // 若 scalableRange 是 0~1 的小数,则作为比例考虑 |
| | | if (expandWidth < 1 && expandWidth > -1) { |
| | | expandWidth = width * expandWidth |
| | | expandHeight = height * expandHeight |
| | | } |
| | | |
| | | const { minX, maxX, minY, maxY } = graphCanvasBBox |
| | | |
| | | if (dx > 0) { |
| | | if (maxX < -expandWidth) { |
| | | dx = 0 |
| | | } else if (maxX - dx < -expandWidth) { |
| | | dx = maxX + expandWidth |
| | | } |
| | | } else if (dx < 0) { |
| | | if (minX > width + expandWidth) { |
| | | dx = 0 |
| | | } else if (minX - dx > width + expandWidth) { |
| | | dx = minX - (width + expandWidth) |
| | | } |
| | | } |
| | | |
| | | if (dy > 0) { |
| | | if (maxY < -expandHeight) { |
| | | dy = 0 |
| | | } else if (maxY - dy < -expandHeight) { |
| | | dy = maxY + expandHeight |
| | | } |
| | | } else if (dy < 0) { |
| | | if (minY > height + expandHeight) { |
| | | dy = 0 |
| | | } else if (minY - dy > height + expandHeight) { |
| | | dy = minY - (height + expandHeight) |
| | | } |
| | | } |
| | | |
| | | if (this.get('direction') === 'x') { |
| | | dy = 0 |
| | | } else if (this.get('direction') === 'y') { |
| | | dx = 0 |
| | | } |
| | | |
| | | graph.translate(-dx, -dy) |
| | | } |
| | | ev.preventDefault() |
| | | } |
| | | }) |
| | | G6.registerBehavior('hover-node', { |
| | | getEvents() { |
| | | return { |
| | | 'node:mouseover': 'onNodeMouseOver', |
| | | 'node:mouseleave': 'onNodeMouseLeave', |
| | | 'node:mouseenter': 'onNodeMouseEnter' |
| | | } |
| | | }, |
| | | onNodeMouseEnter(ev) { |
| | | const { item } = ev |
| | | if (!item || item.get('destroyed')) return |
| | | item.toFront() |
| | | const model = item.getModel() |
| | | const { collapsed, depth } = model |
| | | const rootNode = depth === 0 || model.isRoot |
| | | const group = item.getContainer() |
| | | |
| | | if (rootNode) return |
| | | |
| | | // 控制子节点个数标记 |
| | | if (!collapsed) { |
| | | const childCountGroup = group.find(e => e.get('name') === 'child-count-group') |
| | | if (childCountGroup) { |
| | | childCountGroup.show() |
| | | } |
| | | } |
| | | }, |
| | | onNodeMouseOver(ev) { |
| | | const shape = ev.target |
| | | |
| | | // tooltip显示、隐藏 |
| | | this.graph.emit('tooltip: show', ev) |
| | | |
| | | // expand 状态下,若 hover 到子节点个数标记,填充背景+显示收起 icon |
| | | const { item } = ev |
| | | const group = item.getContainer() |
| | | const model = item.getModel() |
| | | if (!model.collapsed) { |
| | | const childCountGroup = group.find(e => e.get('name') === 'child-count-group') |
| | | if (childCountGroup) { |
| | | childCountGroup.show() |
| | | const back = childCountGroup.find(e => e.get('name') === 'child-count-rect-shape') |
| | | const expandIcon = childCountGroup.find(e => e.get('name') === 'child-count-expand-icon') |
| | | const rootNode = model.depth === 0 || model.isRoot |
| | | const branchColor = rootNode ? '#576286' : model.branchColor |
| | | if (shape.get('parent').get('name') === 'child-count-group') { |
| | | if (back) { |
| | | back.attr('fill', branchColor || '#fff') |
| | | } |
| | | if (expandIcon) { |
| | | expandIcon.show() |
| | | } |
| | | } else { |
| | | if (back) { |
| | | back.attr('fill', '#fff') |
| | | } |
| | | if (expandIcon) { |
| | | expandIcon.hide() |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | onNodeMouseLeave(ev) { |
| | | const { item } = ev |
| | | const model = item.getModel() |
| | | const group = item.getContainer() |
| | | const { collapsed } = model |
| | | |
| | | if (!collapsed) { |
| | | const childCountGroup = group.find(e => e.get('name') === 'child-count-group') |
| | | if (childCountGroup) { |
| | | childCountGroup.hide() |
| | | } |
| | | |
| | | const iconsLinkPath = group.find(e => e.get('name') === 'icons-link-path') |
| | | if (iconsLinkPath) { |
| | | iconsLinkPath.hide() |
| | | } |
| | | } |
| | | |
| | | this.graph.emit('tooltip: hide', ev) |
| | | } |
| | | }) |
| | | G6.registerBehavior('click-node', { |
| | | getEvents() { |
| | | return { |
| | | 'node:click': 'onNodeClick', |
| | | 'canvas:click': 'onCanvasClick' |
| | | } |
| | | }, |
| | | onNodeClick(e) { |
| | | const { item, target } = e |
| | | const shape = target |
| | | const shapeName = shape.cfg.name |
| | | let model = item.getModel() |
| | | |
| | | // 点击收起/展开 icon |
| | | if (shapeName === 'child-count-rect-shape' || shapeName === 'child-count-text-shape') { |
| | | const updatedCollapsed = !model.collapsed |
| | | this.graph.updateItem(item, { collapsed: updatedCollapsed }) |
| | | this.graph.layout() |
| | | return |
| | | } |
| | | |
| | | // 选中节点 |
| | | this.graph.getNodes().forEach(node => { |
| | | let _model = node.get('model') |
| | | if (_model.selected) { |
| | | _model.selected = false |
| | | this.graph.updateItem(node, _model, false) |
| | | } |
| | | }) |
| | | |
| | | model.selected = true |
| | | this.graph.updateItem(item, model, false) |
| | | |
| | | return |
| | | }, |
| | | onCanvasClick(e) { |
| | | this.graph.getNodes().forEach(node => { |
| | | let _model = node.get('model') |
| | | if (_model.selected) { |
| | | _model.selected = false |
| | | this.graph.updateItem(node, _model, false) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | const dataIndTransform = (data) => { |
| | | const changeData = (d) => { |
| | | let data = { ...d } |
| | | |
| | | data.type = data.isRoot ? 'indentedRoot' : 'indentedNode' |
| | | |
| | | if (d.children) { |
| | | data.children = d.children.map((child) => changeData(child)) |
| | | } |
| | | // 给定 branchColor 和 0-2 层节点 depth |
| | | if (data.children && data.children.length) { |
| | | data.depth = 0 |
| | | data.children.forEach((subtree, i) => { |
| | | subtree.branchColor = COLORS[i % COLORS.length] |
| | | // dfs |
| | | let currentDepth = 1 |
| | | subtree.depth = currentDepth |
| | | Util.traverseTree(subtree, child => { |
| | | child.branchColor = COLORS[i % COLORS.length] |
| | | |
| | | if (!child.depth) { |
| | | child.depth = currentDepth + 1 |
| | | } |
| | | else currentDepth = subtree.depth |
| | | if (child.children) { |
| | | child.children.forEach(subChild => { |
| | | subChild.depth = child.depth + 1 |
| | | }) |
| | | } |
| | | |
| | | if (!data.isRoot) { |
| | | child.collapsed = data.collapsed || false |
| | | } |
| | | return true |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | return data |
| | | } |
| | | return changeData(data) |
| | | } |
| | | |
| | | // 知识图谱树 |
| | | G6.registerNode('treeNode', { |
| | | draw: (cfg, group) => { |
| | | const { label, selected, children, isRoot } = cfg |
| | | const rootNode = !!isRoot |
| | | const hasChildren = children && children.length !== 0 |
| | | |
| | | let width = 0 |
| | | const height = 28 |
| | | const x = 0 |
| | | const y = -height / 2 |
| | | |
| | | // 名称文本 |
| | | const text = group.addShape('text', { |
| | | attrs: { |
| | | text: label, |
| | | x: x * 2, |
| | | y, |
| | | textAlign: 'left', |
| | | textBaseline: 'top', |
| | | fontFamily: 'PingFangSC-Regular', |
| | | }, |
| | | cursor: 'pointer', |
| | | name: 'name-text-shape', |
| | | }) |
| | | const textWidth = text.getBBox().width |
| | | width = textWidth + 20 |
| | | |
| | | width = width < 60 ? 60 : width |
| | | |
| | | if (!rootNode && hasChildren) { |
| | | width += 22 |
| | | } |
| | | |
| | | const keyShapeAttrs = { |
| | | x, |
| | | y, |
| | | width, |
| | | height, |
| | | radius: 4 |
| | | } |
| | | |
| | | const keyShape = group.addShape('rect', { |
| | | attrs: keyShapeAttrs, |
| | | name: 'root-key-shape-rect-shape' |
| | | }) |
| | | |
| | | if (!rootNode) { |
| | | // 底部横线 |
| | | group.addShape('path', { |
| | | attrs: { |
| | | path: [ |
| | | ['M', x - 1, 0], |
| | | ['L', width, 0], |
| | | ], |
| | | stroke: '#AAB7C4', |
| | | lineWidth: 1, |
| | | }, |
| | | name: 'node-path-shape' |
| | | }) |
| | | } |
| | | |
| | | const mainX = x - 10 |
| | | const mainY = -height + 15 |
| | | |
| | | if (rootNode) { |
| | | group.addShape('rect', { |
| | | attrs: { |
| | | x: mainX, |
| | | y: mainY, |
| | | width: width + 12, |
| | | height, |
| | | radius: 14, |
| | | fill: systemColor, |
| | | cursor: 'pointer', |
| | | }, |
| | | name: 'main-shape' |
| | | }) |
| | | } |
| | | |
| | | let nameColor = 'rgba(0, 0, 0, 0.85)' |
| | | if (selected) { |
| | | nameColor = systemColor |
| | | } |
| | | |
| | | // 名称 |
| | | if (rootNode) { |
| | | group.addShape('text', { |
| | | attrs: { |
| | | text: label, |
| | | x: mainX + 18, |
| | | y: 1, |
| | | textAlign: 'left', |
| | | textBaseline: 'middle', |
| | | fill: '#ffffff', |
| | | fontSize: 12, |
| | | fontFamily: 'PingFangSC-Regular', |
| | | cursor: 'pointer', |
| | | }, |
| | | name: 'root-text-shape' |
| | | }) |
| | | } else { |
| | | group.addShape('text', { |
| | | attrs: { |
| | | text: label, |
| | | x: mainX + 6, |
| | | y: y - 5, |
| | | textAlign: 'start', |
| | | textBaseline: 'top', |
| | | fill: nameColor, |
| | | fontSize: 12, |
| | | fontFamily: 'PingFangSC-Regular', |
| | | cursor: 'pointer', |
| | | }, |
| | | name: 'not-root-text-shape' |
| | | }) |
| | | } |
| | | |
| | | // 子类数量 |
| | | if (hasChildren && !rootNode) { |
| | | const childCountHeight = 12 |
| | | const childCountX = width - 22 |
| | | const childCountY = -childCountHeight / 2 |
| | | |
| | | group.addShape('rect', { |
| | | attrs: { |
| | | width: 22, |
| | | height: 12, |
| | | stroke: systemColor, |
| | | fill: '#fff', |
| | | x: childCountX, |
| | | y: childCountY, |
| | | radius: 6, |
| | | cursor: 'pointer', |
| | | }, |
| | | name: 'child-count-rect-shape', |
| | | }) |
| | | group.addShape('text', { |
| | | attrs: { |
| | | text: `${children.length}`, |
| | | fill: 'rgba(0, 0, 0, .65)', |
| | | x: childCountX + 11, |
| | | y: childCountY + 12, |
| | | fontSize: 10, |
| | | width: 22, |
| | | textAlign: 'center', |
| | | cursor: 'pointer', |
| | | }, |
| | | name: 'child-count-text-shape' |
| | | }) |
| | | } |
| | | |
| | | return keyShape |
| | | } |
| | | }) |
| | | |
| | | G6.registerEdge('smooth', { |
| | | draw(cfg, group) { |
| | | const { startPoint, endPoint } = cfg |
| | | const hgap = Math.abs(endPoint.x - startPoint.x) |
| | | |
| | | const path = [ |
| | | ['M', startPoint.x, startPoint.y], |
| | | [ |
| | | 'C', |
| | | startPoint.x + hgap / 4, |
| | | startPoint.y, |
| | | endPoint.x - hgap / 2, |
| | | endPoint.y, |
| | | endPoint.x, |
| | | endPoint.y, |
| | | ], |
| | | ] |
| | | |
| | | const shape = group.addShape('path', { |
| | | attrs: { |
| | | stroke: '#AAB7C4', |
| | | path, |
| | | }, |
| | | name: 'smooth-path-shape', |
| | | }) |
| | | return shape |
| | | }, |
| | | }) |
| | | |
| | | G6.registerBehavior('click-item', { |
| | | getEvents() { |
| | | return { |
| | | 'node:click': 'onNodeClick', |
| | | 'canvas:click': 'onCanvasClick' |
| | | } |
| | | }, |
| | | onNodeClick(e) { |
| | | const { item } = e |
| | | let model = item.getModel() |
| | | |
| | | if (model.children) return |
| | | // 选中节点 |
| | | this.graph.getNodes().forEach(node => { |
| | | let _model = node.get('model') |
| | | if (_model.selected) { |
| | | _model.selected = false |
| | | this.graph.updateItem(node, _model, false) |
| | | } |
| | | }) |
| | | |
| | | model.selected = true |
| | | this.graph.updateItem(item, model, false) |
| | | |
| | | return |
| | | }, |
| | | onCanvasClick(e) { |
| | | this.graph.getNodes().forEach(node => { |
| | | let _model = node.get('model') |
| | | if (_model.selected) { |
| | | _model.selected = false |
| | | this.graph.updateItem(node, _model, false) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | class antvG6Chart extends Component { |
| | | class antvX6Chart extends Component { |
| | | static propTpyes = { |
| | | card: PropTypes.object, |
| | | updateConfig: PropTypes.func, |
| | |
| | | plot: _plot, |
| | | } |
| | | |
| | | if (card.config) { |
| | | let config = fromJS(card.config).toJS() |
| | | |
| | | _card.plot = config.plot |
| | | _card.plot.name = card.name |
| | | _card.style = config.style |
| | | _card.headerStyle = config.headerStyle |
| | | |
| | | _card.setting = config.setting |
| | | _card.columns = config.columns |
| | | _card.scripts = config.scripts |
| | | } |
| | | |
| | | this.updateComponent(_card) |
| | | } else { |
| | | this.setState({ |
| | | card: fromJS(card).toJS() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('tabsChange', this.handleTabsChange) |
| | | setTimeout(() => { |
| | | this.viewrender() |
| | | }, 1000) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('tabsChange', this.handleTabsChange) |
| | | } |
| | | |
| | | handleTabsChange = (parentId) => { |
| | | const { card } = this.state |
| | | |
| | | if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') { |
| | | let _element = document.getElementById(card.uuid + 'canvas') |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | | } |
| | | |
| | | this.$timer && clearTimeout(this.$timer) |
| | | this.$timer = setTimeout(this.viewrender, 100) |
| | | } |
| | | } |
| | | |
| | | getdata = () => { |
| | | const { card } = this.state |
| | | |
| | | const setData = (list) => { |
| | | let item = { |
| | | label: list[0], |
| | | id: list[0], |
| | | children: [] |
| | | } |
| | | if (!list[1]) { |
| | | delete item.children |
| | | |
| | | return item |
| | | } else if (!Array.isArray(list[1])) { |
| | | return list.map(m => ({label: m, id: m})) |
| | | } |
| | | |
| | | for (let i = 1; i < list.length; i++) { |
| | | let cell = setData(list[i]) |
| | | |
| | | if (Array.isArray(cell)) { |
| | | item.children.push(...cell) |
| | | } else { |
| | | item.children.push(cell) |
| | | } |
| | | } |
| | | |
| | | return item |
| | | } |
| | | |
| | | let data = setData(MindData) |
| | | |
| | | if (card.plot.subtype === 'mindmap') { |
| | | if (card.plot.dirField) { |
| | | data.children[0].direction = 'left' |
| | | data.children[2].direction = 'left' |
| | | } |
| | | |
| | | data.children.forEach(item => { |
| | | if (item.direction === 'left') { |
| | | item.color = card.plot.leftColor || '#26C281' |
| | | } else { |
| | | item.direction = 'right' |
| | | item.color = card.plot.nodeColor || '#1890ff' |
| | | } |
| | | }) |
| | | |
| | | data.collapsed = false |
| | | data.type = 'dice-mind-map-root' |
| | | |
| | | const collapse = (item) => { |
| | | if (!item.children) return |
| | | |
| | | item.children.forEach(cell => { |
| | | cell.collapsed = card.plot.collapsed === 'true' |
| | | cell.direction = cell.direction || 'right' |
| | | cell.type = 'dice-mind-map-leaf' |
| | | cell.color = cell.color || item.color |
| | | collapse(cell) |
| | | }) |
| | | } |
| | | |
| | | collapse(data) |
| | | } else if (card.plot.subtype === 'indentTree') { |
| | | data.isRoot = true |
| | | data.collapsed = false |
| | | |
| | | data.children.forEach(item => { |
| | | item.collapsed = card.plot.collapsed === 'true' |
| | | }) |
| | | } else if (card.plot.subtype === 'kapmap') { |
| | | data.isRoot = true |
| | | data.collapsed = false |
| | | |
| | | if (card.plot.collapsed === 'true') { |
| | | const collapse = (item) => { |
| | | if (!item.children) return |
| | | |
| | | item.children.forEach(cell => { |
| | | cell.collapsed = true |
| | | collapse(cell) |
| | | }) |
| | | } |
| | | |
| | | collapse(data) |
| | | } |
| | | } |
| | | |
| | | return data |
| | | componentDidMount () { |
| | | setTimeout(() => { |
| | | this.viewrender() |
| | | }, 1000) |
| | | } |
| | | |
| | | viewrender = () => { |
| | | const { card } = this.state |
| | | // const { card } = this.state |
| | | |
| | | if (card.plot.subtype === 'mindmap') { |
| | | this.ponitrender() |
| | | } else if (card.plot.subtype === 'indentTree') { |
| | | this.indentrender() |
| | | } else if (card.plot.subtype === 'kapmap') { |
| | | // if (card.plot.subtype === 'mindmap') { |
| | | // this.ponitrender() |
| | | // } else if (card.plot.subtype === 'indentTree') { |
| | | // this.indentrender() |
| | | // } else if (card.plot.subtype === 'kapmap') { |
| | | this.kapmaprender() |
| | | } |
| | | // } |
| | | } |
| | | |
| | | kapmaprender = () => { |
| | | const { card } = this.state |
| | | const plot = card.plot |
| | | const data = this.getdata() |
| | | const height = getHeight(plot.height) |
| | | |
| | | const graph = new G6.TreeGraph({ |
| | | container: card.uuid + 'canvas', |
| | | width: this.wrap.scrollWidth - 30, |
| | | height: height, |
| | | modes: { |
| | | default: [ |
| | | { |
| | | type: 'collapse-expand', |
| | | preWork() |
| | | |
| | | // #region 初始化画布 |
| | | const graph = new Graph({ |
| | | container: document.getElementById(card.uuid + 'container'), |
| | | grid: true, |
| | | mousewheel: { |
| | | enabled: true, |
| | | zoomAtMousePosition: true, |
| | | modifiers: 'ctrl', |
| | | minScale: 0.5, |
| | | maxScale: 3, |
| | | }, |
| | | connecting: { |
| | | router: 'manhattan', |
| | | connector: { |
| | | name: 'rounded', |
| | | args: { |
| | | radius: 8, |
| | | }, |
| | | 'drag-canvas', |
| | | 'zoom-canvas', |
| | | 'click-item' |
| | | ], |
| | | }, |
| | | anchor: 'center', |
| | | connectionPoint: 'anchor', |
| | | allowBlank: false, |
| | | snap: { |
| | | radius: 20, |
| | | }, |
| | | createEdge() { |
| | | return new Shape.Edge({ |
| | | attrs: { |
| | | line: { |
| | | stroke: '#A2B1C3', |
| | | strokeWidth: 2, |
| | | targetMarker: { |
| | | name: 'block', |
| | | width: 12, |
| | | height: 8, |
| | | }, |
| | | }, |
| | | }, |
| | | zIndex: 0, |
| | | }) |
| | | }, |
| | | validateConnection({ targetMagnet }) { |
| | | return !!targetMagnet |
| | | }, |
| | | }, |
| | | defaultNode: { |
| | | type: 'treeNode', |
| | | anchorPoints: [ |
| | | [0, 0.5], |
| | | [1, 0.5], |
| | | ], |
| | | highlighting: { |
| | | magnetAdsorbed: { |
| | | name: 'stroke', |
| | | args: { |
| | | attrs: { |
| | | fill: '#5F95FF', |
| | | stroke: '#5F95FF', |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | defaultEdge: { |
| | | type: 'smooth', |
| | | }) |
| | | // #endregion |
| | | |
| | | // #region 使用插件 |
| | | graph |
| | | .use( |
| | | new Transform({ |
| | | resizing: true, |
| | | rotating: true, |
| | | }), |
| | | ) |
| | | .use( |
| | | new Selection({ |
| | | rubberband: true, |
| | | showNodeSelectionBox: true, |
| | | }), |
| | | ) |
| | | .use(new Snapline()) |
| | | .use(new Keyboard()) |
| | | .use(new Clipboard()) |
| | | .use(new History()) |
| | | // #endregion |
| | | |
| | | // #region 初始化 stencil |
| | | const stencil = new Stencil({ |
| | | title: '流程图', |
| | | target: graph, |
| | | stencilGraphWidth: 200, |
| | | stencilGraphHeight: 180, |
| | | collapsable: true, |
| | | groups: [ |
| | | { |
| | | title: '基础流程图', |
| | | name: 'group1', |
| | | }, |
| | | { |
| | | title: '系统设计图', |
| | | name: 'group2', |
| | | graphHeight: 250, |
| | | layoutOptions: { |
| | | rowHeight: 70, |
| | | }, |
| | | }, |
| | | ], |
| | | layoutOptions: { |
| | | columns: 2, |
| | | columnWidth: 80, |
| | | rowHeight: 55, |
| | | }, |
| | | layout: { |
| | | type: 'compactBox', |
| | | direction: 'LR', |
| | | getId: function getId(d) { |
| | | return d.id |
| | | }, |
| | | getHeight: function getHeight() { |
| | | return 16 |
| | | }, |
| | | getWidth: function getWidth(d) { |
| | | const labelWidth = G6.Util.getTextSize(d.label, 12)[0] |
| | | const width = 60 + labelWidth |
| | | return width |
| | | }, |
| | | getVGap: function getVGap() { |
| | | return 15 |
| | | }, |
| | | getHGap: function getHGap() { |
| | | return 30 |
| | | } |
| | | }) |
| | | document.getElementById('stencil').appendChild(stencil.container) |
| | | // #endregion |
| | | |
| | | // #region 快捷键与事件 |
| | | graph.bindKey(['meta+c', 'ctrl+c'], () => { |
| | | const cells = graph.getSelectedCells() |
| | | if (cells.length) { |
| | | graph.copy(cells) |
| | | } |
| | | return false |
| | | }) |
| | | graph.bindKey(['meta+x', 'ctrl+x'], () => { |
| | | const cells = graph.getSelectedCells() |
| | | if (cells.length) { |
| | | graph.cut(cells) |
| | | } |
| | | return false |
| | | }) |
| | | graph.bindKey(['meta+v', 'ctrl+v'], () => { |
| | | if (!graph.isClipboardEmpty()) { |
| | | const cells = graph.paste({ offset: 32 }) |
| | | graph.cleanSelection() |
| | | graph.select(cells) |
| | | } |
| | | return false |
| | | }) |
| | | |
| | | // undo redo |
| | | graph.bindKey(['meta+z', 'ctrl+z'], () => { |
| | | if (graph.canUndo()) { |
| | | graph.undo() |
| | | } |
| | | return false |
| | | }) |
| | | graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => { |
| | | if (graph.canRedo()) { |
| | | graph.redo() |
| | | } |
| | | return false |
| | | }) |
| | | |
| | | // select all |
| | | graph.bindKey(['meta+a', 'ctrl+a'], () => { |
| | | const nodes = graph.getNodes() |
| | | if (nodes) { |
| | | graph.select(nodes) |
| | | } |
| | | }) |
| | | |
| | | graph.data(data) |
| | | graph.render() |
| | | graph.fitView() |
| | | // delete |
| | | graph.bindKey('backspace', () => { |
| | | const cells = graph.getSelectedCells() |
| | | if (cells.length) { |
| | | graph.removeCells(cells) |
| | | } |
| | | }) |
| | | |
| | | if (plot.collapsed === 'true') { |
| | | graph.zoomTo(1, { x: 0, y: height / 2 }) |
| | | // zoom |
| | | graph.bindKey(['ctrl+1', 'meta+1'], () => { |
| | | const zoom = graph.zoom() |
| | | if (zoom < 1.5) { |
| | | graph.zoom(0.1) |
| | | } |
| | | }) |
| | | graph.bindKey(['ctrl+2', 'meta+2'], () => { |
| | | const zoom = graph.zoom() |
| | | if (zoom > 0.5) { |
| | | graph.zoom(-0.1) |
| | | } |
| | | }) |
| | | |
| | | // 控制连接桩显示/隐藏 |
| | | const showPorts = (ports, show) => { |
| | | for (let i = 0, len = ports.length; i < len; i += 1) { |
| | | ports[i].style.visibility = show ? 'visible' : 'hidden' |
| | | } |
| | | } |
| | | } |
| | | graph.on('node:mouseenter', () => { |
| | | const container = document.getElementById(card.uuid + 'container') |
| | | const ports = container.querySelectorAll('.x6-port-body') |
| | | showPorts(ports, true) |
| | | }) |
| | | graph.on('node:mouseleave', () => { |
| | | const container = document.getElementById(card.uuid + 'container') |
| | | const ports = container.querySelectorAll('.x6-port-body') |
| | | showPorts(ports, false) |
| | | }) |
| | | // #endregion |
| | | |
| | | indentrender = () => { |
| | | const { card } = this.state |
| | | const plot = card.plot |
| | | const data = this.getdata() |
| | | |
| | | const tree = new G6.TreeGraph({ |
| | | container: card.uuid + 'canvas', |
| | | width: this.wrap.scrollWidth - 30, |
| | | height: getHeight(plot.height), |
| | | layout: { |
| | | type: 'indented', |
| | | direction: 'LR', |
| | | isHorizontal: true, |
| | | indent: 40, |
| | | getHeight: (d) => { |
| | | if (d.isRoot) { |
| | | return 30 |
| | | } |
| | | if (d.collapsed && d.children && d.children.length) { |
| | | return 36 |
| | | } |
| | | return 22 |
| | | // #region 初始化图形 |
| | | const ports = { |
| | | groups: { |
| | | top: { |
| | | position: 'top', |
| | | attrs: { |
| | | circle: { |
| | | r: 4, |
| | | magnet: true, |
| | | stroke: '#5F95FF', |
| | | strokeWidth: 1, |
| | | fill: '#fff', |
| | | style: { |
| | | visibility: 'hidden', |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | getVGap: () => { |
| | | return 10 |
| | | right: { |
| | | position: 'right', |
| | | attrs: { |
| | | circle: { |
| | | r: 4, |
| | | magnet: true, |
| | | stroke: '#5F95FF', |
| | | strokeWidth: 1, |
| | | fill: '#fff', |
| | | style: { |
| | | visibility: 'hidden', |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | bottom: { |
| | | position: 'bottom', |
| | | attrs: { |
| | | circle: { |
| | | r: 4, |
| | | magnet: true, |
| | | stroke: '#5F95FF', |
| | | strokeWidth: 1, |
| | | fill: '#fff', |
| | | style: { |
| | | visibility: 'hidden', |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | left: { |
| | | position: 'left', |
| | | attrs: { |
| | | circle: { |
| | | r: 4, |
| | | magnet: true, |
| | | stroke: '#5F95FF', |
| | | strokeWidth: 1, |
| | | fill: '#fff', |
| | | style: { |
| | | visibility: 'hidden', |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | defaultEdge: { |
| | | type: 'indentedEdge', |
| | | style: { |
| | | lineWidth: 2, |
| | | radius: 16 |
| | | } |
| | | }, |
| | | minZoom: 0.5, |
| | | modes: { |
| | | default: [ |
| | | 'drag-canvas', |
| | | 'wheel-scroll', |
| | | 'hover-node', |
| | | 'click-node' |
| | | ] |
| | | } |
| | | }) |
| | | |
| | | tree.on('afterrender', e => { |
| | | tree.getEdges().forEach(edge => { |
| | | const targetNode = edge.getTarget().getModel() |
| | | const color = targetNode.branchColor |
| | | tree.updateItem(edge, { color }) |
| | | }) |
| | | setTimeout(() => { |
| | | tree.moveTo(32, 32) |
| | | tree.zoomTo(0.7) |
| | | }, 16) |
| | | }) |
| | | |
| | | tree.data(dataIndTransform(data)) |
| | | |
| | | tree.render() |
| | | } |
| | | |
| | | /** |
| | | * @description 散点图 |
| | | */ |
| | | ponitrender = () => { |
| | | const { card } = this.state |
| | | const plot = card.plot |
| | | const data = this.getdata() |
| | | const width = this.wrap.scrollWidth - 30 |
| | | const height = getHeight(plot.height) |
| | | let modes = ['drag-canvas', 'zoom-canvas', 'dice-mindmap'] |
| | | |
| | | if (plot.collapsed === 'true') { |
| | | modes = [{ type: 'collapse-expand' },'drag-canvas', 'zoom-canvas', 'dice-mindmap'] |
| | | items: [ |
| | | { |
| | | group: 'top', |
| | | }, |
| | | { |
| | | group: 'right', |
| | | }, |
| | | { |
| | | group: 'bottom', |
| | | }, |
| | | { |
| | | group: 'left', |
| | | }, |
| | | ], |
| | | } |
| | | |
| | | const tree = new G6.TreeGraph({ |
| | | container: card.uuid + 'canvas', |
| | | width: width, |
| | | height: height, |
| | | fitView: true, |
| | | layout: { |
| | | type: 'mindmap', |
| | | direction: 'H', |
| | | getHeight: () => { |
| | | return 16 |
| | | Graph.registerNode( |
| | | 'custom-rect', |
| | | { |
| | | inherit: 'rect', |
| | | width: 66, |
| | | height: 36, |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 1, |
| | | stroke: '#5F95FF', |
| | | fill: '#EFF4FF', |
| | | }, |
| | | text: { |
| | | fontSize: 12, |
| | | fill: '#262626', |
| | | }, |
| | | }, |
| | | getWidth: (node) => { |
| | | return node.level === 0 ? |
| | | Util.getTextSize(node.label, 16)[0] + 12 : |
| | | Util.getTextSize(node.label, 12)[0] |
| | | }, |
| | | getVGap: () => { |
| | | return 10 |
| | | }, |
| | | getHGap: () => { |
| | | return 60 |
| | | }, |
| | | getSide: (node) => { |
| | | return node.data.direction |
| | | } |
| | | ports: { ...ports }, |
| | | }, |
| | | defaultEdge: { |
| | | type: 'cubic-horizontal', |
| | | style: { |
| | | lineWidth: 2 |
| | | } |
| | | true, |
| | | ) |
| | | |
| | | Graph.registerNode( |
| | | 'custom-polygon', |
| | | { |
| | | inherit: 'polygon', |
| | | width: 66, |
| | | height: 36, |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 1, |
| | | stroke: '#5F95FF', |
| | | fill: '#EFF4FF', |
| | | }, |
| | | text: { |
| | | fontSize: 12, |
| | | fill: '#262626', |
| | | }, |
| | | }, |
| | | ports: { |
| | | ...ports, |
| | | items: [ |
| | | { |
| | | group: 'top', |
| | | }, |
| | | { |
| | | group: 'bottom', |
| | | }, |
| | | ], |
| | | }, |
| | | }, |
| | | minZoom: 0.5, |
| | | modes: { |
| | | default: modes |
| | | } |
| | | true, |
| | | ) |
| | | |
| | | Graph.registerNode( |
| | | 'custom-circle', |
| | | { |
| | | inherit: 'circle', |
| | | width: 45, |
| | | height: 45, |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 1, |
| | | stroke: '#5F95FF', |
| | | fill: '#EFF4FF', |
| | | }, |
| | | text: { |
| | | fontSize: 12, |
| | | fill: '#262626', |
| | | }, |
| | | }, |
| | | ports: { ...ports }, |
| | | }, |
| | | true, |
| | | ) |
| | | |
| | | Graph.registerNode( |
| | | 'custom-image', |
| | | { |
| | | inherit: 'rect', |
| | | width: 52, |
| | | height: 52, |
| | | markup: [ |
| | | { |
| | | tagName: 'rect', |
| | | selector: 'body', |
| | | }, |
| | | { |
| | | tagName: 'image', |
| | | }, |
| | | { |
| | | tagName: 'text', |
| | | selector: 'label', |
| | | }, |
| | | ], |
| | | attrs: { |
| | | body: { |
| | | stroke: '#5F95FF', |
| | | fill: '#5F95FF', |
| | | }, |
| | | image: { |
| | | width: 26, |
| | | height: 26, |
| | | refX: 13, |
| | | refY: 16, |
| | | }, |
| | | label: { |
| | | refX: 3, |
| | | refY: 2, |
| | | textAnchor: 'left', |
| | | textVerticalAnchor: 'top', |
| | | fontSize: 12, |
| | | fill: '#fff', |
| | | }, |
| | | }, |
| | | ports: { ...ports }, |
| | | }, |
| | | true, |
| | | ) |
| | | |
| | | const r1 = graph.createNode({ |
| | | shape: 'custom-rect', |
| | | label: '开始', |
| | | attrs: { |
| | | body: { |
| | | rx: 20, |
| | | ry: 26, |
| | | }, |
| | | }, |
| | | }) |
| | | const r2 = graph.createNode({ |
| | | shape: 'custom-rect', |
| | | label: '过程', |
| | | }) |
| | | const r3 = graph.createNode({ |
| | | shape: 'custom-rect', |
| | | attrs: { |
| | | body: { |
| | | rx: 6, |
| | | ry: 6, |
| | | }, |
| | | }, |
| | | label: '可选过程', |
| | | }) |
| | | const r4 = graph.createNode({ |
| | | shape: 'custom-polygon', |
| | | attrs: { |
| | | body: { |
| | | refPoints: '0,10 10,0 20,10 10,20', |
| | | }, |
| | | }, |
| | | label: '决策', |
| | | }) |
| | | const r5 = graph.createNode({ |
| | | shape: 'custom-polygon', |
| | | attrs: { |
| | | body: { |
| | | refPoints: '10,0 40,0 30,20 0,20', |
| | | }, |
| | | }, |
| | | label: '数据', |
| | | }) |
| | | const r6 = graph.createNode({ |
| | | shape: 'custom-circle', |
| | | label: '连接', |
| | | }) |
| | | stencil.load([r1, r2, r3, r4, r5, r6], 'group1') |
| | | |
| | | tree.data(data) |
| | | |
| | | tree.render() |
| | | const imageShapes = [ |
| | | { |
| | | label: 'Client', |
| | | image: |
| | | 'https://gw.alipayobjects.com/zos/bmw-prod/687b6cb9-4b97-42a6-96d0-34b3099133ac.svg', |
| | | }, |
| | | { |
| | | label: 'Http', |
| | | image: |
| | | 'https://gw.alipayobjects.com/zos/bmw-prod/dc1ced06-417d-466f-927b-b4a4d3265791.svg', |
| | | }, |
| | | { |
| | | label: 'Api', |
| | | image: |
| | | 'https://gw.alipayobjects.com/zos/bmw-prod/c55d7ae1-8d20-4585-bd8f-ca23653a4489.svg', |
| | | }, |
| | | { |
| | | label: 'Sql', |
| | | image: |
| | | 'https://gw.alipayobjects.com/zos/bmw-prod/6eb71764-18ed-4149-b868-53ad1542c405.svg', |
| | | }, |
| | | { |
| | | label: 'Clound', |
| | | image: |
| | | 'https://gw.alipayobjects.com/zos/bmw-prod/c36fe7cb-dc24-4854-aeb5-88d8dc36d52e.svg', |
| | | }, |
| | | { |
| | | label: 'Mq', |
| | | image: |
| | | 'https://gw.alipayobjects.com/zos/bmw-prod/2010ac9f-40e7-49d4-8c4a-4fcf2f83033b.svg', |
| | | }, |
| | | ] |
| | | const imageNodes = imageShapes.map((item) => |
| | | graph.createNode({ |
| | | shape: 'custom-image', |
| | | label: item.label, |
| | | attrs: { |
| | | image: { |
| | | 'xlink:href': item.image, |
| | | }, |
| | | }, |
| | | }), |
| | | ) |
| | | stencil.load(imageNodes, 'group2') |
| | | // #endregion |
| | | |
| | | if (plot.collapsed === 'true' && plot.dirField) { |
| | | tree.zoomTo(1, { x: width / 2, y: height / 2 }) |
| | | } else if (plot.collapsed === 'true') { |
| | | tree.zoomTo(1, { x: 0, y: height / 2 }) |
| | | function preWork() { |
| | | // 这里协助演示的代码,在实际项目中根据实际情况进行调整 |
| | | const container = document.getElementById(card.uuid + 'canvas') |
| | | const stencilContainer = document.createElement('div') |
| | | stencilContainer.id = 'stencil' |
| | | stencilContainer.classList.add('mk-stencil') |
| | | const graphContainer = document.createElement('div') |
| | | graphContainer.id = card.uuid + 'container' |
| | | graphContainer.classList.add('mk-container') |
| | | container.appendChild(stencilContainer) |
| | | container.appendChild(graphContainer) |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | if (card.errors.length === 0) { |
| | | card.$tables = getTables(card) |
| | | } |
| | | |
| | | if (!card.plot.valueField) { |
| | | card.errors.push({ level: 0, detail: '图表信息尚未设置!'}) |
| | | } else { |
| | | let columns = card.columns.map(c => c.field) |
| | | if (!columns.includes(card.plot.valueField)) { |
| | | card.errors.push({ level: 0, detail: '值字段在字段集中不存在'}) |
| | | } else if (!columns.includes(card.plot.labelField)) { |
| | | card.errors.push({ level: 0, detail: '文本字段在字段集中不存在'}) |
| | | } else if (!columns.includes(card.plot.parentField)) { |
| | | card.errors.push({ level: 0, detail: '上级字段在字段集中不存在'}) |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | <ChartCompileForm config={card} plotchange={this.updateComponent}/> |
| | | <CopyComponent type="antvG6" card={card}/> |
| | | <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/> |
| | | <UserComponent config={card}/> |
| | | <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)}/> |
| | | <SettingComponent config={card} updateConfig={this.updateComponent}/> |
| | | </div> |
| | |
| | | <ToolOutlined/> |
| | | </Popover> |
| | | <NormalHeader config={card} updateComponent={this.updateComponent}/> |
| | | <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div> |
| | | <div className="canvas" style={{width: '100%', minHeight: card.plot.height, height: card.plot.height}} id={card.uuid + 'canvas'}> |
| | | </div> |
| | | <div className="component-name"> |
| | | <div className="center"> |
| | | <div className="title" onDoubleClick={() => { |
| | | let oInput = document.createElement('input') |
| | | oInput.value = 'anchor' + card.uuid |
| | | document.body.appendChild(oInput) |
| | | oInput.select() |
| | | document.execCommand('Copy') |
| | | document.body.removeChild(oInput) |
| | | message.success('复制成功。') |
| | | }}>{card.name}</div> |
| | | <div className="title">{card.name}</div> |
| | | <div className="content"> |
| | | {card.errors && card.errors.map((err, index) => { |
| | | if (err.level === 0) { |
| | |
| | | } |
| | | } |
| | | |
| | | export default antvG6Chart |
| | | export default antvX6Chart |
| | |
| | | |
| | | .canvas { |
| | | margin: 0px; |
| | | padding: 15px; |
| | | letter-spacing: 0px; |
| | | display: flex; |
| | | |
| | | .mk-stencil { |
| | | width: 180px; |
| | | height: 100%; |
| | | position: relative; |
| | | z-index: 2; |
| | | border-right: 1px solid #dfe3e8; |
| | | } |
| | | .mk-container { |
| | | width: calc(100% - 180px); |
| | | height: 100%; |
| | | } |
| | | .x6-widget-stencil { |
| | | background-color: #fff; |
| | | } |
| | | .x6-widget-stencil-title { |
| | | background-color: #fff; |
| | | } |
| | | .x6-widget-stencil-group-title { |
| | | background-color: #fff !important; |
| | | } |
| | | .x6-widget-transform { |
| | | margin: -1px 0 0 -1px; |
| | | padding: 0px; |
| | | border: 1px solid #239edd; |
| | | } |
| | | .x6-widget-transform > div { |
| | | border: 1px solid #239edd; |
| | | } |
| | | .x6-widget-transform > div:hover { |
| | | background-color: #3dafe4; |
| | | } |
| | | .x6-widget-transform-active-handle { |
| | | background-color: #3dafe4; |
| | | } |
| | | .x6-widget-transform-resize { |
| | | border-radius: 0; |
| | | } |
| | | .x6-widget-selection-inner { |
| | | border: 1px solid #239edd; |
| | | } |
| | | .x6-widget-selection-box { |
| | | opacity: 0; |
| | | } |
| | | } |
| | | |
| | | .chart-header { |
| | |
| | | cursor: pointer; |
| | | color: rgba(0, 0, 0, 0.85); |
| | | background: rgba(255, 255, 255, 0.55); |
| | | } |
| | | |
| | | .model-menu-action-list { |
| | | position: absolute; |
| | | right: 0px; |
| | | top: 30px; |
| | | z-index: 4; |
| | | font-size: 16px; |
| | | |
| | | .ant-row .anticon-plus { |
| | | float: right; |
| | | } |
| | | |
| | | .page-card { |
| | | float: right; |
| | | } |
| | | } |
| | | .normal-header + .canvas + .model-menu-action-list { |
| | | top: 45px; |
| | | } |
| | | } |
| | | .menu-scatter-chart-edit-box:hover { |
| | |
| | | const Account = asyncComponent(() => import('@/menu/components/module/account')) |
| | | const Iframe = asyncComponent(() => import('@/menu/components/iframe')) |
| | | const AntvG6 = asyncComponent(() => import('@/menu/components/chart/antv-G6')) |
| | | const AntvX6 = asyncComponent(() => import('@/menu/components/chart/antv-X6')) |
| | | |
| | | const Card = ({ id, card, moveCard, findCard, delCard, unGroup, updateConfig }) => { |
| | | const originalIndex = findCard(id).index |
| | |
| | | return (<Iframe card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'antvG6') { |
| | | return (<AntvG6 card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'antvX6') { |
| | | return (<AntvX6 card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'module' && card.subtype === 'voucher') { |
| | | return (<Voucher card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } else if (card.type === 'module' && card.subtype === 'account') { |
| | | return (<Account card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) |
| | | } |
| | | } |
| | | |
| | | // if (card.type === 'antvX6') { // 测试 |
| | | // return ( |
| | | // <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} style={style}> |
| | | // <AntvX6 card={card} updateConfig={updateConfig} deletecomponent={delCard}/> |
| | | // </div> |
| | | // ) |
| | | // } |
| | | |
| | | return ( |
| | | <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} ref={node => drag(drop(node))} style={style}> |
| | | {getCardComponent()} |
| | |
| | | import bar from '@/assets/mobimg/bar.png' |
| | | import bar1 from '@/assets/mobimg/bar1.png' |
| | | import line from '@/assets/mobimg/line.png' |
| | | // import line1 from '@/assets/mobimg/line1.png' |
| | | import tabs from '@/assets/mobimg/tabs.png' |
| | | import group from '@/assets/mobimg/group.png' |
| | | import card1 from '@/assets/mobimg/card1.png' |
| | |
| | | { type: 'menu', url: timeline, component: 'timeline', subtype: 'timeline', title: '时间轴', width: 12 }, |
| | | { type: 'menu', url: tree, component: 'tree', subtype: 'normaltree', title: '树形列表', width: 12, forbid: ['billPrint'] }, |
| | | { type: 'menu', url: line, component: 'line', subtype: 'line', title: '折线图', width: 24 }, |
| | | // { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '阶梯折线图', width: 24 }, |
| | | { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '柱状图', width: 24 }, |
| | | { type: 'menu', url: bar1, component: 'bar', subtype: 'bar1', title: '条形图', width: 24 }, |
| | | { type: 'menu', url: Pie, component: 'pie', subtype: 'pie', title: '饼图', width: 12 }, |
| | |
| | | this.setState({empty: false}) |
| | | |
| | | if (plot.subtype === 'mindmap') { |
| | | this.ponitrender() |
| | | this.mindrender() |
| | | } else if (plot.subtype === 'indentTree') { |
| | | this.indentrender() |
| | | } else if (plot.subtype === 'kapmap') { |
| | |
| | | } |
| | | |
| | | /** |
| | | * @description 散点图 |
| | | * @description 思维导图 |
| | | */ |
| | | ponitrender = () => { |
| | | mindrender = () => { |
| | | const { config, plot, chartId } = this.state |
| | | const data = this.getdata() |
| | | const width = this.wrap.scrollWidth - 30 |
| | |
| | | |
| | | // 数据缓存设置 |
| | | if (config.cacheUseful === 'true') { |
| | | if (!['day', 'hour'].includes(config.timeUnit)) { |
| | | if (!['day', 'hour', 'minute'].includes(config.timeUnit)) { |
| | | config.timeUnit = 'day' |
| | | } |
| | | config.cacheTime = config.cacheTime || 1 |
| | |
| | | |
| | | // 数据缓存设置 |
| | | if (config.cacheUseful === 'true') { |
| | | if (!['day', 'hour'].includes(config.timeUnit)) { |
| | | if (!['day', 'hour', 'minute'].includes(config.timeUnit)) { |
| | | config.timeUnit = 'day' |
| | | } |
| | | config.cacheTime = config.cacheTime || 1 |
| | |
| | | {getFieldDecorator('timeUnit', { |
| | | initialValue: config.timeUnit || 'day' |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio value="day">天</Radio> |
| | | <Radio value="hour">小时</Radio> |
| | | <Radio value="minute">分钟</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/> |
| | | <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | |
| | | {getFieldDecorator('timeUnit', { |
| | | initialValue: config.timeUnit || 'day' |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio value="day">天</Radio> |
| | | <Radio value="hour">小时</Radio> |
| | | <Radio value="minute">分钟</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={(val) => {this.selectChange('cacheTime', val)}}/> |
| | | <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={(val) => {this.selectChange('cacheTime', val)}}/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | |
| | | {getFieldDecorator('timeUnit', { |
| | | initialValue: config.timeUnit || 'day' |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio value="day">天</Radio> |
| | | <Radio value="hour">小时</Radio> |
| | | <Radio value="minute">分钟</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/> |
| | | <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | |
| | | {getFieldDecorator('timeUnit', { |
| | | initialValue: config.timeUnit || 'day' |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio value="day">天</Radio> |
| | | <Radio value="hour">小时</Radio> |
| | | <Radio value="minute">分钟</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/> |
| | | <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | |
| | | {getFieldDecorator('timeUnit', { |
| | | initialValue: config.timeUnit || 'day' |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio value="day">天</Radio> |
| | | <Radio value="hour">小时</Radio> |
| | | <Radio value="minute">分钟</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/> |
| | | <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | |
| | | {getFieldDecorator('timeUnit', { |
| | | initialValue: config.timeUnit || 'day' |
| | | })( |
| | | <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> |
| | | <Radio value="day">天</Radio> |
| | | <Radio value="hour">小时</Radio> |
| | | <Radio value="minute">分钟</Radio> |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | |
| | | } |
| | | ] |
| | | })( |
| | | <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/> |
| | | <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | |
| | | }) |
| | | } else if (key === 'parentId') { |
| | | this.props.updateConfig({...config, parentId: value}) |
| | | } else if (key === 'timeUnit') { |
| | | this.props.updateConfig({...config, timeUnit: value}) |
| | | } else if (key === 'OpenType') { |
| | | this.props.updateConfig({...config, OpenType: value}) |
| | | } else if (key === 'hidden') { |