mirror of
https://gitee.com/antv/g6.git
synced 2024-11-30 02:38:20 +08:00
feat: basic style(light version) for edges and combos
This commit is contained in:
parent
7f2a28dd19
commit
93973b80dc
@ -33,34 +33,34 @@ const graph = new G6.Graph({
|
||||
fitCenter: true,
|
||||
// Set groupByTypes to false to get rendering result with reasonable visual zIndex for combos
|
||||
groupByTypes: false,
|
||||
defaultCombo: {
|
||||
type: 'circle',
|
||||
style: {
|
||||
lineWidth: 1,
|
||||
},
|
||||
labelCfg: {
|
||||
refY: 10,
|
||||
position: 'top',
|
||||
style: {
|
||||
fontSize: 18,
|
||||
},
|
||||
},
|
||||
},
|
||||
modes: {
|
||||
default: ['drag-canvas', 'drag-node', 'drag-combo', 'collapse-expand-combo'],
|
||||
},
|
||||
comboStateStyles: {
|
||||
// the style configurations for the hover state on the combo
|
||||
hover: {
|
||||
lineWidth: 3,
|
||||
},
|
||||
},
|
||||
nodeStateStyles: {
|
||||
// the hover configurations for the hover state on the node
|
||||
hover: {
|
||||
lineWidth: 3,
|
||||
defaultCombo: {
|
||||
type: 'circle',
|
||||
/* style for the keyShape */
|
||||
// style: {
|
||||
// lineWidth: 1,
|
||||
// },
|
||||
labelCfg: {
|
||||
/* label's offset to the keyShape */
|
||||
// refY: 10,
|
||||
/* label's position, options: center, top, bottom, left, right */
|
||||
position: 'top',
|
||||
/* label's style */
|
||||
// style: {
|
||||
// fontSize: 18,
|
||||
// },
|
||||
},
|
||||
},
|
||||
/* styles for different states, there are built-in styles for states: active, inactive, selected, highlight, disable */
|
||||
/* you can extend it or override it as you want */
|
||||
// comboStateStyles: {
|
||||
// active: {
|
||||
// fill: '#f00',
|
||||
// opacity: 0.5
|
||||
// },
|
||||
// },
|
||||
});
|
||||
|
||||
graph.data(data);
|
||||
@ -68,10 +68,19 @@ graph.render();
|
||||
|
||||
graph.on('combo:mouseenter', (evt) => {
|
||||
const { item } = evt;
|
||||
graph.setItemState(item, 'hover', true);
|
||||
graph.setItemState(item, 'active', true);
|
||||
});
|
||||
|
||||
graph.on('combo:mouseleave', (evt) => {
|
||||
const { item } = evt;
|
||||
graph.setItemState(item, 'hover', false);
|
||||
graph.setItemState(item, 'active', false);
|
||||
});
|
||||
graph.on('combo:click', (evt) => {
|
||||
const { item } = evt;
|
||||
graph.setItemState(item, 'selected', true);
|
||||
});
|
||||
graph.on('canvas:click', (evt) => {
|
||||
graph.getCombos().forEach(combo => {
|
||||
graph.clearItemStates(combo);
|
||||
});
|
||||
});
|
||||
|
@ -33,35 +33,36 @@ const graph = new G6.Graph({
|
||||
fitCenter: true,
|
||||
// Set groupByTypes to false to get rendering result with reasonable visual zIndex for combos
|
||||
groupByTypes: false,
|
||||
defaultCombo: {
|
||||
type: 'rect',
|
||||
size: [50, 50], // Combo 的最小大小
|
||||
style: {
|
||||
lineWidth: 1,
|
||||
},
|
||||
labelCfg: {
|
||||
refY: 10,
|
||||
position: 'top',
|
||||
style: {
|
||||
fontSize: 18,
|
||||
},
|
||||
},
|
||||
},
|
||||
modes: {
|
||||
default: ['drag-canvas', 'drag-node', 'drag-combo', 'collapse-expand-combo'],
|
||||
},
|
||||
comboStateStyles: {
|
||||
// the style configurations for the hover state on the combo
|
||||
hover: {
|
||||
lineWidth: 3,
|
||||
},
|
||||
},
|
||||
nodeStateStyles: {
|
||||
// the hover configurations for the hover state on the node
|
||||
hover: {
|
||||
lineWidth: 3,
|
||||
defaultCombo: {
|
||||
type: 'rect',
|
||||
/* The minimum size of the combo. combo 最小大小 */
|
||||
size: [50, 50],
|
||||
/* style for the keyShape */
|
||||
// style: {
|
||||
// lineWidth: 1,
|
||||
// },
|
||||
labelCfg: {
|
||||
/* label's offset to the keyShape */
|
||||
// refY: 10,
|
||||
/* label's position, options: center, top, bottom, left, right */
|
||||
position: 'top',
|
||||
/* label's style */
|
||||
// style: {
|
||||
// fontSize: 18,
|
||||
// },
|
||||
},
|
||||
},
|
||||
/* styles for different states, there are built-in styles for states: active, inactive, selected, highlight, disable */
|
||||
/* you can extend it or override it as you want */
|
||||
// comboStateStyles: {
|
||||
// active: {
|
||||
// fill: '#f00',
|
||||
// opacity: 0.5
|
||||
// },
|
||||
// },
|
||||
});
|
||||
|
||||
graph.data(data);
|
||||
@ -69,10 +70,19 @@ graph.render();
|
||||
|
||||
graph.on('combo:mouseenter', (evt) => {
|
||||
const { item } = evt;
|
||||
graph.setItemState(item, 'hover', true);
|
||||
graph.setItemState(item, 'active', true);
|
||||
});
|
||||
|
||||
graph.on('combo:mouseleave', (evt) => {
|
||||
const { item } = evt;
|
||||
graph.setItemState(item, 'hover', false);
|
||||
graph.setItemState(item, 'active', false);
|
||||
});
|
||||
graph.on('combo:click', (evt) => {
|
||||
const { item } = evt;
|
||||
graph.setItemState(item, 'selected', true);
|
||||
});
|
||||
graph.on('canvas:click', (evt) => {
|
||||
graph.getCombos().forEach(combo => {
|
||||
graph.clearItemStates(combo);
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
// window.g6 = require('./src/index.ts'); // import the source for debugging
|
||||
window.g6 = require('./dist/g6.min.js'); // import the package for webworker
|
||||
window.g6 = require('./src/index.ts'); // import the source for debugging
|
||||
// window.g6 = require('./dist/g6.min.js'); // import the package for webworker
|
||||
window.insertCss = require('insert-css');
|
||||
window.Chart = require('@antv/chart-node-g6');
|
||||
|
@ -72,9 +72,6 @@ export default {
|
||||
fill: colorSet.inactiveFill,
|
||||
stroke: colorSet.inactiveStroke,
|
||||
lineWidth: 1,
|
||||
'text-shape': {
|
||||
fontWeight: 500
|
||||
}
|
||||
},
|
||||
disable: {
|
||||
fill: colorSet.disableFill,
|
||||
@ -87,21 +84,55 @@ export default {
|
||||
fill: textColor,
|
||||
textAlign: 'center',
|
||||
textBaseline: 'middle',
|
||||
fontSize: 12,
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
type: 'line',
|
||||
style: {
|
||||
stroke: disableColor,
|
||||
stroke: colorSet.edgeMainStroke,
|
||||
lineAppendWidth: 4,
|
||||
},
|
||||
size: 1,
|
||||
color: disableColor,
|
||||
color: colorSet.edgeMainStroke,
|
||||
},
|
||||
// 边应用状态后的样式,默认仅提供 active、selected、highlight、inactive、disable,用户可以自己扩展
|
||||
edgeStateStyles: {
|
||||
active: {
|
||||
stroke: colorSet.edgeActiveStroke,
|
||||
lineWidth: 1,
|
||||
},
|
||||
selected: {
|
||||
stroke: colorSet.edgeSelectedStroke,
|
||||
lineWidth: 2,
|
||||
shadowColor: colorSet.edgeSelectedStroke,
|
||||
shadowBlur: 10,
|
||||
'text-shape': {
|
||||
fontWeight: 500
|
||||
},
|
||||
},
|
||||
highlight: {
|
||||
stroke: colorSet.edgeHighlightStroke,
|
||||
lineWidth: 2,
|
||||
'text-shape': {
|
||||
fontWeight: 500
|
||||
}
|
||||
},
|
||||
inactive: {
|
||||
stroke: colorSet.edgeInactiveStroke,
|
||||
lineWidth: 1,
|
||||
},
|
||||
disable: {
|
||||
stroke: colorSet.edgeDisableStroke,
|
||||
lineWidth: 1,
|
||||
},
|
||||
},
|
||||
comboLabel: {
|
||||
style: {
|
||||
fill: textColor,
|
||||
// textAlign: 'center',
|
||||
textBaseline: 'middle',
|
||||
fontSize: 12,
|
||||
},
|
||||
refY: 10, // Combo 的默认文本不居中时的偏移量
|
||||
refX: 10, // Combo 的默认文本不居中时的偏移量
|
||||
@ -109,18 +140,53 @@ export default {
|
||||
defaultCombo: {
|
||||
type: 'circle',
|
||||
style: {
|
||||
fill: '#F3F9FF',
|
||||
fill: colorSet.comboMainFill,
|
||||
lineWidth: 1,
|
||||
stroke: '#A3B1BF',
|
||||
opacity: 0.8,
|
||||
stroke: colorSet.comboMainStroke,
|
||||
r: 5,
|
||||
width: 20,
|
||||
height: 10,
|
||||
},
|
||||
size: [20, 5],
|
||||
color: '#A3B1BF',
|
||||
color: colorSet.comboMainStroke,
|
||||
padding: [25, 20, 15, 20],
|
||||
},
|
||||
// combo 应用状态后的样式,默认仅提供 active、selected、highlight、inactive、disable,用户可以自己扩展
|
||||
comboStateStyles: {
|
||||
active: {
|
||||
stroke: colorSet.comboActiveStroke,
|
||||
lineWidth: 1,
|
||||
fill: colorSet.comboActiveFill,
|
||||
},
|
||||
selected: {
|
||||
stroke: colorSet.comboSelectedStroke,
|
||||
lineWidth: 2,
|
||||
fill: colorSet.comboSelectedFill,
|
||||
shadowColor: colorSet.comboSelectedStroke,
|
||||
shadowBlur: 10,
|
||||
'text-shape': {
|
||||
fontWeight: 500
|
||||
},
|
||||
},
|
||||
highlight: {
|
||||
stroke: colorSet.comboHighlightStroke,
|
||||
lineWidth: 2,
|
||||
fill: colorSet.comboHighlightFill,
|
||||
'text-shape': {
|
||||
fontWeight: 500
|
||||
}
|
||||
},
|
||||
inactive: {
|
||||
stroke: colorSet.comboInactiveStroke,
|
||||
fill: colorSet.comboInactiveFill,
|
||||
lineWidth: 1,
|
||||
},
|
||||
disable: {
|
||||
stroke: colorSet.comboDisableStroke,
|
||||
fill: colorSet.comboDisableFill,
|
||||
lineWidth: 1,
|
||||
},
|
||||
},
|
||||
delegateStyle: {
|
||||
fill: '#F3F9FF',
|
||||
fillOpacity: 0.5,
|
||||
|
@ -24,7 +24,7 @@ export default class Combo extends Node implements ICombo {
|
||||
public getShapeCfg(model: ComboConfig): ComboConfig {
|
||||
const styles = this.get('styles');
|
||||
const bbox = this.get('bbox');
|
||||
if (styles) {
|
||||
if (styles && bbox) {
|
||||
// merge graph的item样式与数据模型中的样式
|
||||
const newModel = model;
|
||||
const size = {
|
||||
|
@ -101,8 +101,10 @@ export default class ItemBase implements IItemBase {
|
||||
const model = this.get('model');
|
||||
let { id } = model;
|
||||
|
||||
const itemType = this.get('type');
|
||||
|
||||
if (!id) {
|
||||
id = uniqueId(this.get('type'));
|
||||
id = uniqueId(itemType);
|
||||
this.get('model').id = id;
|
||||
}
|
||||
|
||||
@ -117,7 +119,7 @@ export default class ItemBase implements IItemBase {
|
||||
this.init();
|
||||
this.draw();
|
||||
|
||||
const shapeType = (model.shape as string) || (model.type as string) || 'circle';
|
||||
const shapeType = (model.shape as string) || (model.type as string) || (itemType === 'edge' ? 'line' : 'circle');
|
||||
const shapeFactory = this.get('shapeFactory');
|
||||
if (shapeFactory && shapeFactory[shapeType]) {
|
||||
const { options } = shapeFactory[shapeType];
|
||||
@ -384,7 +386,6 @@ export default class ItemBase implements IItemBase {
|
||||
public setState(state: string, value: string | boolean) {
|
||||
const states: string[] = this.get('states');
|
||||
const shapeFactory = this.get('shapeFactory');
|
||||
// debugger
|
||||
let stateName = state;
|
||||
let filterStateName = state;
|
||||
if (isString(value)) {
|
||||
|
@ -27,6 +27,23 @@ const singleCombo: ShapeOptions = {
|
||||
*/
|
||||
refX: Global.comboLabel.refX,
|
||||
refY: Global.comboLabel.refY,
|
||||
|
||||
options: {
|
||||
style: {
|
||||
stroke: Global.defaultCombo.style.stroke,
|
||||
fill: Global.defaultCombo.style.fill,
|
||||
lineWidth: Global.defaultCombo.style.lineWidth
|
||||
},
|
||||
labelCfg: {
|
||||
style: {
|
||||
fill: Global.comboLabel.style.fill,
|
||||
fontSize: Global.comboLabel.style.fontSize,
|
||||
},
|
||||
},
|
||||
stateStyles: {
|
||||
...Global.comboStateStyles
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 获取 Combo 宽高
|
||||
* @internal 返回 Combo 的大小,以 [width, height] 的方式维护
|
||||
|
@ -19,15 +19,18 @@ Shape.registerCombo(
|
||||
stroke: Global.defaultCombo.style.stroke,
|
||||
fill: Global.defaultCombo.style.fill,
|
||||
lineWidth: Global.defaultCombo.style.lineWidth,
|
||||
opacity: 0.8,
|
||||
},
|
||||
labelCfg: {
|
||||
style: {
|
||||
fill: '#595959',
|
||||
fill: Global.comboLabel.style.fill,
|
||||
fontSize: Global.comboLabel.style.fontSize,
|
||||
},
|
||||
refX: 0,
|
||||
refY: 0,
|
||||
},
|
||||
stateStyles: {
|
||||
...Global.comboStateStyles
|
||||
}
|
||||
},
|
||||
shapeType: 'circle',
|
||||
// 文本位置
|
||||
|
@ -18,13 +18,13 @@ Shape.registerCombo(
|
||||
radius: 0,
|
||||
stroke: Global.defaultCombo.style.stroke,
|
||||
fill: Global.defaultCombo.style.fill,
|
||||
lineWidth: Global.defaultCombo.style.lineWidth,
|
||||
fillOpacity: 1,
|
||||
lineWidth: Global.defaultCombo.style.lineWidth
|
||||
},
|
||||
// 文本样式配置
|
||||
labelCfg: {
|
||||
style: {
|
||||
fill: '#595959',
|
||||
fill: Global.comboLabel.style.fill,
|
||||
fontSize: Global.comboLabel.style.fontSize,
|
||||
},
|
||||
},
|
||||
// 连接点,默认为左右
|
||||
@ -32,6 +32,9 @@ Shape.registerCombo(
|
||||
[0, 0.5],
|
||||
[1, 0.5],
|
||||
],
|
||||
stateStyles: {
|
||||
...Global.comboStateStyles
|
||||
}
|
||||
},
|
||||
shapeType: 'rect',
|
||||
labelPosition: 'top',
|
||||
|
@ -55,6 +55,26 @@ const singleEdge: ShapeOptions = {
|
||||
* @type {Boolean}
|
||||
*/
|
||||
labelAutoRotate: false,
|
||||
|
||||
// 自定义边时的配置
|
||||
options: {
|
||||
size: Global.defaultEdge.size,
|
||||
style: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
stroke: Global.defaultEdge.style.stroke,
|
||||
lineWidth: Global.defaultEdge.style.lineWidth
|
||||
},
|
||||
labelCfg: {
|
||||
style: {
|
||||
fill: Global.edgeLabel.style.fill,
|
||||
fontSize: Global.edgeLabel.style.fontSize,
|
||||
},
|
||||
},
|
||||
stateStyles: {
|
||||
...Global.edgeStateStyles
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 获取边的 path
|
||||
* @internal 供扩展的边覆盖
|
||||
|
@ -15,16 +15,20 @@ Shape.registerEdge(
|
||||
{
|
||||
options: {
|
||||
color: Global.defaultEdge.color,
|
||||
size: Global.defaultEdge.size,
|
||||
style: {
|
||||
radius: 0,
|
||||
offset: 15,
|
||||
x: 0,
|
||||
y: 0,
|
||||
stroke: Global.defaultEdge.style.stroke,
|
||||
lineWidth: Global.defaultEdge.style.lineWidth
|
||||
},
|
||||
// 文本样式配置
|
||||
labelCfg: {
|
||||
style: {
|
||||
fill: Global.edgeLabel.style.fill,
|
||||
fontSize: Global.edgeLabel.style.fontSize,
|
||||
},
|
||||
},
|
||||
routeCfg: {
|
||||
@ -33,6 +37,9 @@ Shape.registerEdge(
|
||||
maximumLoops: 1000,
|
||||
gridSize: 10, // 指定精度
|
||||
},
|
||||
stateStyles: {
|
||||
...Global.edgeStateStyles
|
||||
}
|
||||
},
|
||||
shapeType: 'polyline',
|
||||
// 文本位置
|
||||
|
@ -41,6 +41,34 @@ export const getColorsWithSubjectColor = (subjectColor, backColor = '#fff', disa
|
||||
highlightFill: mixColor(backColor, subjectColor, 0.2).rgb().toString(),
|
||||
|
||||
disableStroke: mixColor(backColor, disableColor, 0.3).rgb().toString(),
|
||||
disableFill: mixColor(backColor, disableColor, 0.05).rgb().toString()
|
||||
disableFill: mixColor(backColor, disableColor, 0.05).rgb().toString(),
|
||||
|
||||
|
||||
edgeMainStroke: disableColor,
|
||||
edgeActiveStroke: subjectColor,
|
||||
edgeInactiveStroke: mixColor(backColor, disableColor, 0.2).rgb().toString(),
|
||||
edgeSelectedStroke: subjectColor,
|
||||
edgeHighlightStroke: subjectColor,
|
||||
edgeDisableStroke: mixColor(backColor, disableColor, 0.1).rgb().toString(),
|
||||
|
||||
|
||||
comboMainStroke: mixColor(backColor, disableColor, 0.3).rgb().toString(),
|
||||
comboMainFill: mixColor(backColor, disableColor, 0.02).rgb().toString(),
|
||||
|
||||
comboActiveStroke: subjectColor,
|
||||
comboActiveFill: lightSubject,
|
||||
|
||||
comboInactiveStroke: mixColor(backColor, disableColor, 0.3).rgb().toString(),
|
||||
comboInactiveFill: mixColor(backColor, disableColor, 0.02).rgb().toString(),
|
||||
|
||||
comboSelectedStroke: subjectColor,
|
||||
comboSelectedFill: mixColor(backColor, disableColor, 0.02).rgb().toString(),
|
||||
|
||||
comboHighlightStroke: 'rgb(53, 119, 222)', // TODO: how to generate it ???
|
||||
comboHighlightFill: mixColor(backColor, disableColor, 0.02).rgb().toString(),
|
||||
|
||||
comboDisableStroke: mixColor(backColor, disableColor, 0.2).rgb().toString(),
|
||||
comboDisableFill: mixColor(backColor, disableColor, 0.05).rgb().toString(),
|
||||
|
||||
}
|
||||
}
|
@ -51,7 +51,7 @@ describe('graph state controller', () => {
|
||||
setTimeout(() => {
|
||||
expect(graphCount).toBe(1);
|
||||
done();
|
||||
}, 16);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it('state with activate-relations', done => {
|
||||
|
@ -1208,12 +1208,12 @@ describe('mapper fn', () => {
|
||||
expect(keyShape.attr('fillOpacity')).toEqual(1);
|
||||
|
||||
graph.setItemState(edge, 'selected', true);
|
||||
expect(keyShape.attr('stroke')).toEqual('rgb(150, 150, 150)');
|
||||
expect(keyShape.attr('stroke')).toEqual('rgb(95, 149, 255)');
|
||||
expect(keyShape.attr('lineWidth')).toEqual(2);
|
||||
expect(keyShape.attr('fillOpacity')).toEqual(1);
|
||||
|
||||
graph.setItemState(edge, 'custom', true);
|
||||
expect(keyShape.attr('stroke')).toEqual('rgb(150, 150, 150)');
|
||||
expect(keyShape.attr('stroke')).toEqual('rgb(95, 149, 255)');
|
||||
expect(keyShape.attr('lineWidth')).toEqual(2);
|
||||
expect(keyShape.attr('opacity')).toEqual(0.5);
|
||||
});
|
||||
|
@ -1290,7 +1290,7 @@ describe('behaviors', () => {
|
||||
expect(unrelativeNodeKeyShape.attr('opacity')).toBe(0.1);
|
||||
const unrelativeEdge = graph.getEdges()[1];
|
||||
const unrelativeEdgeKeyShape = unrelativeEdge.get('group').get('children')[0];
|
||||
expect(unrelativeEdgeKeyShape.attr('stroke')).toBe('rgb(150, 150, 150)');
|
||||
expect(unrelativeEdgeKeyShape.attr('stroke')).toBe('rgb(234, 234, 234)');
|
||||
expect(unrelativeEdgeKeyShape.attr('opacity')).toBe(0.1);
|
||||
|
||||
graph.emit('node:mouseleave', { item });
|
||||
|
@ -523,12 +523,13 @@ describe('shape edge test', () => {
|
||||
const edge = graph.getEdges()[0];
|
||||
const path = edge.get('group').get('children')[0];
|
||||
let bbox = path.getBBox();
|
||||
expect(bbox.minX).toEqual(91.60845891791658);
|
||||
console.log(bbox);
|
||||
expect(bbox.minX).toEqual(89.60845891791658);
|
||||
graph.emit('node:dragstart', { x: 100, y: 100, item: node });
|
||||
graph.emit('node:drag', { x: 200, y: 200, item: node });
|
||||
graph.emit('node:dragend', { x: 200, y: 200, item: node });
|
||||
bbox = path.getBBox();
|
||||
expect(bbox.minX).toEqual(191.6084589179166);
|
||||
expect(bbox.minX).toEqual(189.6084589179166);
|
||||
});
|
||||
|
||||
it('clear', () => {
|
||||
|
@ -141,6 +141,7 @@ describe('graph edge states', () => {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 20,
|
||||
lineWidth: 10
|
||||
},
|
||||
},
|
||||
defaultEdge: {
|
||||
|
Loading…
Reference in New Issue
Block a user