diff --git a/cypress/integration/rendering/pie.spec.js b/cypress/integration/rendering/pie.spec.js index 019fa41af..8a89a0cde 100644 --- a/cypress/integration/rendering/pie.spec.js +++ b/cypress/integration/rendering/pie.spec.js @@ -75,4 +75,15 @@ describe('Pie Chart', () => { expect(svg).to.not.have.attr('style'); }); }); + it('should render a pie diagram when textPosition is set', () => { + imgSnapshotTest( + ` + pie + "Dogs": 50 + "Cats": 25 + `, + { logLevel: 1, pie: { textPosition: 0.9 } } + ); + cy.get('svg'); + }); }); diff --git a/demos/pie.html b/demos/pie.html index 51c5fe7b5..3d832d83c 100644 --- a/demos/pie.html +++ b/demos/pie.html @@ -26,6 +26,7 @@
+    %%{init: {"pie": {"textPosition": 0.9}, "themeVariables": {"pieOuterStrokeWidth": "5px"}} }%%
     pie
       title Key elements in Product X
         accTitle: Key elements in Product X
diff --git a/docs/config/setup/modules/defaultConfig.md b/docs/config/setup/modules/defaultConfig.md
index 302bd51e1..3b2e33842 100644
--- a/docs/config/setup/modules/defaultConfig.md
+++ b/docs/config/setup/modules/defaultConfig.md
@@ -14,7 +14,7 @@
 
 #### Defined in
 
-[defaultConfig.ts:2084](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2084)
+[defaultConfig.ts:2093](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2093)
 
 ---
 
diff --git a/docs/config/theming.md b/docs/config/theming.md
index 014ac1374..580afb488 100644
--- a/docs/config/theming.md
+++ b/docs/config/theming.md
@@ -261,6 +261,34 @@ The theming engine will only recognize hex colors and not color names. So, the v
 | activationBkgColor    | secondaryColor                 | Activation Background Color |
 | sequenceNumberColor   | calculated from lineColor      | Sequence Number Color       |
 
+## Pie Diagram Variables
+
+| Variable            | Default value                  | Description                                |
+| ------------------- | ------------------------------ | ------------------------------------------ |
+| pie1                | primaryColor                   | Fill for 1st section in pie diagram        |
+| pie2                | secondaryColor                 | Fill for 2nd section in pie diagram        |
+| pie3                | calculated from tertiary       | Fill for 3rd section in pie diagram        |
+| pie4                | calculated from primaryColor   | Fill for 4th section in pie diagram        |
+| pie5                | calculated from secondaryColor | Fill for 5th section in pie diagram        |
+| pie6                | calculated from tertiaryColor  | Fill for 6th section in pie diagram        |
+| pie7                | calculated from primaryColor   | Fill for 7th section in pie diagram        |
+| pie8                | calculated from primaryColor   | Fill for 8th section in pie diagram        |
+| pie9                | calculated from primaryColor   | Fill for 9th section in pie diagram        |
+| pie10               | calculated from primaryColor   | Fill for 10th section in pie diagram       |
+| pie11               | calculated from primaryColor   | Fill for 11th section in pie diagram       |
+| pie12               | calculated from primaryColor   | Fill for 12th section in pie diagram       |
+| pieTitleTextSize    | 25px                           | Title text size                            |
+| pieTitleTextColor   | taskTextDarkColor              | Title text color                           |
+| pieSectionTextSize  | 17px                           | Text size of individual section labels     |
+| pieSectionTextColor | textColor                      | Text color of individual section labels    |
+| pieLegendTextSize   | 17px                           | Text size of labels in diagram legend      |
+| pieLegendTextColor  | taskTextDarkColor              | Text color of labels in diagram legend     |
+| pieStrokeColor      | black                          | Border color of individual pie sections    |
+| pieStrokeWidth      | 2px                            | Border width of individual pie sections    |
+| pieOuterStrokeWidth | 2px                            | Border width of pie diagram's outer circle |
+| pieOuterStrokeColor | black                          | Border color of pie diagram's outer circle |
+| pieOpacity          | 0.7                            | Opacity of individual pie sections         |
+
 ## State Colors
 
 | Variable      | Default value    | Description                                  |
diff --git a/docs/syntax/pie.md b/docs/syntax/pie.md
index 63f371e87..8b1de3856 100644
--- a/docs/syntax/pie.md
+++ b/docs/syntax/pie.md
@@ -48,6 +48,7 @@ Drawing a pie chart is really simple in mermaid.
 ## Example
 
 ```mermaid-example
+%%{init: {"pie": {"textPosition": 0.5}, "themeVariables": {"pieOuterStrokeWidth": "5px"}} }%%
 pie showData
     title Key elements in Product X
     "Calcium" : 42.96
@@ -57,6 +58,7 @@ pie showData
 ```
 
 ```mermaid
+%%{init: {"pie": {"textPosition": 0.5}, "themeVariables": {"pieOuterStrokeWidth": "5px"}} }%%
 pie showData
     title Key elements in Product X
     "Calcium" : 42.96
@@ -64,3 +66,11 @@ pie showData
     "Magnesium" : 10.01
     "Iron" :  5
 ```
+
+## Configuration
+
+Possible pie diagram configuration parameters:
+
+| Parameter      | Description                                                                                                  | Default value |
+| -------------- | ------------------------------------------------------------------------------------------------------------ | ------------- |
+| `textPosition` | The axial position of the pie slice labels, from 0.0 at the center to 1.0 at the outside edge of the circle. | `0.75`        |
diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts
index 39ab3f4d9..157304149 100644
--- a/packages/mermaid/src/config.type.ts
+++ b/packages/mermaid/src/config.type.ts
@@ -222,7 +222,9 @@ export interface MindmapDiagramConfig extends BaseDiagramConfig {
   maxNodeWidth: number;
 }
 
-export type PieDiagramConfig = BaseDiagramConfig;
+export interface PieDiagramConfig extends BaseDiagramConfig {
+  textPosition?: number;
+}
 
 export interface ErDiagramConfig extends BaseDiagramConfig {
   titleTopMargin?: number;
diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts
index ec741e908..666efc364 100644
--- a/packages/mermaid/src/defaultConfig.ts
+++ b/packages/mermaid/src/defaultConfig.ts
@@ -1247,6 +1247,15 @@ const config: Partial = {
      * Default value: true
      */
     useMaxWidth: true,
+
+    /**
+     * | Parameter    | Description                                                                      | Type    | Required | Values              |
+     * | ------------ | -------------------------------------------------------------------------------- | ------- | -------- | ------------------- |
+     * | textPosition | Axial position of slice's label from zero at the center to 1 at the outside edge | Number  | Optional | Decimal from 0 to 1 |
+     *
+     * **Notes:** Default value: 0.75
+     */
+    textPosition: 0.75,
   },
 
   /** The object containing configurations specific for req diagrams */
diff --git a/packages/mermaid/src/diagrams/pie/pieRenderer.js b/packages/mermaid/src/diagrams/pie/pieRenderer.js
index 83f301207..9b25f5f43 100644
--- a/packages/mermaid/src/diagrams/pie/pieRenderer.js
+++ b/packages/mermaid/src/diagrams/pie/pieRenderer.js
@@ -3,6 +3,7 @@ import { select, scaleOrdinal, pie as d3pie, arc } from 'd3';
 import { log } from '../../logger';
 import { configureSvgSize } from '../../setupGraphViewbox';
 import * as configApi from '../../config';
+import { parseFontSize } from '../../utils';
 
 let conf = configApi.getConfig();
 
@@ -88,6 +89,10 @@ export const draw = (txt, id, _version, diagObj) => {
       themeVariables.pie12,
     ];
 
+    const textPosition = conf.pie?.textPosition ?? 0.75;
+    let [outerStrokeWidth] = parseFontSize(themeVariables.pieOuterStrokeWidth);
+    outerStrokeWidth ??= 2;
+
     // Set the color scale
     var color = scaleOrdinal().range(myGeneratedColors);
 
@@ -111,6 +116,16 @@ export const draw = (txt, id, _version, diagObj) => {
 
     // Shape helper to build arcs:
     var arcGenerator = arc().innerRadius(0).outerRadius(radius);
+    var labelArcGenerator = arc()
+      .innerRadius(radius * textPosition)
+      .outerRadius(radius * textPosition);
+
+    svg
+      .append('circle')
+      .attr('cx', 0)
+      .attr('cy', 0)
+      .attr('r', radius + outerStrokeWidth / 2)
+      .attr('class', 'pieOuterCircle');
 
     // Build the pie chart: each part of the pie is a path that we build using the arc function.
     svg
@@ -135,7 +150,7 @@ export const draw = (txt, id, _version, diagObj) => {
         return ((d.data.value / sum) * 100).toFixed(0) + '%';
       })
       .attr('transform', function (d) {
-        return 'translate(' + arcGenerator.centroid(d) + ')';
+        return 'translate(' + labelArcGenerator.centroid(d) + ')';
       })
       .style('text-anchor', 'middle')
       .attr('class', 'slice');
diff --git a/packages/mermaid/src/diagrams/pie/styles.js b/packages/mermaid/src/diagrams/pie/styles.js
index 8544501a3..6f0f60006 100644
--- a/packages/mermaid/src/diagrams/pie/styles.js
+++ b/packages/mermaid/src/diagrams/pie/styles.js
@@ -5,6 +5,11 @@ const getStyles = (options) =>
     stroke-width : ${options.pieStrokeWidth};
     opacity : ${options.pieOpacity};
   }
+  .pieOuterCircle{
+    stroke: ${options.pieOuterStrokeColor};
+    stroke-width: ${options.pieOuterStrokeWidth};
+    fill: none;
+  }
   .pieTitleText {
     text-anchor: middle;
     font-size: ${options.pieTitleTextSize};
diff --git a/packages/mermaid/src/docs/config/theming.md b/packages/mermaid/src/docs/config/theming.md
index da021f7f8..0e4571d15 100644
--- a/packages/mermaid/src/docs/config/theming.md
+++ b/packages/mermaid/src/docs/config/theming.md
@@ -183,6 +183,34 @@ The theming engine will only recognize hex colors and not color names. So, the v
 | activationBkgColor    | secondaryColor                 | Activation Background Color |
 | sequenceNumberColor   | calculated from lineColor      | Sequence Number Color       |
 
+## Pie Diagram Variables
+
+| Variable            | Default value                  | Description                                |
+| ------------------- | ------------------------------ | ------------------------------------------ |
+| pie1                | primaryColor                   | Fill for 1st section in pie diagram        |
+| pie2                | secondaryColor                 | Fill for 2nd section in pie diagram        |
+| pie3                | calculated from tertiary       | Fill for 3rd section in pie diagram        |
+| pie4                | calculated from primaryColor   | Fill for 4th section in pie diagram        |
+| pie5                | calculated from secondaryColor | Fill for 5th section in pie diagram        |
+| pie6                | calculated from tertiaryColor  | Fill for 6th section in pie diagram        |
+| pie7                | calculated from primaryColor   | Fill for 7th section in pie diagram        |
+| pie8                | calculated from primaryColor   | Fill for 8th section in pie diagram        |
+| pie9                | calculated from primaryColor   | Fill for 9th section in pie diagram        |
+| pie10               | calculated from primaryColor   | Fill for 10th section in pie diagram       |
+| pie11               | calculated from primaryColor   | Fill for 11th section in pie diagram       |
+| pie12               | calculated from primaryColor   | Fill for 12th section in pie diagram       |
+| pieTitleTextSize    | 25px                           | Title text size                            |
+| pieTitleTextColor   | taskTextDarkColor              | Title text color                           |
+| pieSectionTextSize  | 17px                           | Text size of individual section labels     |
+| pieSectionTextColor | textColor                      | Text color of individual section labels    |
+| pieLegendTextSize   | 17px                           | Text size of labels in diagram legend      |
+| pieLegendTextColor  | taskTextDarkColor              | Text color of labels in diagram legend     |
+| pieStrokeColor      | black                          | Border color of individual pie sections    |
+| pieStrokeWidth      | 2px                            | Border width of individual pie sections    |
+| pieOuterStrokeWidth | 2px                            | Border width of pie diagram's outer circle |
+| pieOuterStrokeColor | black                          | Border color of pie diagram's outer circle |
+| pieOpacity          | 0.7                            | Opacity of individual pie sections         |
+
 ## State Colors
 
 | Variable      | Default value    | Description                                  |
diff --git a/packages/mermaid/src/docs/syntax/pie.md b/packages/mermaid/src/docs/syntax/pie.md
index 2fe8c3e54..81ec720c4 100644
--- a/packages/mermaid/src/docs/syntax/pie.md
+++ b/packages/mermaid/src/docs/syntax/pie.md
@@ -35,6 +35,7 @@ Drawing a pie chart is really simple in mermaid.
 ## Example
 
 ```mermaid-example
+%%{init: {"pie": {"textPosition": 0.5}, "themeVariables": {"pieOuterStrokeWidth": "5px"}} }%%
 pie showData
     title Key elements in Product X
     "Calcium" : 42.96
@@ -42,3 +43,11 @@ pie showData
     "Magnesium" : 10.01
     "Iron" :  5
 ```
+
+## Configuration
+
+Possible pie diagram configuration parameters:
+
+| Parameter      | Description                                                                                                  | Default value |
+| -------------- | ------------------------------------------------------------------------------------------------------------ | ------------- |
+| `textPosition` | The axial position of the pie slice labels, from 0.0 at the center to 1.0 at the outside edge of the circle. | `0.75`        |
diff --git a/packages/mermaid/src/themes/theme-base.js b/packages/mermaid/src/themes/theme-base.js
index 8ff544feb..01f8a9c0b 100644
--- a/packages/mermaid/src/themes/theme-base.js
+++ b/packages/mermaid/src/themes/theme-base.js
@@ -212,6 +212,8 @@ class Theme {
     this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
     this.pieStrokeColor = this.pieStrokeColor || 'black';
     this.pieStrokeWidth = this.pieStrokeWidth || '2px';
+    this.pieOuterStrokeWidth = this.pieOuterStrokeWidth || '2px';
+    this.pieOuterStrokeColor = this.pieOuterStrokeColor || 'black';
     this.pieOpacity = this.pieOpacity || '0.7';
 
     /* requirement-diagram */
diff --git a/packages/mermaid/src/themes/theme-dark.js b/packages/mermaid/src/themes/theme-dark.js
index af21b4f13..9585a2e27 100644
--- a/packages/mermaid/src/themes/theme-dark.js
+++ b/packages/mermaid/src/themes/theme-dark.js
@@ -222,6 +222,8 @@ class Theme {
     this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
     this.pieStrokeColor = this.pieStrokeColor || 'black';
     this.pieStrokeWidth = this.pieStrokeWidth || '2px';
+    this.pieOuterStrokeWidth = this.pieOuterStrokeWidth || '2px';
+    this.pieOuterStrokeColor = this.pieOuterStrokeColor || 'black';
     this.pieOpacity = this.pieOpacity || '0.7';
 
     /* class */
diff --git a/packages/mermaid/src/themes/theme-default.js b/packages/mermaid/src/themes/theme-default.js
index 391c0298f..c91029de3 100644
--- a/packages/mermaid/src/themes/theme-default.js
+++ b/packages/mermaid/src/themes/theme-default.js
@@ -244,6 +244,8 @@ class Theme {
     this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
     this.pieStrokeColor = this.pieStrokeColor || 'black';
     this.pieStrokeWidth = this.pieStrokeWidth || '2px';
+    this.pieOuterStrokeWidth = this.pieOuterStrokeWidth || '2px';
+    this.pieOuterStrokeColor = this.pieOuterStrokeColor || 'black';
     this.pieOpacity = this.pieOpacity || '0.7';
 
     /* requirement-diagram */
diff --git a/packages/mermaid/src/themes/theme-forest.js b/packages/mermaid/src/themes/theme-forest.js
index 59adc9139..96d6c35c1 100644
--- a/packages/mermaid/src/themes/theme-forest.js
+++ b/packages/mermaid/src/themes/theme-forest.js
@@ -213,6 +213,8 @@ class Theme {
     this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
     this.pieStrokeColor = this.pieStrokeColor || 'black';
     this.pieStrokeWidth = this.pieStrokeWidth || '2px';
+    this.pieOuterStrokeWidth = this.pieOuterStrokeWidth || '2px';
+    this.pieOuterStrokeColor = this.pieOuterStrokeColor || 'black';
     this.pieOpacity = this.pieOpacity || '0.7';
 
     /* requirement-diagram */
diff --git a/packages/mermaid/src/themes/theme-neutral.js b/packages/mermaid/src/themes/theme-neutral.js
index e7a136c6b..8bb5ff693 100644
--- a/packages/mermaid/src/themes/theme-neutral.js
+++ b/packages/mermaid/src/themes/theme-neutral.js
@@ -243,6 +243,8 @@ class Theme {
     this.pieLegendTextColor = this.pieLegendTextColor || this.taskTextDarkColor;
     this.pieStrokeColor = this.pieStrokeColor || 'black';
     this.pieStrokeWidth = this.pieStrokeWidth || '2px';
+    this.pieOuterStrokeWidth = this.pieOuterStrokeWidth || '2px';
+    this.pieOuterStrokeColor = this.pieOuterStrokeColor || 'black';
     this.pieOpacity = this.pieOpacity || '0.7';
 
     /* requirement-diagram */