Skip to content

Commit

Permalink
*** Version V0.2.3 ***
Browse files Browse the repository at this point in the history
Markers exact positioning
Lint corrections
  • Loading branch information
sgateau committed Nov 13, 2020
1 parent 0103018 commit ed9ca0f
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 73 deletions.
22 changes: 10 additions & 12 deletions src/iotMapManager/iotMapManager.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
"anchored": true,
"plain": true
},
"size": {
"fullSvgWidth": 100,
"fullSvgHeight": 100,
"unselectedSvgWidth": 44,
"unselectedSvgHeight": 44,
"selectedSvgWidth": 64,
"selectedSvgHeight": 64,
"anchorHeight": 10
},

"circles": {
"borderColor": "white",
Expand All @@ -27,21 +36,10 @@

"poi": {
"borderColor": "white"
},

"size": {
"selected": {
"width": 100,
"height": 100
},
"unselected": {
"width": 40,
"height": 40
}
}
},
"cluster": {
"iconSize": 60,
"iconSize": 64,
"circleLayer": {
},
"squareLayer": {
Expand Down
32 changes: 19 additions & 13 deletions src/iotMapManager/iotMapManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Software Name : IotMapManager
* Version: 0.2.2
* Version: 0.2.3
* SPDX-FileCopyrightText: Copyright (c) 2020 Orange
* SPDX-License-Identifier: MIT
*
Expand Down Expand Up @@ -144,21 +144,24 @@ export class IotMapManager {
let content = cluster.layer._childCount + ' ' + cluster.target.options.clusterType + '(s) : <br>';
const tabDistribution: any = {};
const allChildMarkers = cluster.layer.getAllChildMarkers();
allChildMarkers.forEach( marker => {
allChildMarkers.forEach(marker => {
const markerColor = marker.markerInfo.shape.color;
if (tabDistribution[markerColor]) {
tabDistribution[markerColor] += 1;
} else {
tabDistribution[markerColor] = 1;
}
});

for (const color in tabDistribution) {
content += '<span style="color:' + color + '; font-size: 30px">&#x25CF; </span>' +
'<span style="color: black">' + tabDistribution[color] + ' marker(s) </span><br>';
if (tabDistribution[color]) {
content += '<span style="color:' + color + '; font-size: 30px">&#x25CF; </span>' +
'<span style="color: black">' + tabDistribution[color] + ' marker(s) </span><br>';
}
}

// create popup
const popup = L.popup({closeButton: false})
L.popup({closeButton: false})
.setLatLng(cluster.layer.getLatLng())
.setContent(content)
.openOn(this.map);
Expand Down Expand Up @@ -303,7 +306,7 @@ export class IotMapManager {
// marker Distribution
const tabDistribution: any = {};
const allChildMarkers = cluster.getAllChildMarkers();
allChildMarkers.forEach( marker => {
allChildMarkers.forEach(marker => {
const markerColor = marker.markerInfo.shape.color;
if (tabDistribution[markerColor]) {
tabDistribution[markerColor] += 1;
Expand All @@ -318,24 +321,27 @@ export class IotMapManager {
let angle = -90.0;
let arc = 0.0;
for (const color in tabDistribution) {
const n = tabDistribution[color];
arc = n * 1193 / childCount - (60 / childCount); // todo I DON'T KNOW WHY !!!
svgGauge += commonSvg.circleGauge + `stroke='` + color
+ `' stroke-dasharray='` + arc + `, 1193' transform='rotate(` + angle + ` 225 225)'/>`;
angle += n * 360 / childCount;
if (tabDistribution[color]) {
const n = tabDistribution[color];
arc = n * 1193 / childCount - (60 / childCount); // todo I DON'T KNOW WHY !!!
svgGauge += commonSvg.circleGauge + `stroke='` + color
+ `' stroke-dasharray='` + arc + `, 1193' transform='rotate(` + angle + ` 225 225)'/>`;
angle += n * 360 / childCount;
}
}


// tslint:disable:max-line-length
return new L.DivIcon({
html: `<svg xmlns='http://www.w3.org/2000/svg' width='` + size + `' height='` + size + `' viewBox='0 0 450 545'>`
+ `<path fill='white' d='M197 2.21h46c20.84-.18 51.79 8.71 71 16.94 25.45 10.9 49.03 26.7 69 45.89 12.7 12.21 25.89 29.81 35 44.96 46.3 77.02 41.96 173.09-8.34 247-16.66 24.48-38.69 45.13-63.66 60.95-27.28 17.28-70.4 34-103 34.05h-40c-16.83-.2-44.1-7.57-60-13.58C78.05 413.9 27.77 360.57 7.72 294 4.12 282.06.02 265.38 0 253v-52c.03-16.82 7.04-40.18 12.95-56C33.42 90.25 76.01 45.64 129 21.31c23.6-10.84 42.64-15.06 68-19.1zm17 30.07c-19.58 2.82-31.62 3.77-51 10.23-47.98 16-90.54 52.95-112.74 98.49C39.28 163.52 30.3 195.88 30 221c-1.01 86.54 53.52 165.06 137 190.72 15.49 4.76 35.8 9.09 52 9.28 31.6.37 58.09-5.85 87-18.42 18.54-8.07 40.75-24.35 55-38.58 51.31-51.25 70.58-124.64 49.02-194-3.21-10.35-8.2-23.51-13.33-33-13.66-25.27-31.11-46.02-53.69-63.79-18.95-14.92-39.04-25.1-62-32.23-19.38-6.03-46.79-10.58-67-8.7z'/>`
+ `<path fill='white' d='M200 77.15h41c23.72-.11 54 13.64 73 27.28 70.98 50.95 81.12 153.07 26.39 219.57-13.14 15.96-29.98 28.55-48.39 37.75-16.3 8.16-39.71 15.22-58 15.25h-21c-7.19-.09-18.88-2.39-26-4.13C135.54 360.31 94.8 320.6 79.72 270c-6.46-21.69-4.75-37.81-4.72-60 .02-15.57 6.83-36.12 13.75-50 22.96-46.01 61.12-73.33 111.25-82.85z'/>`
+ `<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-size="160" font-family='arial'>` + childCount + `</text>`
+ `<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-size="160" font-family='helvetica neue'>` + childCount + `</text>`
+ svgGauge
+ `</svg>`,
className: 'my-cluster-class',
iconSize: [size, size],
popupAnchor: [0, 0]
});
}
// tslint:enable:max-line-length
}
20 changes: 6 additions & 14 deletions src/iotMapManager/iotMapMarkers/iotCircleMarker.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Software Name : IotMapManager
* Version: 0.2.2
* Version: 0.2.3
* SPDX-FileCopyrightText: Copyright (c) 2020 Orange
* SPDX-License-Identifier: MIT
*
Expand All @@ -26,8 +26,8 @@ export class IotCircleMarker {
let svgGauge = '';

// sizing
const width = (selected) ? config.markers.size.selected.width : config.markers.size.unselected.width;
const height = (selected) ? config.markers.size.selected.height : config.markers.size.unselected.height;
const width = (selected) ? 64 : 44;
const height = (selected) ? 64 : 44;

// border color
const borderColor = (selected) ? marker.shape.color : config.markers.circles.borderColor;
Expand All @@ -41,27 +41,19 @@ export class IotCircleMarker {
// label
// todo : a revoir pour bien centrer
svgInnerDesign = (marker.inner.label) ? `<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle"
font-size="160" font-family='Arial' fill='` + marker.inner.color + `'>`
font-size="160" font-family='helvetica neue' fill='` + marker.inner.color + `'>`
+ marker.inner.label[0] + `</text>` : '';

// icon
// todo : import des icones solaris
/*fetch(marker.icon.svg)
.then(response => response.text())
.then((fileContent) => {
let start = fileContent.search('<path');
let fileLength = fileContent.length;
svgIcon = fileContent.substring(start, fileLength - 7);
alert(svgIcon)
})*/

if (marker.inner.icon === 'temp') {
svgInnerDesign = `<path fill='` + marker.inner.color
// tslint:disable-next-line:max-line-length
+ `' d='M216 103.52c26.69-4.23 45.96 11.06 46 38.48v113c.02 12.33 3.89 11.02 9.02 21 3.8 7.4 4.97 13.79 4.98 22v6c-.24 19.8-14.61 37.89-33 44.45-8.1 2.9-13.64 2.64-22 2.55-19.88-.24-37.87-14.54-44.45-33-2.9-8.1-2.64-13.64-2.55-22 .09-7.31 1.96-14.59 5.51-21 5.26-9.49 8.47-8.17 8.49-20V140c.21-17.92 10.56-31.8 28-36.48zm-12 80.32V262c-.03 12.59-4.14 9.61-10.12 20-4.99 8.68-6.01 18.4-3.39 28 9 32.97 55.73 34.79 68.04 3 3.9-10.06 2.96-21.66-2.41-31-5.98-10.39-10.09-7.41-10.12-20V142c-.01-5.76-.11-10.06-3.65-14.99-7.91-11.02-23.97-11.85-33.14-1.92-5.94 6.44-5.21 12.89-5.21 21.07 2.01-.16 7.31-.28 8.98 0 4.27 1.27 5.85 5.26 1.87 7.67-2.52 1.52-7.87 1.17-10.85 1.17v6c2.42 0 8.92-.25 10.85.6 2.94 1.29 3.47 4.58.83 6.38-2.11 1.43-8.94 1.02-11.68 1.02v6c2.98 0 8.33-.35 10.85 1.17 3.98 2.41 2.4 6.4-1.87 7.67-1.67.28-6.97.16-8.98 0zm19 13.73c11.08-.93 13.89 7.02 14 16.43v58c.03 15.93 9.99 10.67 9.99 28 0 10.24-5.6 19.07-15.99 21.47-17.48 4.04-31.51-9.99-27.47-27.47 2.71-11.75 9.44-7.72 9.47-22v-40c0-7.21-1.24-24.38 2.72-29.89 2.04-2.84 4.12-3.58 7.28-4.54z'/>
`;
}
if (marker.inner.icon === 'bat') {
svgInnerDesign = `<path fill='` + marker.inner.color
// tslint:disable-next-line:max-line-length
+ `' d='M133 168v-8c0-2.27-.22-5.66 1.02-7.61 1.77-2.78 13.36-7.38 16.98-9.13l51-23.52c4.9-2.36 19.34-9.93 24-9.49 3.19.31 11.45 4.62 15 6.17l36 16.8 27 12.47c3.18 1.46 10.15 3.83 11.98 6.7 1.59 2.49 1.02 12.24 1.02 15.61h50v17h-8v141h8v8h8v9H75v-9h8v-8h8V185h-8v-17h50zm138-18l-30-13.78-15-6.38-14 4.92L179 151h63c6.26 0 24.17.91 29-1zm-96 35h-16v133h16V185zm33 0h-16v133h16V185zm50 0h-16v133h16V185zm33 0h-16v133h16V185zm-150 17h-32v41h32v-41zm200 0h-32v41h32v-41zm-200 59h-32v40h32v-40zm200 0h-32v40h32v-40z'/>
`;
}
Expand Down
7 changes: 5 additions & 2 deletions src/iotMapManager/iotMapMarkers/iotMapCommonSvg.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Software Name : IotMapManager
* Version: 0.2.2
* Version: 0.2.3
* SPDX-FileCopyrightText: Copyright (c) 2020 Orange
* SPDX-License-Identifier: MIT
*
Expand All @@ -13,6 +13,7 @@
*/

// circle
// tslint:disable:max-line-length
export let circleAnchoredBorder = `d='M224 545l-37.33-56c-5.06-7.59-16.16-25.3-21.71-30.99-4.12-4.21-23.76-18.92-28.96-22.03l-21-10.29c-10.91-5.91-24.45-14.9-34-22.77C47.21 375.06 23.19 340.57 9.33 299 5.02 286.07.02 266.53 0 253v-54c.24-19.89 11.82-54.08 20.75-72C47.21 73.96 88.61 36.25 144 15.19c15.22-5.78 42.91-13 59-13.19 37.75-.44 60.4-1.33 97 11.69C372.89 39.63 427.7 100.26 444.42 176c2.62 11.83 5.44 28.99 5.58 41 .21 17.95-.39 34.26-3.61 52-9.71 53.41-38.38 100.57-80.39 134.74-9.2 7.49-24.45 17.56-35 23l-17.91 8.66-10.09 7.26c-3.26 2.14-6.86 3.99-9.72 6.67-12.34 11.56-20.02 24.78-29.28 38.67l-38 57h-2zm2-61l34.14-52 17.03-22.78c3.56-3.28 16.49-7.2 21.83-9.5 13.06-5.62 24.53-12.46 36-20.87 49.14-36.04 79.71-94.69 79-155.85-.27-22.9-7.68-51.03-16.72-72-9.28-21.51-23.74-41.48-40.28-58-30.41-30.37-67.59-48.24-110-54.13L228 37C140.56 35.98 62.36 97.43 41.13 182c-2.86 11.38-5.99 29.39-6.13 41-.71 61 29.41 118.72 78 155.11 7.82 5.86 22.17 15.09 31 19.03 5.77 2.57 20.98 7.89 24.71 11.25L184.08 427c11.74 14.14 31.01 41.13 39.92 57h2z'`;
export let circleAnchoredInnerColor = `d='M224 494c-9.25-16.48-31.71-48.3-43.92-63l-15.37-18.61c-3.3-2.94-18.44-8.28-23.71-10.7-9.82-4.51-24.38-13.77-33-20.34C57.31 342.64 29.26 284.59 30 221c.25-20.81 6.82-47.73 14.6-67 8.7-21.52 19.75-38.39 34.83-56C90.23 85.39 104.2 73.87 118 64.67c57.85-38.58 129.61-42.82 192-12.41 19.14 9.33 38.03 23.7 53 38.74 15.36 15.43 30.24 36.95 38.85 57 9.33 21.73 13.97 40.54 16.32 64l.83 9c.74 63.76-27.76 122.73-79 161.11-9.21 6.89-23.49 15.89-34 20.47-4.82 2.09-22.13 8.36-24.83 10.72L262.71 438 226 494h-2zm-26-43h-1l1 1v-1z'`;

Expand Down Expand Up @@ -42,5 +43,7 @@ export let sqrBorder = `<path fill='white' d='M34,28H66a6,6,0,0,1,6,6V66a6,6,0,0

// backgrounds
export let sqrFunBg = `<rect fill='white' x="29" y="29" width="42" height="42" rx="5.25" ry="5.25"/>`;
export let sqrPinFunBg = `d="M65,70H57.675a5,5,0,0,0-4.159,2.226L50,77.5l-3.516-5.274A5,5,0,0,0,42.325,70H35a5.015,5.015,0,0,1-5-5V35a5.015,5.015,0,0,1,5-5H65a5.015,5.015,0,0,1,5,5V65A5.015,5.015,0,0,1,65,70Z"`
export let sqrPinFunBg = `d="M65,70H57.675a5,5,0,0,0-4.159,2.226L50,77.5l-3.516-5.274A5,5,0,0,0,42.325,70H35a5.015,5.015,0,0,1-5-5V35a5.015,5.015,0,0,1,5-5H65a5.015,5.015,0,0,1,5,5V65A5.015,5.015,0,0,1,65,70Z"`;
export let sqrSelFunBg = `<rect fill='white' x="25" y="25" width="50" height="50" rx="3.125" ry="3.125"/>`;

// tslint:enable:max-line-length
27 changes: 18 additions & 9 deletions src/iotMapManager/iotMapMarkers/iotMapMarkers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Software Name : IotMapManager
* Version: 0.2.2
* Version: 0.2.3
* SPDX-FileCopyrightText: Copyright (c) 2020 Orange
* SPDX-License-Identifier: MIT
*
Expand Down Expand Up @@ -29,26 +29,35 @@ export class IotMapMarkers {
getMarker(marker, selected = false) {
let html = '';

// shape
// default values
if (!marker.shape) {
marker.shape = config.markers.default;
}

// only anchored markers can be selected
if (!marker.shape.anchored) {
selected = false;
}

if (marker.shape.shape === 'circle') {
html = this.iotCircleMarker.getSvg(marker, selected);
} else if (marker.shape.shape === 'poi' || marker.shape.shape === 'square') {
html = this.iotSquareMarker.getSvg(marker, selected);
}

// sizing
const iconSize: L.Point = L.point(100, 100);
const size = config.markers.size;
const iconSize: L.Point = L.point(size.fullSvgWidth, size.fullSvgHeight);

const iconAnchor: L.Point = (marker.shape.anchored)
? L.point(iconSize.x / 2, iconSize.y)
: L.point(iconSize.x / 2, iconSize.y / 2);
let iconAnchor: L.Point = L.point(size.fullSvgWidth / 2, size.fullSvgHeight / 2); // by default = center
if (marker.shape.anchored) {
const height = (size.fullSvgHeight + ((selected) ? size.selectedSvgHeight : size.unselectedSvgHeight)) / 2 + size.anchorHeight;
iconAnchor = L.point(size.fullSvgWidth / 2, height);
}

const popupAnchor: L.Point = (marker.shape.anchored)
? L.point(0, -iconSize.y)
: L.point(0, -iconSize.y / 2);
const popupAnchor: L.Point = (selected)
? L.point(0, - (size.selectedSvgHeight + size.anchorHeight)) // from anchor point
: L.point(0, - (size.unselectedSvgHeight / 2)); // from center point

// creating icon
return L.divIcon({
Expand Down
27 changes: 13 additions & 14 deletions src/iotMapManager/iotMapMarkers/iotSquareMarker.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Software Name : IotMapManager
* Version: 0.2.2
* Version: 0.2.3
* SPDX-FileCopyrightText: Copyright (c) 2020 Orange
* SPDX-License-Identifier: MIT
*
Expand All @@ -22,34 +22,33 @@ export class IotSquareMarker {
let svgBorder = '';
let shadowFile = '';

if (selected) {
// todo anchored ?
if (marker.shape.shape == 'poi' || marker.shape.plain) { // STD
svgShape = `<path fill='`+ marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrSelStdColour + `/>`;
if (selected) { // Only anchored markers can be selected
if (marker.shape.shape === 'poi' || marker.shape.plain) { // STD
svgShape = `<path fill='` + marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrSelStdColour + `/>`;
} else { // FUN
svgShape = `<path fill='`+ marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrSelFunColour + `/>`;
svgShape = `<path fill='` + marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrSelFunColour + `/>`;
svgBG = commonSvg.sqrSelFunBg;
}
shadowFile = 'assets/img/POI_SQR_SEL_Shadow.png';
} else if (marker.shape.shape == 'poi' || marker.shape.plain) { // STD
} else if (marker.shape.shape === 'poi' || marker.shape.plain) { // STD
if (marker.shape.anchored) {
svgBorder = commonSvg.sqrPinBorder;
svgShape = `<path fill='`+ marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrPinStdColour + `/>`;
svgShape = `<path fill='` + marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrPinStdColour + `/>`;
shadowFile = 'assets/img/POI_SQR_PIN_Shadow.png';
} else {
} else { // FUN
svgBorder = commonSvg.sqrBorder;
svgShape = `<rect fill='`+ marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrStdColour + `/>`;
svgShape = `<rect fill='` + marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrStdColour + `/>`;
shadowFile = 'assets/img/POI_SQR_Shadow.png';
}
} else { // FUN
if (marker.shape.anchored) {
svgBorder = commonSvg.sqrPinBorder;
svgShape = `<path fill='`+ marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrPinFunColour + `/>`;
svgShape = `<path fill='` + marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrPinFunColour + `/>`;
svgBG = `<path fill='white' fill-rule='evenodd' ` + commonSvg.sqrPinFunBg + `/>`;
shadowFile = 'assets/img/POI_SQR_PIN_Shadow.png';
} else {
svgBorder = commonSvg.sqrBorder;
svgShape = `<path fill='`+ marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrFunColour + `/>`;
svgShape = `<path fill='` + marker.shape.color + `' fill-rule='evenodd' ` + commonSvg.sqrFunColour + `/>`;
svgBG = commonSvg.sqrFunBg;
shadowFile = 'assets/img/POI_SQR_Shadow.png';
}
Expand All @@ -61,7 +60,7 @@ export class IotSquareMarker {
if (marker.inner) {
// todo : à revoir pour bien centrer
svgInnerDesign = (marker.inner.label) ? `<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle"
font-size="20" font-family='Arial' fill='` + marker.inner.color + `'>`
font-size="20" font-family='helvetica neue' fill='` + marker.inner.color + `'>`
+ marker.inner.label[0] + `</text>` : '';

// icon
Expand All @@ -73,7 +72,7 @@ export class IotSquareMarker {

// shadow
const shadowClass = (selected) ? 'shadowSelected' : 'shadowUnselected';
const imgShadow = `<img class='` + shadowClass + `' src='`+ shadowFile + `'/>`;
const imgShadow = `<img class='` + shadowClass + `' src='` + shadowFile + `'/>`;


// result
Expand Down
4 changes: 2 additions & 2 deletions src/iotMapManager/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"_from": "iotmapmanager",
"_id": "[email protected].2",
"_id": "[email protected].3",
"_inBundle": false,
"_integrity": "sha512-Q7PVTJ/WHujDFcuO1B+MGJMXHLlJndJ9JrgDSf0UXdEdbsyf8otVrDBbE7bYZ2J5p4nfbT15ex+x1aTbJxgAMA==",
"_location": "/iotmapmanager",
Expand Down Expand Up @@ -37,7 +37,7 @@
"map"
],
"license": "MIT",
"main": "iotMapManager.ts",
"main": "iotMapManager.js",
"name": "iotmapmanager",
"repository": {
"type": "git",
Expand Down
14 changes: 7 additions & 7 deletions src/map/map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export class MapComponent implements AfterViewInit {
anchored: false
},
inner : {
label : "H",
color: "green"
label : 'H',
color: 'green'
},
},
{
Expand Down Expand Up @@ -110,7 +110,7 @@ export class MapComponent implements AfterViewInit {
},
{
id: 'p3',
location: [44.888798, 4.885407],
location: [44.888793, 4.885409],
shape: {
shape : 'poi',
color: '#d24d50',
Expand Down Expand Up @@ -155,7 +155,7 @@ export class MapComponent implements AfterViewInit {
icon: 'map_pin.svg',
color: 'white'
},
}];/*,
}]; /*,
// circle
{
Expand Down Expand Up @@ -281,11 +281,11 @@ export class MapComponent implements AfterViewInit {
this.commonIotMap.addMarker(this.markerToUpdate);

// update marker
this.commonIotMap.updateMarker('s3', {inner: {icon:'Orange_garden.svg', color:'blue'}});
this.commonIotMap.updateMarker('s3', {inner: {icon: 'Orange_garden.svg', color: 'blue'}});
setTimeout(() => { this.commonIotMap.updateMarker(this.markerToUpdate.id,
{location: [44.887, 4.898],
shape: {color: 'blue'},
gauge: {percent: '40'}});
shape: {color: 'blue'},
gauge: {percent: '40'}});
}, 2000);
setTimeout(() => { this.commonIotMap.updateMarker(this.markerToAdd.id,
{shape: {shape: 'square', color: 'green'}});
Expand Down

0 comments on commit ed9ca0f

Please sign in to comment.