custom icons in diagram definition
This commit is contained in:
@@ -193,7 +193,7 @@ Array of object as following:
|
|||||||
| Key | Type | Required | Info |
|
| Key | Type | Required | Info |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| **`name`** | string | **yes** | used in links to reference nodes |
|
| **`name`** | string | **yes** | used in links to reference nodes |
|
||||||
| **`icon`** | string | **yes** | name of the Font-Awesome icon of the node (see [Icon names](#icon-names)) |
|
| **`icon`** | string/object | **yes** | name of the Font-Awesome icon of the node (see [Icon names](#icon-names)) |
|
||||||
| `top`, `bottom`, `left`, `right` | string or object | no | see [Sub-elements](#sub-elements) |
|
| `top`, `bottom`, `left`, `right` | string or object | no | see [Sub-elements](#sub-elements) |
|
||||||
| `color` | string | no | redefined the color |
|
| `color` | string | no | redefined the color |
|
||||||
| `scale` | number | no | redefine this node icon scale |
|
| `scale` | number | no | redefine this node icon scale |
|
||||||
@@ -236,7 +236,7 @@ You can define a relative icon with the following:
|
|||||||
|
|
||||||
| Key | Type | Required | Info |
|
| Key | Type | Required | Info |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| **`icon`** | string | **yes** | name of the Font-Awesome icon of the sub-element (see [Icon names](#icon-names)) |
|
| **`icon`** | string/object | **yes** | name of the Font-Awesome icon of the sub-element (see [Icon names](#icon-names)) |
|
||||||
| `color` | string | no | redefine the color |
|
| `color` | string | no | redefine the color |
|
||||||
| `scale` | number | no | redefine this icon scale |
|
| `scale` | number | no | redefine this icon scale |
|
||||||
|
|
||||||
@@ -250,6 +250,15 @@ When you reference an icon, for example `circle`, it's searched in the `solid` f
|
|||||||
If, in this case you want the hollow circle from the regular style, just enter `regular circle` or `circle regular` instead.
|
If, in this case you want the hollow circle from the regular style, just enter `regular circle` or `circle regular` instead.
|
||||||
It's very flexible as you can copy-paste from an HTML page `far fa-circle` and it will also works.
|
It's very flexible as you can copy-paste from an HTML page `far fa-circle` and it will also works.
|
||||||
|
|
||||||
|
|
||||||
|
You can also specify a custom icon by entering the following object instead of a string:
|
||||||
|
|
||||||
|
| Key | Type | Required | Info |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| **`path`** | string | **yes** | the SVG path of your icon |
|
||||||
|
| `width` | string | no | the custom width of the path (if blank, height is taken, then the height of all icons: 512) |
|
||||||
|
| `height` | string | no | the custom height of the path (if blank, width is taken) |
|
||||||
|
|
||||||
### Link types
|
### Link types
|
||||||
|
|
||||||
Here are the accepted types and their preview :
|
Here are the accepted types and their preview :
|
||||||
|
|||||||
+33
-13
@@ -25,7 +25,7 @@ try {
|
|||||||
* @property {string} name
|
* @property {string} name
|
||||||
* @property {number} x
|
* @property {number} x
|
||||||
* @property {number} y
|
* @property {number} y
|
||||||
* @property {string} icon
|
* @property {string|{path:string,width:number:height:number}} icon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +38,12 @@ try {
|
|||||||
const SUB_DEF = {
|
const SUB_DEF = {
|
||||||
'_': 'string',
|
'_': 'string',
|
||||||
'text': 'string',
|
'text': 'string',
|
||||||
'icon': 'string',
|
'icon': {
|
||||||
|
'_': 'string',
|
||||||
|
'path': 'string',
|
||||||
|
'width': 'number',
|
||||||
|
'height': 'number'
|
||||||
|
},
|
||||||
'color': 'string',
|
'color': 'string',
|
||||||
'font': 'string',
|
'font': 'string',
|
||||||
'font-size': 'number',
|
'font-size': 'number',
|
||||||
@@ -48,7 +53,12 @@ const SUB_DEF = {
|
|||||||
|
|
||||||
const NODE_DEF = {
|
const NODE_DEF = {
|
||||||
'name': '!string',
|
'name': '!string',
|
||||||
'icon': '!string',
|
'icon': {
|
||||||
|
'_': 'string',
|
||||||
|
'path': 'string',
|
||||||
|
'width': 'number',
|
||||||
|
'height': 'number'
|
||||||
|
},
|
||||||
'x': '!number',
|
'x': '!number',
|
||||||
'y': '!number',
|
'y': '!number',
|
||||||
'color': 'string',
|
'color': 'string',
|
||||||
@@ -110,16 +120,25 @@ module.exports = (options) => {
|
|||||||
const self = {
|
const self = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find icon data from given name
|
* Find icon data from given name or data
|
||||||
* @param {string} name
|
* @param {string|{path: string, width: number, height: number}} icon
|
||||||
* @returns {null|{path: string, width: number}}
|
* @returns {null|{path: string, width: number, height: number}}
|
||||||
*/
|
*/
|
||||||
getIcon: (name) => {
|
getIcon: (icon) => {
|
||||||
if (!name || !name.trim())
|
if (!icon)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (typeof icon === 'object') {
|
||||||
|
icon.height = icon.height || icon.width || resources.height;
|
||||||
|
icon.width = icon.width || icon.height;
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!icon.trim())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
let search = utils.ezClone(resources.index);
|
let search = utils.ezClone(resources.index);
|
||||||
const spl = name.trim().split(' ').map(t => t.indexOf('fa-') === 0 ? t.substr(3) : t);
|
const spl = icon.trim().split(' ').map(t => t.indexOf('fa-') === 0 ? t.substr(3) : t);
|
||||||
|
|
||||||
for (let i = 0; i < spl.length; i++) {
|
for (let i = 0; i < spl.length; i++) {
|
||||||
//replace fas by regular for example
|
//replace fas by regular for example
|
||||||
@@ -131,11 +150,12 @@ module.exports = (options) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
name = spl[0];
|
icon = spl[0];
|
||||||
|
|
||||||
for (let i = 0; i < search.length; i++) {
|
for (let i = 0; i < search.length; i++) {
|
||||||
if (resources.icons[search[i]] && resources.icons[search[i]][name]) {
|
if (resources.icons[search[i]] && resources.icons[search[i]][icon]) {
|
||||||
return resources.icons[search[i]][name];
|
resources.icons[search[i]][icon].height = resources.height;
|
||||||
|
return resources.icons[search[i]][icon];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +236,7 @@ module.exports = (options) => {
|
|||||||
},
|
},
|
||||||
'g': {
|
'g': {
|
||||||
'_attributes': {
|
'_attributes': {
|
||||||
'transform': `scale(${scale / resources.height} ${scale / resources.height}) translate(${-icon.width / 2} ${-resources.height / 2})`,
|
'transform': `scale(${scale / icon.height} ${scale / icon.height}) translate(${-icon.width / 2} ${-icon.height / 2})`,
|
||||||
'stroke': (node['color'] || options['icons']['color'] || undefined),
|
'stroke': (node['color'] || options['icons']['color'] || undefined),
|
||||||
'fill': (node['color'] || options['icons']['color'] || undefined)
|
'fill': (node['color'] || options['icons']['color'] || undefined)
|
||||||
},
|
},
|
||||||
|
|||||||
+60
-8
@@ -61,56 +61,64 @@ describe('getIcon', () => {
|
|||||||
const res = rendering().getIcon('circle');
|
const res = rendering().getIcon('circle');
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
path: solidCirclePath,
|
path: solidCirclePath,
|
||||||
width: 512
|
width: 512,
|
||||||
|
height: 512
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('valid circle alt name', () => {
|
test('valid circle alt name', () => {
|
||||||
const res = rendering().getIcon('fa-circle');
|
const res = rendering().getIcon('fa-circle');
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
path: solidCirclePath,
|
path: solidCirclePath,
|
||||||
width: 512
|
width: 512,
|
||||||
|
height: 512
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('ignored other name', () => {
|
test('ignored other name', () => {
|
||||||
const res = rendering().getIcon('circle server');
|
const res = rendering().getIcon('circle server');
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
path: solidCirclePath,
|
path: solidCirclePath,
|
||||||
width: 512
|
width: 512,
|
||||||
|
height: 512
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('forcing regular', () => {
|
test('forcing regular', () => {
|
||||||
const res = rendering().getIcon('far circle');
|
const res = rendering().getIcon('far circle');
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
path: regularCirclePath,
|
path: regularCirclePath,
|
||||||
width: 512
|
width: 512,
|
||||||
|
height: 512
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('forcing regular 2', () => {
|
test('forcing regular 2', () => {
|
||||||
const res = rendering().getIcon('regular circle');
|
const res = rendering().getIcon('regular circle');
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
path: regularCirclePath,
|
path: regularCirclePath,
|
||||||
width: 512
|
width: 512,
|
||||||
|
height: 512
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('forcing regular 3', () => {
|
test('forcing regular 3', () => {
|
||||||
const res = rendering().getIcon('circle far');
|
const res = rendering().getIcon('circle far');
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
path: regularCirclePath,
|
path: regularCirclePath,
|
||||||
width: 512
|
width: 512,
|
||||||
|
height: 512
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('double type', () => {
|
test('double type', () => {
|
||||||
const res = rendering().getIcon('circle far solid');
|
const res = rendering().getIcon('circle far solid');
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
path: regularCirclePath,
|
path: regularCirclePath,
|
||||||
width: 512
|
width: 512,
|
||||||
|
height: 512
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('double type 2', () => {
|
test('double type 2', () => {
|
||||||
const res = rendering().getIcon('circle solid far');
|
const res = rendering().getIcon('circle solid far');
|
||||||
expect(res).toEqual({
|
expect(res).toEqual({
|
||||||
path: solidCirclePath,
|
path: solidCirclePath,
|
||||||
width: 512
|
width: 512,
|
||||||
|
height: 512
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('forcing solid on brands icon', () => {
|
test('forcing solid on brands icon', () => {
|
||||||
@@ -119,6 +127,50 @@ describe('getIcon', () => {
|
|||||||
const res2 = rendering().getIcon('fas usb');
|
const res2 = rendering().getIcon('fas usb');
|
||||||
expect(res2).toBeNull();
|
expect(res2).toBeNull();
|
||||||
});
|
});
|
||||||
|
test('custom icon 1', () => {
|
||||||
|
const res = rendering().getIcon({
|
||||||
|
path: 'hello',
|
||||||
|
width: 80,
|
||||||
|
height: 160
|
||||||
|
});
|
||||||
|
expect(res).toEqual({
|
||||||
|
path: 'hello',
|
||||||
|
width: 80,
|
||||||
|
height: 160
|
||||||
|
});
|
||||||
|
});
|
||||||
|
test('custom icon 2', () => {
|
||||||
|
const res = rendering().getIcon({
|
||||||
|
path: 'hello',
|
||||||
|
width: 80
|
||||||
|
});
|
||||||
|
expect(res).toEqual({
|
||||||
|
path: 'hello',
|
||||||
|
width: 80,
|
||||||
|
height: 80
|
||||||
|
});
|
||||||
|
});
|
||||||
|
test('custom icon 3', () => {
|
||||||
|
const res = rendering().getIcon({
|
||||||
|
path: 'hello',
|
||||||
|
height: 160
|
||||||
|
});
|
||||||
|
expect(res).toEqual({
|
||||||
|
path: 'hello',
|
||||||
|
width: 160,
|
||||||
|
height: 160
|
||||||
|
});
|
||||||
|
});
|
||||||
|
test('custom icon 4', () => {
|
||||||
|
const res = rendering().getIcon({
|
||||||
|
path: 'hello'
|
||||||
|
});
|
||||||
|
expect(res).toEqual({
|
||||||
|
path: 'hello',
|
||||||
|
width: 512,
|
||||||
|
height: 512
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getLinkPath (non-regression)', () => {
|
describe('getLinkPath (non-regression)', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user