diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md
index 00eefa603..56fdac3f4 100644
--- a/ci/release/changelogs/next.md
+++ b/ci/release/changelogs/next.md
@@ -2,6 +2,7 @@
- Arrowhead labels are now supported. [#182](https://github.com/terrastruct/d2/pull/182)
- `stroke-dash` on shapes is now supported. [#188](https://github.com/terrastruct/d2/issues/188)
+- `font-color` is now supported on shapes and connections. [#215](https://github.com/terrastruct/d2/pull/215)
#### Improvements 🔧
diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go
index d32a1749a..ba1459c9e 100644
--- a/d2renderers/d2svg/d2svg.go
+++ b/d2renderers/d2svg/d2svg.go
@@ -437,7 +437,11 @@ func drawConnection(writer io.Writer, connection d2target.Connection, markers ma
} else if connection.Italic {
fontClass += "-italic"
}
- textStyle := fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "middle", connection.FontSize, "black")
+ fontColor := "black"
+ if connection.Color != "" {
+ fontColor = connection.Color
+ }
+ textStyle := fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "middle", connection.FontSize, fontColor)
x := labelTL.X + float64(connection.LabelWidth)/2
y := labelTL.Y + float64(connection.FontSize)
fmt.Fprintf(writer, `%s`,
@@ -706,7 +710,11 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
fmt.Fprintf(writer, `
%v
`, render)
fmt.Fprint(writer, ``)
default:
- textStyle := fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "middle", targetShape.FontSize, "black")
+ fontColor := "black"
+ if targetShape.Color != "" {
+ fontColor = targetShape.Color
+ }
+ textStyle := fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "middle", targetShape.FontSize, fontColor)
x := labelTL.X + float64(targetShape.LabelWidth)/2
// text is vertically positioned at its baseline which is at labelTL+FontSize
y := labelTL.Y + float64(targetShape.FontSize)
diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go
index 31acccc44..3c109f416 100644
--- a/e2etests/stable_test.go
+++ b/e2etests/stable_test.go
@@ -947,6 +947,20 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit,\
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
}
+`,
+ },
+ {
+ name: "font_colors",
+ script: `
+alpha: {
+ style.font-color: '#4A6FF3'
+}
+beta: {
+ style.font-color: red
+}
+alpha -> beta: gamma {
+ style.font-color: green
+}
`,
},
}
diff --git a/e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg b/e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg
index 73c194056..3d41cc01a 100644
--- a/e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg
+++ b/e2etests/testdata/sanity/1_to_2/dagre/sketch.exp.svg
@@ -14,7 +14,7 @@ width="486" height="552" viewBox="-100 -100 486 552">abc abc abc abc ab ab ab ab acbd acbd acbd acbd ab
+ab
-helloab
+ab
-hellorectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud cba * cba * cba * cba * ab
+ab
-To err is human, to moo bovine1*ab
+ab
-To err is human, to moo bovine1*abcdefghijklmno abcdefghijklmno abcdefghijklmno abcdefghijklmno aaadddeeebbbccc
+aaadddeeebbbccc
-111
+111
-222aaadddeeebbbccc
+aaadddeeebbbccc
-111
+111
-222aabbllmmoocciikkddhhjjff
+aabbllmmoocciikkddhhjjff
-11
+11
-22
+22
-33
+33
-44
+44
-55
+55
-66
+66
-77
+77
-88aabbllmmoocciikkddhhjjff
+aabbllmmoocciikkddhhjjff
-11
+11
-22
+22
-33
+33
-44
+44
-55
+55
-66
+66
-77
+77
-88abcd abcd abcd abcd abc abc abc abc acfbdhg acfbdhg acfbdhg acfbdhg agdfbhec agdfbhec agdfbhec agdfbhec abcdefghijklmnopq abcdefghijklmnopq abcdefghijklmnopq abcdefghijklmnopq finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot finallyatreeandnodessomemoremanythenhereyouhavehierarchyanotherofnestingtreesatreeinsidehierarchyroot alphabeta
+
+
+gamma
\ No newline at end of file
diff --git a/e2etests/testdata/stable/font_colors/elk/board.exp.json b/e2etests/testdata/stable/font_colors/elk/board.exp.json
new file mode 100644
index 000000000..0c8ebea65
--- /dev/null
+++ b/e2etests/testdata/stable/font_colors/elk/board.exp.json
@@ -0,0 +1,121 @@
+{
+ "name": "",
+ "shapes": [
+ {
+ "id": "alpha",
+ "type": "",
+ "pos": {
+ "x": 12,
+ "y": 12
+ },
+ "width": 145,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "alpha",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#4A6FF3",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 45,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "beta",
+ "type": "",
+ "pos": {
+ "x": 409,
+ "y": 12
+ },
+ "width": 136,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": false,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "beta",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "red",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 36,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ }
+ ],
+ "connections": [
+ {
+ "id": "(alpha -> beta)[0]",
+ "src": "alpha",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "beta",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "gamma",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "green",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 52,
+ "labelHeight": 21,
+ "labelPosition": "INSIDE_MIDDLE_CENTER",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 157,
+ "y": 75
+ },
+ {
+ "x": 409,
+ "y": 75
+ }
+ ],
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ }
+ ]
+}
diff --git a/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg b/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg
new file mode 100644
index 000000000..7ac6b6878
--- /dev/null
+++ b/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg
index 0199cf74c..951a662b1 100644
--- a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg
+++ b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg
@@ -1027,7 +1027,7 @@ title for the link, surrounded in quotes. For example:
Code
Unlike a pre-formatted code block, a code span indicates code within a
normal paragraph. For example:
-ab ab ab ab ab aabbccddllffwwyyadnniijjkkssuurmeemmmmgghhzzooppqqrrttvvxxabac
+aabbccddllffwwyyadnniijjkkssuurmeemmmmgghhzzooppqqrrttvvxxabac
-1
+1
-2
+2
-3
+3
-4
+4
-5
+5
-6aabbccddllffwwyyadnniijjkkssuurmeemmmmgghhzzooppqqrrttvvxxabac
+aabbccddllffwwyyadnniijjkkssuurmeemmmmgghhzzooppqqrrttvvxxabac
-1
+1
-2
+2
-3
+3
-4
+4
-5
+5
-6abcdefghiqrjmnoszaabbeeffggklptuwxyccddv abcdefghiqrjmnoszaabbeeffggklptuwxyccddv abcdefghiqrjmnoszaabbeeffggklptuwxyccddv abcdefghiqrjmnoszaabbeeffggklptuwxyccddv Markdown: Syntax
-ab Markdown: Syntax
-ab markdownLorem ipsum dolor sit amet, consectetur adipiscing elit,
+markdownLorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
markdownLorem ipsum dolor sit amet, consectetur adipiscing elit,
+markdownLorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
markdownLorem ipsum dolor sit amet, consectetur adipiscing elit,
+markdownLorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
markdownLorem ipsum dolor sit amet, consectetur adipiscing elit,
+markdownLorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
ab ab thisgoesmultiple linesthisgoesmultiple linesthisgoesmultiple linesthisgoesmultiple linesabcdefghijklmnopqrstuvw abcdefghijklmnopqrstuvw abcdefghijklmnopqrstuvw abcdefghijklmnopqrstuvw abcdefghijklmnopqrstu abcdefghijklmnopqrstu abcdefghijklmnopqrstu abcdefghijklmnopqrstu acdefgbh acdefgbh acdefgbh acdefgbh topabcbottomstartend topabcbottomstartend topabcbottomstartend topabcbottomstartend rectanglesquare rectanglesquare rectanglesquare rectanglesquare acbl1l2c1l2c3l2c2l3c1l3c2l4bacacbabcc1c2c3abc acbl1l2c1l2c3l2c2l3c1l3c2l4bacacbabcc1c2c3abc acbl1l2c1l2c3l2c2l3c1l3c2l4bacacbabcc1c2c3abc acbl1l2c1l2c3l2c2l3c1l3c2l4bacacbabcc1c2c3abc AKHIALFLGAMSTNAZCANVNMUTARLAMOOKTXORCOKSNEWYCTMANYRIDEMDNJPANCSCIDMTWAILINIAMIKYWIOHMNSDVAWVMENHVTNDAKHIALFLGAMSTNAZCANVNMUTARLAMOOKTXORCOKSNEWYCTMANYRIDEMDNJPANCSCIDMTWAILINIAMIKYWIOHMNSDVAWVMENHVTNDAKHIALFLGAMSTNAZCANVNMUTARLAMOOKTXORCOKSNEWYCTMANYRIDEMDNJPANCSCIDMTWAILINIAMIKYWIOHMNSDVAWVMENHVTNDAKHIALFLGAMSTNAZCANVNMUTARLAMOOKTXORCOKSNEWYCTMANYRIDEMDNJPANCSCIDMTWAILINIAMIKYWIOHMNSDVAWVMENHVTNDcontainerfirstsecond
+containerfirstsecond
-1->2
+1->2
-c->2containerfirstsecond
+containerfirstsecond
-1->2
+1->2
-c->2