- ANALYSIS.md: Full architecture analysis of draw.io shape systems (XML stencils vs JS shapes, plugin loading, desktop/web support) - Example plugin with 5 custom shapes demonstrating JS logic: - StatusIndicator: conditional rendering based on status param - ProgressBar: computed geometry (percentage-based fill) - DataFlowArrow: dynamic arrows with direction/speed params - HexagonCluster: loop-based hexagonal grid generation - MetricGauge: radial gauge with arc computation + zones - Webpack build pipeline (npm run build / build:dev / watch) - Pre-built dist/drawio-custom-shapes.js ready for installation - Full README with installation instructions for desktop + web
1 line
12 KiB
JavaScript
1 line
12 KiB
JavaScript
(()=>{var e={294(){function e(){mxShape.call(this)}mxUtils.extend(e,mxShape),e.prototype.cst={SHAPE:"customShapes.dataFlowArrow"},e.prototype.customProperties=[{name:"direction",dispName:"Direction",type:"enum",defVal:"right",enumList:[{val:"right",dispName:"Right"},{val:"left",dispName:"Left"},{val:"both",dispName:"Bidirectional"}]},{name:"flowSpeed",dispName:"Flow Speed",type:"enum",defVal:"medium",enumList:[{val:"fast",dispName:"Fast"},{val:"medium",dispName:"Medium"},{val:"slow",dispName:"Slow"}]}],e.prototype.paintVertexShape=function(e,t,o,l,r){e.translate(t,o);var a=mxUtils.getValue(this.style,"direction","right"),s=mxUtils.getValue(this.style,"flowSpeed","medium"),n=mxUtils.getValue(this.style,"flowColor","#1976D2"),i=parseInt(mxUtils.getValue(this.style,"thickness","3")),m=r/2,p=Math.min(r/2,12),h="left"===a||"both"===a?p:0,u="right"===a||"both"===a?l-p:l;e.setStrokeColor(n),e.setStrokeWidth(i),e.setFillColor(n),e.begin(),e.moveTo(h,m),e.lineTo(u,m),e.stroke(),"right"!==a&&"both"!==a||(e.begin(),e.moveTo(l-p,m-p),e.lineTo(l,m),e.lineTo(l-p,m+p),e.close(),e.fillAndStroke()),"left"!==a&&"both"!==a||(e.begin(),e.moveTo(p,m-p),e.lineTo(0,m),e.lineTo(p,m+p),e.close(),e.fillAndStroke());var c={fast:8,medium:14,slow:22},x=c[s]||c.medium,d=Math.max(2,.8*i);e.setFillColor("#FFFFFF"),e.setStrokeWidth(0);for(var C=h+x;C<u-x/2;C+=x)e.ellipse(C-d,m-d,2*d,2*d),e.fill();e.setStrokeColor(n),e.setAlpha(.15),e.setStrokeWidth(3*i),e.begin(),e.moveTo(h,m),e.lineTo(u,m),e.stroke()},mxCellRenderer.registerShape(e.prototype.cst.SHAPE,e)},421(){function e(){mxShape.call(this)}mxUtils.extend(e,mxShape),e.prototype.cst={SHAPE:"customShapes.hexCluster"},e.prototype.customProperties=[{name:"hexCount",dispName:"Hex Count (across)",type:"int",min:1,max:10,defVal:3},{name:"hexFill",dispName:"Hex Fill Color",type:"color",defVal:"#E3F2FD"},{name:"hexStroke",dispName:"Hex Stroke Color",type:"color",defVal:"#1565C0"}],e.prototype.drawHexagon=function(e,t,o,l){e.begin();for(var r=0;r<6;r++){var a=Math.PI/3*r-Math.PI/6,s=t+l*Math.cos(a),n=o+l*Math.sin(a);0===r?e.moveTo(s,n):e.lineTo(s,n)}e.close()},e.prototype.paintVertexShape=function(e,t,o,l,r){e.translate(t,o);var a=parseInt(mxUtils.getValue(this.style,"hexCount","3")),s=mxUtils.getValue(this.style,"hexFill","#E3F2FD"),n=mxUtils.getValue(this.style,"hexStroke","#1565C0"),i=mxUtils.getValue(this.style,"filled",""),m=r-8,p=(l-8)/(a=Math.max(1,Math.min(10,a))),h=p/Math.sqrt(3),u=1.5*h,c=Math.max(1,Math.floor((m-.5*h)/u)),x={};i&&i.split(",").forEach(function(e){x[parseInt(e.trim())]=!0});var d=0;e.setStrokeColor(n),e.setStrokeWidth(1.5);for(var C=0;C<c;C++)for(var S=C%2==0?a:a-1,g=C%2==0?0:p/2,f=0;f<S;f++){var F=4+g+p/2+f*p,k=4+h+C*u;if(!(k+h>r)){var y=""===i||x[d];e.setFillColor(y?s:"#FAFAFA"),e.setAlpha(y?1:.5),this.drawHexagon(e,F,k,.9*h),e.fillAndStroke(),e.setAlpha(1),d++}}e.setStrokeColor(n),e.setStrokeWidth(1),e.setAlpha(.3),e.setDashed(!0),e.rect(0,0,l,r),e.stroke()},mxCellRenderer.registerShape(e.prototype.cst.SHAPE,e)},504(){function e(){mxShape.call(this)}mxUtils.extend(e,mxShape),e.prototype.cst={SHAPE:"customShapes.metricGauge"},e.prototype.customProperties=[{name:"value",dispName:"Value",type:"float",defVal:75},{name:"minVal",dispName:"Min Value",type:"float",defVal:0},{name:"maxVal",dispName:"Max Value",type:"float",defVal:100},{name:"zones",dispName:"Zone Colors (comma-sep)",type:"string",defVal:"#4CAF50,#FF9800,#F44336"},{name:"label",dispName:"Label",type:"string",defVal:""}],e.prototype.paintVertexShape=function(e,t,o,l,r){e.translate(t,o);var a=parseFloat(mxUtils.getValue(this.style,"value","75")),s=parseFloat(mxUtils.getValue(this.style,"minVal","0")),n=parseFloat(mxUtils.getValue(this.style,"maxVal","100")),i=mxUtils.getValue(this.style,"zones","#4CAF50,#FF9800,#F44336"),m=mxUtils.getValue(this.style,"label",""),p=parseInt(mxUtils.getValue(this.style,"arcWidth","8")),h=i.split(","),u=l/2,c=.7*r,x=Math.min(l/2,.65*r)-p,d=Math.PI,C=Math.PI,S=h.length,g=C/S;e.setStrokeWidth(p),e.setLineCap("round");for(var f=0;f<S;f++){e.setStrokeColor(h[f]),e.setAlpha(.3);var F=d-f*g,k=F-g;e.begin();for(var y=0;y<=20;y++){var V=F+y/20*(k-F),E=u+x*Math.cos(V),w=c-x*Math.sin(V);0===y?e.moveTo(E,w):e.lineTo(E,w)}e.stroke()}var v=Math.max(0,Math.min(1,(a-s)/(n-s))),A=d-C*v,T=h[Math.min(S-1,Math.floor(v*S))];e.setStrokeColor(T),e.setAlpha(1),e.setStrokeWidth(p);var M=Math.max(2,Math.floor(40*v));for(e.begin(),y=0;y<=M;y++)V=d+y/M*(A-d),E=u+x*Math.cos(V),w=c-x*Math.sin(V),0===y?e.moveTo(E,w):e.lineTo(E,w);e.stroke(),e.setStrokeColor("#333333"),e.setStrokeWidth(2),e.setAlpha(1);var b=.85*x,N=u+b*Math.cos(A),P=c-b*Math.sin(A);e.begin(),e.moveTo(u,c),e.lineTo(N,P),e.stroke(),e.setFillColor("#333333"),e.ellipse(u-4,c-4,8,8),e.fill(),e.setFontColor("#333333"),e.setFontSize(Math.min(.4*x,24)),e.setFontStyle(1),e.text(u,c+.25*x,0,0,String(Math.round(10*a)/10),mxConstants.ALIGN_CENTER,mxConstants.ALIGN_MIDDLE,0,null,0,0,0),m&&(e.setFontColor("#666666"),e.setFontSize(Math.min(.2*x,12)),e.setFontStyle(0),e.text(u,c+.45*x,0,0,m,mxConstants.ALIGN_CENTER,mxConstants.ALIGN_MIDDLE,0,null,0,0,0)),e.setFontColor("#999999"),e.setFontSize(Math.min(.15*x,10)),e.text(u-x,c+12,0,0,String(s),mxConstants.ALIGN_CENTER,mxConstants.ALIGN_TOP,0,null,0,0,0),e.text(u+x,c+12,0,0,String(n),mxConstants.ALIGN_CENTER,mxConstants.ALIGN_TOP,0,null,0,0,0)},mxCellRenderer.registerShape(e.prototype.cst.SHAPE,e)},879(){function e(){mxShape.call(this)}mxUtils.extend(e,mxShape),e.prototype.cst={SHAPE:"customShapes.progressBar"},e.prototype.customProperties=[{name:"progress",dispName:"Progress (%)",type:"int",min:0,max:100,defVal:50},{name:"barColor",dispName:"Bar Color",type:"color",defVal:"#4CAF50"}],e.prototype.paintVertexShape=function(e,t,o,l,r){e.translate(t,o);var a=parseInt(mxUtils.getValue(this.style,"progress","50")),s=mxUtils.getValue(this.style,"barColor","#4CAF50"),n=mxUtils.getValue(this.style,"showPercent","1"),i=mxUtils.getValue(this.style,"animated","0");a=Math.max(0,Math.min(100,a));var m=Math.min(r/2,8);e.setFillColor("#E0E0E0"),e.setStrokeColor("#BDBDBD"),e.setStrokeWidth(1),e.roundrect(0,0,l,r,m,m),e.fillAndStroke();var p=(l-4)*a/100;if(p>0&&(e.setStrokeWidth(0),e.setFillColor(s),a<30?e.setFillColor("#F44336"):a<70?e.setFillColor(s):e.setFillColor("#2E7D32"),e.roundrect(2,2,p,r-4,m-1,m-1),e.fill(),"1"===i&&p>10)){e.setStrokeColor("rgba(255,255,255,0.3)"),e.setStrokeWidth(2);for(var h=12;h<p-4;h+=12)e.begin(),e.moveTo(2+h,2),e.lineTo(2+h-4,r-2),e.stroke()}"1"===n&&(e.setFontColor(a>50?"#FFFFFF":"#333333"),e.setFontSize(Math.min(.6*r,14)),e.setFontStyle(1),e.text(l/2,r/2,0,0,a+"%",mxConstants.ALIGN_CENTER,mxConstants.ALIGN_MIDDLE,0,null,0,0,0))},mxCellRenderer.registerShape(e.prototype.cst.SHAPE,e)},656(){function e(){mxShape.call(this)}mxUtils.extend(e,mxShape),e.prototype.cst={SHAPE:"customShapes.statusIndicator"},e.prototype.customProperties=[{name:"status",dispName:"Status",type:"enum",defVal:"unknown",enumList:[{val:"ok",dispName:"OK"},{val:"warning",dispName:"Warning"},{val:"error",dispName:"Error"},{val:"unknown",dispName:"Unknown"}]}],e.prototype.paintVertexShape=function(e,t,o,l,r){e.translate(t,o);var a=mxUtils.getValue(this.style,"status","unknown"),s=mxUtils.getValue(this.style,"showLabel","1"),n={ok:{fill:"#4CAF50",stroke:"#2E7D32",icon:"✓"},warning:{fill:"#FF9800",stroke:"#E65100",icon:"⚠"},error:{fill:"#F44336",stroke:"#B71C1C",icon:"✗"},unknown:{fill:"#9E9E9E",stroke:"#424242",icon:"?"}},i=n[a]||n.unknown;if(e.setFillColor(i.fill),e.setStrokeColor(i.stroke),e.setStrokeWidth(2),l>1.5*r){var m=r/2;e.begin(),e.moveTo(m,0),e.lineTo(l-m,0),e.arcTo(m,m,0,0,1,l-m,r),e.lineTo(m,r),e.arcTo(m,m,0,0,1,m,0),e.close(),e.fillAndStroke()}else{var p=Math.min(l,r),h=l/2,u=r/2;e.ellipse(h-p/2,u-p/2,p,p),e.fillAndStroke()}"1"===s&&(e.setFontColor("#FFFFFF"),e.setFontSize(.4*Math.min(l,r)),e.setFontStyle(1),e.text(l/2,r/2,0,0,i.icon,mxConstants.ALIGN_CENTER,mxConstants.ALIGN_MIDDLE,0,null,0,0,0)),"error"===a&&(e.setStrokeColor(i.fill),e.setStrokeWidth(1),e.setAlpha(.3),e.ellipse(-4,-4,l+8,r+8),e.stroke())},mxCellRenderer.registerShape(e.prototype.cst.SHAPE,e)}};const t={};function o(l){const r=t[l];if(void 0!==r)return r.exports;const a=t[l]={exports:{}};return e[l](a,a.exports,o),a.exports}(()=>{"use strict";o(656),o(879),o(294),o(421),o(504),Draw.loadPlugin(function(e){!function(e){var t=e.sidebar,o=[t.createVertexTemplateEntry("shape=customShapes.statusIndicator;status=ok;showLabel=1;fillColor=none;strokeColor=none;",60,40,"","Status: OK",null,null,"status indicator ok green check"),t.createVertexTemplateEntry("shape=customShapes.statusIndicator;status=warning;showLabel=1;fillColor=none;strokeColor=none;",60,40,"","Status: Warning",null,null,"status indicator warning orange"),t.createVertexTemplateEntry("shape=customShapes.statusIndicator;status=error;showLabel=1;fillColor=none;strokeColor=none;",60,40,"","Status: Error",null,null,"status indicator error red"),t.createVertexTemplateEntry("shape=customShapes.statusIndicator;status=unknown;showLabel=1;fillColor=none;strokeColor=none;",60,40,"","Status: Unknown",null,null,"status indicator unknown grey"),t.createVertexTemplateEntry("shape=customShapes.statusIndicator;status=ok;showLabel=1;fillColor=none;strokeColor=none;",120,30,"","Status Pill: OK",null,null,"status pill indicator wide"),t.createVertexTemplateEntry("shape=customShapes.progressBar;progress=75;barColor=#4CAF50;showPercent=1;fillColor=none;strokeColor=none;",200,30,"","Progress Bar (75%)",null,null,"progress bar percentage loading"),t.createVertexTemplateEntry("shape=customShapes.progressBar;progress=30;barColor=#FF9800;showPercent=1;fillColor=none;strokeColor=none;",200,30,"","Progress Bar (30%)",null,null,"progress bar low warning"),t.createVertexTemplateEntry("shape=customShapes.progressBar;progress=90;barColor=#4CAF50;showPercent=1;animated=1;fillColor=none;strokeColor=none;",200,30,"","Progress Bar Animated (90%)",null,null,"progress bar animated stripes"),t.createVertexTemplateEntry("shape=customShapes.dataFlowArrow;direction=right;flowSpeed=medium;flowColor=#1976D2;fillColor=none;strokeColor=none;",180,40,"","Data Flow → Right",null,null,"data flow arrow right direction"),t.createVertexTemplateEntry("shape=customShapes.dataFlowArrow;direction=left;flowSpeed=medium;flowColor=#1976D2;fillColor=none;strokeColor=none;",180,40,"","Data Flow ← Left",null,null,"data flow arrow left direction"),t.createVertexTemplateEntry("shape=customShapes.dataFlowArrow;direction=both;flowSpeed=fast;flowColor=#7B1FA2;fillColor=none;strokeColor=none;",180,40,"","Data Flow ↔ Bidirectional",null,null,"data flow arrow bidirectional both"),t.createVertexTemplateEntry("shape=customShapes.hexCluster;hexCount=3;hexFill=#E3F2FD;hexStroke=#1565C0;fillColor=none;strokeColor=none;",120,120,"","Hex Cluster (3x)",null,null,"hexagon cluster grid honeycomb"),t.createVertexTemplateEntry("shape=customShapes.hexCluster;hexCount=5;hexFill=#FFF3E0;hexStroke=#E65100;fillColor=none;strokeColor=none;",200,150,"","Hex Cluster (5x)",null,null,"hexagon cluster large grid"),t.createVertexTemplateEntry("shape=customShapes.hexCluster;hexCount=4;hexFill=#E8F5E9;hexStroke=#2E7D32;filled=0,2,5;fillColor=none;strokeColor=none;",160,140,"","Hex Cluster (partial fill)",null,null,"hexagon cluster partial highlight"),t.createVertexTemplateEntry("shape=customShapes.metricGauge;value=75;minVal=0;maxVal=100;label=CPU;fillColor=none;strokeColor=none;",140,100,"","Metric Gauge (75/100)",null,null,"gauge meter speedometer metric"),t.createVertexTemplateEntry("shape=customShapes.metricGauge;value=45;minVal=0;maxVal=100;zones=#4CAF50,#FF9800,#F44336;label=Memory;fillColor=none;strokeColor=none;",140,100,"","Metric Gauge (45/100)",null,null,"gauge meter memory usage"),t.createVertexTemplateEntry("shape=customShapes.metricGauge;value=92;minVal=0;maxVal=100;zones=#4CAF50,#FF9800,#F44336;label=Disk;fillColor=none;strokeColor=none;",140,100,"","Metric Gauge Critical (92/100)",null,null,"gauge meter disk critical high"),t.createVertexTemplateEntry("shape=customShapes.metricGauge;value=3.5;minVal=0;maxVal=5;zones=#F44336,#FF9800,#4CAF50;label=Rating;fillColor=none;strokeColor=none;",140,100,"","Metric Gauge (3.5/5 Rating)",null,null,"gauge rating stars score")];t.addPaletteFunctions("customShapesExample","Custom Shapes Example",!1,o)}(e),console.log("[CustomShapes] Plugin loaded successfully — 5 shapes registered")})})()})(); |