Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active February 19, 2016 23:20
Show Gist options
  • Save mbostock/2839676 to your computer and use it in GitHub Desktop.
Save mbostock/2839676 to your computer and use it in GitHub Desktop.
SVG Path Cleaning
license: gpl-3.0
<!DOCTYPE html>
<meta charset="utf-8">
<svg width="960" height="500" viewBox="0 -10 150 150">
<path d="m 96.804996,128.94908 c 0.24939,-0.76756 0.40646,-0.92151 0.89998,-0.88215 0.34153,0.0272 0.49785,-0.0345 1.02442,-0.4048 l 0.62138,-0.43696 -0.14638,-0.28308 c -0.0805,-0.15569 -0.14605,-0.47656 -0.14564,-0.71304 10e-4,-0.37536 0.0565,-0.48469 0.43946,-0.86079 0.49228,-0.48344 0.611754,-0.84692 0.38974,-1.18575 -0.18379,-0.2805 -0.19607,-0.78095 -0.0401,-1.63343 0.0654,-0.3575 0.14538,-0.83 0.177684,-1.05 0.0323,-0.22 0.11362,-0.4675 0.18069,-0.55 0.0671,-0.0825 0.23961,-0.5325 0.38341,-1 0.1438,-0.4675 0.33725,-0.95725 0.4299,-1.08833 0.0926,-0.13108 0.26911,-0.42765 0.39215,-0.65904 0.12303,-0.23139 0.3905,-0.65289 0.59437,-0.93667 0.35757,-0.49772 0.3876,-0.51596 0.84906,-0.51596 0.30322,0 0.52395,0.0549 0.60286,0.15 0.0685,0.0825 0.20347,0.15 0.3,0.15 0.0965,0 0.23247,0.0686 0.30209,0.15252 0.11337,0.1366 0.14448,0.13634 0.29795,-0.002 0.134,-0.12127 0.29982,-0.14065 0.76066,-0.0889 0.64476,0.0724 0.83929,0.17327 0.83929,0.43512 0,0.17547 0.37989,0.40381 0.67183,0.40381 0.0893,0 0.25235,0.0787 0.36225,0.175 0.19221,0.16833 0.19655,0.16737 0.11384,-0.025 -0.0473,-0.11 -0.0887,-0.3575 -0.092,-0.55 -0.003,-0.19972 -0.0754,-0.40208 -0.1676,-0.4713 -0.17545,-0.13169 -0.33142,-1.00016 -0.22801,-1.26965 0.08,-0.20854 0.55329,-0.45905 0.86724,-0.45905 0.13065,0 0.34083,0.10995 0.46708,0.24434 0.22239,0.23672 0.2415,0.23956 0.61218,0.0913 0.35269,-0.14112 0.40659,-0.13895 0.68869,0.0277 0.30092,0.17776 0.30983,0.17702 0.53026,-0.0441 0.23587,-0.23657 0.92682,-0.75805 1.365,-1.03021 0.29393,-0.18256 0.29476,-0.23063 0.0171,-0.98901 -0.28754,-0.78535 -0.26601,-1.39538 0.0754,-2.1357 0.62534,-1.35616 0.64021,-1.40901 0.57047,-2.02764 -0.1088,-0.96523 -0.0831,-1.57339 0.0876,-2.07631 0.34572,-1.01828 0.61802,-1.32608 1.37185,-1.55069 0.24025,-0.0716 0.56195,-0.19641 0.71489,-0.27738 0.15295,-0.081 0.44311,-0.13261 0.6448,-0.11475 0.34318,0.0304 0.37111,0.0114 0.4349,-0.29545 0.0545,-0.26223 0.0305,-0.34808 -0.1198,-0.42852 -0.33707,-0.18039 -0.50842,-0.57793 -0.59933,-1.39047 -0.0754,-0.67411 -0.0585,-0.91159 0.10835,-1.52573 0.10872,-0.40005 0.21771,-0.92986 0.24221,-1.17736 0.0245,-0.2475 0.0973,-0.63 0.16169,-0.850002 0.0644,-0.22 0.15122,-0.671 0.19286,-1.00223 0.1442,-1.14704 0.43705,-1.74777 0.85199,-1.74777 0.16635,0 0.25429,-0.10997 0.39021,-0.48792 0.0965,-0.26836 0.27794,-0.58421 0.40321,-0.7019 0.19614,-0.18426 0.30295,-0.20533 0.7693,-0.15175 0.29785,0.0342 0.81567,0.0556 1.15073,0.0476 0.44076,-0.0106 0.64459,0.028 0.73724,0.13968 0.16408,0.1977 0.49794,0.19712 0.78132,-0.001 0.28676,-0.20085 0.29219,-0.66523 0.0124,-1.05819 -0.11543,-0.16211 -0.27293,-0.56504 -0.35,-0.8954 -0.0771,-0.33036 -0.20327,-0.72277 -0.28045,-0.87202 -0.0772,-0.14924 -0.17133,-0.47816 -0.20924,-0.73092 -0.0811,-0.54048 0.13578,-1.05368 0.64973,-1.5378 0.17516,-0.165 0.42301,-0.50481 0.55077,-0.75513 0.22977,-0.45019 0.56722,-0.69487 0.95831,-0.69487 0.36231,0 0.64633,-0.43466 1.04494,-1.59916 0.21585,-0.63059 0.60696,-1.50342 0.86913,-1.93964 0.3179,-0.52893 0.47668,-0.90546 0.47668,-1.130373 0,-0.461434 0.24727,-1.015868 0.62891,-1.410189 0.26545,-0.274265 0.29388,-0.345104 0.16993,-0.423468 -0.0819,-0.05176 -0.27084,-0.0948 -0.41994,-0.09564 -0.4936,-0.0028 -0.92921,-0.609745 -1.02586,-1.429358 -0.0656,-0.556388 -0.0565,-0.588664 0.2445,-0.869878 0.17195,-0.160627 0.4116,-0.320433 0.53255,-0.355124 0.42163,-0.120932 0.83174,-0.339249 1.01252,-0.539 0.19705,-0.217741 0.18332,-0.372147 -0.0986,-1.108171 -0.1094,-0.285667 -0.18985,-0.856379 -0.22031,-1.562801 l -0.048,-1.112802 -0.37449,-0.112198 c -0.20597,-0.06171 -0.55706,-0.112199 -0.78021,-0.112199 -0.74772,0 -1.42142,-0.839822 -1.4207,-1.771016 0,-0.585327 0.24361,-1.016244 0.75002,-1.329224 0.32138,-0.198624 0.43213,-0.217282 0.82817,-0.139523 0.40564,0.07964 0.50307,0.155386 0.86431,0.671902 0.55546,0.794229 0.71199,0.869844 0.93349,0.450948 0.0955,-0.180606 0.31864,-0.466485 0.49586,-0.635288 0.31539,-0.300399 0.62778,-0.980803 0.62778,-1.367323 0,-0.106909 0.14189,-0.535209 0.31531,-0.951778 0.22865,-0.549249 0.48429,-0.938961 0.9302,-1.418049 1.00872,-1.083766 1.05449,-1.163161 1.05449,-1.829101 0,-0.731676 0.15502,-1.041543 0.78491,-1.568918 0.4853,-0.406313 0.92929,-0.532364 1.07048,-0.303917 0.0417,0.06744 0.10268,0.07321 0.16069,0.01521 0.15138,-0.151383 0.69255,-1.73173 0.77568,-2.265174 0.0773,-0.496248 0.36362,-0.85875 0.67821,-0.85875 0.10743,0 0.0794,-0.0813 -0.10261,-0.297605 -0.2921,-0.347138 -0.42132,-0.823741 -0.28795,-1.062056 0.0997,-0.178117 -0.16614,-0.540339 -0.39654,-0.540339 -0.0644,0 -0.20178,-0.07661 -0.30525,-0.170252 -0.15823,-0.143195 -0.37934,-0.166991 -1.39135,-0.149733 -0.87996,0.01501 -1.26066,0.06075 -1.417,0.170252 -0.11757,0.08235 -0.28814,0.149733 -0.37904,0.149733 -0.0909,0 -0.51087,0.1575 -0.93329,0.35 -0.97368,0.443721 -1.20535,0.447694 -1.45776,0.025 -0.10674,-0.17875 -0.35272,-0.432051 -0.54662,-0.56289 -0.19391,-0.13084 -0.35256,-0.32209 -0.35256,-0.425 0,-0.139276 -0.0733,-0.18711 -0.28651,-0.18711 -0.37697,0 -0.81349,-0.349606 -0.81349,-0.651508 0,-0.207324 -0.0532,-0.240842 -0.425,-0.267742 l -0.425,-0.03075 0.003,-0.6 c 0.002,-0.33 0.0621,-1.138593 0.13379,-1.796873 0.10419,-0.956388 0.10553,-1.272198 0.007,-1.571757 -0.16528,-0.500807 -0.003,-0.716008 0.49565,-0.65778 0.5237,0.06114 0.76275,-0.271382 0.91559,-1.27359 0.0671,-0.44 0.1834,-0.921515 0.25845,-1.070034 0.075,-0.148519 0.13646,-0.471038 0.13646,-0.716709 0,-0.245672 0.0975,-0.664157 0.21671,-0.929966 0.11919,-0.26581 0.24386,-0.763359 0.27705,-1.105665 0.0603,-0.62204 0.0602,-0.622433 -0.24171,-0.733258 -0.55044,-0.202069 -0.60103,-0.258839 -0.73857,-0.828716 -0.13534,-0.560756 -0.13972,-0.565652 -0.50576,-0.565652 -0.33206,0 -0.38627,0.03862 -0.53848,0.383602 -0.0931,0.210981 -0.16924,0.482393 -0.16924,0.603138 0,0.30107 -0.16365,0.340262 -0.9624,0.230489 -0.5196,-0.07141 -0.72425,-0.06393 -0.8376,0.03061 -0.0825,0.06881 -0.32354,0.151642 -0.53564,0.184074 -0.2121,0.03243 -0.4371,0.126491 -0.5,0.209018 -0.0629,0.08253 -0.34903,0.180167 -0.63585,0.216977 -0.50588,0.06493 -0.525,0.05833 -0.63905,-0.220489 -0.0647,-0.158079 -0.17851,-0.428723 -0.25299,-0.601431 -0.0745,-0.172707 -0.18453,-0.667036 -0.24454,-1.098508 -0.06,-0.431473 -0.17746,-0.965166 -0.26099,-1.185987 -0.0835,-0.22082 -0.23924,-0.648991 -0.34602,-0.951491 -0.10678,-0.3025 -0.29332,-0.643516 -0.41453,-0.757813 -0.55159,-0.520114 -0.95482,-1.849466 -0.66642,-2.196976 0.10825,-0.130428 0.0969,-0.18884 -0.0693,-0.354992 -0.16188,-0.161883 -0.24759,-0.180351 -0.46081,-0.09929 -0.25808,0.09812 -0.26264,0.116995 -0.30946,1.279328 -0.0261,0.648857 -0.10414,1.629739 -0.17335,2.179739 -0.0692,0.55 -0.11854,1.644521 -0.10962,2.432268 0.0113,1.002783 -0.0229,1.512551 -0.11413,1.7 -0.0717,0.147253 -0.18944,0.515232 -0.26169,0.817732 -0.0722,0.3025 -0.17608,0.60625 -0.23073,0.675 -0.1239,0.155872 -0.53948,0.160446 -0.98495,0.01084 -0.75585,-0.253847 -0.83802,-0.510341 -0.84447,-2.63584 -0.006,-2.067877 -0.11715,-3.019273 -0.35928,-3.08259 -0.21101,-0.05518 -0.25634,-0.569816 -0.089,-1.010032 0.16624,-0.437219 0.0535,-0.523743 -0.77324,-0.593631 -0.57452,-0.04856 -0.85967,-0.126984 -1.14262,-0.314231 -0.20737,-0.137234 -0.44392,-0.249516 -0.52567,-0.249516 -0.0817,0 -0.19679,-0.09 -0.25566,-0.2 -0.0589,-0.11 -0.17385,-0.2 -0.25551,-0.2 -0.18307,0 -0.83417,-0.406536 -1.06506,-0.665005 -0.0938,-0.10502 -0.233,-0.339438 -0.30931,-0.520929 -0.0763,-0.18149 -0.24706,-0.383968 -0.37943,-0.449951 -0.4288,-0.21373 -0.51286,-0.549037 -0.34607,-1.380416 0.26796,-1.335669 0.33344,-1.983699 0.20046,-1.983699 -0.0663,0 -0.17317,-0.06336 -0.23744,-0.140789 -0.0643,-0.07743 -0.2719,-0.214368 -0.46141,-0.304299 -0.20101,-0.09538 -0.36913,-0.26135 -0.40351,-0.398334 -0.0593,-0.236112 -0.36581,-0.356578 -0.90736,-0.356578 -0.15597,0 -0.27786,-0.08387 -0.34909,-0.240189 -0.15582,-0.34199 0.30415,-1.150726 0.98557,-1.732884 0.29049,-0.248172 0.52816,-0.50827 0.52816,-0.577996 0,-0.06973 0.0819,-0.22786 0.1819,-0.351409 0.17737,-0.219049 0.17613,-0.230401 -0.05,-0.456533 -0.12755,-0.127544 -0.2319,-0.347078 -0.2319,-0.487853 0,-0.310168 -0.54952,-0.845947 -0.87201,-0.850205 -0.12843,-0.0017 -0.31549,-0.129381 -0.4438,-0.302931 -0.12199,-0.165 -0.31347,-0.3 -0.42552,-0.3 -0.11203,0 -0.51306,-0.121369 -0.89115,-0.26971 -0.77466,-0.303926 -0.96666,-0.563752 -0.78388,-1.060782 0.0941,-0.255996 0.0753,-0.297446 -0.21524,-0.474626 -0.17512,-0.106774 -0.43169,-0.194303 -0.57018,-0.194508 -0.13848,-2e-4 -0.42686,-0.119339 -0.64083,-0.26474 -0.3721,-0.252846 -0.3949,-0.256371 -0.52322,-0.08089 -0.0738,0.100913 -0.13416,0.236309 -0.13416,0.30088 0,0.229138 -0.41617,0.644373 -0.64583,0.644373 -0.27107,0 -0.74827,-0.230126 -0.867684,-0.418435 -0.0459,-0.07236 -0.0841,-0.232815 -0.085,-0.356565 -0.001,-0.180624 -0.058,-0.225 -0.28804,-0.225 -0.15759,0 -0.40093,-0.09 -0.54078,-0.2 -0.13984,-0.11 -0.31466,-0.201431 -0.38848,-0.20318 -0.14324,-0.0034 -0.48423,-0.231828 -0.48423,-0.324393 0,-0.03054 -0.25875,-0.305921 -0.575,-0.611961 -0.42381,-0.410127 -0.65063,-0.556965 -0.86262,-0.558451 -0.15819,-0.0011 -0.68356,-0.09497 -1.16749,-0.208582 -1.12679,-0.264539 -1.39551,-0.488964 -1.39336,-1.163658 0.002,-0.573134 0.0391,-0.640534 0.54246,-0.982156 0.31533,-0.213987 0.4322,-0.245007 0.6129,-0.162676 0.18637,0.08492 0.23192,0.06865 0.27561,-0.09842 0.0288,-0.110085 0.007,-0.330109 -0.0483,-0.488941 -0.0795,-0.227984 -0.0623,-0.358138 0.0815,-0.618181 0.28469,-0.514838 0.44838,-0.679396 0.6758,-0.679396 0.11575,0 0.26666,-0.09 0.33535,-0.2 0.0687,-0.11 0.20327,-0.200055 0.29906,-0.200122 0.0958,-6.7e-5 0.30067,-0.108932 0.4553,-0.241922 l 0.28116,-0.241801 -0.20351,-0.398901 c -0.11192,-0.219395 -0.23458,-0.59428 -0.27256,-0.833077 -0.038,-0.238798 -0.19667,-0.744116 -0.35265,-1.122931 -0.15597,-0.378814 -0.28359,-0.836225 -0.28359,-1.016467 l 0,-0.327714 -0.625,-0.04835 c -0.98556,-0.07625 -1.60735,-0.22958 -2.27567,-0.561168 -0.34092,-0.169149 -0.65653,-0.307543 -0.70136,-0.307543 -0.0448,0 -0.16395,0.166555 -0.26473,0.370122 -0.1912,0.386205 -0.63536,0.710058 -0.991,0.722569 -0.23456,0.0082 -1.17931,-0.358519 -1.87144,-0.726525 -0.73556,-0.3911 -1.41491,-0.533025 -1.80056,-0.376159 -0.8648,0.351765 -1.20885,0.269801 -1.47514,-0.351432 -0.1073,-0.250336 -0.1951,-0.53932 -0.1951,-0.642186 0,-0.125389 -0.14767,-0.252353 -0.44807,-0.385232 -0.24643,-0.109011 -0.56328,-0.313414 -0.70409,-0.454229 -0.14082,-0.140815 -0.38248,-0.321416 -0.53703,-0.401336 -0.24584,-0.127132 -0.30702,-0.127078 -0.48906,4e-4 -0.11444,0.08016 -0.2224,0.246591 -0.23991,0.369858 -0.028,0.197367 -0.0904,0.22412 -0.52228,0.22412 l -0.49045,0 -0.32524,-0.647242 c -0.17888,-0.355983 -0.53473,-0.879965 -0.79078,-1.164404 -0.25605,-0.28444 -0.5275,-0.600681 -0.60323,-0.702759 -0.11657,-0.157138 -0.16907,-0.166429 -0.34241,-0.06059 -0.27415,0.167382 -1.3509,0.16363 -1.49101,-0.0052 -0.0594,-0.07161 -0.10062,-0.398326 -0.0915,-0.726041 0.0124,-0.448949 -0.0327,-0.669551 -0.1832,-0.894805 -0.10984,-0.164428 -0.24291,-0.371397 -0.29571,-0.459932 -0.0528,-0.08854 -0.18125,-0.281825 -0.28546,-0.429533 -0.16516,-0.234094 -0.17441,-0.318846 -0.0721,-0.660408 0.0646,-0.215518 0.21385,-0.459408 0.33174,-0.541979 0.20655,-0.144677 0.20736,-0.15247 0.0221,-0.21457 -0.58713,-0.19678 -1.23104,-0.588221 -1.28239,-0.779582 -0.15006,-0.559163 0.14392,-1.158707 0.57238,-1.167344 0.14486,-0.0029 0.0843,-0.05191 -0.18094,-0.146356 C 77.424286,5.826567 77.300876,5.667996 77.095516,4.953688 76.933056,4.388642 76.902556,4.323317 76.556846,3.8 76.283366,3.386021 76.302046,3.008462 76.607946,2.767866 76.947306,2.500928 76.924316,2.45 76.464456,2.45 c -0.21642,0 -0.52017,-0.05098 -0.675,-0.113279 -0.15483,-0.0623 -0.73151,-0.127073 -1.28151,-0.143931 -0.81459,-0.02497 -1.08343,-0.07407 -1.45,-0.264826 -0.86865,-0.45204 -1.31588,-0.792602 -1.45609,-1.10882 L 71.460346,0.5 l 0.0607,0.419165 c 0.0486,0.335698 0.0185,0.472794 -0.1512,0.688486 -0.24691,0.313894 -0.27647,0.764232 -0.0618,0.942349 0.18135,0.150511 0.20238,0.907615 0.03,1.08 -0.16727,0.167268 -0.73052,0.150114 -0.87728,-0.02672 -0.067,-0.08069 -0.41327,-0.30974 -0.76956,-0.50899 -0.64196,-0.359003 -0.65346,-0.361289 -1.27368,-0.253283 -0.90165,0.157016 -1.31067,0.13554 -1.73336,-0.09101 -0.55274,-0.296248 -0.72612,-0.266175 -0.72612,0.125945 0,0.217645 0.0665,0.367446 0.2,0.450848 0.52325,0.326773 -0.006,1.123207 -0.74595,1.123207 -0.19473,0 -0.35405,0.04055 -0.35405,0.09012 0,0.14244 -0.60324,0.461372 -1.33027,0.703313 -0.70423,0.234351 -1.06973,0.5605 -1.06973,0.954552 0,0.580207 -1.535,1.141809 -1.90437,0.696743 -0.0709,-0.0854 -0.39487,-0.341858 -0.71998,-0.56991 -0.32511,-0.228052 -0.65636,-0.540837 -0.73613,-0.695079 l -0.14502,-0.280439 -0.30761,0.350349 c -0.18339,0.208871 -0.40006,0.350349 -0.53655,0.350349 -0.25758,0 -0.35034,0.168383 -0.35034,0.635928 0,0.473617 -0.22592,0.727802 -0.70384,0.791905 -0.22643,0.03037 -0.48694,0.121886 -0.57892,0.203369 -0.092,0.08148 -0.25689,0.164596 -0.36647,0.184695 -0.13057,0.02395 -0.21701,0.139508 -0.25083,0.335324 -0.0484,0.280498 -0.0883,0.303928 -0.65077,0.382935 -0.32954,0.04629 -0.79112,0.09489 -1.02572,0.108012 -0.24674,0.0138 -0.4786,0.09069 -0.55,0.182393 -0.0679,0.0872 -0.32595,0.183409 -0.57345,0.213809 -0.2475,0.0304 -0.63322,0.08316 -0.85715,0.117252 -0.45756,0.06965 -1.1073,-0.146635 -1.20495,-0.401107 -0.0326,-0.08498 -0.1145,-0.154515 -0.18196,-0.154515 -0.0675,0 -0.31675,-0.179181 -0.55397,-0.39818 -0.7191,-0.663872 -1.11285,-0.80182 -2.28865,-0.80182 l -1.02353,0 -0.14323,-0.325 c -0.21508,-0.488024 -0.39397,-0.675 -0.64578,-0.675 -0.13008,0 -0.36824,-0.149586 -0.55726,-0.35 -0.18155,-0.1925 -0.3712,-0.35 -0.42144,-0.35 -0.22615,0 -0.74613,-0.344878 -0.97766,-0.648429 -0.13969,-0.183138 -0.28096,-0.499249 -0.31394,-0.702468 -0.033,-0.203219 -0.17041,-0.479941 -0.30541,-0.614938 -0.15476,-0.154761 -0.22667,-0.317261 -0.19462,-0.439807 0.0413,-0.157952 -10e-4,-0.194358 -0.22633,-0.194358 -0.15243,0 -0.40357,-0.09944 -0.55809,-0.220989 -0.1851,-0.145599 -0.39023,-0.211573 -0.60129,-0.193388 -0.58571,0.05046 -1.51758,-0.183857 -2.08139,-0.52337 l -0.55042,-0.331442 -1.11943,0.191998 c -0.61568,0.105598 -1.2288,0.233582 -1.36248,0.284407 -0.25863,0.09833 -0.22913,0.292784 0.0444,0.292784 0.09,0 0.28984,0.120919 0.4441,0.268709 0.21573,0.206683 0.28047,0.361006 0.28047,0.668555 0,0.842568 -0.84824,1.150366 -1.65725,0.601358 -0.22818,-0.154844 -0.40001,-0.216831 -0.4216,-0.152084 -0.02,0.06011 -0.25799,0.229884 -0.52879,0.377271 -0.48434,0.263612 -0.49236,0.275804 -0.49236,0.748566 0,0.52341 -0.15283,0.687625 -0.63995,0.687625 -0.28158,0 -0.96005,-0.539733 -0.96005,-0.763732 0,-0.07866 -0.1575,-0.23594 -0.35,-0.349518 -0.1925,-0.113578 -0.35606,-0.28081 -0.36346,-0.371628 -0.007,-0.09082 -0.0187,-0.431407 -0.025,-0.756866 -0.011,-0.562299 -0.0258,-0.595599 -0.29728,-0.669225 -0.15716,-0.04261 -0.37232,-0.155822 -0.47812,-0.251572 -0.16644,-0.150629 -0.21028,-0.154776 -0.32531,-0.03077 -0.19585,0.211133 -0.42612,1.011719 -0.61649,2.143316 -0.0925,0.55 -0.20165,1.045 -0.2425,1.1 -0.0408,0.055 -0.10449,0.226388 -0.14143,0.380863 -0.0369,0.154475 -0.41955,0.649475 -0.850238,1.1 -0.731094,0.764766 -0.841268,0.94795 -1.086205,1.806018 -0.0942,0.330017 -0.0088,1.203525 0.216415,2.213119 0.08588,0.385 0.156924,0.996595 0.157879,1.3591 0.002,0.762471 -0.170574,2.248686 -0.295054,2.5409 -0.384989,0.903748 -0.58726,1.186976 -1.464038,2.05 -0.886311,0.872373 -1.839212,2.109443 -1.839212,2.387645 0,0.06329 -0.0402,0.193213 -0.08934,0.288717 -0.269141,0.523132 -0.349871,1.360217 -0.335004,3.473643 0.01102,1.566787 -0.028,2.455839 -0.135576,3.088874 -0.125279,0.737214 -0.130993,1.048224 -0.03349,1.822825 0.06466,0.513673 0.09586,1.047429 0.06935,1.186126 -0.042,0.219693 -0.01309,0.252175 0.22444,0.252175 0.292875,0 0.799619,0.338125 0.799619,0.533545 0,0.06547 0.10125,0.16345 0.225,0.217742 0.205555,0.09018 0.224403,0.16353 0.21809,0.848713 -0.0051,0.558014 -0.06274,0.8636 -0.225,1.193783 -0.236656,0.481562 -0.274957,0.759268 -0.11809,0.856217 0.055,0.03399 0.1,0.168797 0.1,0.299566 0,0.19476 0.05837,0.24343 0.32272,0.269098 0.222504,0.02161 0.359773,0.106077 0.442041,0.272022 0.15244,0.307488 0.631494,0.508445 1.22172,0.512494 0.254935,0.0018 0.55087,0.06925 0.657632,0.15 0.106762,0.08075 0.268538,0.14682 0.359501,0.14682 0.09096,0 0.244541,0.08746 0.341283,0.194361 0.09674,0.106898 0.291632,0.208148 0.433089,0.225 0.163578,0.01949 0.317318,0.139594 0.422368,0.329958 0.13162,0.238527 0.26596,0.319767 0.66143,0.4 0.75473,0.153117 1.17568,0.447589 1.31776,0.921842 0.0663,0.221123 0.12046,0.472916 0.12046,0.559539 0,0.259723 0.17905,0.290339 0.47286,0.08086 0.35126,-0.250443 2.05512,-0.505807 2.30908,-0.34607 0.0936,0.05885 0.19351,0.291715 0.22548,0.525348 0.0487,0.355971 0.17855,0.544024 0.85579,1.239404 0.43911,0.450869 0.85963,0.943512 0.93448,1.094762 0.1062,0.214583 0.2066,0.275 0.45696,0.275 0.17648,0 0.37688,0.0675 0.44535,0.15 0.0685,0.0825 0.18852,0.15 0.26679,0.15 0.0783,0 0.2512,0.108901 0.3843,0.242003 0.33067,0.330668 0.5648,0.356408 0.78117,0.08588 0.10025,-0.126266 0.2465,-0.228814 0.32501,-0.228814 0.09504,0 0.14274,-0.111134 0.14274,-0.332569 0,-0.690476 0.5776,-0.928775 1.73233,-0.714713 0.2837,0.05259 0.47002,0.02366 0.7222,-0.112152 0.30113,-0.162166 0.40492,-0.169383 0.91061,-0.06331 0.35225,0.07388 0.67126,0.216007 0.83328,0.371232 0.14439,0.138333 0.35006,0.25301 0.45705,0.254837 0.10699,0.0018 0.37453,0.135541 0.59453,0.297142 0.22,0.1616 0.5125,0.37071 0.65,0.464687 0.4111,0.280978 0.9,0.765853 0.9,0.892597 0,0.06518 0.15609,0.237572 0.34687,0.383088 0.23545,0.179586 0.38299,0.400225 0.45931,0.686869 0.12147,0.456279 0.34802,0.772295 0.55365,0.772295 0.0709,0 0.18763,0.0833 0.2595,0.185109 0.0719,0.101809 0.27334,0.258611 0.4477,0.348448 0.34721,0.178884 1.03297,0.956936 1.03297,1.171981 0,0.07422 0.13855,0.27789 0.30789,0.452606 0.20418,0.210657 0.32634,0.455146 0.36264,0.725792 0.0495,0.369367 0.0151,0.455414 -0.36214,0.906046 -0.39951,0.477171 -0.41415,0.518533 -0.35126,0.992627 0.0558,0.420831 0.0306,0.544936 -0.16895,0.83105 -0.40298,0.577781 -0.61665,0.786338 -0.80561,0.786338 -0.10041,0 -0.18257,0.06199 -0.18257,0.137756 0,0.303925 -0.27778,0.39341 -0.90678,0.292113 -0.54142,-0.08719 -0.61379,-0.07828 -0.70196,0.08646 -0.0541,0.101021 -0.20397,0.183674 -0.33312,0.183674 -0.15071,0 -0.25355,0.07163 -0.28711,0.2 -0.0288,0.11 -0.11877,0.2 -0.2,0.2 -0.20768,0 -0.28042,0.367714 -0.10204,0.515764 0.0972,0.08068 0.1342,0.244376 0.10728,0.47494 -0.0339,0.290518 0.008,0.393229 0.24133,0.589449 0.15532,0.130694 0.2824,0.295877 0.2824,0.367073 0,0.173717 0.36035,0.282183 0.85657,0.257831 0.26759,-0.01313 0.45125,0.03387 0.53725,0.137495 0.0994,0.119775 0.32633,0.157448 0.94842,0.157448 0.87304,0 1.05776,0.08208 1.05776,0.47 0,0.149604 0.0593,0.23 0.16962,0.23 0.17403,0 0.80486,0.385923 1.20538,0.737409 0.24837,0.217963 0.29412,0.631593 0.10939,0.988948 -0.0636,0.123004 -0.15359,0.301782 -0.2,0.397286 -0.0464,0.0955 -0.0844,0.422364 -0.0844,0.726357 0,0.513344 -0.081,0.771379 -0.3609,1.15 -0.18972,0.256619 -0.22635,0.586092 -0.0788,0.708568 0.0768,0.06376 0.13968,0.224025 0.13968,0.356152 0,0.324184 -0.40057,0.470426 -1.07705,0.39321 -0.62362,-0.07118 -0.65841,-0.02195 -0.77541,1.096989 -0.04,0.382295 -0.13331,0.814256 -0.20742,0.959915 -0.12767,0.250934 -0.12045,0.268401 0.13757,0.332791 0.32726,0.08167 0.62231,0.33037 0.62231,0.524546 0,0.07765 0.1125,0.288668 0.25,0.46894 0.1375,0.180272 0.25,0.422114 0.25,0.537426 0,0.115313 0.045,0.237471 0.1,0.271463 0.055,0.03399 0.1,0.169827 0.1,0.301855 0,0.310976 0.47333,0.748145 0.81002,0.748145 0.14414,0 0.42785,0.1125 0.63047,0.25 0.20261,0.1375 0.40813,0.25 0.4567,0.25 0.0486,0 0.19283,0.132062 0.32056,0.293471 0.19674,0.248595 0.32782,0.304089 0.85725,0.362916 0.51543,0.05727 0.625,0.0436 0.625,-0.07797 0,-0.280992 0.38733,-0.511179 0.91307,-0.542628 0.28054,-0.01678 0.56225,-0.07381 0.62601,-0.126721 0.19922,-0.165338 1.14298,-0.248448 1.30397,-0.11483 0.0794,0.0659 0.33567,0.13345 0.56947,0.150103 0.27723,0.01975 0.48126,0.09965 0.5866,0.229739 0.1604,0.198085 0.16348,0.19777 0.4464,-0.04559 0.23445,-0.201667 0.34857,-0.233095 0.64468,-0.177529 0.19789,0.03714 0.52348,0.07919 0.72353,0.09344 0.38399,0.02737 0.92233,0.34927 1.0815,0.646675 0.34204,0.639104 0.49516,1.511408 0.31518,1.795501 -0.0528,0.08333 -0.0329,0.239284 0.0509,0.4 0.0756,0.144879 0.13773,0.359157 0.13806,0.476173 0,0.117015 0.0712,0.271334 0.15747,0.34293 0.12922,0.107243 0.14479,0.263547 0.0884,0.887245 -0.0377,0.416388 -0.12813,0.825223 -0.20105,0.908522 -0.18725,0.213901 -0.99362,0.432924 -1.3056,0.354622 -0.17689,-0.0444 -0.3208,-0.01268 -0.4426,0.09754 -0.0993,0.08983 -0.37522,0.188095 -0.61324,0.218362 -0.23802,0.03027 -0.47776,0.088 -0.53276,0.128291 -0.23028,0.168702 -1.62454,0.207516 -2.06038,0.05736 -0.45508,-0.156789 -0.60521,-0.133222 -0.40795,0.06404 0.0651,0.06508 0.11833,0.24275 0.11833,0.394815 0,0.305791 -0.23403,0.483518 -0.63669,0.483518 -0.2884,0 -0.42709,0.288747 -0.27319,0.568745 0.0548,0.09969 0.12628,0.38889 0.15885,0.642665 0.0395,0.307702 0.14113,0.538371 0.30512,0.692432 0.13525,0.127061 0.24591,0.29545 0.24591,0.374197 0,0.07875 0.1125,0.231669 0.25,0.339827 0.1375,0.108158 0.25,0.281818 0.25,0.385912 0,0.286898 0.58138,0.896222 0.85512,0.896222 0.15125,0 0.46682,0.222362 0.88964,0.626868 0.36038,0.344777 0.65524,0.661152 0.65524,0.703055 0,0.0419 0.16284,0.219159 0.36186,0.393902 0.19902,0.174743 0.46958,0.488368 0.60125,0.696945 0.13167,0.208576 0.29508,0.379209 0.36314,0.379184 0.0681,-2.5e-5 0.30512,-0.326275 0.52679,-0.725 0.34989,-0.629369 0.38973,-0.762546 0.30213,-1.010068 -0.0904,-0.255484 -0.0672,-0.31524 0.22355,-0.575 0.31963,-0.285593 0.65715,-0.374555 0.76415,-0.201416 0.0809,0.130915 0.6217,0.213275 1.36167,0.207378 0.39183,-0.0031 0.76879,0.05406 0.9392,0.142467 0.25521,0.132406 0.31134,0.130304 0.54252,-0.02031 0.14181,-0.0924 0.41066,-0.33675 0.59743,-0.543 0.27643,-0.305256 0.40876,-0.375 0.71154,-0.375 0.47733,0 1.30477,0.606618 1.30477,0.956568 0,0.235935 0.45608,0.643432 0.72014,0.643432 0.17708,0 0.83885,0.685419 0.91808,0.950894 0.033,0.110492 0.1603,0.245492 0.28294,0.3 0.14105,0.06269 0.24849,0.225918 0.2924,0.44422 0.0382,0.189813 0.14374,0.399466 0.23458,0.465895 0.18184,0.132963 1.23635,0.338991 1.73505,0.338991 0.29412,0 0.31681,-0.02454 0.31681,-0.342742 0,-0.241009 0.07,-0.397812 0.23587,-0.528277 0.17961,-0.14128 0.22536,-0.257146 0.1918,-0.485766 -0.0311,-0.212118 0.0369,-0.423932 0.2319,-0.721723 0.15177,-0.231821 0.3114,-0.421492 0.35471,-0.421492 0.0433,0 0.22764,-0.130715 0.4096,-0.290477 0.21643,-0.190032 0.49563,-0.315189 0.8074,-0.361943 0.53517,-0.08025 0.74108,0.03819 1.03193,0.593591 0.089,0.169856 0.22692,0.432579 0.30659,0.583829 0.0797,0.15125 0.2203,0.277262 0.31252,0.280028 0.92882,0.02785 1.41768,0.219586 1.41768,0.55603 0,0.267917 0.53055,0.899749 1.01064,1.20356 0.5219,0.330272 0.88936,0.346476 0.88936,0.03922 0,-0.246541 0.29123,-0.467986 0.71527,-0.543876 0.22861,-0.04091 0.42504,-0.156581 0.525,-0.309148 0.2188,-0.33392 0.20047,-1.028928 -0.0403,-1.527198 -0.20508,-0.424469 -0.26789,-1.069852 -0.11341,-1.165326 0.0476,-0.02943 0.0663,-0.159498 0.0416,-0.289033 -0.0439,-0.22978 0.33925,-0.922935 0.60285,-1.090538 0.42274,-0.268786 1.16775,0.121883 1.17036,0.613714 0.003,0.559028 0.10074,0.707569 0.46578,0.707569 0.1891,0 0.54371,0.09106 0.78801,0.202353 0.24431,0.111294 0.55682,0.245172 0.69447,0.297507 0.32442,0.123345 0.66791,0.678513 0.62412,1.00874 l -0.0343,0.258599 0.34797,-0.236134 c 0.4507,-0.305858 0.77828,-0.38402 0.96388,-0.229987 0.11857,0.0984 0.1487,0.0972 0.1487,-0.006 0,-0.231574 0.32448,-0.495119 0.6096,-0.495119 0.15323,0 0.30641,-0.045 0.3404,-0.1 0.034,-0.055 0.16082,-0.1 0.28185,-0.1 0.12102,0 0.27625,-0.09 0.34494,-0.2 0.0687,-0.11 0.20327,-0.201426 0.29906,-0.203168 0.13413,-0.0024 0.11095,-0.05032 -0.10085,-0.208341 -0.54456,-0.406287 -0.33794,-0.754084 0.78365,-1.319065 0.45796,-0.23069 0.5045,-0.284512 0.46699,-0.540076 -0.0825,-0.562472 0.0896,-0.610043 2.577,-0.711988 1.48171,-0.06073 2.28995,-0.05817 2.37236,0.0075 0.20626,0.164372 0.14272,0.612284 -0.17534,1.236082 -0.16519,0.323975 -0.3262,0.724756 -0.35781,0.890624 -0.0782,0.410055 0.22388,0.776012 0.77595,0.940178 0.75894,0.225683 1.36576,0.530141 1.65189,0.828794 0.23874,0.249194 0.28132,0.382262 0.30053,0.939251 0.0235,0.680494 0.21529,1.08281 0.70208,1.472457 0.16606,0.132922 0.2277,0.286651 0.2277,0.567908 0,0.334269 0.069,0.451438 0.51764,0.87944 0.51394,0.490268 0.51804,0.499057 0.575,1.232092 0.0558,0.718856 0.0648,0.73915 0.33821,0.770509 0.5007,0.05742 0.90417,1.142779 0.55471,1.492239 -0.15842,0.15842 0.0812,0.72556 0.30657,0.72556 0.2653,0 0.40787,0.21019 0.40787,0.60129 0,0.2709 -0.0751,0.4332 -0.3,0.64871 -0.165,0.15808 -0.3,0.34043 -0.3,0.40522 0,0.0648 -0.0868,0.22815 -0.19287,0.36301 -0.10608,0.13486 -0.20733,0.42217 -0.225,0.63848 l -0.0321,0.39329 -0.94195,0.029 c -0.61795,0.019 -1.1167,-0.0221 -1.45,-0.11939 -0.27943,-0.0816 -0.74044,-0.17443 -1.02447,-0.20629 l -0.51641,-0.0579 -0.37615,0.4773 c -0.7356,0.93341 -1.06581,1.05424 -1.44102,0.52731 -0.14918,-0.20951 -0.29703,-0.3 -0.49014,-0.3 -0.15209,0 -0.3072,-0.0307 -0.34468,-0.0682 -0.0375,-0.0375 -0.30486,-0.0572 -0.59416,-0.0438 -0.46434,0.0215 -0.57872,-0.0159 -0.97572,-0.31902 l -0.44971,-0.34338 -0.49144,0.23717 c -0.27029,0.13045 -0.56334,0.23718 -0.65123,0.23718 -0.22777,0 -0.50292,0.517 -0.50292,0.94497 0,0.47646 -0.33074,0.80885 -0.90062,0.90513 -0.23799,0.0402 -0.56142,0.15138 -0.71872,0.24704 -0.25695,0.15626 -0.26963,0.18753 -0.12482,0.30771 0.1066,0.0885 0.14607,0.23681 0.11654,0.43799 -0.0296,0.20167 0.0687,0.56897 0.29149,1.08955 0.39076,0.91296 0.42633,1.26275 0.13613,1.33864 -0.11,0.0288 -0.2,0.10904 -0.2,0.17839 0,0.0694 -0.0666,0.18134 -0.14793,0.24886 -0.0814,0.0675 -0.21708,0.26139 -0.3016,0.43083 -0.14973,0.30014 -0.14529,0.31712 0.17292,0.66102 0.17964,0.19413 0.40536,0.41332 0.50161,0.48709 0.28368,0.21742 0.22563,0.70303 -0.10687,0.89385 -0.26631,0.15284 -0.27946,0.19258 -0.23828,0.72035 0.0326,0.4175 0.10036,0.60908 0.26839,0.75857 0.12364,0.11 0.32665,0.35006 0.45112,0.533472 0.19683,0.29001 0.21987,0.42333 0.17693,1.02353 -0.0549,0.76785 -0.16461,0.96654 -0.55861,1.01207 -0.25635,0.0296 -0.26768,0.0558 -0.26768,0.61839 0,0.67716 -0.0151,0.69143 -0.925,0.87661 l -0.625,0.12719 0,0.36712 c 0,0.47255 -0.15529,0.59131 -0.86809,0.66392 -0.40292,0.041 -0.6221,0.11594 -0.71258,0.24349 -0.11426,0.16107 -0.27818,0.18421 -1.30506,0.18421 -1.15908,0 -1.71179,0.11701 -1.71349,0.36276 -0.002,0.26735 -0.50281,0.46443 -1.54472,0.60769 -0.5025,0.0691 -0.74841,0.35807 -0.75273,0.88455 -0.004,0.44121 -0.13951,0.645 -0.43007,0.645 -0.14713,0 -0.17232,0.0477 -0.11876,0.225 0.0374,0.12375 0.10792,0.26775 0.15674,0.32 0.14215,0.15215 0.1024,0.71919 -0.0599,0.85386 -0.0817,0.0678 -0.30675,0.10488 -0.5,0.0823 -0.35136,-0.041 -0.35138,-0.041 -0.35138,0.3689 0,0.22546 -0.0431,0.45304 -0.0958,0.50574 -0.0527,0.0527 -0.12635,0.63609 -0.16367,1.29641 -0.059,1.04354 -0.0464,1.21836 0.0958,1.33642 0.09,0.0747 0.16367,0.20213 0.16367,0.28316 0,0.22104 0.37764,0.70762 0.60527,0.77986 0.11003,0.0349 0.42151,0.3296 0.69217,0.65482 0.27066,0.32523 0.51961,0.54682 0.55323,0.49242 0.11401,-0.18446 0.61848,-0.10864 0.76717,0.11531 0.1203,0.18118 0.25122,0.21755 0.84873,0.23578 0.38857,0.0119 0.74945,0.0481 0.80195,0.0805 0.17576,0.10863 0.84882,1.49401 0.99096,2.03972 0.17774,0.6824 0.17593,0.90948 -0.0101,1.26617 -0.0822,0.15754 -0.14938,0.29624 -0.14938,0.30823 0,0.012 0.23625,0.003 0.525,-0.0207 0.34113,-0.0276 0.6826,0.0163 0.975,0.12551 0.53574,0.20003 0.98064,0.19906 1.20349,-0.003 0.0892,-0.0808 0.21496,-0.14684 0.27938,-0.14684 0.0644,0 0.11713,-0.0752 0.11713,-0.16713 0,-0.18467 0.27754,-0.53287 0.42473,-0.53287 0.0516,0 0.20814,-0.09 0.34798,-0.19999 0.30538,-0.24021 0.60461,-0.25477 0.90546,-0.044 0.21309,0.14926 0.24029,0.1366 0.63252,-0.29439 0.22542,-0.24769 0.50482,-0.46413 0.62088,-0.48096 0.14348,-0.0208 0.23057,-0.12679 0.27208,-0.33108 0.0865,-0.42557 0.58137,-1.13664 0.909,-1.30607 0.62353,-0.32244 1.08735,-0.06 1.08735,0.61536 0,0.33888 0.0425,0.46059 0.175,0.50154 0.34157,0.10555 0.47536,0.21249 0.50408,0.40291 0.016,0.10605 0.12849,0.23645 0.25,0.28978 0.17205,0.0755 0.22302,0.18544 0.23043,0.49696 0.0125,0.52336 0.10158,0.78379 0.34304,1.00231 0.25603,0.23169 0.25918,0.70761 0.006,0.84334 -0.20553,0.10999 -0.35766,0.59153 -0.31982,1.01233 0.0128,0.14188 -0.0456,0.31511 -0.12978,0.38494 -0.12471,0.1035 -0.65853,1.13232 -0.65853,1.26916 0,0.0209 0.0605,0.0379 0.1345,0.0379 0.074,0 0.22023,0.0958 0.325,0.21296 0.37419,0.4183 0.99521,0.59948 1.80369,0.52622 0.49538,-0.0449 0.77824,-0.0293 0.87145,0.0481 0.18361,0.15238 0.32139,1.77474 0.16657,1.96129 -0.0842,0.1015 -0.0476,0.19593 0.15409,0.39767 0.25625,0.25625 0.26235,0.2896 0.19405,1.06118 -0.0506,0.57099 -0.036,0.83827 0.0515,0.94369 0.0673,0.0811 0.10076,0.29227 0.0745,0.47093 -0.0501,0.3411 0.24529,0.87799 0.48301,0.87799 0.14704,0 0.71534,0.63307 0.8669,0.96571 l 0.10985,0.24109 0.11655,-0.2784 c 0.0641,-0.15312 0.19696,-0.5259 0.29524,-0.8284 z"></path>
</svg>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="path-data-polyfill.js"></script>
<script>
var svg = d3.select("svg"),
path = svg.select("path"),
segments = path.node().getPathData(),
segment,
segmentValues,
x = 0,
y = 0,
points = [],
m,
n = segments.length - 1, // drop Z
i = -1;
while (++i < n) {
segment = segments[i];
segmentValues = segment.values;
m = segmentValues.length;
points.push(/[a-z]/.test(segment.type)
? [x += segmentValues[m - 2], y += segmentValues[m - 1]]
: [x = segmentValues[m - 2], y = segmentValues[m - 1]]);
}
svg.append("path")
.style("fill", "none")
.style("stroke", "red")
.style("stroke-linejoin", "round")
.attr("d", "M" + points[0] + "L" + points.slice(1).join(" "));
</script>
// @info
// Polyfill for SVG 2 getPathData() and setPathData() methods. Based on:
// - SVGPathSeg polyfill by Philip Rogers (MIT License)
// https://github.com/progers/pathseg
// - SVGPathNormalizer by Tadahisa Motooka (MIT License)
// https://github.com/motooka/SVGPathNormalizer/tree/master/src
// - arcToCubicCurves() by Dmitry Baranovskiy (MIT License)
// https://github.com/DmitryBaranovskiy/raphael/blob/v2.1.1/raphael.core.js#L1837
// @author
// Jarosław Foksa
// @license
// MIT License
if (!SVGPathElement.prototype.getPathData || !SVGPathElement.prototype.setPathData) {
(function() {
var commandsMap = {
"Z":"Z", "M":"M", "L":"L", "C":"C", "Q":"Q", "A":"A", "H":"H", "V":"V", "S":"S", "T":"T",
"z":"Z", "m":"m", "l":"l", "c":"c", "q":"q", "a":"a", "h":"h", "v":"v", "s":"s", "t":"t"
};
var Source = function(string) {
this._string = string;
this._currentIndex = 0;
this._endIndex = this._string.length;
this._prevCommand = null;
this._skipOptionalSpaces();
};
var isIE = window.navigator.userAgent.indexOf("MSIE ") !== -1;
Source.prototype = {
parseSegment: function() {
var char = this._string[this._currentIndex];
var command = commandsMap[char] ? commandsMap[char] : null;
if (command === null) {
// Possibly an implicit command. Not allowed if this is the first command.
if (this._prevCommand === null) {
return null;
}
// Check for remaining coordinates in the current command.
if (
(char === "+" || char === "-" || char === "." || (char >= "0" && char <= "9")) && this._prevCommand !== "Z"
) {
if (this._prevCommand === "M") {
command = "L";
}
else if (this._prevCommand === "m") {
command = "l";
}
else {
command = this._prevCommand;
}
}
else {
command = null;
}
if (command === null) {
return null;
}
}
else {
this._currentIndex += 1;
}
this._prevCommand = command;
var values = null;
var cmd = command.toUpperCase();
if (cmd === "H" || cmd === "V") {
values = [this._parseNumber()];
}
else if (cmd === "M" || cmd === "L" || cmd === "T") {
values = [this._parseNumber(), this._parseNumber()];
}
else if (cmd === "S" || cmd === "Q") {
values = [this._parseNumber(), this._parseNumber(), this._parseNumber(), this._parseNumber()];
}
else if (cmd === "C") {
values = [
this._parseNumber(),
this._parseNumber(),
this._parseNumber(),
this._parseNumber(),
this._parseNumber(),
this._parseNumber()
];
}
else if (cmd === "A") {
values = [
this._parseNumber(),
this._parseNumber(),
this._parseNumber(),
this._parseArcFlag(),
this._parseArcFlag(),
this._parseNumber(),
this._parseNumber()
];
}
else if (cmd === "Z") {
this._skipOptionalSpaces();
values = [];
}
if (values === null || values.indexOf(null) >= 0) {
// Unknown command or known command with invalid values
return null;
}
else {
return {type: command, values: values};
}
},
hasMoreData: function() {
return this._currentIndex < this._endIndex;
},
peekSegmentType: function() {
var char = this._string[this._currentIndex];
return commandsMap[char] ? commandsMap[char] : null;
},
initialCommandIsMoveTo: function() {
// If the path is empty it is still valid, so return true.
if (!this.hasMoreData()) {
return true;
}
var command = this.peekSegmentType();
// Path must start with moveTo.
return command === "M" || command === "m";
},
_isCurrentSpace: function() {
var char = this._string[this._currentIndex];
return char <= " " && (char === " " || char === "\n" || char === "\t" || char === "\r" || char === "\f");
},
_skipOptionalSpaces: function() {
while (this._currentIndex < this._endIndex && this._isCurrentSpace()) {
this._currentIndex += 1;
}
return this._currentIndex < this._endIndex;
},
_skipOptionalSpacesOrDelimiter: function() {
if (
this._currentIndex < this._endIndex &&
!this._isCurrentSpace() &&
this._string[this._currentIndex] !== ","
) {
return false;
}
if (this._skipOptionalSpaces()) {
if (this._currentIndex < this._endIndex && this._string[this._currentIndex] === ",") {
this._currentIndex += 1;
this._skipOptionalSpaces();
}
}
return this._currentIndex < this._endIndex;
},
// Parse a number from an SVG path. This very closely follows genericParseNumber(...) from
// Source/core/svg/SVGParserUtilities.cpp.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
_parseNumber: function() {
var exponent = 0;
var integer = 0;
var frac = 1;
var decimal = 0;
var sign = 1;
var expsign = 1;
var startIndex = this._currentIndex;
this._skipOptionalSpaces();
// Read the sign.
if (this._currentIndex < this._endIndex && this._string[this._currentIndex] === "+") {
this._currentIndex += 1;
}
else if (this._currentIndex < this._endIndex && this._string[this._currentIndex] === "-") {
this._currentIndex += 1;
sign = -1;
}
if (
this._currentIndex === this._endIndex ||
(
(this._string[this._currentIndex] < "0" || this._string[this._currentIndex] > "9") &&
this._string[this._currentIndex] !== "."
)
) {
// The first character of a number must be one of [0-9+-.].
return null;
}
// Read the integer part, build right-to-left.
var startIntPartIndex = this._currentIndex;
while (
this._currentIndex < this._endIndex &&
this._string[this._currentIndex] >= "0" &&
this._string[this._currentIndex] <= "9"
) {
this._currentIndex += 1; // Advance to first non-digit.
}
if (this._currentIndex !== startIntPartIndex) {
var scanIntPartIndex = this._currentIndex - 1;
var multiplier = 1;
while (scanIntPartIndex >= startIntPartIndex) {
integer += multiplier * (this._string[scanIntPartIndex] - "0");
scanIntPartIndex -= 1;
multiplier *= 10;
}
}
// Read the decimals.
if (this._currentIndex < this._endIndex && this._string[this._currentIndex] === ".") {
this._currentIndex += 1;
// There must be a least one digit following the .
if (
this._currentIndex >= this._endIndex ||
this._string[this._currentIndex] < "0" ||
this._string[this._currentIndex] > "9"
) {
return null;
}
while (
this._currentIndex < this._endIndex &&
this._string[this._currentIndex] >= "0" &&
this._string[this._currentIndex] <= "9"
) {
decimal += (this._string[this._currentIndex] - "0") * (frac *= 0.1);
this._currentIndex += 1;
}
}
// Read the exponent part.
if (
this._currentIndex !== startIndex &&
this._currentIndex + 1 < this._endIndex &&
(this._string[this._currentIndex] === "e" || this._string[this._currentIndex] === "E") &&
(this._string[this._currentIndex + 1] !== "x" && this._string[this._currentIndex + 1] !== "m")
) {
this._currentIndex += 1;
// Read the sign of the exponent.
if (this._string[this._currentIndex] === "+") {
this._currentIndex += 1;
}
else if (this._string[this._currentIndex] === "-") {
this._currentIndex += 1;
expsign = -1;
}
// There must be an exponent.
if (
this._currentIndex >= this._endIndex ||
this._string[this._currentIndex] < "0" ||
this._string[this._currentIndex] > "9"
) {
return null;
}
while (
this._currentIndex < this._endIndex &&
this._string[this._currentIndex] >= "0" &&
this._string[this._currentIndex] <= "9"
) {
exponent *= 10;
exponent += (this._string[this._currentIndex] - "0");
this._currentIndex += 1;
}
}
var number = integer + decimal;
number *= sign;
if (exponent) {
number *= Math.pow(10, expsign * exponent);
}
if (startIndex === this._currentIndex) {
return null;
}
this._skipOptionalSpacesOrDelimiter();
return number;
},
_parseArcFlag: function() {
if (this._currentIndex >= this._endIndex) {
return null;
}
var flag = null;
var flagChar = this._string[this._currentIndex];
this._currentIndex += 1;
if (flagChar === "0") {
flag = 0;
}
else if (flagChar === "1") {
flag = 1;
}
else {
return null;
}
this._skipOptionalSpacesOrDelimiter();
return flag;
}
};
var parsePathDataString = function(string) {
if (!string || string.length === 0) return [];
var source = new Source(string);
var pathData = [];
if (source.initialCommandIsMoveTo()) {
while (source.hasMoreData()) {
var pathSeg = source.parseSegment();
if (pathSeg === null) {
break;
}
else {
pathData.push(pathSeg);
}
}
}
return pathData;
}
var setAttribute = SVGPathElement.prototype.setAttribute;
var removeAttribute = SVGPathElement.prototype.removeAttribute;
var symbols;
if (window.Symbol) {
symbols = {cachedPathData: Symbol(), cachedNormalizedPathData: Symbol()};
}
else {
symbols = {cachedPathData: "__cachedPathData", cachedNormalizedPathData: "__cachedNormalizedPathData"};
}
// @info
// Get an array of corresponding cubic bezier curve parameters for given arc curve paramters.
var arcToCubicCurves = function(x1, y1, x2, y2, r1, r2, angle, largeArcFlag, sweepFlag, _recursive) {
var degToRad = function(degrees) {
return (Math.PI * degrees) / 180;
};
var rotate = function(x, y, angleRad) {
var X = x * Math.cos(angleRad) - y * Math.sin(angleRad);
var Y = x * Math.sin(angleRad) + y * Math.cos(angleRad);
return {x: X, y: Y};
};
var angleRad = degToRad(angle);
var params = [];
var f1, f2, cx, cy;
if (_recursive) {
f1 = _recursive[0];
f2 = _recursive[1];
cx = _recursive[2];
cy = _recursive[3];
}
else {
var p1 = rotate(x1, y1, -angleRad);
x1 = p1.x;
y1 = p1.y;
var p2 = rotate(x2, y2, -angleRad);
x2 = p2.x;
y2 = p2.y;
var x = (x1 - x2) / 2;
var y = (y1 - y2) / 2;
var h = (x * x) / (r1 * r1) + (y * y) / (r2 * r2);
if (h > 1) {
h = Math.sqrt(h);
r1 = h * r1;
r2 = h * r2;
}
var sign;
if (largeArcFlag === sweepFlag) {
sign = -1;
}
else {
sign = 1;
}
var r1Pow = r1 * r1;
var r2Pow = r2 * r2;
var left = r1Pow * r2Pow - r1Pow * y * y - r2Pow * x * x;
var right = r1Pow * y * y + r2Pow * x * x;
var k = sign * Math.sqrt(Math.abs(left/right));
cx = k * r1 * y / r2 + (x1 + x2) / 2;
cy = k * -r2 * x / r1 + (y1 + y2) / 2;
f1 = Math.asin(((y1 - cy) / r2).toFixed(9));
f2 = Math.asin(((y2 - cy) / r2).toFixed(9));
if (x1 < cx) {
f1 = Math.PI - f1;
}
if (x2 < cx) {
f2 = Math.PI - f2;
}
if (f1 < 0) {
f1 = Math.PI * 2 + f1;
}
if (f2 < 0) {
f2 = Math.PI * 2 + f2;
}
if (sweepFlag && f1 > f2) {
f1 = f1 - Math.PI * 2;
}
if (!sweepFlag && f2 > f1) {
f2 = f2 - Math.PI * 2;
}
}
var df = f2 - f1;
if (Math.abs(df) > (Math.PI * 120 / 180)) {
var f2old = f2;
var x2old = x2;
var y2old = y2;
if (sweepFlag && f2 > f1) {
f2 = f1 + (Math.PI * 120 / 180) * (1);
}
else {
f2 = f1 + (Math.PI * 120 / 180) * (-1);
}
x2 = cx + r1 * Math.cos(f2);
y2 = cy + r2 * Math.sin(f2);
params = arcToCubicCurves(x2, y2, x2old, y2old, r1, r2, angle, 0, sweepFlag, [f2, f2old, cx, cy]);
}
df = f2 - f1;
var c1 = Math.cos(f1);
var s1 = Math.sin(f1);
var c2 = Math.cos(f2);
var s2 = Math.sin(f2);
var t = Math.tan(df / 4);
var hx = 4 / 3 * r1 * t;
var hy = 4 / 3 * r2 * t;
var m1 = [x1, y1];
var m2 = [x1 + hx * s1, y1 - hy * c1];
var m3 = [x2 + hx * s2, y2 - hy * c2];
var m4 = [x2, y2];
m2[0] = 2 * m1[0] - m2[0];
m2[1] = 2 * m1[1] - m2[1];
if (_recursive) {
return [m2, m3, m4].concat(params);
}
else {
params = [m2, m3, m4].concat(params).join().split(",");
var curves = [];
var curveParams = [];
params.forEach( function(param, i) {
if (i % 2) {
curveParams.push(rotate(params[i - 1], params[i], angleRad).y);
}
else {
curveParams.push(rotate(params[i], params[i + 1], angleRad).x);
}
if (curveParams.length === 6) {
curves.push(curveParams);
curveParams = [];
}
});
return curves;
}
};
var clonePathData = function(pathData) {
return pathData.map( function(seg) {
return {type: seg.type, values: Array.prototype.slice.call(seg.values)}
});
};
// @info
// Takes any path data, returns path data that consists only from absolute commands.
var absolutizePathData = function(pathData) {
var absolutizedPathData = [];
var currentX = null;
var currentY = null;
var subpathX = null;
var subpathY = null;
pathData.forEach( function(seg) {
var type = seg.type;
if (type === "M") {
var x = seg.values[0];
var y = seg.values[1];
absolutizedPathData.push({type: "M", values: [x, y]});
subpathX = x;
subpathY = y;
currentX = x;
currentY = y;
}
else if (type === "m") {
var x = currentX + seg.values[0];
var y = currentY + seg.values[1];
absolutizedPathData.push({type: "M", values: [x, y]});
subpathX = x;
subpathY = y;
currentX = x;
currentY = y;
}
else if (type === "L") {
var x = seg.values[0];
var y = seg.values[1];
absolutizedPathData.push({type: "L", values: [x, y]});
currentX = x;
currentY = y;
}
else if (type === "l") {
var x = currentX + seg.values[0];
var y = currentY + seg.values[1];
absolutizedPathData.push({type: "L", values: [x, y]});
currentX = x;
currentY = y;
}
else if (type === "C") {
var x1 = seg.values[0];
var y1 = seg.values[1];
var x2 = seg.values[2];
var y2 = seg.values[3];
var x = seg.values[4];
var y = seg.values[5];
absolutizedPathData.push({type: "C", values: [x1, y1, x2, y2, x, y]});
currentX = x;
currentY = y;
}
else if (type === "c") {
var x1 = currentX + seg.values[0];
var y1 = currentY + seg.values[1];
var x2 = currentX + seg.values[2];
var y2 = currentY + seg.values[3];
var x = currentX + seg.values[4];
var y = currentY + seg.values[5];
absolutizedPathData.push({type: "C", values: [x1, y1, x2, y2, x, y]});
currentX = x;
currentY = y;
}
else if (type === "Q") {
var x1 = seg.values[0];
var y1 = seg.values[1];
var x = seg.values[2];
var y = seg.values[3];
absolutizedPathData.push({type: "Q", values: [x1, y1, x, y]});
currentX = x;
currentY = y;
}
else if (type === "q") {
var x1 = currentX + seg.values[0];
var y1 = currentY + seg.values[1];
var x = currentX + seg.values[2];
var y = currentY + seg.values[3];
absolutizedPathData.push({type: "Q", values: [x1, y1, x, y]});
currentX = x;
currentY = y;
}
else if (type === "A") {
var x = seg.values[5];
var y = seg.values[6];
absolutizedPathData.push({
type: "A",
values: [seg.values[0], seg.values[1], seg.values[2], seg.values[3], seg.values[4], x, y]
});
currentX = x;
currentY = y;
}
else if (type === "a") {
var x = currentX + seg.values[5];
var y = currentY + seg.values[6];
absolutizedPathData.push({
type: "A",
values: [seg.values[0], seg.values[1], seg.values[2], seg.values[3], seg.values[4], x, y]
});
currentX = x;
currentY = y;
}
else if (type === "H") {
var x = seg.values[0];
absolutizedPathData.push({type: "H", values: [x]});
currentX = x;
}
else if (type === "h") {
var x = currentX + seg.values[0];
absolutizedPathData.push({type: "H", values: [x]});
currentX = x;
}
else if (type === "V") {
var y = seg.values[0];
absolutizedPathData.push({type: "V", values: [y]});
currentY = y;
}
else if (type === "v") {
var y = currentY + seg.values[0];
absolutizedPathData.push({type: "V", values: [y]});
currentY = y;
}
else if (type === "S") {
var x2 = seg.values[0];
var y2 = seg.values[1];
var x = seg.values[2];
var y = seg.values[3];
absolutizedPathData.push({type: "S", values: [x2, y2, x, y]});
currentX = x;
currentY = y;
}
else if (type === "s") {
var x2 = currentX + seg.values[0];
var y2 = currentY + seg.values[1];
var x = currentX + seg.values[2];
var y = currentY + seg.values[3];
absolutizedPathData.push({type: "S", values: [x2, y2, x, y]});
currentX = x;
currentY = y;
}
else if (type === "T") {
var x = seg.values[0];
var y = seg.values[1]
absolutizedPathData.push({type: "T", values: [x, y]});
currentX = x;
currentY = y;
}
else if (type === "t") {
var x = currentX + seg.values[0];
var y = currentY + seg.values[1]
absolutizedPathData.push({type: "T", values: [x, y]});
currentX = x;
currentY = y;
}
else if (type === "Z" || type === "z") {
absolutizedPathData.push({type: "Z", values: []});
currentX = subpathX;
currentY = subpathY;
}
});
return absolutizedPathData;
};
// @info
// Takes path data that consists only from absolute commands, returns path data that consists only from
// "M", "L", "C" and "Z" commands.
var reducePathData = function(pathData) {
var reducedPathData = [];
var lastType = null;
var lastControlX = null;
var lastControlY = null;
var currentX = null;
var currentY = null;
var subpathX = null;
var subpathY = null;
pathData.forEach( function(seg) {
if (seg.type === "M") {
var x = seg.values[0];
var y = seg.values[1];
reducedPathData.push({type: "M", values: [x, y]});
subpathX = x;
subpathY = y;
currentX = x;
currentY = y;
}
else if (seg.type === "C") {
var x1 = seg.values[0];
var y1 = seg.values[1];
var x2 = seg.values[2];
var y2 = seg.values[3];
var x = seg.values[4];
var y = seg.values[5];
reducedPathData.push({type: "C", values: [x1, y1, x2, y2, x, y]});
lastControlX = x2;
lastControlY = y2;
currentX = x;
currentY = y;
}
else if (seg.type === "L") {
var x = seg.values[0];
var y = seg.values[1];
reducedPathData.push({type: "L", values: [x, y]});
currentX = x;
currentY = y;
}
else if (seg.type === "H") {
var x = seg.values[0];
reducedPathData.push({type: "L", values: [x, currentY]});
currentX = x;
}
else if (seg.type === "V") {
var y = seg.values[0];
reducedPathData.push({type: "L", values: [currentX, y]});
currentY = y;
}
else if (seg.type === "S") {
var x2 = seg.values[0];
var y2 = seg.values[1];
var x = seg.values[2];
var y = seg.values[3];
var cx1, cy1;
if (lastType === "C" || lastType === "S") {
cx1 = currentX + (currentX - lastControlX);
cy1 = currentY + (currentY - lastControlY);
}
else {
cx1 = currentX;
cy1 = currentY;
}
reducedPathData.push({type: "C", values: [cx1, cy1, x2, y2, x, y]});
lastControlX = x2;
lastControlY = y2;
currentX = x;
currentY = y;
}
else if (seg.type === "T") {
var x = seg.values[0];
var y = seg.values[1];
var x1, y1;
if (lastType === "Q" || lastType === "T") {
x1 = currentX + (currentX - lastControlX);
y1 = currentY + (currentY - lastControlY);
}
else {
x1 = currentX;
y1 = currentY;
}
var cx1 = currentX + 2 * (x1 - currentX) / 3;
var cy1 = currentY + 2 * (y1 - currentY) / 3;
var cx2 = x + 2 * (x1 - x) / 3;
var cy2 = y + 2 * (y1 - y) / 3;
reducedPathData.push({type: "C", values: [cx1, cy1, cx2, cy2, x, y]});
lastControlX = x1;
lastControlY = y1;
currentX = x;
currentY = y;
}
else if (seg.type === "Q") {
var x1 = seg.values[0];
var y1 = seg.values[1];
var x = seg.values[2];
var y = seg.values[3];
var cx1 = currentX + 2 * (x1 - currentX) / 3;
var cy1 = currentY + 2 * (y1 - currentY) / 3;
var cx2 = x + 2 * (x1 - x) / 3;
var cy2 = y + 2 * (y1 - y) / 3;
reducedPathData.push({type: "C", values: [cx1, cy1, cx2, cy2, x, y]});
lastControlX = x1;
lastControlY = y1;
currentX = x;
currentY = y;
}
else if (seg.type === "A") {
var r1 = seg.values[0];
var r2 = seg.values[1];
var angle = seg.values[2];
var largeArcFlag = seg.values[3];
var sweepFlag = seg.values[4];
var x = seg.values[5];
var y = seg.values[6];
if (r1 === 0 || r2 === 0) {
reducedPathData.push({type: "C", values: [currentX, currentY, x, y, x, y]});
currentX = x;
currentY = y;
}
else {
if (currentX !== x || currentY !== y) {
var curves = arcToCubicCurves(currentX, currentY, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
curves.forEach( function(curve) {
reducedPathData.push({type: "C", values: curve});
currentX = x;
currentY = y;
});
}
}
}
else if (seg.type === "Z") {
reducedPathData.push(seg);
currentX = subpathX;
currentY = subpathY;
}
lastType = seg.type;
});
return reducedPathData;
};
SVGPathElement.prototype.setAttribute = function(name, value) {
if (name === "d") {
this[symbols.cachedPathData] = null;
this[symbols.cachedNormalizedPathData] = null;
}
setAttribute.call(this, name, value);
};
SVGPathElement.prototype.removeAttribute = function(name, value) {
if (name === "d") {
this[symbols.cachedPathData] = null;
this[symbols.cachedNormalizedPathData] = null;
}
removeAttribute.call(this, name);
};
SVGPathElement.prototype.getPathData = function(options) {
if (options && options.normalize) {
if (this[symbols.cachedNormalizedPathData]) {
return clonePathData(this[symbols.cachedNormalizedPathData]);
}
else {
var pathData;
if (this[symbols.cachedPathData]) {
pathData = clonePathData(this[symbols.cachedPathData]);
}
else {
pathData = parsePathDataString(this.getAttribute("d") || "");
this[symbols.cachedPathData] = clonePathData(pathData);
}
var normalizedPathData = reducePathData(absolutizePathData(pathData));
this[symbols.cachedNormalizedPathData] = clonePathData(normalizedPathData);
return normalizedPathData;
}
}
else {
if (this[symbols.cachedPathData]) {
return clonePathData(this[symbols.cachedPathData]);
}
else {
var pathData = parsePathDataString(this.getAttribute("d") || "");
this[symbols.cachedPathData] = clonePathData(pathData);
return pathData;
}
}
};
SVGPathElement.prototype.setPathData = function(pathData) {
if (pathData.length === 0) {
if (isIE) {
// @bugfix https://github.com/mbostock/d3/issues/1737
this.setAttribute("d", "");
}
else {
this.removeAttribute("d");
}
}
else {
var d = "";
for (var i = 0, l = pathData.length; i < l; i += 1) {
var seg = pathData[i];
if (i > 0) {
d += " ";
}
d += seg.type;
if (seg.values) {
d += " " + seg.values.join(" ");
}
}
this.setAttribute("d", d);
}
};
})();
}
@johan
Copy link

johan commented Jun 14, 2012

Thanks for this! I had been meaning to do something like it for a long time to clean up the superfluous segments of https://github.com/johan/svg-cleanups/blob/master/logos/twitter.svg but never got around to it. http://bl.ocks.org/2932504 made it so much easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment