From 3d3bd12abede8f73516b32bb8ef084fdd68cbbbb Mon Sep 17 00:00:00 2001 From: Jean-Philippe Doyle Date: Thu, 14 Jun 2018 18:11:13 -0400 Subject: [PATCH] Add function to set axis labels alignment --- docs/images/chart_axis_label_alignment1.png | Bin 0 -> 8114 bytes include/xlsxwriter/chart.h | 36 ++++++++++++++ src/chart.c | 21 +++++++-- test/functional/src/test_chart_axis42.c | 47 +++++++++++++++++++ test/functional/test_chart_axis.py | 3 ++ test/functional/xlsx_files/chart_axis42.xlsx | Bin 0 -> 7869 bytes 6 files changed, 104 insertions(+), 3 deletions(-) create mode 100755 docs/images/chart_axis_label_alignment1.png create mode 100644 test/functional/src/test_chart_axis42.c create mode 100644 test/functional/xlsx_files/chart_axis42.xlsx diff --git a/docs/images/chart_axis_label_alignment1.png b/docs/images/chart_axis_label_alignment1.png new file mode 100755 index 0000000000000000000000000000000000000000..0e4f87e149df6000dcc596089629b90403f44a1e GIT binary patch literal 8114 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 element. */ STATIC void -_chart_write_label_align(lxw_chart *self) +_chart_write_label_align(lxw_chart *self, lxw_chart_axis *axis) { struct xml_attribute_list attributes; struct xml_attribute *attribute; LXW_INIT_ATTRIBUTES(); - LXW_PUSH_ATTRIBUTES_STR("val", "ctr"); + + if (axis->label_alignment == LXW_CHART_AXIS_LABEL_ALIGNMENT_LEFT) + LXW_PUSH_ATTRIBUTES_STR("val", "l"); + else if (axis->label_alignment == LXW_CHART_AXIS_LABEL_ALIGNMENT_RIGHT) + LXW_PUSH_ATTRIBUTES_STR("val", "r"); + else + LXW_PUSH_ATTRIBUTES_STR("val", "ctr"); lxw_xml_empty_tag(self->file, "c:lblAlgn", &attributes); @@ -4098,7 +4104,7 @@ _chart_write_cat_axis(lxw_chart *self) _chart_write_auto(self); /* Write the c:lblAlgn element. */ - _chart_write_label_align(self); + _chart_write_label_align(self, self->x_axis); /* Write the c:lblOffset element. */ _chart_write_label_offset(self); @@ -6047,6 +6053,15 @@ chart_axis_minor_gridlines_set_line(lxw_chart_axis *axis, axis->minor_gridlines.visible = LXW_TRUE; } +/* + * Set the labels alignement. + */ +void +chart_axis_set_label_alignment(lxw_chart_axis *axis, uint8_t alignment) +{ + axis->label_alignment = alignment; +} + /* * Set the chart title. */ diff --git a/test/functional/src/test_chart_axis42.c b/test/functional/src/test_chart_axis42.c new file mode 100644 index 00000000..ba22bef0 --- /dev/null +++ b/test/functional/src/test_chart_axis42.c @@ -0,0 +1,47 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2018, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = new_workbook("test_chart_axis42.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN); + + /* For testing, copy the randomly generated axis ids in the target file. */ + chart->axis_id_1 = 43704320; + chart->axis_id_2 = 43706624; + + uint8_t data[5][3] = { + {1, 2, 3}, + {2, 4, 6}, + {3, 6, 9}, + {4, 8, 12}, + {5, 10, 15} + }; + + int row, col; + for (row = 0; row < 5; row++) + for (col = 0; col < 3; col++) + worksheet_write_number(worksheet, row, col, data[row][col], NULL); + + chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5"); + chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5"); + chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5"); + + chart_axis_set_name(chart->x_axis, "XXX"); + chart_axis_set_name(chart->y_axis, "YYY"); + + chart_axis_set_label_alignment(chart->x_axis, LXW_CHART_AXIS_LABEL_ALIGNMENT_RIGHT); + + worksheet_insert_chart(worksheet, CELL("E9"), chart); + + return workbook_close(workbook); +} diff --git a/test/functional/test_chart_axis.py b/test/functional/test_chart_axis.py index 11ea64df..fc5c8445 100644 --- a/test/functional/test_chart_axis.py +++ b/test/functional/test_chart_axis.py @@ -130,3 +130,6 @@ class TestCompareXLSXFiles(base_test_class.XLSXBaseTest): def test_chart_axis41(self): self.run_exe_test('test_chart_axis41') + + def test_chart_axis42(self): + self.run_exe_test('test_chart_axis42') diff --git a/test/functional/xlsx_files/chart_axis42.xlsx b/test/functional/xlsx_files/chart_axis42.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a01642481c40ca716580f8aef9fff4fd588d509f GIT binary patch literal 7869 zcma)hWmr_}_x2#6LpO*BlF~UeA~|$-Nq2WS)R58*igcHBNJuHt-6bJNIe?^u|MB=< zzXK;;&xgHd?+^Qa=34i9?q{ugDaj%t;R67Gd+>__fC?r%c!mG~Tp|GgcmPs>u9$

wy1TQyR{!8$H-Eub6&~v=p%a^igspn+UXnZ37B1XF zU?v2{*JJK+HK*sY-ov<&oeW0l!RdQ|+1kdomjfPTY}vLEe5J-mSn0WCS%j&4SjicQ zEEAMt>`aYB&h&)s4wAV7EU%*sO-LSKXvi%U`DYPObKqV5Yh2|NR4~;ceO@mqNGwZgvQj%!e)Qor0%@cuxiDQBz}T)@;Yipw zP^C;xE~6oDDUGcClUGY?+I_Qnm|;GIJo{a?uOc@K)6;a_XLCuk=5-?{-EyW9lDnPz z%t|7*mUYGc8kI5fd^Mj0ohi{bL^;us8IGxe6x*;U-m%j*6~P6)vQxYT^QAq<*ajos z)6Gxsj(&V@bwwCr{j?7O&HC{U&HHH{0F`c0^_VxJ+Xo(a97F&B8%~v}gNc%}gQE+p zk)z}9czPW#Vzb7E9SjS;!UCU)yK5!mnkL2Xj&&uY#MfJ>llA0OQ-f3!j;1x;!**(Y zbTXF)1T%zUsO>S!2l>M+TNt(3hqX}@F8UfFy<{GK=F?1KDitbI0(7%Dv5OzcHI4Bg z{!%DxvN)KsQ`o^Yn?(;S35LdJ@}>7oO6iiEh9UY7Fl^o|>o|53d0j_z1+=Rx4R#WL zR0!{nzUHYte7o6IxX7L-NN+Dz31*b>qlZOBlR@NXVNevtGgms55yB%~kZWSor*ReA zy6Q@qj%p1;k^SM2M#M>0yIeVOdVU@Etll2d<>>hgU!W`x3nO=7W6gxzf z#9^T}V?<%Pvl-I$34zItLM9Y3+!U}-AT=bsk<%1`d^_sJ5!R})j38SjaIJomvF+fs z;`jL0LpvoF=Gd6+H%@QPh~0h5?+xv=*uJpKrBvHO`QR3V;gr&tvv*YrZhE3-F?=fG zcdl4S#1ipdP;uFDb2H;prh~RG;5La0L;4SR;UsF`ffIR?L=y*Rv){289Iq_f#fBfe zjQm5a*XLE;xnkb&(K-#^rtj&3Z1uUur7Z;9oHnxptt2XWQ6g*l1oAEx;0*1C=N|IQWNU3jjJ7kZL zLrCx~VQlhrLf%ibKC=)W^@Xdd`&xX;IerxVwY(H;GG8w(uvJd+^gVh1=CtobuvxZ|HbPVUz)Hw2^iasllZmKE z3YgEH7Nm;XY3^amf3-W8F-aa^ZF$J*M3PXONB=56atv=3LFuSz_^H?d+HDHz)Y+(Z z;8G?BrvMF3fq}D`tqUv5&-?#Z>f#5j;Zo-hgSJ9PTb1WJh;tQKO-AO4XAv#y55;i% zXY5nju3EZg?&xnBN%oHwDvHi83Px>zq&Qgxl||s<3sBX2l!r8Y_c{hJ&^jlBoyu0a zaoi{O22YYCWt!;RTVohh^(IF0*U52mw>)#S!Yoq!NPu|xm*~vi9Ef$1uc}*m_Fo}P z1{R-ah|SCkC>{5Ht6r(P=L2_^YLPtKMt=_iZEmR<6KaCX|r3+@jkMAo;7!W*@^L z7v@F|5?S6{sJfd^4Qb?)=OiwM)LHt#^3yBI7kZ1vJ&OZJMO*po^=lbLi;@)$AA@ah zAcZ-g=!l{RC^>QXKdKI9E8dK>b*M$WJ+rqAKyT%N+IObv*+(=>HXhIC1qx6jP=!qa!JHEW@vEyzo`TSV}CzR;3GiCoOe5~9MF zTv7c5zfN}w;7pwqIM}Luqoe?o9SOBce*DeJxLO~Ac$)^~m29_kI1RmU`6vF91{X^+ zGglYZKYrM6@nQLyQui;%byR}9LpmF_Ff8diIn#3UhKaN)lK8B+vP+R#ofYgEaXada zG(Q(#!00j3Y?;K`qj|UX$*K3*J-%Q6y_by36k1C(J-@mWg~CLEZ^2!~gm+s}gK}aSFUxl{_Erzu$jVl^m2^B4eZU}mMH;wv`JT~$pJhHHnuRri1k$itlYSaXqN?HR640m^4N z#dxC%OPYhW@ab~Fr=8nax7j9mQzBRg7b!+K<5YiR`$@y=^D{8nOwUZ4Sd8GBz z)1cW`wJhR!Ry>rhjK_!}rr+DSfzr>9V1wYQPo19!%!V8zw)vuV6@<{Iq&|9~L`GJ7 zv%Lvz@Pp=H#k3gv(tXh+4+POfbcL5qN>i z>jx7u8p1=%Vd~B?KEHE2BA=JBtf25{?EIPkrp`tlR`wPytpD%fcK-iEx%ygl)Vk{t zK7@Riy!&*Lno%Dp-)H${rhh7Q53xHH97a-6Fa5)}fZdLtgBTL$Gd$_i(z9c|*oXR% zk2qUBuuIz?M^kQ7bPw@Ee3{u$3p?t)l!)pe0&R8}Ke_v-XIaX&uFFekG zo^zaufnF4-8xSh9glD_{1$wznMz)o$!%VMU->8{i|Fq%!JBKDKK zbVm+$LVxr;wA)4juO68f%d#xuP94yl(`{R0%&4Uk{?XS80_2RbZ&Gk0e38C;R2xXc>K~`B5Hls! z=vp{PrX^>|r7#p96if*^_Evvw)tM;kL<}+2u2SxdjemL%XHu9G{8ex^{fK2C^^iDn zzo^1e$~MCIac3dIaZ0ZaGezxNq$%c%>ni=_m>1Csi{{l^J-}=fbb2T;It?)W9XBj% z{XUYi=ITz<_Zu}ndhC!~mk{nD4Lrd|QQ_z9uWfH)Y2*wS_&xq3vR+;)Z$PDqv*OTWzW=``unK}|ViOrMQ+z^n*{$89eD z%PWt1f|#cxmbHh+6T2Nhta02eD8oa*XB_lTj}!eKrx0zN?4_8B`P}fr1CLyyKQc;5 zsUqY~r38y-F~bFZ#3*jgXHLqph*Z^`M|dqvAIDteWQ&D`jiYdbyy8sl2Lsey;{3J7 zEoWP_(w2p-^FS{L0BUDu4vj=7M~*X+U>gytvfd&?0yL@&VOIonqyhrle6BRBV$;5_ z9+sz!iG@&(dCg|YZ0!^Lv??We;V*!4JO5U%s7PGKdszp-g^SAgCRQ%t4uCokNIUBCU*J zV)P7{$3uWJ$siCJY@y?t`(!QS#a9>%Lq*-wNK^e__Q@zm&|8aKb60BLmh>@xZxk1| ze*H}%y}p%8n%p5IdkhwW9|)c095rXm z^>Z|3sz&=cJ5fmGP(1qK@|lc`Y{`J{$}4@dPZx5DxO|KR@mk3bTZylfl-lOMR4&%c z?0S%2Ay=4{fk1koD®Op+7TjA+^(pQLuTR`5ZTt)|x6ia^|SBnwF)8W-$wAR8A# zzH3#!@&I7xgU?V?o5Kuu7-wTAC6%1F>LLbKG$wQdFQiS95mI?gdY&eKi=Jjr|~gCm`-F-4{397IRH)2wKgH`+N5 z^hcs%(>N5L@MC>3liptJ3G)#?sTJatXu;6Oxd6!YB(B?5&D)Zp7NYmPwSA(3A4MM9 z7@=L%e&*lc|;e!fMSA8TX zpmC0`aE&a>B7=zLIw3O|Lg0n z^$>GTlSA5rH&$s^%UVuW4(Djz46b4ZYH=I-y_s9mvjh~;&??h?Rt!#6gQ;haS&OOO zExckF7#S()7&CIxaIP~De$@fd&3QIBJ5E|RH*BRcA6g7O_L+d)=5?!prm-3s08oAK z%h`grEv}Ykc4oise=6y}I9q$#@-g$`#BEduE6KmaR zGvkp@rUpzKnzB#Af`aJ6&~SM$?-fnR==HtPrVFGzX5Ifz)$7T*WIiu}U&lwCaq!L8 z@9g2`VbTSTSg5#E-&*}=y)x~vZXxnfUQ6AEyH{w;Xwt!JIOc-1b~fNVH?y5CES5ES zg7~mUSuvk!?RB$NdJF7i$?L0HKH}kawXzf8XjI|{Ji$G?cLpA)n6{P|=mga(MN%31 z*a#K~i9i$c>$ohIO!f&F)9laWNYB#5UsHBP(<*$YvZ(Gy;_oiA3rNR#N)mg~CyFkM z%rmFKe4%wRW#%K&t%h6!5HxVy55KSxjL}rr)>o%%_4J?G4Ce+xrMnVd6Z!ICGmgGv?UBA*;6dQ0#GB zWK0Arz=@jHouzam^G-LZSuYPH5CCs~`{ z(KRIpvjCie{zWM*ykhj;DhDV1y=<0q^Ha=iM|0zMVwn9>boU12n1GB;2Mieur1!Z# z;Ec!dRHDkukPQSGI5(()kYki%~L7FpX!E=onWwLQm34n^-u%uJ&?)h^0d8(U2Oxe)EJM z6-nk)wrs>KjGLI?xXE z2H42B2-bjLYF70d@T`KlXRL?yG5G*6k<*YfP5jN$|P=@5K5?1WR1 zo#qeKjrtfP&ht7pYF(|9P*TLHMN1wsb)_>jbNRX9vL3(jvEL5;#@;>>H8q|y>U=H6 zyql0sv&Md){(i_=dtpsgqFaQQUsQ~n;DY$b{o5{yGH^KZ`*Vsc(M8IGz9a*+j$TcW zgqvYmUaqz_7v!a(nb?>lJ}fds$0p9_o2zeB zq6lS444QzU5tDLgXAuQfOR0-8K~~bYWiV49jGJ*hO^?(rK*E8dg{s+)Oce>-+XB;6 zr!(KUfF&}uix?9wJ)|&!5Ar7G<@Oqscww}`R2&PvS+fP(Bq&!6o`+71w3*{Q(ELZI zOf_MpT#!BG$^&zT^aEvG9$mfDDc=cN$1~wAB9J}9^ZIm$yU)pUVhHhQ0>xWK82TKl z_>f-fzI385_4A0-3CU8&fqf$t;%iTUQ5_tJgVS3&(;5 z>^|hBlTV93pU=B+oY)=u!2u9DiFe&0zb*e!p>vLN@Xmr6?pl%jI@W(R6gR!A-!>HG zaf>hD4Mi}F=;UGNg2T9mmMQx&n9!T?7(tZ(s)HMtrd{XYpw~f;eb8CDB9{tF?`293 zb;1@vpAaa0B&&jL8CB{t&oHC*&cFq`dv40xk&r-6s**|QDWMH1sE1Q z6gmT`V9|P{2uiXDcgPU`Z4gBKvv~%h5e=(x|+d{V;otq1lz}sJVz4kvV;HC+nuJ+&1 zZ(9pD(f!bGqyMYX@cV`S-m~9aC;&;D57qZnq{kk?-LAfqb)3`Td{$ zIq$t)72kxMgU@&Wu}1!Hz_<1GCh#o$1rGeL>ici_$nXvFvn9g-WWo2|U6P+~{|B@x B;hF#d literal 0 HcmV?d00001