From 260e719e70d7cd109db30bee2f27021e5d16fae4 Mon Sep 17 00:00:00 2001 From: "AzureAD\\DharanidharanDharmas" Date: Tue, 17 Sep 2019 23:37:51 +0530 Subject: [PATCH] Added samples for new features --- .../.gradle/4.10.2/fileHashes/fileHashes.bin | Bin 91515 -> 209760 bytes .../.gradle/4.10.2/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../4.10.2/fileHashes/resourceHashesCache.bin | Bin 18837 -> 19109 bytes .../4.10.2/javaCompile/classAnalysis.bin | Bin 100479 -> 200513 bytes .../4.10.2/javaCompile/jarAnalysis.bin | Bin 54953 -> 103029 bytes .../4.10.2/javaCompile/javaCompile.lock | Bin 17 -> 17 bytes .../4.10.2/javaCompile/taskHistory.bin | Bin 19487 -> 19487 bytes .../4.10.2/taskHistory/taskHistory.bin | Bin 769764 -> 1302011 bytes .../4.10.2/taskHistory/taskHistory.lock | Bin 17 -> 17 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .../buildOutputCleanup/outputFiles.bin | Bin 22655 -> 26813 bytes android/local.properties | 4 +- images/ball.png | Bin 0 -> 3173 bytes images/circle_gauge.png | Bin 0 -> 2193 bytes images/circle_gauge.svg | 15 + images/funnel.png | Bin 0 -> 938 bytes images/funnel.svg | 15 + images/pyramid.png | Bin 0 -> 1151 bytes images/pyramid.svg | 15 + images/shotput.png | Bin 0 -> 3274 bytes images/sun.png | Bin 0 -> 7347 bytes lib/model/helper.dart | 178 +++++ lib/model/model.dart | 250 ++++++- lib/sample_browser.dart | 12 +- .../axis_crossing/axis_crossing.dart | 503 ++++++++++++++ .../handling_label_collision.dart | 2 +- .../opposed_axes/opposed_axes.dart | 2 +- .../plot_band/Plot_band_recurrence.dart | 417 ++++++++++++ .../axis_features/plot_band/plot_band.dart | 535 +++++++++++++++ .../category_types/default_category_axis.dart | 2 +- .../category_types/indexed_category_axis.dart | 2 +- .../category_types/label_placement.dart | 2 +- .../date_time_axis_with_label_format.dart | 2 +- .../default_date_time_axis.dart | 2 +- .../default_logarithmic_axis.dart | 240 +++++++ .../inversed_logarithmic_axis.dart | 284 ++++++++ .../numeric_types/default_numeric_axis.dart | 2 +- .../numeric_types/inversed_numeric_axis.dart | 2 +- .../numeric_axis_with_label_format.dart | 2 +- .../area_series/default_area_chart.dart | 2 +- .../default_rangecolumn_chart.dart | 272 ++++++++ .../rangecolumn_with_track.dart | 244 +++++++ .../vertical_rangecolumn_chart.dart | 279 ++++++++ .../stacked_series/stacked_area_chart.dart | 274 ++++++++ .../stacked_series/stacked_bar_chart.dart | 250 +++++++ .../stacked_series/stacked_column_chart.dart | 258 +++++++ .../stacked_series/stacked_line_chart.dart | 264 ++++++++ .../pie_series/semi_pie_chart.dart | 3 +- .../add_remove_data/add_remove_points.dart | 2 +- .../add_remove_data/add_remove_series.dart | 2 +- .../live_update/live_update.dart | 2 +- .../live_update/vertical_live_chart.dart | 6 +- .../update_data_source.dart | 2 +- .../funnel_charts/default_funnel_chart.dart | 507 ++++++++++++++ .../funnel_charts/funnel_with_legend.dart | 224 +++++++ .../funnel_with_smart_labels.dart | 455 +++++++++++++ .../chart/home/axes_features_home.dart | 91 ++- lib/samples/chart/home/axis_types.dart | 92 ++- lib/samples/chart/home/cartesian_types.dart | 92 ++- lib/samples/chart/home/circular_types.dart | 119 +++- lib/samples/chart/home/dynamic_updates.dart | 95 ++- lib/samples/chart/home/funnel_chart.dart | 181 +++++ lib/samples/chart/home/legend_home.dart | 93 ++- lib/samples/chart/home/other_features.dart | 91 ++- lib/samples/chart/home/pyramid_chart.dart | 181 +++++ lib/samples/chart/home/radial_gauge.dart | 193 ++++++ lib/samples/chart/home/user_interaction.dart | 93 ++- .../pyramid_charts/default_pyramid_chart.dart | 479 +++++++++++++ .../pyramid_charts/pyramid_with_legend.dart | 250 +++++++ .../pyramid_with_smart_labels.dart | 490 ++++++++++++++ .../animation/dynamic_animation.dart | 633 ++++++++++++++++++ .../animation/series_animation.dart | 2 +- .../annotation/chart_with_annotation.dart | 2 +- .../annotation/chart_with_watermark.dart | 5 +- .../data_label/default_datalabels.dart | 2 +- .../empty_point/chart_with_empty_points.dart | 2 +- .../marker/various_marker_shapes.dart | 2 +- .../sorting/sorting_options.dart | 2 +- .../crosshair/chart_with_crosshair.dart | 6 +- .../selection/selection_modes.dart | 2 +- .../tooltip/default_tooltip.dart | 2 +- .../trackball/chart_with_trackball.dart | 2 +- .../zooming_panning/pinch_zooming.dart | 2 +- .../zooming_panning/selection_zooming.dart | 2 +- .../zooming_with_custom_buttons.dart | 2 +- pubspec.yaml | 4 +- 86 files changed, 8538 insertions(+), 208 deletions(-) create mode 100644 images/ball.png create mode 100644 images/circle_gauge.png create mode 100644 images/circle_gauge.svg create mode 100644 images/funnel.png create mode 100644 images/funnel.svg create mode 100644 images/pyramid.png create mode 100644 images/pyramid.svg create mode 100644 images/shotput.png create mode 100644 images/sun.png create mode 100644 lib/samples/chart/axis_features/axis_crossing/axis_crossing.dart create mode 100644 lib/samples/chart/axis_features/plot_band/Plot_band_recurrence.dart create mode 100644 lib/samples/chart/axis_features/plot_band/plot_band.dart create mode 100644 lib/samples/chart/axis_types/logarithmic_types/default_logarithmic_axis.dart create mode 100644 lib/samples/chart/axis_types/logarithmic_types/inversed_logarithmic_axis.dart create mode 100644 lib/samples/chart/cartesian_charts/rangecolumn_series/default_rangecolumn_chart.dart create mode 100644 lib/samples/chart/cartesian_charts/rangecolumn_series/rangecolumn_with_track.dart create mode 100644 lib/samples/chart/cartesian_charts/rangecolumn_series/vertical_rangecolumn_chart.dart create mode 100644 lib/samples/chart/cartesian_charts/stacked_series/stacked_area_chart.dart create mode 100644 lib/samples/chart/cartesian_charts/stacked_series/stacked_bar_chart.dart create mode 100644 lib/samples/chart/cartesian_charts/stacked_series/stacked_column_chart.dart create mode 100644 lib/samples/chart/cartesian_charts/stacked_series/stacked_line_chart.dart create mode 100644 lib/samples/chart/funnel_charts/default_funnel_chart.dart create mode 100644 lib/samples/chart/funnel_charts/funnel_with_legend.dart create mode 100644 lib/samples/chart/funnel_charts/funnel_with_smart_labels.dart create mode 100644 lib/samples/chart/home/funnel_chart.dart create mode 100644 lib/samples/chart/home/pyramid_chart.dart create mode 100644 lib/samples/chart/home/radial_gauge.dart create mode 100644 lib/samples/chart/pyramid_charts/default_pyramid_chart.dart create mode 100644 lib/samples/chart/pyramid_charts/pyramid_with_legend.dart create mode 100644 lib/samples/chart/pyramid_charts/pyramid_with_smart_labels.dart create mode 100644 lib/samples/chart/series_features/animation/dynamic_animation.dart diff --git a/android/.gradle/4.10.2/fileHashes/fileHashes.bin b/android/.gradle/4.10.2/fileHashes/fileHashes.bin index 84c2254b240fb1524b2a6eb7daccb6bd6334bb8e..5a91455da4613f14792a5b0b52a0d1588dadb9c0 100644 GIT binary patch delta 77945 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 delta 2688 zcmZuy3s6+o8Rp&wS_qPwX}$NNXo#|o2H1-eXvEQsPJz3|IFru6B+ek}6rE%Oios<; z!Jq=sD3bkMPDsQS;(~ynU;rgb42Bg}Aj)IK2gDaxNFY8~6ot_5#J1^l%FKTEe|-OU z{(H{3KR5b4pW0oIzbXq?DOe7oTseZAvO@7n1Vwu*HJhWfO`t~EdX*e{ zncP(Lt?p+_ZKBK)Y@)&nxwY;*p!B?$#1=LowxdbZ*sUf}VpE%uC}>7(kXy^`fU9;S z-n}5Aqu>ZOuSHB|buEYwwumZ?hR7_XRg@|7PcrjpgE8$jJO+;5$)e zhKphl^SFdif2f{KZHHXZB8j>d8Q5UE7{S(dAYa_|pg*l1^iTNB646Nb^tjH2j zGD-xEg_WWWpk)M zg@jujtdKfbX&ibv=)U6QuRxx58t&@TXf5OnI#@A|y-yv-@$_);n*c;k;86VP!ON&e zh4E{&5j%;5g+n6;=Oj+hc@~t#-{9R2eZ%*lK`3Ev=U~O2Ls{-Qv|;10IhZ+w3 z9Kss`#zrBB&9p(jfY>YffCNa(FR`dcS17rx(K)bBHZXppk!Y{*)WIo?T9(s z5sT`8mEVCS`#T^N)`^(0Q_%nZ-}lnR#XsG}O~O8dW#!=dIRr*N$L)wa zh-=t)5Uzi|AfE`qI%+68zSExjo#@EqQc&8GJl^#p*K{r-_TRSO%tuXrBLZDjXZ9vwBxo+_Ssb6`$L($M^sujB2meRLLN?){^FD<-Kmh>DZg-b<=t0fo3B0F zg@-YojEVlyuC1_Ce=@jjz6Z5~yr4$ndS7Ce$^-6M?}9tF|!k0lCy97AJ|6`DUL z)2cD>#?a3b1DT)5)bJ#R@}8=6^C@~Azf6V+g;FNu6AcqD3H0J53MMtGn^Y|ea5;>J z#08dXxKA7YCdM$`-|+$N5plGGA`V_EKtB;2k_zyNISMc&L!ZMT=N5uD_X{MlzQDf| z=`gGmH(Y_shcS6KSm81&Dr{Ep=Kl_ftRjqGZ+Fxh+;Lxui}6*596^>H0r`ms?p19G zEN@Rid!hAu$8XCb>z?gU@j2!nFDzu1cy#Hx5yba5@+-R$UAAt7bl4`SCT@ai*Cu`` z6VQ2V0unt5AjfS+teQjLW`21;5cabbi4aIlM65g!u_;?1aAym?tNAOGNrCIP6>j8KxZ_(PAH59~ z)@@iLI2BNy3fGwmieDP6{4`jtX(0b$J8JiBhkJ&@&~{`SKZND{5Z2;!A%=~oLtyU? z@Va&&;kpwLyc4zCc4DDM?m9U{?n3O~E@3VEV+QtbZw9Z(K+ma}Tr?Bekxbrc7W6W* z;Erb@arz@{r_XM<2X-UdxErx4djN5JAX?3#k3;mwxI>3OhIMo=cs+Ze61fj<#y-^k zIUBJp*(mGEMk01U5|;gNo!pAc!5K~Dz_oq?w~K?T8D%TXC`&cNEjOd=mq`{$=pK{I zz`_oIf^ml9KEOpSLN|-!qwCip7Qp8hCYj1787TjmWPW*w{m&%Z^55f3W2ygtrr|v> e*w~qTLGt`{;078heVYXKUW4dWTjnWTeEXlSVl&eK diff --git a/android/.gradle/4.10.2/fileHashes/fileHashes.lock b/android/.gradle/4.10.2/fileHashes/fileHashes.lock index 777a51f43c931e27e7f5452437d38b604dd67efa..3ac5226be8a7a81b6d5260859167700ca3807344 100644 GIT binary patch literal 17 VcmZQJzZH2)y)4w80Sveg0RSzr1V#V= literal 17 UcmZQJzZH2)y)4w80Swrp04+ZQ*#H0l diff --git a/android/.gradle/4.10.2/fileHashes/resourceHashesCache.bin b/android/.gradle/4.10.2/fileHashes/resourceHashesCache.bin index c59d5007d3095271a1e751786c773ec45abe2a25..70cc4e0e735cc48287ddd54ba99be6815a511db1 100644 GIT binary patch delta 439 zcmbO_nQ`e<#tkMCj6#!5B@6^6$RDnre%?%y0Sr8+PL7pO5V&Yl$@Au^dIv<%OLlUp zgoVIUE2|_arsRlvo0G3f1lZI(k_q=^+9M1#!5(Hp?ZxsZ4pm~DP{rF};xL+lf$`u*#UJ7u z4I;!gJ9>mLPUiLG6WRRzn2KSJbNv+Us@CJ%;+=uIK^jz00$ z7Zz87B#eOs$m4<_Eb#WwTW+ljUoOvi?PkoFGhY-_#XO_HRaDx0fPh$o&4s8ASsm!NmY1!-|Dors%p?2cML>oC0P&oZ AFaQ7m delta 61 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 DRi&N@ delta 502 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 z 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 IoOJyE0qG!a;{X5v delta 50 zcmeymgl*+o<_#tif-K!P4UFELxIcvf3@&V*94lcl`KW|4W8p@{AL1JgR)}wQ^vLJ~ E0Qd|OasU7T diff --git a/android/.gradle/4.10.2/javaCompile/javaCompile.lock b/android/.gradle/4.10.2/javaCompile/javaCompile.lock index fc9f5faab29d3fbf245c76e98ef27d3d57b235e8..098b7e7b554b30c5e1458b19cb13568dc0df51c2 100644 GIT binary patch literal 17 VcmZQx5^`YP|Ht367{Gw>8~{bz25bNT literal 17 UcmZQx5^`YP|Ht367$D#o07dZzg8%>k diff --git a/android/.gradle/4.10.2/javaCompile/taskHistory.bin b/android/.gradle/4.10.2/javaCompile/taskHistory.bin index 3d97e30ee6f4863ae322c5ad8218f088fc5fb245..179b431f12fca7872abff58d047058854ca5e01c 100644 GIT binary patch literal 19487 zcmeI&J!lj`6bJC#6%kZ03PQ@$+Pl4|2qx9R8lsR!5u1@?W_K<-advOBvwN3H6u~CN zS)>SlVG)Rk2xn(+5fqCQiUDmz&?1eXrNp`2TXV`G0Yyaq3v)C3c8+=T+c(vnV;G|& zoBhk!x(;p)F@gXDAOHafKmY;|fB*y_009U<00Izz00bZa0SG|ge-SvZH?lk5%;*uT zH`v!UjOt!JuvT`;?$yg*?&Ob8FBHEYjK7@Nyl+=m^Y~P)h!?$%*Yaohga8B}009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG|gZweeU3{(H9-#n??p--kWP9|lVBs?Zj%1XLPp?soPNzovZToINE>5(*+bxG6E z_4P~<>iGfp1WojWS=yp5@i#z+!S7!#=(i>#TP2GG#iH9hI`$8Af}DEb3{JN`|;wclVU-gjO}QZSXhqqpV5%j>rv`!Ax6VD93n z>mRng#4l=gu!76F5>!#Yd6i}hci7Y`|NVp2sCZ>=e literal 19487 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%0Ayq{qb0|3MA4i}cHk;fV_ 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�Haf=eTCW(E!ZJYT~ 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 F_5Vf&r^EmN delta 27844 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 diff --git a/android/.gradle/4.10.2/taskHistory/taskHistory.lock b/android/.gradle/4.10.2/taskHistory/taskHistory.lock index 98a8ac4183b1cc620db52ceed28f762765ae7fb4..3936293679d713d2798e7c2732ba55ff8d079ce4 100644 GIT binary patch literal 17 UcmZR6@22|x@q@8A_YWk_ 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 diff --git a/android/local.properties b/android/local.properties index a015ad51..23ca7df8 100644 --- a/android/local.properties +++ b/android/local.properties @@ -1,5 +1,5 @@ -sdk.dir=/Users/ashwink/Library/Android/sdk -flutter.sdk=/Users/ashwink/Documents/FlutterSDK/flutter +sdk.dir=C:\\Users\\DharanidharanDharmas\\AppData\\Local\\Android\\sdk +flutter.sdk=D:\\Applications\\Softwares backup\\flutter\\flutter_windows_v1.2.1-stable\\flutter flutter.buildMode=debug flutter.versionName=1.0.0 flutter.versionCode=1 \ No newline at end of file diff --git a/images/ball.png b/images/ball.png new file mode 100644 index 0000000000000000000000000000000000000000..22adafd7d92e9bd343ebf227a39ea99bc37ba85f GIT binary patch literal 3173 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 LNkvXXu0mjfqAmat literal 0 HcmV?d00001 diff --git a/images/circle_gauge.png b/images/circle_gauge.png new file mode 100644 index 0000000000000000000000000000000000000000..1c7e2416413a62be9be0aa0d243a118cbdfcd8ac GIT binary patch literal 2193 zcmV;C2yXX@P)F!)#Wfqe`HlhqN8H;m}U&GI8W1nPkV*93&7yIo7HxlKBrr{#5_+)Ob zHs{2bm2+$i$QVM(Ikmw!!l}lJjge}|AY-^( z*v}rZ`ye6jGVpc+J@3{TeO_iHwWV!=4AhL^??i_dC4ad$V^0 zx>+NTF@$2a17KMOIf|WK{2Lja>OK5P#0e(Q8lj8TW@obPQ6EFFNg$^n-TaW!rLMs5 zf$7h>c(<|GOTRFDGvaF z5RyC=H7TFw&lq!1#v}6-t3dphvNb2tQ<2jWalaGeL#Ch0>%EJd;-lmwml4DP%dR9H zyhb_6e{Na)liU;KrGvkf)~F%vVih_|6W0q)X!l#TaO~iXw1fZBvirIY_9^5Dnmy4D z_Cgwk;X060(00DZ(iQayc968QS1n!NwDT6TCvt+bxruC5my+Y?7$HPk`4US-ALkyh z(bARsaqV;PGHLQPIVWGVO>7};=op5!@qWwi!P((*j5;@8pMxRzSS7XLzWjE8^>6Lfie3#=~;@1e&;t<`zpWwFWIO@Bol zDZH8?N5yi|f({WzY9n{r(?d!$EGcr2lK_-n+24q>oeV~bc1^C6eVj$G8k z>dYRAN32g?m?Ny2G-KxoKeeSW%~&2Z^Aq;u!iwJP(ZdfX@6^PHft==u`W0J_;t_rU z`A*yNyrzkNHOk{*A(9v7F#j8nQ@EP+2Q5|Edg*SZNmL`(IJgF(rB=UPbREJf*yIs8 zN0S%kp!hG4Gm-USeMnTs=h3!jJd$BF+g_*?@*(?5+JiuP@ z4{FbQU3ls0Nlm_35zmup%lj*)uoJdF(tJSjhfT$A8ETMj~<_OjU{trtg=cdFIa zkUDe-qtpuPZwVUxA4aY*@NZidlXarr?2*)KzezsK_OQpv9_&1gJvWhdHu$<|_Goxc z+G$avzmU}6l3jyNA26xZvya{`MJcRN7a5*R{sM;Q)GAsn{6J2#+xiDpwvCouVs(_a zU2`}iNEM!P?J_z|4sRs5BdI~VNM?k81R2*@xYT50XWaC?d}vNYCLK_&nA z+=5hUUQ&V1VQ7W6=aw%_h1Ov91djuAzob=YFOZ$+9N~IFxpgnxtZqd+*(bJ9R$6&@w+$Y zMS%uds`Y)KN&k`Y(SmJ$7q;Jt@!&VSWj0}z>W?B>0LTc!R)`4U>9U!^5T63v8bi#Bh* z&g$BX)29R@Ctl|j6vmo29?lZ}Fm-EVK*ms=^&^qy$TqYj&^M-(41dPjBeD^fJ~xKz zCS6A1)>|CE%H3uABW|x^Xo%CbNgsE)N1n20Y3&xv=|=s1AY=He%WeMz?AoY3joj}f z&~uHr^>5od(Y-eO2;HFn6UZ1QNwK!Z){(LSBRF2i6<4vIoBw!Q@T&g-Qmns8iy_3! z`jKzidXS3slQA0pT(mYv|Hw7fKDOpfCtaskfFO|IZM!F8*V^G9hI0p8>-6$m&UJB3 zSwHewx>o0Oo%V|D$&FiqwR*3iVSe7i;zijacZ$zX^DW= + + + Circle Gauge + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/images/funnel.png b/images/funnel.png new file mode 100644 index 0000000000000000000000000000000000000000..c6d87f26ae05b8bf14eebe69e9e98b65420318ad GIT binary patch literal 938 zcmW-ge^8V~7{}iikau_AJ4_(quF(Kdm_w}bkEWVQ!Vcv|2M>a=fk_SdsE$Qm_Mnn{=-qf+}ZT)WKd`@GNdyzldT zKhN&$2iAh^dSpa`Am}am<|6jq#vc&P?frP4Ac$V;&f+{43XzD=5aHJ86dL@3-!C|) z1)oo7(*$ogPSf-qL4DY-`%0CEt|C=MVHFVqdjepD0?!0+2Eb)3xv|tuq<#|X&~#r? zxmVL^DsT|wBfKy`x&R2Rg|M;8gg7=SL3o+4anC0aV zmNkrq2?{J{&Muc=vAx)~+q{EtI*FX~m z$0%r~poM}~3O=OZI0YvtXj=y8;>CAO|tW4r6(eGqc$vkx0eH&}MdOwu40lFAHK+RCG*CtOQYfLgM2|27__U zlPRfb8!|F7H)iMLT3#tD+fz|lwQv8M2Wsoye(zZ8sh+c6xZIv0uXps~rLl2Lv|uPS zef{Q-v$Jz^^9u{VEiNwp@#ljF4ix5Zre>y1zpX4=e?unV#;rp-ZoqsyPrLGA{FK= zmY*xR@l%Wa-{YTsZB1@H+}Q!wt=Ls$TvI{3Gli=8*_~ud{?$f@YOl!N^z_WF+69EWNf~A9wz)*ON2sO5EDi5|=&ud!zDg^p2vG{PK|l z?rkdzbC23T*VL3v)z^zxr+@$5Lh}BarjOe1RKGN{s{PcJ%FLvbzs@~l`6SDABoHg& z=S6H3u}Q>8#G6GNFXA*2M>S4+lnk4)&ZexlDXBJPgH1`ZDd~^uwuq1BN6VCftiSlB Nv*Z<+-CJ!<{{zp`s}TSI literal 0 HcmV?d00001 diff --git a/images/funnel.svg b/images/funnel.svg new file mode 100644 index 00000000..ad63df9b --- /dev/null +++ b/images/funnel.svg @@ -0,0 +1,15 @@ + + + + Funnel + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/images/pyramid.png b/images/pyramid.png new file mode 100644 index 0000000000000000000000000000000000000000..90c1be377fefca1e1c69564e213d06f73f6a2db9 GIT binary patch literal 1151 zcmW-f3rrkE7{?a`;kcPOIUYrXrhv3pFlqoJVrne%=-C!21+gSpLnXG(aUpT3ZPs$iw2So9ynl`~Cml_nU8~G%_L_ z+PT_s90%1$LZa9^OuB6!lb$O|6USM)MIMU|WuM&cE;ls9878@E6K67UpA(LdJuOp? zrMx50E32u!VNy{trWhMTodgz(uvY{a%P)<~dZ^4qmHAYeGcN1r?OS+7HAYnwW=+C2 z0T6fDkv}$lr6$+5%d$-Oyrb@6%<|}=u-;%upE!UuL(30 zFv`Q8|FiW17{UtHy^{dUqYEPZLV)b&PZ$+Yrh)B*1(Lo-U@7n;W=e%tWG+U9v?8n& zSPGc2q|6bSk@2tqvT3js)0`K92{Qo$V0O@tnFb7ERsoD)R#_Ss<^ka)3!`PODyb%{ zl{&&Yi3c_a5_t<@Yhg8|y=W(FTnt8<592hlHHxekTfQ_LjmX$g9%b;TkfI9|>FDn6 zuHO-BB|9F)A4f%;FPJ_9UWag#_vt$ z{t;1}ygf5Fx45`;@813U4}ZT48&Y*?!I4`~~+MzM8j@yoMGGmU>8 z8qPC2UkuyK(`K%=tA4E$y&T3D&dkJf4bk)YC;T#OdC?rfRDU zdU;cyT{*hP)H3_YbD>S1N&A;0IurWz3-dkEKc_|-x}UO~dfur^JY#uh>j}e-Z?HJ; zB=*{yWOnyct5I&@*2-lN8|5*YxXTqJ5RI@c)jk}Q(r#l;p*osCJlK`IKFu{ z`E=#+Q+9s%hKpY7`)v0C@Jx!fc=I!zI)3={KNhtfUwJz&UH*ve3#Sf^2 + + + Pyramid + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/images/shotput.png b/images/shotput.png new file mode 100644 index 0000000000000000000000000000000000000000..3179b3843bc51bf9bb2458a3a199b789ce6fc800 GIT binary patch literal 3274 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 builder: (BuildContext context) => CircularTypes())); } + if (sample.title == 'Radial Gauge') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => RadialGaugeExamples())); + } + if (sample.title == 'Pyramid Chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => PyramidFeatures())); + } + if (sample.title == 'Funnel Chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => FunnelCharts())); + } if (sample.title == 'Series Features') { Navigator.push( context, @@ -143,6 +183,9 @@ void onTapControlItem( } } +class PyramidType { +} + void onTapSampleItem(BuildContext context, SubItemList sample) { //......................Cartesian Charts...............................// if (sample.category == 'Line') { @@ -326,6 +369,47 @@ void onTapSampleItem(BuildContext context, SubItemList sample) { MaterialPageRoute( builder: (BuildContext context) => StepLineVertical(sample))); } + } else if (sample.category == 'Range Column') { + if (sample.title == 'Default range column chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => RangeColumnDefault(sample))); + } else if (sample.title == 'Transposed range column') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => RangeBarChart(sample))); + } else if (sample.title == 'Range column with track') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => RangeColumnWithTrack(sample))); + } + } + else if (sample.category == 'Stacked Charts') { + if (sample.title == 'Stacked bar chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => StackedBarChart(sample))); + } else if (sample.title == 'Stacked column chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => StackedColumnChart(sample))); + } + else if (sample.title == 'Stacked area chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => StackedAreaChart(sample))); + } else if (sample.title == 'Stacked line chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => StackedLineChart(sample))); + } } //......................Cartesian Charts End...............................// @@ -377,6 +461,21 @@ void onTapSampleItem(BuildContext context, SubItemList sample) { MaterialPageRoute( builder: (BuildContext context) => DateTimeLabel(sample))); } + } else if (sample.category == 'Logarithmic') { + if (sample.title == 'Default logarithmic axis') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => + LogarithmicAxisDefault(sample))); + } + else if (sample.title == 'Inversed logarithmic axis') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => + LogarithmicAxisInversed(sample))); + } } else if (sample.category == 'Axis Features') { if (sample.title == 'Opposed axes') { Navigator.push( @@ -398,6 +497,11 @@ void onTapSampleItem(BuildContext context, SubItemList sample) { context, MaterialPageRoute( builder: (BuildContext context) => EdgeLabel(sample))); + } else if (sample.title == 'Axis crossing') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => AxisCrossing(sample))); } } @@ -481,6 +585,45 @@ void onTapSampleItem(BuildContext context, SubItemList sample) { //......................End Circular Types...............................// + //......................Triangular Types...............................// + else if (sample.category == 'Pyramid') { + if (sample.title == 'Default pyramid chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => PyramidDefault(sample))); + } else if (sample.title == 'Pyramid with smart labels') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => PyramidSmartLabels(sample))); + } else if (sample.title == 'Pyramid with legend') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => PyramidLegend(sample))); + } + } else if (sample.category == 'Funnel') { + if (sample.title == 'Default funnel chart') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => FunnelDefault(sample))); + } else if (sample.title == 'Funnel with smart labels') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => FunnelSmartLabels(sample))); + } else if (sample.title == 'Funnel with legend') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => FunnelLegend(sample))); + } + } + + //......................End Triangular Types..................................// + //......................Dynamic Updates..................................// else if (sample.category == 'Live Update') { @@ -580,6 +723,18 @@ void onTapSampleItem(BuildContext context, SubItemList sample) { MaterialPageRoute( builder: (BuildContext context) => SortingDefault(sample))); } + } else if (sample.category == 'Axis Features') { + if (sample.title == 'Plot band') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => PlotBandDefault(sample))); + } else if (sample.title == 'Plot band recurrence') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => PlotBandRecurrence(sample))); + } } else if (sample.category == 'Animation') { if (sample.title == 'Series animation') { Navigator.push( @@ -587,6 +742,13 @@ void onTapSampleItem(BuildContext context, SubItemList sample) { MaterialPageRoute( builder: (BuildContext context) => AnimationDefault(sample))); } + if (sample.title == 'Dynamic update') { + Navigator.push( + context, + MaterialPageRoute( + builder: (BuildContext context) => + CartesianDynamicAnimation(sample))); + } } //......................End Series Features......................................// @@ -640,4 +802,20 @@ void onTapSampleItem(BuildContext context, SubItemList sample) { } } } + +String getStatus(List model) { + int newCount = 0; + int updateCount = 0; + for (int i = 0; i < model.length; + i++) { + if (model.length > 0 && model[i].status!=null) { + if(model[i].status == 'New'){ + newCount++; + }else if(model[i].status == 'Updated'){ + updateCount++; + } + } + } + return (newCount == model.length) ? 'N' : (newCount!=0 || updateCount!=0) ? 'U' : ''; + } //......................End User Interactions......................................// diff --git a/lib/model/model.dart b/lib/model/model.dart index 46907e72..260daf78 100755 --- a/lib/model/model.dart +++ b/lib/model/model.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_examples/samples/chart/axis_features/axis_crossing/axis_crossing.dart'; import 'package:flutter_examples/samples/chart/axis_features/handling_label_collision/handling_label_collision.dart'; import 'package:flutter_examples/samples/chart/axis_features/multiple_axis_chart/multiple_axis_chart.dart'; import 'package:flutter_examples/samples/chart/axis_features/edge_label_placement/edgelabel_placement.dart'; @@ -8,6 +9,8 @@ import 'package:flutter_examples/samples/chart/axis_types/category_types/indexed import 'package:flutter_examples/samples/chart/axis_types/category_types/label_placement.dart'; import 'package:flutter_examples/samples/chart/axis_types/date_time_types/date_time_axis_with_label_format.dart'; import 'package:flutter_examples/samples/chart/axis_types/date_time_types/default_date_time_axis.dart'; +import 'package:flutter_examples/samples/chart/axis_types/logarithmic_types/default_logarithmic_axis.dart'; +import 'package:flutter_examples/samples/chart/axis_types/logarithmic_types/inversed_logarithmic_axis.dart'; import 'package:flutter_examples/samples/chart/axis_types/numeric_types/default_numeric_axis.dart'; import 'package:flutter_examples/samples/chart/axis_types/numeric_types/inversed_numeric_axis.dart'; import 'package:flutter_examples/samples/chart/axis_types/numeric_types/numeric_axis_with_label_format.dart'; @@ -34,6 +37,9 @@ import 'package:flutter_examples/samples/chart/cartesian_charts/line_series/cust import 'package:flutter_examples/samples/chart/cartesian_charts/line_series/default_line_chart.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/line_series/line_with_dashes.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/line_series/multi_colored_line.dart'; +import 'package:flutter_examples/samples/chart/cartesian_charts/rangecolumn_series/default_rangecolumn_chart.dart'; +import 'package:flutter_examples/samples/chart/cartesian_charts/rangecolumn_series/vertical_rangecolumn_chart.dart'; +import 'package:flutter_examples/samples/chart/cartesian_charts/rangecolumn_series/rangecolumn_with_track.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/scatter_series/default_scatter_chart.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/scatter_series/scatter_with_various_shapes.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/spline_series/customized_spline_chart.dart'; @@ -41,6 +47,10 @@ import 'package:flutter_examples/samples/chart/cartesian_charts/spline_series/de import 'package:flutter_examples/samples/chart/cartesian_charts/spline_series/spline_types.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/spline_series/spline_with_dashes.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/spline_series/vertical_spline_chart.dart'; +import 'package:flutter_examples/samples/chart/cartesian_charts/stacked_series/stacked_area_chart.dart'; +import 'package:flutter_examples/samples/chart/cartesian_charts/stacked_series/stacked_bar_chart.dart'; +import 'package:flutter_examples/samples/chart/cartesian_charts/stacked_series/stacked_column_chart.dart'; +import 'package:flutter_examples/samples/chart/cartesian_charts/stacked_series/stacked_line_chart.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/stepLine_series/default_stepline_chart.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/stepLine_series/stepline_with_dashes.dart'; import 'package:flutter_examples/samples/chart/cartesian_charts/stepLine_series/vertical_stepline_chart.dart'; @@ -62,15 +72,24 @@ import 'package:flutter_examples/samples/chart/dynamic_updates/add_remove_data/a import 'package:flutter_examples/samples/chart/dynamic_updates/live_update/live_update.dart'; import 'package:flutter_examples/samples/chart/dynamic_updates/live_update/vertical_live_chart.dart'; import 'package:flutter_examples/samples/chart/dynamic_updates/update_data_source/update_data_source.dart'; +import 'package:flutter_examples/samples/chart/funnel_charts/default_funnel_chart.dart'; +import 'package:flutter_examples/samples/chart/funnel_charts/funnel_with_legend.dart'; +import 'package:flutter_examples/samples/chart/funnel_charts/funnel_with_smart_labels.dart'; import 'package:flutter_examples/samples/chart/legend/chart_with_customized_legend.dart'; import 'package:flutter_examples/samples/chart/legend/chart_with_legend.dart'; import 'package:flutter_examples/samples/chart/legend/legend_with_various_options.dart'; +import 'package:flutter_examples/samples/chart/pyramid_charts/default_pyramid_chart.dart'; +import 'package:flutter_examples/samples/chart/pyramid_charts/pyramid_with_legend.dart'; +import 'package:flutter_examples/samples/chart/pyramid_charts/pyramid_with_smart_labels.dart'; import 'package:flutter_examples/samples/chart/series_features/animation/series_animation.dart'; +import 'package:flutter_examples/samples/chart/series_features/animation/dynamic_animation.dart'; import 'package:flutter_examples/samples/chart/series_features/annotation/chart_with_annotation.dart'; import 'package:flutter_examples/samples/chart/series_features/annotation/chart_with_watermark.dart'; import 'package:flutter_examples/samples/chart/series_features/data_label/default_datalabels.dart'; import 'package:flutter_examples/samples/chart/series_features/empty_point/chart_with_empty_points.dart'; import 'package:flutter_examples/samples/chart/series_features/marker/various_marker_shapes.dart'; +import 'package:flutter_examples/samples/chart/axis_features/plot_band/Plot_band_recurrence.dart'; +import 'package:flutter_examples/samples/chart/axis_features/plot_band/plot_band.dart'; import 'package:flutter_examples/samples/chart/series_features/sorting/sorting_options.dart'; import 'package:flutter_examples/samples/chart/user_interactions/crosshair/chart_with_crosshair.dart'; import 'package:flutter_examples/samples/chart/user_interactions/selection/selection_modes.dart'; @@ -79,26 +98,27 @@ import 'package:flutter_examples/samples/chart/user_interactions/trackball/chart import 'package:flutter_examples/samples/chart/user_interactions/zooming_panning/pinch_zooming.dart'; import 'package:flutter_examples/samples/chart/user_interactions/zooming_panning/selection_zooming.dart'; import 'package:flutter_examples/samples/chart/user_interactions/zooming_panning/zooming_with_custom_buttons.dart'; - import 'package:scoped_model/scoped_model.dart'; class SampleList { - SampleList(this.title, this.description, this.image, [this.subItemList]); + SampleList(this.title, this.description, this.image, [this.subItemList, this.status]); final String title; final String description; - final String image; + final String image; final List> subItemList; + final String status; } class SubItemList { SubItemList(this.category, this.title, this.description, this.image, - [this.previewWidget, this.codeViewerLink]); + [this.previewWidget, this.codeViewerLink, this.status]); final String category; final String title; final String description; final String image; final String codeViewerLink; final Widget previewWidget; + final String status; } class SampleListModel extends Model { @@ -131,6 +151,7 @@ class SampleListModel extends Model { List numericAxisSubItemList; List categoryAxisSubItemList; List dateTimeAxisSubItemList; + List logarithmicAxisSubItemList; List axisFeaturesSubItemList; List multipleAxisSubItemList; List labelIntersectActionSubItemList; @@ -147,6 +168,8 @@ class SampleListModel extends Model { List bubbleSeriesSubItemList; List scatterSeriesSubItemList; List stepLineSeriesSubItemList; + List rangeColumnSeriesSubItemList; + List stackedSeriesSubItemList; List legendSubItemList; List markerSubItemList; List dataLabelSubItemList; @@ -156,6 +179,8 @@ class SampleListModel extends Model { List emptyPointSubItemList; List> cartesianSubItemList; List> accumulationSubItemList; + List> pyramidSubItemList; + List> funnelSubItemList; List> otherFeaturesSubItemList; List> legendFeaturesSubItemList; List> userInteractionSubItemList; @@ -178,6 +203,12 @@ class SampleListModel extends Model { List doughnutSeriesSubItemList; List radialBarSeriesSubItemList; + //Triangular Types + List pyramidSeriesSubItemList; + List funnelSeriesSubItemList; + + + SampleListModel() { controlList = []; searchControlListItems = []; @@ -187,7 +218,8 @@ class SampleListModel extends Model { // For Axis Types numericAxisSubItemList = []; categoryAxisSubItemList = []; - dateTimeAxisSubItemList = []; + dateTimeAxisSubItemList = []; + logarithmicAxisSubItemList = []; axisFeaturesSubItemList = []; multipleAxisSubItemList = []; labelIntersectActionSubItemList = []; @@ -235,6 +267,31 @@ class SampleListModel extends Model { '', 'images/axes.png', getMultipleAxisLineChart(isTileView))); + axisFeaturesSubItemList.add(SubItemList( + 'Axis Features', + 'Axis crossing', + '', + 'images/axes.png', + getAxisCrossingSample(isTileView), '', + 'New')); + axisFeaturesSubItemList.add(SubItemList( + 'Axis Features', + 'Plot band', + '', + 'images/circular.png', + getPlotBandChart(isTileView), '', + 'New' + )); + axisFeaturesSubItemList.add(SubItemList( + 'Axis Features', + 'Plot band recurrence', + '', + 'images/circular.png', + getPlotBandRecurrenceChart(isTileView), '', + 'New' + )); + + dateTimeAxisSubItemList.add(SubItemList( 'Date time', 'Default Date time axis', @@ -247,9 +304,24 @@ class SampleListModel extends Model { '', 'images/axes.png', getLabelDateTimeAxisChart(isTileView))); + logarithmicAxisSubItemList.add(SubItemList( + 'Logarithmic', + 'Default logarithmic axis', + '', + 'images/axes.png', + getDefaultLogarithmicAxisChart(isTileView), '', + 'New')); + logarithmicAxisSubItemList.add(SubItemList( + 'Logarithmic', + 'Inversed logarithmic axis', + '', + 'images/axes.png', + getInversedLogarithmicAxisChart(isTileView), '', + 'New')); axisSubItemList.add(numericAxisSubItemList); axisSubItemList.add(categoryAxisSubItemList); axisSubItemList.add(dateTimeAxisSubItemList); + axisSubItemList.add(logarithmicAxisSubItemList); axesFeaturesSubItemList.add(axisFeaturesSubItemList); // For Accumulation Types @@ -257,6 +329,10 @@ class SampleListModel extends Model { doughnutSeriesSubItemList = []; radialBarSeriesSubItemList = []; + //Triagular series types + pyramidSeriesSubItemList = []; + funnelSeriesSubItemList = []; + pieSeriesSubItemList.add(SubItemList( 'Pie', 'Default pie chart', @@ -351,6 +427,56 @@ class SampleListModel extends Model { getCustomizedRadialBarChart(isTileView), )); + pyramidSeriesSubItemList.add(SubItemList( + 'Pyramid', + 'Default pyramid chart', + '', + 'images/axes.png', + getDefaultPyramidChart(isTileView), '', + 'New' + )); + pyramidSeriesSubItemList.add(SubItemList( + 'Pyramid', + 'Pyramid with smart labels', + '', + 'images/axes.png', + getPyramidSmartLabelChart(isTileView), '', + 'New' + )); + pyramidSeriesSubItemList.add(SubItemList( + 'Pyramid', + 'Pyramid with legend', + '', + 'images/axes.png', + getLegendPyramidChart(isTileView), '', + 'New' + )); + + funnelSeriesSubItemList.add(SubItemList( + 'Funnel', + 'Default funnel chart', + '', + 'images/axes.png', + getDefaultFunnelChart(isTileView), '', + 'New' + )); + funnelSeriesSubItemList.add(SubItemList( + 'Funnel', + 'Funnel with smart labels', + '', + 'images/axes.png', + getFunnelSmartLabelChart(isTileView), '', + 'New' + )); + funnelSeriesSubItemList.add(SubItemList( + 'Funnel', + 'Funnel with legend', + '', + 'images/axes.png', + getLegendFunnelChart(isTileView), '', + 'New' + )); + // Cartesian Types lineSeriesSubItemList = []; columnSeriesSubItemList = []; @@ -360,6 +486,8 @@ class SampleListModel extends Model { bubbleSeriesSubItemList = []; scatterSeriesSubItemList = []; stepLineSeriesSubItemList = []; + stackedSeriesSubItemList = []; + rangeColumnSeriesSubItemList = []; legendSubItemList = []; markerSubItemList = []; dataLabelSubItemList = []; @@ -369,6 +497,8 @@ class SampleListModel extends Model { emptyPointSubItemList = []; cartesianSubItemList = >[]; accumulationSubItemList = >[]; + funnelSubItemList = >[]; + pyramidSubItemList = >[]; otherFeaturesSubItemList = >[]; legendFeaturesSubItemList = >[]; userInteractionSubItemList = >[]; @@ -473,7 +603,8 @@ class SampleListModel extends Model { 'Selection zooming', 'This sample depicts the working of selection zooming. Long press and drag on the chart to select the region for zooming.', 'images/circular.png', - getDefaultZoomingChart(isTileView), + getDefaultZoomingChart(isTileView), '', + 'Updated' )); zoomingPanningSubItemList.add(SubItemList( 'Zooming and Panning', @@ -567,6 +698,14 @@ class SampleListModel extends Model { 'images/circular.png', getDefaultAnimationChart(isTileView), )); + animationSubItemList.add(SubItemList( + 'Animation', + 'Dynamic update', + '', + 'images/circular.png', + getDynamicAnimationChart(isTileView), '', + 'New' + )); emptyPointSubItemList.add(SubItemList( 'Empty Points', 'Chart with empty points', @@ -696,6 +835,7 @@ class SampleListModel extends Model { 'images/cartesian.png', getCustomizedBarChart(isTileView), )); + bubbleSeriesSubItemList.add(SubItemList( 'Bubble', 'Default bubble chart', @@ -783,6 +923,63 @@ class SampleListModel extends Model { 'images/circular.png', getVerticalColumnChart(isTileView), )); + rangeColumnSeriesSubItemList.add(SubItemList( + 'Range Column', + 'Default range column chart', + '', + 'images/cartesian.png', + getDefaultRangeColumnChart(isTileView), + '', + 'New' + )); + rangeColumnSeriesSubItemList.add(SubItemList( + 'Range Column', + 'Transposed range column', + '', + 'images/cartesian.png', + getRangeBarChart(isTileView), '', + 'New' + )); + rangeColumnSeriesSubItemList.add(SubItemList( + 'Range Column', + 'Range column with track', + '', + 'images/cartesian.png', + getRangeColumnwithTrack(isTileView), '', + 'New' + )); + stackedSeriesSubItemList.add(SubItemList( + 'Stacked Charts', + 'Stacked line chart', + '', + 'images/cartesian.png', + getStackedLineChart(isTileView), '', + 'New' + )); + stackedSeriesSubItemList.add(SubItemList( + 'Stacked Charts', + 'Stacked area chart', + '', + 'images/cartesian.png', + getStackedAreaChart(isTileView), '', + 'New' + )); + stackedSeriesSubItemList.add(SubItemList( + 'Stacked Charts', + 'Stacked column chart', + '', + 'images/cartesian.png', + getStackedColumnChart(isTileView), '', + 'New' + )); + stackedSeriesSubItemList.add(SubItemList( + 'Stacked Charts', + 'Stacked bar chart', + '', + 'images/cartesian.png', + getStackedBarChart(isTileView), '', + 'New' + )); cartesianSubItemList.add(lineSeriesSubItemList); cartesianSubItemList.add(columnSeriesSubItemList); @@ -792,11 +989,16 @@ class SampleListModel extends Model { cartesianSubItemList.add(bubbleSeriesSubItemList); cartesianSubItemList.add(scatterSeriesSubItemList); cartesianSubItemList.add(stepLineSeriesSubItemList); + cartesianSubItemList.add(rangeColumnSeriesSubItemList); + cartesianSubItemList.add(stackedSeriesSubItemList); accumulationSubItemList.add(pieSeriesSubItemList); accumulationSubItemList.add(doughnutSeriesSubItemList); accumulationSubItemList.add(radialBarSeriesSubItemList); + pyramidSubItemList.add(pyramidSeriesSubItemList); + funnelSubItemList.add(funnelSeriesSubItemList); + legendFeaturesSubItemList.add(legendSubItemList); otherFeaturesSubItemList.add(markerSubItemList); otherFeaturesSubItemList.add(dataLabelSubItemList); @@ -819,42 +1021,62 @@ class SampleListModel extends Model { 'Cartesian Charts', 'Demos of various chart types supported in cartesian axes', 'images/cartesian_types.png', - cartesianSubItemList)); + cartesianSubItemList, + 'Updated')); controlList.add(SampleList( 'Circular Charts', 'Demos of various circular chart types including pie and doughnut', 'images/circle_series.png', - accumulationSubItemList)); + accumulationSubItemList, + '')); + controlList.add(SampleList( + 'Pyramid Chart', + 'Interactive demos of pyramid charts', + 'images/pyramid.png', + pyramidSubItemList, + 'New')); + controlList.add(SampleList( + 'Funnel Chart', + 'Interactive demos of funnel charts', + 'images/funnel.png', + funnelSubItemList, + 'New')); controlList.add(SampleList( 'Axis Types', 'Various types of an axis available to plot the desired data', 'images/axis_types.png', - axisSubItemList)); + axisSubItemList, + 'Updated')); controlList.add(SampleList( 'Axis Features', 'Set of features helpful for customizing the axis and its elements', 'images/axis_feature.png', - axesFeaturesSubItemList)); + axesFeaturesSubItemList, + 'Updated')); controlList.add(SampleList( 'Series Features', 'Set of features helpful for customizing series and data points', 'images/other_features.png', - otherFeaturesSubItemList)); + otherFeaturesSubItemList, + 'Updated')); controlList.add(SampleList( 'Legend', 'Various legend features useful in displaying additional information about the series', 'images/legend.png', - legendFeaturesSubItemList)); + legendFeaturesSubItemList, + '')); controlList.add(SampleList( 'User Interactions', 'Real-time demos of the interactive features in chart', 'images/user_interaction.png', - userInteractionSubItemList)); + userInteractionSubItemList, + 'Updated')); controlList.add(SampleList( 'Dynamic Updates', 'This sample demonstrates the chart with dynamic updates at run time', 'images/live_update.png', - dynamicUpdatesSubItemList)); + dynamicUpdatesSubItemList, + '')); // For search results diff --git a/lib/sample_browser.dart b/lib/sample_browser.dart index 0c8b6520..f24facb2 100755 --- a/lib/sample_browser.dart +++ b/lib/sample_browser.dart @@ -330,7 +330,10 @@ class _HomePageState extends State { child: ListTile( leading: Image.asset(model.controlList[i].image, fit: BoxFit.cover), - title: Text( + title: Row( + mainAxisAlignment:MainAxisAlignment.spaceBetween, + children: [ + Text( model.controlList[i].title, textAlign: TextAlign.left, softWrap: true, @@ -343,6 +346,12 @@ class _HomePageState extends State { letterSpacing: 0.3, fontFamily: 'MontserratBold'), ), + Container( + decoration: BoxDecoration(shape: BoxShape.rectangle,color:model.controlList[i].status == 'New' ? Color.fromRGBO(101,193,0,1): model.controlList[i].status =='Updated' ? Color.fromRGBO(245,166,35,1) : model.controlList[i].status == 'Preview' ? Color.fromRGBO(238,245,255,1) : Colors.transparent, borderRadius: BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10))), + padding: EdgeInsets.fromLTRB(7, 3, 6, 3), + child:Text( model.controlList[i].status, style:TextStyle(color:model.controlList[i].status == 'Preview' ? Color.fromRGBO(0,98,255,1):Colors.white,fontSize: 12))) + ]), + subtitle: Padding( padding: const EdgeInsets.fromLTRB(0.0, 7.0, 0.0, 0.0), @@ -361,6 +370,7 @@ class _HomePageState extends State { ), ), ), + // trailing: ), )))), ), diff --git a/lib/samples/chart/axis_features/axis_crossing/axis_crossing.dart b/lib/samples/chart/axis_features/axis_crossing/axis_crossing.dart new file mode 100644 index 00000000..77ed235f --- /dev/null +++ b/lib/samples/chart/axis_features/axis_crossing/axis_crossing.dart @@ -0,0 +1,503 @@ +import 'package:flutter_examples/widgets/checkbox.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/bottom_sheet.dart'; +import 'package:flutter_examples/widgets/customDropDown.dart'; +import 'package:flutter_examples/widgets/custom_button.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class AxisCrossing extends StatefulWidget { + final SubItemList sample; + const AxisCrossing(this.sample, {Key key}) : super(key: key); + + @override + _AxisCrossingState createState() => _AxisCrossingState(sample); +} + +class _AxisCrossingState extends State { + final SubItemList sample; + + _AxisCrossingState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(AxisCrossing oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/cartesian_charts/rangecolumn_series/axis_crossing.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + final List _axis = + ['X', 'Y'].toList(); + String _selectedAxisType = 'X'; + String _selectedAxis; + double crossAt = 0; + bool isPlaceLabelsNearAxisLine = true; + @override + void initState() { + super.initState(); + crossAt = 0; + _selectedAxis = 'X'; + // _selectedPyramidMode = PyramidMode.linear; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getAxisCrossingSample(false,_selectedAxisType, crossAt, isPlaceLabelsNearAxisLine)), + ), + floatingActionButton: Stack( + children: [ + Align( + alignment: Alignment.bottomLeft, + child: Padding( + padding: const EdgeInsets.fromLTRB(30, 50, 0, 0), + child: Container( + height: 50, + width: 250, + // child: InkWell( + // onTap: () => launch( + // 'https://data.worldbank.org/indicator/sp.rur.totl.zs'), + // child: Row( + // children: [ + // Text('Source: ', + // style: TextStyle( + // fontSize: 16, color: model.textColor)), + // Text('data.worldbank.org', + // style: TextStyle( + // fontSize: 14, color: Colors.blue)), + // ], + // ), + // ), + ), + ), + ), + Align( + alignment: Alignment.bottomRight, + child: FloatingActionButton( + heroTag: null, + onPressed: () { + _showSettingsPanel(model); + }, + child: Icon(Icons.graphic_eq, color: Colors.white), + backgroundColor: model.backgroundColor, + ), + ), + + ])); + }); + } + void onPyramidModeChange(String item) { + setState(() { + _selectedAxis = item; + if (_selectedAxis == 'X') { + _selectedAxisType = 'X'; + } + else if (_selectedAxis == 'Y') { + _selectedAxisType = 'Y'; + } + }); + } + void _showSettingsPanel(SampleListModel model) { + double height = + (MediaQuery.of(context).size.height > MediaQuery.of(context).size.width) + ? 0.3 + : 0.4; + showRoundedModalBottomSheet( + dismissOnTap: false, + context: context, + radius: 12.0, + color: model.bottomSheetBackgroundColor, + builder: (context) => ScopedModelDescendant( + rebuildOnChange: false, + builder: (context, _, model) => Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 170, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: MediaQuery.of(context).size.height * height, + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 5), + child: Stack(children: [ + Container( + height: 40, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('Settings', + style: TextStyle( + color: model.textColor, + fontSize: 18, + letterSpacing: 0.34, + fontWeight: FontWeight.w500)), + IconButton( + icon: Icon( + Icons.close, + color: model.textColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets.fromLTRB(10, 50, 0, 0), + child: ListView( + children: [ + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Axis ', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + padding: + const EdgeInsets.fromLTRB( + 20, 0, 0, 0), + height: 50, + width: 150, + child: Align( + alignment: + Alignment.bottomCenter, + child: Theme( + data: Theme.of(context) + .copyWith( + canvasColor: model + .bottomSheetBackgroundColor), + child: DropDown( + value: _selectedAxis, + item: _axis + .map( + (String value) { + return DropdownMenuItem< + String>( + value: (value != + null) + ? value + : 'X', + child: Text( + '$value', + style: TextStyle( + color: model + .textColor))); + }).toList(), + valueChanged: + (dynamic value) { + onPyramidModeChange( + value.toString()); + }), + ), + )) + ], + ), + ), + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Cross At ', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 10, 0, 0, 0), + child: CustomButton( + minValue: -8, + maxValue: 8, + initialValue: + crossAt, + onChanged: (val) => + setState(() { + crossAt = val; + }), + step: 2, + horizontal: true, + loop: false, + padding: 0, + iconUp: + Icons.keyboard_arrow_up, + iconDown: + Icons.keyboard_arrow_down, + iconLeft: + Icons.keyboard_arrow_left, + iconRight: Icons + .keyboard_arrow_right, + iconUpRightColor: + model.textColor, + iconDownLeftColor: + model.textColor, + style: TextStyle( + fontSize: 20.0, + color: model.textColor), + ), + ), + ), + ], + ), + ), + Container( + child: Row( + children: [ + Text('Labels Near Axisline', + style: TextStyle( + color: model.textColor, + fontSize: 16, + letterSpacing: 0.34, + fontWeight: + FontWeight.normal)), + Padding( + padding: EdgeInsets.fromLTRB(20, 0, 0, 0) + ), + BottomSheetCheckbox( + activeColor: + model.backgroundColor, + switchValue: isPlaceLabelsNearAxisLine, + valueChanged: (value) { + setState(() { + isPlaceLabelsNearAxisLine = value; + }); + }, + ), + ], + ), + ), + ], + ), + ), + ]), + ))))))); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getAxisCrossingSample(bool isTileView,[String _selectedAxis, double _crossAt, bool isPlaceLabelsNearAxisLine]) { + return SfCartesianChart( + plotAreaBorderWidth: 0, + title: ChartTitle( + text: isTileView ? '' : 'Spline Interpolation'), + legend:Legend(isVisible: !isTileView), + primaryXAxis: NumericAxis( + minimum: -8, + maximum: 8, + interval: 2, + placeLabelsNearAxisLine: isTileView ? true : _selectedAxis == 'X' ? isPlaceLabelsNearAxisLine : true, + crossesAt: _selectedAxis == 'X' ? _crossAt: 0, + minorTicksPerInterval: 3), + primaryYAxis: NumericAxis( + minimum: -8, + maximum: 8, + interval: 2, + placeLabelsNearAxisLine: isTileView ? true : _selectedAxis == 'Y' ? isPlaceLabelsNearAxisLine : true, + crossesAt: _selectedAxis == 'Y' ? _crossAt: 0, + minorTicksPerInterval: 3), + series: getSeries(isTileView), + tooltipBehavior: + TooltipBehavior(enable: true, header: '', canShowMarker: false), + ); +} + +List> getSeries(bool isTileView) { + final dynamic splineData = <_ChartData>[ + _ChartData( -7, -3), + _ChartData( -4.5, -2), + _ChartData( -3.5, 0), + _ChartData( -3, 2), + _ChartData( 0, 7), + _ChartData( 3, 2), + _ChartData( 3.5, 0), + _ChartData( 4.5, -2), + _ChartData( 7, -3), + ]; + + return >[ + SplineSeries<_ChartData, dynamic>( + dataSource: splineData, + xValueMapper: (_ChartData sales, _) => sales.value1, + yValueMapper: (_ChartData sales, _) => sales.value2, + color: const Color.fromRGBO(20, 122, 20, 1), + name: 'Cubic Interpolation', + width: 2), + ]; +} + +class _ChartData { + _ChartData(this.value1, this.value2); + final num value1; + final num value2; +} diff --git a/lib/samples/chart/axis_features/handling_label_collision/handling_label_collision.dart b/lib/samples/chart/axis_features/handling_label_collision/handling_label_collision.dart index b10539ce..6c26505b 100755 --- a/lib/samples/chart/axis_features/handling_label_collision/handling_label_collision.dart +++ b/lib/samples/chart/axis_features/handling_label_collision/handling_label_collision.dart @@ -396,7 +396,7 @@ class _BackPanelState extends State { SfCartesianChart getLabelIntersectActionChart(bool isTileView, [AxisLabelIntersectAction _labelIntersectAction]) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, title: ChartTitle(text: isTileView ? '' : 'Football players with most goals'), primaryXAxis: CategoryAxis( diff --git a/lib/samples/chart/axis_features/opposed_axes/opposed_axes.dart b/lib/samples/chart/axis_features/opposed_axes/opposed_axes.dart index 4dd74007..aa2be2e1 100755 --- a/lib/samples/chart/axis_features/opposed_axes/opposed_axes.dart +++ b/lib/samples/chart/axis_features/opposed_axes/opposed_axes.dart @@ -220,7 +220,7 @@ SfCartesianChart getOpposedNumericAxisChart(bool isTileView) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Light vehicle retail sales in US'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: NumericAxis( minimum: 1974, maximum: 2022, diff --git a/lib/samples/chart/axis_features/plot_band/Plot_band_recurrence.dart b/lib/samples/chart/axis_features/plot_band/Plot_band_recurrence.dart new file mode 100644 index 00000000..6002a7ea --- /dev/null +++ b/lib/samples/chart/axis_features/plot_band/Plot_band_recurrence.dart @@ -0,0 +1,417 @@ +import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:flutter_examples/widgets/checkbox.dart'; +import 'package:url_launcher/url_launcher.dart'; +import '../../../../widgets/bottom_sheet.dart'; + +class PlotBandRecurrence extends StatefulWidget { + final SubItemList sample; + const PlotBandRecurrence(this.sample, {Key key}) : super(key: key); + + @override + _PlotBandRecurrenceState createState() => _PlotBandRecurrenceState(sample); +} + +class _PlotBandRecurrenceState extends State { + final SubItemList sample; + _PlotBandRecurrenceState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(PlotBandRecurrence oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: + Image.asset('images/code.png', color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/series_features/sorting/sorting_options.dart'); + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Icon( + Icons.info_outline, + color: Colors.white, + ), + onPressed: () { + if (frontPanelVisible.value) + frontPanelVisible.value = false; + else + frontPanelVisible.value = true; + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + _FrontPanelState(this.sample); + bool xAxis = false, yAxis = true; + + @override + void initState() { + xAxis = false; + yAxis = true; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 60), + child: Container( + child: getPlotBandRecurrenceChart(false, xAxis, yAxis)), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + _showSettingsPanel(model); + }, + child: Icon(Icons.graphic_eq, color: Colors.white), + backgroundColor: model.backgroundColor, + )); + }); + } + + void _showSettingsPanel(SampleListModel model) { + double height = + (MediaQuery.of(context).size.height > MediaQuery.of(context).size.width) + ? 0.3 + : 0.4; + showRoundedModalBottomSheet( + dismissOnTap: false, + context: context, + radius: 12.0, + color: model.bottomSheetBackgroundColor, + builder: (context) => ScopedModelDescendant( + rebuildOnChange: false, + builder: (context, _, model) => Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 180, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: MediaQuery.of(context).size.height * height, + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 5), + child: Stack(children: [ + Container( + height: 40, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('Settings', + style: TextStyle( + color: model.textColor, + fontSize: 18, + letterSpacing: 0.34, + fontWeight: FontWeight.w500)), + IconButton( + icon: Icon( + Icons.close, + color: model.textColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets.fromLTRB(10, 50, 0, 0), + child: ListView( + children: [ + Container( + child: Row( + children: [ + Text('X Axis', + style: TextStyle( + color: model.textColor, + fontSize: 16, + letterSpacing: 0.34, + fontWeight: + FontWeight.normal)), + BottomSheetCheckbox( + activeColor: + model.backgroundColor, + switchValue: xAxis, + valueChanged: (value) { + setState(() { + xAxis = value; + }); + }, + ), + ], + ), + ), + Container( + child: Row( + children: [ + Text('Y Axis', + style: TextStyle( + color: model.textColor, + fontSize: 16, + letterSpacing: 0.34, + fontWeight: + FontWeight.normal)), + BottomSheetCheckbox( + activeColor: + model.backgroundColor, + switchValue: yAxis, + valueChanged: (value) { + setState(() { + yAxis = value; + }); + }, + ), + ], + ), + ), + ], + ), + ), + ]), + ))))))); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getPlotBandRecurrenceChart(bool isTileView, + [bool xVisible, bool yVisible]) { + return SfCartesianChart( + title: ChartTitle(text: isTileView ? '' : "World pollution report"), + legend: Legend(isVisible: !isTileView), + plotAreaBorderWidth: 0, + primaryXAxis: DateTimeAxis( + interval: 5, + dateFormat: DateFormat.y(), + majorGridLines: MajorGridLines(width: 0), + intervalType: DateTimeIntervalType.years, + edgeLabelPlacement: EdgeLabelPlacement.hide, + minimum: DateTime(1975, 1, 1), + maximum: DateTime(2010, 1, 1), + plotBands: [ + PlotBand( + isRepeatable: true, + isVisible: isTileView ? false : xVisible, + repeatEvery: 10, + sizeType: DateTimeIntervalType.years, + size: 5, + repeatUntil: DateTime(2010, 1, 1), + start: DateTime(1965, 1, 1), + end: DateTime(2010, 1, 1), + shouldRenderAboveSeries:true, + color: Color.fromRGBO(227, 228, 230, 0.4)) + ]), + primaryYAxis: NumericAxis( + isVisible: true, + minimum: 0, + interval: 2000, + maximum: 18000, + plotBands: [ + PlotBand( + isRepeatable: true, + isVisible: isTileView ? true : yVisible, + repeatEvery: 4000, + size: 2000, + start: 0, + end: 18000, + repeatUntil: 18000, + shouldRenderAboveSeries:true, + color: Color.fromRGBO(227, 228, 230, 0.1)) + ], + majorGridLines: MajorGridLines(color: Colors.grey), + majorTickLines: MajorTickLines(size: 0), + axisLine: AxisLine(width: 0), + labelStyle: ChartTextStyle(fontSize: 0)), + series: _getColumnSeries(isTileView), + tooltipBehavior: + TooltipBehavior(enable: true, canShowMarker: false, header: ''), + ); +} + +List> _getColumnSeries(bool isTileView) { + final List<_ColumnData> chartData = <_ColumnData>[ + _ColumnData(DateTime(1980, 1, 1), 15400, 6400), + _ColumnData(DateTime(1985, 1, 1), 15800, 3700), + _ColumnData(DateTime(1990, 1, 1), 14000, 7200), + _ColumnData(DateTime(1995, 1, 1), 10500, 2300), + _ColumnData(DateTime(2000, 1, 1), 13300, 4000), + _ColumnData(DateTime(2005, 1, 1), 12800, 4800) + ]; + return >[ + ColumnSeries<_ColumnData, DateTime>( + dataSource: chartData, + name: 'All sources', + xValueMapper: (_ColumnData sales, _) => sales.x, + yValueMapper: (_ColumnData sales, _) => sales.y, + ), + ColumnSeries<_ColumnData, DateTime>( + dataSource: chartData, + name: 'Autos & Light Trucks', + xValueMapper: (_ColumnData sales, _) => sales.x, + yValueMapper: (_ColumnData sales, _) => sales.yVal, + ) + ]; +} + +class _ColumnData { + _ColumnData(this.x, this.y, this.yVal); + final DateTime x; + final double y; + final double yVal; +} diff --git a/lib/samples/chart/axis_features/plot_band/plot_band.dart b/lib/samples/chart/axis_features/plot_band/plot_band.dart new file mode 100644 index 00000000..92bbbeee --- /dev/null +++ b/lib/samples/chart/axis_features/plot_band/plot_band.dart @@ -0,0 +1,535 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import '../../../../widgets/bottom_sheet.dart'; +import '../../../../widgets/customDropDown.dart'; + +class PlotBandDefault extends StatefulWidget { + final SubItemList sample; + const PlotBandDefault(this.sample, {Key key}) : super(key: key); + + @override + _PlotBandDefaultState createState() => _PlotBandDefaultState(sample); +} + +class _PlotBandDefaultState extends State { + final SubItemList sample; + _PlotBandDefaultState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(PlotBandDefault oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: + Image.asset('images/code.png', color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/series_features/sorting/sorting_options.dart'); + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Icon( + Icons.info_outline, + color: Colors.white, + ), + onPressed: () { + if (frontPanelVisible.value) + frontPanelVisible.value = false; + else + frontPanelVisible.value = true; + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + _FrontPanelState(this.sample); + final List _plotBandType = + ['vertical', 'horizontal', 'segment'].toList(); + bool isHorizontal = true; + bool isVertical = false; + bool isSegment = false; + + String _selectedType; + @override + void initState() { + super.initState(); + _selectedType = _plotBandType.first; + isHorizontal = true; + isVertical = false; + isSegment = false; + } + + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 60), + child: Container( + child: getPlotBandChart( + false, isHorizontal, isVertical, isSegment)), + ), + floatingActionButton: Stack( + children: [ + Align( + alignment: Alignment.bottomRight, + child: FloatingActionButton( + heroTag: null, + onPressed: () { + _showSettingsPanel(model); + }, + child: Icon(Icons.graphic_eq, color: Colors.white), + backgroundColor: model.backgroundColor, + ), + ), + ], + )); + }); + } + + void onEmptyPointModeChange(String item) { + setState(() { + _selectedType = item; + if (_selectedType == 'horizontal') { + isVertical = true; + isHorizontal = false; + isSegment = false; + } + if (_selectedType == 'vertical') { + isHorizontal = true; + isVertical = false; + isSegment = false; + } + if (_selectedType == 'segment') { + isHorizontal = false; + isVertical = false; + isSegment = true; + } + }); + } + + void _showSettingsPanel(SampleListModel model) { + double height = + (MediaQuery.of(context).size.height > MediaQuery.of(context).size.width) + ? 0.3 + : 0.4; + showRoundedModalBottomSheet( + dismissOnTap: false, + context: context, + radius: 12.0, + color: model.bottomSheetBackgroundColor, + builder: (context) => ScopedModelDescendant( + rebuildOnChange: false, + builder: (context, _, model) => Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 120, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: MediaQuery.of(context).size.height * height, + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 5), + child: Stack(children: [ + Container( + height: 40, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('Settings', + style: TextStyle( + color: model.textColor, + fontSize: 18, + letterSpacing: 0.34, + fontWeight: FontWeight.w500)), + IconButton( + icon: Icon( + Icons.close, + color: model.textColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets.fromLTRB(10, 50, 0, 0), + child: ListView(children: [ + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Plot band type', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + padding: + const EdgeInsets.fromLTRB( + 20, 0, 0, 0), + height: 50, + width: 150, + child: Align( + alignment: + Alignment.bottomCenter, + child: Theme( + data: Theme.of(context) + .copyWith( + canvasColor: model + .bottomSheetBackgroundColor), + child: DropDown( + value: _selectedType, + item: _plotBandType.map( + (String value) { + return DropdownMenuItem< + String>( + value: (value != + null) + ? value + : 'gap', + child: Text( + '$value', + style: TextStyle( + color: model + .textColor))); + }).toList(), + valueChanged: + (dynamic value) { + onEmptyPointModeChange( + value.toString()); + }), + ), + )) + ], + ), + ), + ]), + ) + ])))))))); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getPlotBandChart(bool isTileView, + [bool isHorizontal, bool isVertical, bool isSegment]) { + return SfCartesianChart( + title: ChartTitle(text: isTileView ? '' : 'Weather report'), + legend: Legend(isVisible: false), + plotAreaBorderWidth: 0, + primaryXAxis: CategoryAxis( + interval: 1, + plotBands: [ + PlotBand( + isVisible: isTileView ? true : isHorizontal, + start: -0.5, + end: 1.5, + text: 'Winter', + shouldRenderAboveSeries: true, + textStyle: ChartTextStyle(color: Colors.black, fontSize: 13), + color: const Color.fromRGBO(101, 199, 209, 1)), + PlotBand( + isVisible: isTileView ? true : isHorizontal, + start: 4.5, + end: 7.5, + text: 'Summer', + shouldRenderAboveSeries: true, + textStyle: ChartTextStyle(color: Colors.black, fontSize: 13), + color: const Color.fromRGBO(254, 213, 2, 1)), + PlotBand( + isVisible: isTileView ? true : isHorizontal, + start: 1.5, + end: 4.5, + text: 'Spring', + shouldRenderAboveSeries: true, + textStyle: ChartTextStyle(color: Colors.black, fontSize: 13), + color: const Color.fromRGBO(140, 198, 62, 1)), + PlotBand( + isVisible: isTileView ? true : isHorizontal, + start: 7.5, + end: 9.5, + text: 'Autumn', + shouldRenderAboveSeries: true, + textStyle: ChartTextStyle(color: Colors.black, fontSize: 13), + color: const Color.fromRGBO(217, 112, 1, 1)), + PlotBand( + isVisible: isTileView ? true : isHorizontal, + start: 9.5, + end: 10.5, + text: 'Winter', + textStyle: ChartTextStyle(color: Colors.black, fontSize: 13), + shouldRenderAboveSeries: true, + color: const Color.fromRGBO(101, 199, 209, 1)), + PlotBand( + size: 2, + start: -0.5, + end: 4.5, + textAngle: 0, + associatedAxisStart: 20.5, + text: 'Average', + associatedAxisEnd: 27.5, + isVisible: isTileView ? false : isSegment, + color: const Color.fromRGBO(224, 155, 0, 1), + shouldRenderAboveSeries: true, + textStyle: ChartTextStyle(color: Colors.white, fontSize: 17)), + PlotBand( + start: 7.5, + end: 10.5, + size: 3, + associatedAxisStart: 20.5, + text: 'Average', + associatedAxisEnd: 27.5, + textAngle: 0, + isVisible: isTileView ? false : isSegment, + color: const Color.fromRGBO(224, 155, 0, 1), + shouldRenderAboveSeries: true, + textStyle: ChartTextStyle(color: Colors.white, fontSize: 17)), + PlotBand( + start: 4.5, + end: 7.5, + size: 2, + associatedAxisStart: 32.5, + text: 'High', + associatedAxisEnd: 37.5, + textAngle: 0, + isVisible: isTileView ? false : isSegment, + color: const Color.fromRGBO(207, 85, 7, 1), + shouldRenderAboveSeries: true, + textStyle: ChartTextStyle(color: Colors.white, fontSize: 17)), + ], majorGridLines: MajorGridLines(width: 0)), + primaryYAxis: NumericAxis( + minimum: 10, + maximum: 40, + interval: 5, + labelFormat: '{value} °C', + rangePadding: ChartRangePadding.none, + plotBands: [ + PlotBand( + isVisible: isTileView ? false : isVertical, + start: 30, + end: 40, + text: 'High Temperature', + shouldRenderAboveSeries: true, + color: const Color.fromRGBO(207, 85, 7, 1), + textStyle: ChartTextStyle(color: Color.fromRGBO(255, 255, 255, 1))), + PlotBand( + isVisible: isTileView ? false : isVertical, + start: 20, + end: 30, + text: 'Average Temperature', + shouldRenderAboveSeries: true, + color: const Color.fromRGBO(224, 155, 0, 1), + textStyle: ChartTextStyle(color: Color.fromRGBO(255, 255, 255, 1))), + PlotBand( + isVisible: isTileView ? false : isVertical, + start: 10, + end: 20, + text: 'Low Temperature', + shouldRenderAboveSeries: true, + color: const Color.fromRGBO(237, 195, 12, 1)) + ], + ), + series: _getColumnSeries(isTileView, isSegment), + tooltipBehavior: + TooltipBehavior(enable: true, canShowMarker: false, header: ''), + ); +} + +List> _getColumnSeries(bool isTileView, + [bool isSegment]) { + final dynamic lineData = <_ColumnData>[ + _ColumnData(xValue: 'Jan', yValue: 23), + _ColumnData(xValue: 'Feb', yValue: 24), + _ColumnData(xValue: 'Mar', yValue: 23), + _ColumnData(xValue: 'Apr', yValue: 22), + _ColumnData(xValue: 'May', yValue: 21), + _ColumnData(xValue: 'Jun', yValue: 27), + _ColumnData(xValue: 'Jul', yValue: 33), + _ColumnData(xValue: 'Aug', yValue: 36), + _ColumnData(xValue: 'Sep', yValue: 23), + _ColumnData(xValue: 'Oct', yValue: 25), + _ColumnData(xValue: 'Nov', yValue: 22), + // _ColumnData(xValue: 'Dec', yValue: 23), + ]; + return >[ + LineSeries<_ColumnData, dynamic>( + dataSource: lineData, + xValueMapper: (_ColumnData sales, _) => sales.xValue, + yValueMapper: (_ColumnData sales, _) => sales.yValue, + color: + isTileView ? Colors.white : isSegment ? Colors.black : Colors.white, + name: 'Weather', + markerSettings: MarkerSettings( + isVisible: true, + borderColor: Colors.white, + borderWidth: 2, + color: const Color.fromRGBO(102, 102, 102, 1))) + ]; +} + +class _ColumnData { + _ColumnData({this.xValue, this.yValue}); + final String xValue; + final num yValue; +} diff --git a/lib/samples/chart/axis_types/category_types/default_category_axis.dart b/lib/samples/chart/axis_types/category_types/default_category_axis.dart index d5620b2e..2ca17fa9 100755 --- a/lib/samples/chart/axis_types/category_types/default_category_axis.dart +++ b/lib/samples/chart/axis_types/category_types/default_category_axis.dart @@ -189,7 +189,7 @@ class _BackPanelState extends State { SfCartesianChart getDefaultCategoryAxisChart(bool isTileView) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Internet Users - 2016'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: CategoryAxis( majorGridLines: MajorGridLines(width: 0), ), diff --git a/lib/samples/chart/axis_types/category_types/indexed_category_axis.dart b/lib/samples/chart/axis_types/category_types/indexed_category_axis.dart index 5d9549f8..442562fd 100755 --- a/lib/samples/chart/axis_types/category_types/indexed_category_axis.dart +++ b/lib/samples/chart/axis_types/category_types/indexed_category_axis.dart @@ -305,7 +305,7 @@ SfCartesianChart getIndexedCategoryAxisChart(bool isTileView, [bool isIndexed]) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Real GDP growth'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, legend: Legend(isVisible: isTileView ? false : true), primaryXAxis: CategoryAxis( arrangeByIndex: isTileView ? true : isIndexed, diff --git a/lib/samples/chart/axis_types/category_types/label_placement.dart b/lib/samples/chart/axis_types/category_types/label_placement.dart index f6feb1c7..c8ed6bc3 100755 --- a/lib/samples/chart/axis_types/category_types/label_placement.dart +++ b/lib/samples/chart/axis_types/category_types/label_placement.dart @@ -336,7 +336,7 @@ SfCartesianChart getTicksCategoryAxisChart(bool isTileView, [LabelPlacement _labelPlacement]) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Employees task count'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: CategoryAxis( majorGridLines: MajorGridLines(width: 0), labelPlacement: _labelPlacement != null diff --git a/lib/samples/chart/axis_types/date_time_types/date_time_axis_with_label_format.dart b/lib/samples/chart/axis_types/date_time_types/date_time_axis_with_label_format.dart index 217983d3..5891fec4 100755 --- a/lib/samples/chart/axis_types/date_time_types/date_time_axis_with_label_format.dart +++ b/lib/samples/chart/axis_types/date_time_types/date_time_axis_with_label_format.dart @@ -215,7 +215,7 @@ class _BackPanelState extends State { SfCartesianChart getLabelDateTimeAxisChart(bool isTileView) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, title: ChartTitle(text: isTileView ? '' : 'Earthquakes in Indonesia'), primaryXAxis: DateTimeAxis( intervalType: DateTimeIntervalType.months, diff --git a/lib/samples/chart/axis_types/date_time_types/default_date_time_axis.dart b/lib/samples/chart/axis_types/date_time_types/default_date_time_axis.dart index c31333c8..2e3e2062 100755 --- a/lib/samples/chart/axis_types/date_time_types/default_date_time_axis.dart +++ b/lib/samples/chart/axis_types/date_time_types/default_date_time_axis.dart @@ -214,7 +214,7 @@ class _BackPanelState extends State { SfCartesianChart getDefaultDateTimeAxisChart(bool isTileView) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, title: ChartTitle( text: isTileView ? '' diff --git a/lib/samples/chart/axis_types/logarithmic_types/default_logarithmic_axis.dart b/lib/samples/chart/axis_types/logarithmic_types/default_logarithmic_axis.dart new file mode 100644 index 00000000..e5b33a8d --- /dev/null +++ b/lib/samples/chart/axis_types/logarithmic_types/default_logarithmic_axis.dart @@ -0,0 +1,240 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class LogarithmicAxisDefault extends StatefulWidget { + final SubItemList sample; + const LogarithmicAxisDefault(this.sample, {Key key}) : super(key: key); + + @override + _LogarithmicAxisDefaultState createState() => + _LogarithmicAxisDefaultState(sample); +} + +class _LogarithmicAxisDefaultState extends State { + final SubItemList sample; + + _LogarithmicAxisDefaultState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(LogarithmicAxisDefault oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/axis_types/logarithmic_type/default_logarithmic_axis.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getDefaultLogarithmicAxisChart(false)), + )); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getDefaultLogarithmicAxisChart(bool isTileView) { + return SfCartesianChart( + plotAreaBorderWidth: 1, + title: + ChartTitle(text: isTileView ? '' : 'Growth of a product [1995-2005]'), + primaryXAxis: DateTimeAxis(), + primaryYAxis: LogarithmicAxis( + minorTicksPerInterval: 5, + majorGridLines: MajorGridLines(width: 1.5), + minorTickLines: MinorTickLines(size: 4), + labelFormat: '\${value}', + interval: 1), + series: _getSeries(isTileView), + tooltipBehavior: + TooltipBehavior(enable: true, header: '', canShowMarker: false), + ); +} + +List> _getSeries(bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData(new DateTime(1996, 1, 1), 200), + _ChartData(new DateTime(1997, 1, 1), 400), + _ChartData(new DateTime(1998, 1, 1), 600), + _ChartData(new DateTime(1999, 1, 1), 700), + _ChartData(new DateTime(2000, 1, 1), 1400), + _ChartData(new DateTime(2001, 1, 1), 2000), + _ChartData(new DateTime(2002, 1, 1), 4000), + _ChartData(new DateTime(2003, 1, 1), 6000), + _ChartData(new DateTime(2004, 1, 1), 8000), + _ChartData(new DateTime(2005, 1, 1), 11000) + ]; + return >[ + LineSeries<_ChartData, DateTime>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.y, + markerSettings: MarkerSettings(isVisible: true)) + ]; +} + +class _ChartData { + _ChartData(this.x, this.y); + final DateTime x; + final int y; +} diff --git a/lib/samples/chart/axis_types/logarithmic_types/inversed_logarithmic_axis.dart b/lib/samples/chart/axis_types/logarithmic_types/inversed_logarithmic_axis.dart new file mode 100644 index 00000000..d802da8c --- /dev/null +++ b/lib/samples/chart/axis_types/logarithmic_types/inversed_logarithmic_axis.dart @@ -0,0 +1,284 @@ +import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; +dynamic text; +class LogarithmicAxisInversed extends StatefulWidget { + final SubItemList sample; + const LogarithmicAxisInversed(this.sample, {Key key}) : super(key: key); + + @override + _LogarithmicAxisInversedState createState() => + _LogarithmicAxisInversedState(sample); +} + +class _LogarithmicAxisInversedState extends State { + final SubItemList sample; + + _LogarithmicAxisInversedState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(LogarithmicAxisInversed oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/axis_types/logarithmic_type/inversed_logarithmic_axis.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getInversedLogarithmicAxisChart(false)), + ), + floatingActionButton: Stack(children: [ + Align( + alignment: Alignment.bottomLeft, + child: Padding( + padding: const EdgeInsets.fromLTRB(30, 50, 0, 0), + child: Container( + height: 50, + width: 250, + child: InkWell( + onTap: () => launch( + 'https://www.worldometers.info/world-population/population-by-country/'), + child: Row( + children: [ + Text('Source: ', + style: TextStyle( + fontSize: 16, color: model.textColor)), + Text('worldometers.com', + style: TextStyle( + fontSize: 14, color: Colors.blue)), + ], + ), + ), + ), + ), + ) + ])); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getInversedLogarithmicAxisChart(bool isTileView) { + return SfCartesianChart( + onTooltipRender: (TooltipArgs args) { + final NumberFormat format = NumberFormat.decimalPattern(); + text = format.format(args.dataPoints[args.pointIndex].y).toString(); + args.text = text; + }, + onAxisLabelRender: (AxisLabelRenderArgs args) { + final NumberFormat format = NumberFormat.decimalPattern(); + if(args.axisName == 'primaryYAxis') + args.text = format.format(double.parse(args.text)).toString(); + }, + plotAreaBorderWidth: 0, + title: + ChartTitle(text: isTileView ? '' : 'Population of various countries'), + primaryXAxis: CategoryAxis( + labelIntersectAction: isTileView + ? AxisLabelIntersectAction.hide + : AxisLabelIntersectAction.none, + labelRotation: isTileView ? 0 : 45, + ), + primaryYAxis: LogarithmicAxis( + minorTicksPerInterval: 5, + majorGridLines: MajorGridLines(width: 1.5), + minorTickLines: MinorTickLines(size: 4), + isInversed: true, + interval: 1, + ), + series: _getSeries(isTileView), + tooltipBehavior: TooltipBehavior( + enable: true, format: 'point.y', header: '', canShowMarker: false), + ); +} + +List> _getSeries(bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData('China', 1433783686), + _ChartData('India', 1366417754), + _ChartData('US', 329064917), + _ChartData('Japan', 126860301), + _ChartData('UK', 67530172), + _ChartData('Canada', 37411047), + _ChartData('Greece', 10473455), + _ChartData('Maldives', 530953), + _ChartData('Dominica', 71808), + ]; + return >[ + StepLineSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.y, + markerSettings: MarkerSettings(isVisible: true, + width: 5, + height: 5, + shape: DataMarkerType.rectangle)) + ]; +} + +class _ChartData { + _ChartData(this.x, this.y); + final String x; + final int y; +} diff --git a/lib/samples/chart/axis_types/numeric_types/default_numeric_axis.dart b/lib/samples/chart/axis_types/numeric_types/default_numeric_axis.dart index 7348236d..9f929e8f 100755 --- a/lib/samples/chart/axis_types/numeric_types/default_numeric_axis.dart +++ b/lib/samples/chart/axis_types/numeric_types/default_numeric_axis.dart @@ -218,7 +218,7 @@ class _BackPanelState extends State { SfCartesianChart getDefaultNumericAxisChart(bool isTileView) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Australia vs India ODI - 2019'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, legend: Legend( isVisible: isTileView ? false : true, position: LegendPosition.top), primaryXAxis: NumericAxis( diff --git a/lib/samples/chart/axis_types/numeric_types/inversed_numeric_axis.dart b/lib/samples/chart/axis_types/numeric_types/inversed_numeric_axis.dart index 4e708864..0ce9f92b 100755 --- a/lib/samples/chart/axis_types/numeric_types/inversed_numeric_axis.dart +++ b/lib/samples/chart/axis_types/numeric_types/inversed_numeric_axis.dart @@ -358,7 +358,7 @@ class _BackPanelState extends State { SfCartesianChart getInversedNumericAxisChart(bool isTileView, [bool isXInversed, bool isYInversed]) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, title: ChartTitle(text: isTileView ? '' : 'Airports count in US'), primaryXAxis: NumericAxis( minimum: 2000, diff --git a/lib/samples/chart/axis_types/numeric_types/numeric_axis_with_label_format.dart b/lib/samples/chart/axis_types/numeric_types/numeric_axis_with_label_format.dart index 31c5f051..cfeeff58 100755 --- a/lib/samples/chart/axis_types/numeric_types/numeric_axis_with_label_format.dart +++ b/lib/samples/chart/axis_types/numeric_types/numeric_axis_with_label_format.dart @@ -188,7 +188,7 @@ class _BackPanelState extends State { SfCartesianChart getLabelNumericAxisChart(bool isTileView) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, title: ChartTitle(text: isTileView ? '' : 'Farenheit - Celsius conversion'), primaryXAxis: NumericAxis( labelFormat: '{value}°C', diff --git a/lib/samples/chart/cartesian_charts/area_series/default_area_chart.dart b/lib/samples/chart/cartesian_charts/area_series/default_area_chart.dart index b9bd79f5..752045e3 100755 --- a/lib/samples/chart/cartesian_charts/area_series/default_area_chart.dart +++ b/lib/samples/chart/cartesian_charts/area_series/default_area_chart.dart @@ -191,7 +191,7 @@ SfCartesianChart getDefaultAreaChart(bool isTileView) { return SfCartesianChart( legend: Legend(isVisible: isTileView ? false : true, opacity: 0.7), title: ChartTitle(text: isTileView ? '' : 'Average sales comparison'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: DateTimeAxis( dateFormat: DateFormat.y(), interval: 1, diff --git a/lib/samples/chart/cartesian_charts/rangecolumn_series/default_rangecolumn_chart.dart b/lib/samples/chart/cartesian_charts/rangecolumn_series/default_rangecolumn_chart.dart new file mode 100644 index 00000000..7ddc12c4 --- /dev/null +++ b/lib/samples/chart/cartesian_charts/rangecolumn_series/default_rangecolumn_chart.dart @@ -0,0 +1,272 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class RangeColumnDefault extends StatefulWidget { + final SubItemList sample; + const RangeColumnDefault(this.sample, {Key key}) : super(key: key); + + @override + _RangeColumnDefaultState createState() => _RangeColumnDefaultState(sample); +} + +class _RangeColumnDefaultState extends State { + final SubItemList sample; + + _RangeColumnDefaultState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(RangeColumnDefault oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/cartesian_charts/rangecolumn_series/default_rangecolumn_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getDefaultRangeColumnChart(false)), + ), + floatingActionButton: Stack(children: [ + Align( + alignment: Alignment.bottomLeft, + child: Padding( + padding: const EdgeInsets.fromLTRB(30, 50, 0, 0), + child: Container( + height: 50, + width: 250, + child: InkWell( + onTap: () => launch( + 'https://www.holiday-weather.com/london/averages/'), + child: Row( + children: [ + Text('Source: ', + style: TextStyle( + fontSize: 16, color: model.textColor)), + Text('holiday-weather.com', + style: TextStyle( + fontSize: 14, color: Colors.blue)), + ], + ), + ), + ), + ), + ) + ]) + ); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getDefaultRangeColumnChart(bool isTileView) { + return SfCartesianChart( + plotAreaBorderWidth: 0, + title: ChartTitle( + text: isTileView + ? '' + : 'Average half-yearly temperature variation of London, UK'), + primaryXAxis: CategoryAxis( + majorGridLines: MajorGridLines(width: 0), + ), + primaryYAxis: NumericAxis( + axisLine: AxisLine(width: 0), + interval: isTileView ? 5 : 2, + labelFormat: '{value}°C', + majorTickLines: MajorTickLines(size: 0)), + series: getRangeColumnSeries(isTileView), + tooltipBehavior: + TooltipBehavior(enable: true, header: '', canShowMarker: false), + ); +} + +List> getRangeColumnSeries( + bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData('Jan', 3, 6), + _ChartData('Feb', 3, 7), + _ChartData('Mar', 4, 10), + _ChartData('Apr', 6, 13), + _ChartData('May', 9, 17), + _ChartData('June', 12, 20), + ]; + return >[ + RangeColumnSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + lowValueMapper: (_ChartData sales, _) => sales.low, + highValueMapper: (_ChartData sales, _) => sales.high, + dataLabelSettings: DataLabelSettings( + isVisible: isTileView ? false : true, + position: CartesianLabelPosition.top, + textStyle: ChartTextStyle(fontSize: 10)), + ) + ]; +} + +class _ChartData { + _ChartData(this.x, this.low, this.high); + final String x; + final int low; + final int high; +} diff --git a/lib/samples/chart/cartesian_charts/rangecolumn_series/rangecolumn_with_track.dart b/lib/samples/chart/cartesian_charts/rangecolumn_series/rangecolumn_with_track.dart new file mode 100644 index 00000000..e5443eb6 --- /dev/null +++ b/lib/samples/chart/cartesian_charts/rangecolumn_series/rangecolumn_with_track.dart @@ -0,0 +1,244 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class RangeColumnWithTrack extends StatefulWidget { + final SubItemList sample; + const RangeColumnWithTrack(this.sample, {Key key}) : super(key: key); + + @override + _RangeColumnWithTrackState createState() => + _RangeColumnWithTrackState(sample); +} + +class _RangeColumnWithTrackState extends State { + final SubItemList sample; + + _RangeColumnWithTrackState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(RangeColumnWithTrack oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/cartesian_charts/rangecolumn_series/rangecolumn_with_track.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getRangeColumnwithTrack(false)), + )); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getRangeColumnwithTrack(bool isTileView) { + return SfCartesianChart( + plotAreaBorderWidth: 0, + title: ChartTitle(text: isTileView ? '' : 'Meeting timings of an employee'), + primaryXAxis: CategoryAxis( + majorGridLines: MajorGridLines(width: 0), + ), + primaryYAxis: NumericAxis( + axisLine: AxisLine(width: 0), + minimum: 1, + maximum: 10, + labelFormat: '{value} PM', + majorTickLines: MajorTickLines(size: 0)), + series: getRangeColumnSeries(isTileView), + tooltipBehavior: + TooltipBehavior(enable: true, canShowMarker: false, header: ''), + ); +} + +List> getRangeColumnSeries( + bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData('Day 1', 3, 5), + _ChartData('Day 2', 4, 7), + _ChartData('Day 3', 4, 8), + _ChartData('Day 4', 2, 5), + _ChartData('Day 5', 5, 7), + ]; + return >[ + RangeColumnSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + isTrackVisible: true, + trackColor: Color.fromRGBO(198, 201, 207, 1), + borderRadius: BorderRadius.circular(15), + trackBorderColor: Colors.grey[100], + xValueMapper: (_ChartData sales, _) => sales.x, + lowValueMapper: (_ChartData sales, _) => sales.low, + highValueMapper: (_ChartData sales, _) => sales.high, + dataLabelSettings: DataLabelSettings( + isVisible: !isTileView, position: CartesianLabelPosition.top)) + ]; +} + +class _ChartData { + _ChartData(this.x, this.low, this.high); + final String x; + final double low; + final double high; +} diff --git a/lib/samples/chart/cartesian_charts/rangecolumn_series/vertical_rangecolumn_chart.dart b/lib/samples/chart/cartesian_charts/rangecolumn_series/vertical_rangecolumn_chart.dart new file mode 100644 index 00000000..7399649e --- /dev/null +++ b/lib/samples/chart/cartesian_charts/rangecolumn_series/vertical_rangecolumn_chart.dart @@ -0,0 +1,279 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class RangeBarChart extends StatefulWidget { + final SubItemList sample; + const RangeBarChart(this.sample, {Key key}) : super(key: key); + + @override + _RangeBarChartState createState() => _RangeBarChartState(sample); +} + +class _RangeBarChartState extends State { + final SubItemList sample; + + _RangeBarChartState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(RangeBarChart oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/cartesian_charts/rangecolumn_series/vertical_rangecolumn_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getRangeBarChart(false)), + ), + floatingActionButton: Stack(children: [ + Align( + alignment: Alignment.bottomLeft, + child: Padding( + padding: const EdgeInsets.fromLTRB(30, 50, 0, 0), + child: Container( + height: 50, + width: 250, + child: InkWell( + onTap: () => launch( + 'https://www.holiday-weather.com/sydney/averages/'), + child: Row( + children: [ + Text('Source: ', + style: TextStyle( + fontSize: 16, color: model.textColor)), + Text('holiday-weather.com', + style: TextStyle( + fontSize: 14, color: Colors.blue)), + ], + ), + ), + ), + ), + ) + ])); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getRangeBarChart(bool isTileView) { + return SfCartesianChart( + plotAreaBorderWidth: 1, + title: ChartTitle( + text: isTileView ? '' : 'Temperature variation – Sydney vs Melbourne'), + primaryXAxis: CategoryAxis( + majorGridLines: MajorGridLines(width: 0), + ), + legend: Legend(isVisible: !isTileView), + primaryYAxis: NumericAxis( + axisLine: AxisLine(width: 0), + labelFormat: '{value}°F', + minimum: 40, + maximum: 80), + series: getRangeColumnSeries(isTileView), + tooltipBehavior: TooltipBehavior(enable: true), + isTransposed: true, + ); +} + +List> getRangeColumnSeries( + bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData('Jul', 46, 63, 43, 57), + _ChartData('Aug', 48, 64, 45, 59), + _ChartData('Sep', 54, 68, 48, 63), + _ChartData('Oct', 57, 72, 50, 68), + _ChartData('Nov', 61, 75, 54, 72), + _ChartData('Dec', 64, 79, 57, 75), + ]; + return >[ + RangeColumnSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + lowValueMapper: (_ChartData sales, _) => sales.lowSyd, + highValueMapper: (_ChartData sales, _) => sales.highSyd, + name: 'Sydney', + dataLabelSettings: DataLabelSettings( + isVisible: !isTileView, position: CartesianLabelPosition.top)), + RangeColumnSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + lowValueMapper: (_ChartData sales, _) => sales.lowMel, + highValueMapper: (_ChartData sales, _) => sales.highMel, + name: 'Melbourne', + dataLabelSettings: DataLabelSettings( + isVisible: !isTileView, position: CartesianLabelPosition.top)) + ]; +} + +class _ChartData { + _ChartData(this.x, this.lowSyd, this.highSyd, this.lowMel, this.highMel); + final String x; + final int lowSyd; + final int highSyd; + final int lowMel; + final int highMel; +} diff --git a/lib/samples/chart/cartesian_charts/stacked_series/stacked_area_chart.dart b/lib/samples/chart/cartesian_charts/stacked_series/stacked_area_chart.dart new file mode 100644 index 00000000..e678ced3 --- /dev/null +++ b/lib/samples/chart/cartesian_charts/stacked_series/stacked_area_chart.dart @@ -0,0 +1,274 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:intl/intl.dart'; + +class StackedAreaChart extends StatefulWidget { + final SubItemList sample; + const StackedAreaChart(this.sample, {Key key}) : super(key: key); + + @override + _StackedAreaChartState createState() => _StackedAreaChartState(sample); +} + +class _StackedAreaChartState extends State { + final SubItemList sample; + + _StackedAreaChartState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(StackedAreaChart oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/cartesian_charts/rangecolumn_series/stacked_area_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getStackedAreaChart(false)), + )); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getStackedAreaChart(bool isTileView) { + return SfCartesianChart( + plotAreaBorderWidth: 0, + title: + ChartTitle(text: isTileView ? '' : 'Sales comparision of fruits in a shop'), + legend: Legend( + isVisible: !isTileView, overflowMode: LegendItemOverflowMode.wrap), + primaryXAxis: DateTimeAxis( + majorGridLines: MajorGridLines(width: 0), + intervalType: DateTimeIntervalType.years, + dateFormat: DateFormat.y()), + primaryYAxis: NumericAxis( + axisLine: AxisLine(width: 0), + labelFormat: '{value}B', + majorTickLines: MajorTickLines(size: 0)), + series: getStackedAreaSeries(isTileView), + tooltipBehavior: + TooltipBehavior(enable: true, header: '', canShowMarker: false), + ); +} + +List> getStackedAreaSeries( + bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData(DateTime(2000, 1, 1), 0.61, 0.03, 0.48, 0.23), + _ChartData(DateTime(2001, 1, 1), 0.81, 0.05, 0.53, 0.17), + _ChartData(DateTime(2002, 1, 1), 0.91, 0.06, 0.57, 0.17), + _ChartData(DateTime(2003, 1, 1), 1.00, 0.09, 0.61, 0.20), + _ChartData(DateTime(2004, 1, 1), 1.19, 0.14, 0.63, 0.23), + _ChartData(DateTime(2005, 1, 1), 1.47, 0.20, 0.64, 0.36), + _ChartData(DateTime(2006, 1, 1), 1.74, 0.29, 0.66, 0.43), + _ChartData(DateTime(2007, 1, 1), 1.98, 0.46, 0.76, 0.52), + _ChartData(DateTime(2008, 1, 1), 1.99, 0.64, 0.77, 0.72), + _ChartData(DateTime(2009, 1, 1), 1.70, 0.75, 0.55, 1.29), + _ChartData(DateTime(2010, 1, 1), 1.48, 1.06, 0.54, 1.38), + _ChartData(DateTime(2011, 1, 1), 1.38, 1.25, 0.57, 1.82), + _ChartData(DateTime(2012, 1, 1), 1.66, 1.55, 0.61, 2.16), + _ChartData(DateTime(2013, 1, 1), 1.66, 1.55, 0.67, 2.51), + _ChartData(DateTime(2014, 1, 1), 1.67, 1.65, 0.67, 2.61), + ]; + return >[ + StackedAreaSeries<_ChartData, DateTime>( + animationDuration: 2500, + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.organic, + name: 'Apple'), + StackedAreaSeries<_ChartData, DateTime>( + animationDuration: 2500, + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.fairTrade, + name: 'Orange'), + StackedAreaSeries<_ChartData, DateTime>( + animationDuration: 2500, + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.veg, + name: 'Pears'), + StackedAreaSeries<_ChartData, DateTime>( + animationDuration: 2500, + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.others, + name: 'Others') + ]; +} + +class _ChartData { + _ChartData(this.x, this.organic, this.fairTrade, this.veg, this.others); + final DateTime x; + final num organic; + final num fairTrade; + final num veg; + final num others; +} diff --git a/lib/samples/chart/cartesian_charts/stacked_series/stacked_bar_chart.dart b/lib/samples/chart/cartesian_charts/stacked_series/stacked_bar_chart.dart new file mode 100644 index 00000000..4f15e1b9 --- /dev/null +++ b/lib/samples/chart/cartesian_charts/stacked_series/stacked_bar_chart.dart @@ -0,0 +1,250 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class StackedBarChart extends StatefulWidget { + final SubItemList sample; + const StackedBarChart(this.sample, {Key key}) : super(key: key); + + @override + _StackedBarChartState createState() => _StackedBarChartState(sample); +} + +class _StackedBarChartState extends State { + final SubItemList sample; + + _StackedBarChartState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(StackedBarChart oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/cartesian_charts/rangecolumn_series/stacked_bar_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getStackedBarChart(false)), + )); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getStackedBarChart(bool isTileView) { + return SfCartesianChart( + plotAreaBorderWidth: 1, + title: ChartTitle(text: isTileView ? '' : 'Sales comparison of fruits'), + legend: Legend(isVisible: !isTileView), + primaryXAxis: CategoryAxis( + majorGridLines: MajorGridLines(width: 0), + ), + primaryYAxis: NumericAxis( + axisLine: AxisLine(width: 0), + labelFormat: '{value}%', + majorTickLines: MajorTickLines(size: 0)), + series: getStackedBarSeries(isTileView), + tooltipBehavior: + TooltipBehavior(enable: true, header: '', canShowMarker: false), + ); +} + +List> getStackedBarSeries( + bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData('Jan', 6, 6, -1), + _ChartData('Feb', 8, 8, -1.5), + _ChartData('Mar', 12, 11, -2), + _ChartData('Apr', 15.5, 16, -2.5), + _ChartData('May', 20, 21, -3), + _ChartData('June', 24, 25, -3.5), + ]; + return >[ + StackedBarSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.apple, + name: 'Apple'), + StackedBarSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.orange, + name: 'Orange'), + StackedBarSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.wastage, + name: 'Wastage') + ]; +} + +class _ChartData { + _ChartData(this.x, this.apple, this.orange, this.wastage); + final String x; + final num apple; + final num orange; + final num wastage; +} diff --git a/lib/samples/chart/cartesian_charts/stacked_series/stacked_column_chart.dart b/lib/samples/chart/cartesian_charts/stacked_series/stacked_column_chart.dart new file mode 100644 index 00000000..89021439 --- /dev/null +++ b/lib/samples/chart/cartesian_charts/stacked_series/stacked_column_chart.dart @@ -0,0 +1,258 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class StackedColumnChart extends StatefulWidget { + final SubItemList sample; + const StackedColumnChart(this.sample, {Key key}) : super(key: key); + + @override + _StackedColumnChartState createState() => _StackedColumnChartState(sample); +} + +class _StackedColumnChartState extends State { + final SubItemList sample; + + _StackedColumnChartState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(StackedColumnChart oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/cartesian_charts/rangecolumn_series/stacked_column_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getStackedColumnChart(false)), + )); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getStackedColumnChart(bool isTileView) { + return SfCartesianChart( + plotAreaBorderWidth: 0, + title: + ChartTitle(text: isTileView ? '' : 'Quarterly wise sales of products'), + legend: Legend( + isVisible: !isTileView, overflowMode: LegendItemOverflowMode.wrap), + primaryXAxis: CategoryAxis( + majorGridLines: MajorGridLines(width: 0), + ), + primaryYAxis: NumericAxis( + axisLine: AxisLine(width: 0), + labelFormat: '{value}K', + maximum: 300, + majorTickLines: MajorTickLines(size: 0)), + series: getStackedColumnSeries(isTileView), + tooltipBehavior: + TooltipBehavior(enable: true, header: '', canShowMarker: false), + ); +} + +List> getStackedColumnSeries( + bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData('Q1', 50, 55, 72, 65), + _ChartData('Q2', 80, 75, 70, 60), + _ChartData('Q3', 35, 45, 55, 52), + _ChartData('Q4', 65, 50, 70, 65), + ]; + return >[ + StackedColumnSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.y1, + name: 'Product A'), + StackedColumnSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.y2, + name: 'Product B'), + StackedColumnSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.y3, + name: 'Product C'), + StackedColumnSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.y4, + name: 'Product D') + ]; +} + +class _ChartData { + _ChartData(this.x, this.y1, this.y2, this.y3, this.y4); + final String x; + final num y1; + final num y2; + final num y3; + final num y4; +} diff --git a/lib/samples/chart/cartesian_charts/stacked_series/stacked_line_chart.dart b/lib/samples/chart/cartesian_charts/stacked_series/stacked_line_chart.dart new file mode 100644 index 00000000..ed4d8a99 --- /dev/null +++ b/lib/samples/chart/cartesian_charts/stacked_series/stacked_line_chart.dart @@ -0,0 +1,264 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class StackedLineChart extends StatefulWidget { + final SubItemList sample; + const StackedLineChart(this.sample, {Key key}) : super(key: key); + + @override + _StackedLineChartState createState() => _StackedLineChartState(sample); +} + +class _StackedLineChartState extends State { + final SubItemList sample; + + _StackedLineChartState(this.sample); + + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(StackedLineChart oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + frontHeaderHeight: 20, + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/cartesian_charts/stacked_series/stacked_line_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + TextEditingController editingController = TextEditingController(); + TextEditingController spacingEditingController = TextEditingController(); + _FrontPanelState(this.sample); + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getStackedLineChart(false)), + )); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getStackedLineChart(bool isTileView) { + return SfCartesianChart( + plotAreaBorderWidth: 0, + title: ChartTitle(text: isTileView ? '' : 'Monthly expense of a family'), + legend: Legend(isVisible: !isTileView), + primaryXAxis: CategoryAxis( + majorGridLines: MajorGridLines(width: 0), + labelRotation: isTileView ? 0 : 45, + ), + primaryYAxis: NumericAxis( + maximum: 200, + axisLine: AxisLine(width: 0), + labelFormat: '\${value}', + majorTickLines: MajorTickLines(size: 0)), + series: getStackedLineSeries(isTileView), + trackballBehavior:TrackballBehavior(enable: true, activationMode: ActivationMode.singleTap), + tooltipBehavior: + TooltipBehavior(enable: false, header: '', canShowMarker: false), + ); +} + +List> getStackedLineSeries( + bool isTileView) { + final List<_ChartData> chartData = <_ChartData>[ + _ChartData('Food', 55, 40, 45, 48), + _ChartData('Transport', 33, 45, 54, 28), + _ChartData('Medical', 43, 23, 20, 34), + _ChartData('Clothes', 32, 54, 23, 54), + _ChartData('Books', 56, 18, 43, 55), + _ChartData('Others', 23, 54, 33, 56), + ]; + return >[ + StackedLineSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.father, + name: 'Father', + markerSettings: MarkerSettings(isVisible: true)), + StackedLineSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.mother, + name: 'Mother', + markerSettings: MarkerSettings(isVisible: true)), + StackedLineSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.son, + name: 'Son', + markerSettings: MarkerSettings(isVisible: true)), + StackedLineSeries<_ChartData, String>( + enableTooltip: true, + dataSource: chartData, + xValueMapper: (_ChartData sales, _) => sales.x, + yValueMapper: (_ChartData sales, _) => sales.daughter, + name: 'Daughter', + markerSettings: MarkerSettings(isVisible: true)) + ]; +} + +class _ChartData { + _ChartData(this.x, this.father, this.mother, this.son, this.daughter); + final String x; + final num father; + final num mother; + final num son; + final num daughter; +} diff --git a/lib/samples/chart/circular_charts/pie_series/semi_pie_chart.dart b/lib/samples/chart/circular_charts/pie_series/semi_pie_chart.dart index 0d52a151..b76ea591 100755 --- a/lib/samples/chart/circular_charts/pie_series/semi_pie_chart.dart +++ b/lib/samples/chart/circular_charts/pie_series/semi_pie_chart.dart @@ -400,8 +400,7 @@ class _BackPanelState extends State { SfCircularChart getSemiPieChart(bool isTileView, [int startAngle, int endAngle]) { return SfCircularChart( - centerX: '40%', - centerY: '50%', + centerY: '60%', title: ChartTitle( text: isTileView ? '' : 'Rural population of various countries'), legend: Legend( diff --git a/lib/samples/chart/dynamic_updates/add_remove_data/add_remove_points.dart b/lib/samples/chart/dynamic_updates/add_remove_data/add_remove_points.dart index 506a993d..bd9b6324 100755 --- a/lib/samples/chart/dynamic_updates/add_remove_data/add_remove_points.dart +++ b/lib/samples/chart/dynamic_updates/add_remove_data/add_remove_points.dart @@ -281,7 +281,7 @@ class _BackPanelState extends State { SfCartesianChart getAddRemovePointsChart([List<_ChartData> chartData]) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: NumericAxis( majorGridLines: MajorGridLines(width: 0), edgeLabelPlacement: EdgeLabelPlacement.shift), diff --git a/lib/samples/chart/dynamic_updates/add_remove_data/add_remove_series.dart b/lib/samples/chart/dynamic_updates/add_remove_data/add_remove_series.dart index 13008b14..1a59c5ab 100755 --- a/lib/samples/chart/dynamic_updates/add_remove_data/add_remove_series.dart +++ b/lib/samples/chart/dynamic_updates/add_remove_data/add_remove_series.dart @@ -349,7 +349,7 @@ SfCartesianChart getAddRemoveSeriesChart(bool isTileView) { ) ]; return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: NumericAxis( majorGridLines: MajorGridLines(width: 0), edgeLabelPlacement: EdgeLabelPlacement.shift), diff --git a/lib/samples/chart/dynamic_updates/live_update/live_update.dart b/lib/samples/chart/dynamic_updates/live_update/live_update.dart index 58889f05..987e0c85 100755 --- a/lib/samples/chart/dynamic_updates/live_update/live_update.dart +++ b/lib/samples/chart/dynamic_updates/live_update/live_update.dart @@ -280,7 +280,7 @@ void updateLiveData() { SfCartesianChart getLiveUpdateChart(bool isTileView) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: NumericAxis(majorGridLines: MajorGridLines(width: 0)), primaryYAxis: NumericAxis( axisLine: AxisLine(width: 0), majorTickLines: MajorTickLines(size: 0)), diff --git a/lib/samples/chart/dynamic_updates/live_update/vertical_live_chart.dart b/lib/samples/chart/dynamic_updates/live_update/vertical_live_chart.dart index 49cb5568..3c528635 100755 --- a/lib/samples/chart/dynamic_updates/live_update/vertical_live_chart.dart +++ b/lib/samples/chart/dynamic_updates/live_update/vertical_live_chart.dart @@ -115,11 +115,11 @@ class FrontPanel extends StatefulWidget { } class _FrontPanelState extends State { - Timer timer; + @override void initState() { super.initState(); - this.timer = Timer.periodic(Duration(milliseconds: 10), setTime); + timer = Timer.periodic(Duration(milliseconds: 10), setTime); } @override @@ -231,7 +231,7 @@ class _BackPanelState extends State { SfCartesianChart getVerticalLineUpdateChart(bool isTileView) { return SfCartesianChart( isTransposed: true, - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: NumericAxis( isInversed: false, title: AxisTitle(text: isTileView ? '' : 'Time(s)'), diff --git a/lib/samples/chart/dynamic_updates/update_data_source/update_data_source.dart b/lib/samples/chart/dynamic_updates/update_data_source/update_data_source.dart index cd6f6c51..be3d900f 100644 --- a/lib/samples/chart/dynamic_updates/update_data_source/update_data_source.dart +++ b/lib/samples/chart/dynamic_updates/update_data_source/update_data_source.dart @@ -254,7 +254,7 @@ class _BackPanelState extends State { SfCartesianChart getUpdateDataSourceChart(bool isTileView, [List<_ChartData> chartData]) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: NumericAxis( minimum: 0, interval: 1, majorGridLines: MajorGridLines(width: 0)), primaryYAxis: NumericAxis( diff --git a/lib/samples/chart/funnel_charts/default_funnel_chart.dart b/lib/samples/chart/funnel_charts/default_funnel_chart.dart new file mode 100644 index 00000000..32d8b6ea --- /dev/null +++ b/lib/samples/chart/funnel_charts/default_funnel_chart.dart @@ -0,0 +1,507 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/bottom_sheet.dart'; +import 'package:flutter_examples/widgets/custom_button.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import '../../../widgets/checkbox.dart'; + +class FunnelDefault extends StatefulWidget { + final SubItemList sample; + const FunnelDefault(this.sample, {Key key}) : super(key: key); + + @override + _FunnelDefaultState createState() => _FunnelDefaultState(sample); +} + +class _FunnelDefaultState extends State { + final SubItemList sample; + _FunnelDefaultState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(FunnelDefault oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/circular_charts/pie_series/default_pie_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + _FrontPanelState(this.sample); + double gapRatio = 0; + int neckWidth = 20; + int neckHeight = 20; + bool explode = false; + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getDefaultFunnelChart(false, gapRatio,neckWidth, neckHeight, explode)), + ), + floatingActionButton: Stack( + children: [ + Align( + alignment: Alignment.bottomLeft, + child: Padding( + padding: const EdgeInsets.fromLTRB(30, 50, 0, 0), + child: Container( + height: 50, + width: 250, + // child: InkWell( + // onTap: () => launch( + // 'https://data.worldbank.org/indicator/sp.rur.totl.zs'), + // child: Row( + // children: [ + // Text('Source: ', + // style: TextStyle( + // fontSize: 16, color: model.textColor)), + // Text('data.worldbank.org', + // style: TextStyle( + // fontSize: 14, color: Colors.blue)), + // ], + // ), + // ), + ), + ), + ), + Align( + alignment: Alignment.bottomRight, + child: FloatingActionButton( + heroTag: null, + onPressed: () { + _showSettingsPanel(model); + }, + child: Icon(Icons.graphic_eq, color: Colors.white), + backgroundColor: model.backgroundColor, + ), + ), + + ])); + }); + } + void _showSettingsPanel(SampleListModel model) { + double height = + (MediaQuery.of(context).size.height > MediaQuery.of(context).size.width) + ? 0.3 + : 0.4; + showRoundedModalBottomSheet( + dismissOnTap: false, + context: context, + radius: 12.0, + color: model.bottomSheetBackgroundColor, + builder: (context) => ScopedModelDescendant( + rebuildOnChange: false, + builder: (context, _, model) => Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 170, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: MediaQuery.of(context).size.height * height, + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 5), + child: Stack(children: [ + Container( + height: 40, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('Settings', + style: TextStyle( + color: model.textColor, + fontSize: 18, + letterSpacing: 0.34, + fontWeight: FontWeight.w500)), + IconButton( + icon: Icon( + Icons.close, + color: model.textColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets.fromLTRB(10, 50, 0, 0), + child: ListView( + children: [ + + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Gap ratio ', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 40, 0, 0, 0), + child: CustomButton( + minValue: 0, + maxValue: 0.5, + initialValue: + gapRatio, + onChanged: (val) => + setState(() { + gapRatio = val; + }), + step: 0.1, + horizontal: true, + loop: false, + padding: 0, + iconUp: + Icons.keyboard_arrow_up, + iconDown: + Icons.keyboard_arrow_down, + iconLeft: + Icons.keyboard_arrow_left, + iconRight: Icons + .keyboard_arrow_right, + iconUpRightColor: + model.textColor, + iconDownLeftColor: + model.textColor, + style: TextStyle( + fontSize: 20.0, + color: model.textColor), + ), + ), + ), + ], + ), + ), + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Neck height ', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 25, 0, 0, 0), + child: CustomButton( + minValue: 0, + maxValue: 50, + initialValue: + neckHeight.toDouble(), + onChanged: (val) => + setState(() { + neckHeight = val.toInt(); + }), + step: 10, + horizontal: true, + loop: false, + padding: 0, + iconUp: + Icons.keyboard_arrow_up, + iconDown: + Icons.keyboard_arrow_down, + iconLeft: + Icons.keyboard_arrow_left, + iconRight: Icons + .keyboard_arrow_right, + iconUpRightColor: + model.textColor, + iconDownLeftColor: + model.textColor, + style: TextStyle( + fontSize: 20.0, + color: model.textColor), + ), + ), + ), + ], + ), + ), + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Neck width', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 40, 0, 0, 0), + child: CustomButton( + minValue: 0, + maxValue: 50, + initialValue: + neckWidth.toDouble(), + onChanged: (val) => + setState(() { + neckWidth = val.toInt(); + }), + step: 10, + horizontal: true, + loop: false, + padding: 0, + iconUp: + Icons.keyboard_arrow_up, + iconDown: + Icons.keyboard_arrow_down, + iconLeft: + Icons.keyboard_arrow_left, + iconRight: Icons + .keyboard_arrow_right, + iconUpRightColor: + model.textColor, + iconDownLeftColor: + model.textColor, + style: TextStyle( + fontSize: 20.0, + color: model.textColor), + ), + ), + ), + ], + ), + ), + + Container( + child: Row( + children: [ + Text('Explode', + style: TextStyle( + color: model.textColor, + fontSize: 16, + letterSpacing: 0.34, + fontWeight: + FontWeight.normal)), + Padding( + padding: EdgeInsets.fromLTRB(40, 0, 0, 0) + ), + BottomSheetCheckbox( + activeColor: + model.backgroundColor, + switchValue: explode, + valueChanged: (value) { + setState(() { + explode = value; + }); + }, + ), + ], + ), + ), + ], + ), + ), + ]), + ))))))); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfFunnelChart getDefaultFunnelChart(bool isTileView,[double gapRatio, int neckWidth, int neckHeight, bool explode]) { + return SfFunnelChart( + smartLabelMode: SmartLabelMode.shift, + title: ChartTitle(text: isTileView ? '' : 'Website conversion rate'), + tooltipBehavior: TooltipBehavior(enable: true), + series: _getFunnelSeries(isTileView, gapRatio,neckWidth,neckHeight, explode), + ); +} + +FunnelSeries<_FunnelData, String> _getFunnelSeries(bool isTileView,[double _gapRatio, int _neckWidth, int _neckHeight, bool _explode]) { + final List<_FunnelData> pieData = <_FunnelData>[ + _FunnelData('Purchased ', 150), + _FunnelData('Requested price list', 300), + _FunnelData('Downloaded trail', 600), + _FunnelData('Visit download page', 1500), + _FunnelData('Watched demo', 2600), + _FunnelData('Website visitors', 3000) + ]; + return FunnelSeries<_FunnelData, String>( + dataSource: pieData, + xValueMapper: (_FunnelData data, _) => data.xData, + yValueMapper: (_FunnelData data, _) => data.yData, + explode: isTileView ? false : _explode, + gapRatio: isTileView ? 0 : _gapRatio, + neckHeight: isTileView ? '20%' : _neckHeight.toString()+'%', + neckWidth: isTileView ? '20%' : _neckWidth.toString()+'%', + dataLabelSettings: DataLabelSettings(isVisible: true)); +} + +class _FunnelData { + _FunnelData(this.xData, this.yData, [this.text]); + final String xData; + final num yData; + final String text; +} diff --git a/lib/samples/chart/funnel_charts/funnel_with_legend.dart b/lib/samples/chart/funnel_charts/funnel_with_legend.dart new file mode 100644 index 00000000..426c2676 --- /dev/null +++ b/lib/samples/chart/funnel_charts/funnel_with_legend.dart @@ -0,0 +1,224 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class FunnelLegend extends StatefulWidget { + final SubItemList sample; + const FunnelLegend(this.sample, {Key key}) : super(key: key); + + @override + _FunnelLegendState createState() => _FunnelLegendState(sample); +} + +class _FunnelLegendState extends State { + final SubItemList sample; + _FunnelLegendState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(FunnelLegend oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/circular_charts/pie_series/default_pie_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + _FrontPanelState(this.sample); + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getLegendFunnelChart(false)), + )); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfFunnelChart getLegendFunnelChart(bool isTileView) { + return SfFunnelChart( + smartLabelMode: SmartLabelMode.none, + title: ChartTitle( + text: isTileView ? '' : 'Monthly expenditure of an individual'), + legend: Legend(isVisible: true, overflowMode: LegendItemOverflowMode.wrap), + tooltipBehavior: + TooltipBehavior(enable: true, format: 'point.x : point.y%'), + series: _getFunnelSeries(isTileView), + ); +} + +FunnelSeries<_FunnelData, String> _getFunnelSeries(bool isTileView) { + final List<_FunnelData> pieData = <_FunnelData>[ + _FunnelData('Others', 10, '10%'), + _FunnelData('Medical ', 11, '11%'), + _FunnelData('Saving ', 14, '14%'), + _FunnelData('Shopping', 17, '17%'), + _FunnelData('Travel', 21, '21%'), + _FunnelData('Food', 27, '27%'), + ]; + return FunnelSeries<_FunnelData, String>( + dataSource: pieData, + textFieldMapper: (_FunnelData data, _) => data.text, + xValueMapper: (_FunnelData data, _) => data.xData, + yValueMapper: (_FunnelData data, _) => data.yData, + dataLabelSettings: DataLabelSettings( + isVisible: isTileView ? false : true, + labelPosition: LabelPosition.inside)); +} + +class _FunnelData { + _FunnelData(this.xData, this.yData, [this.text]); + final String xData; + final num yData; + final String text; +} diff --git a/lib/samples/chart/funnel_charts/funnel_with_smart_labels.dart b/lib/samples/chart/funnel_charts/funnel_with_smart_labels.dart new file mode 100644 index 00000000..b680ee23 --- /dev/null +++ b/lib/samples/chart/funnel_charts/funnel_with_smart_labels.dart @@ -0,0 +1,455 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:flutter_examples/widgets/bottom_sheet.dart'; +import 'package:flutter_examples/widgets/customDropDown.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class FunnelSmartLabels extends StatefulWidget { + final SubItemList sample; + const FunnelSmartLabels(this.sample, {Key key}) : super(key: key); + + @override + _FunnelSmartLabelState createState() => _FunnelSmartLabelState(sample); +} + +class _FunnelSmartLabelState extends State { + final SubItemList sample; + _FunnelSmartLabelState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(FunnelSmartLabels oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/circular_charts/pie_series/default_pie_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + _FrontPanelState(this.sample); + final List _labelPositon = ['outside', 'inside'].toList(); + LabelPosition _selectedLabelPosition = LabelPosition.outside; + String _selectedPosition; + + final List _modeList = ['shift', 'none', 'hide'].toList(); + String _smartLabelMode = 'shift'; + SmartLabelMode _mode = SmartLabelMode.shift; + + @override + void initState() { + super.initState(); + _selectedPosition = _labelPositon.first; + _selectedLabelPosition = LabelPosition.outside; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container( + child: getFunnelSmartLabelChart( + false, _selectedLabelPosition, _mode)), + ), + floatingActionButton: Stack(children: [ + Align( + alignment: Alignment.bottomRight, + child: FloatingActionButton( + heroTag: null, + onPressed: () { + _showSettingsPanel(model); + }, + child: Icon(Icons.graphic_eq, color: Colors.white), + backgroundColor: model.backgroundColor, + ), + ), + ])); + }); + } + + void onLabelPositionChange(String item) { + setState(() { + _selectedPosition = item; + if (_selectedPosition == 'inside') { + _selectedLabelPosition = LabelPosition.inside; + } else if (_selectedPosition == 'outside') { + _selectedLabelPosition = LabelPosition.outside; + } + }); + } + + void onSmartLabelModeChange(String item, SampleListModel model) { + setState(() { + _smartLabelMode = item; + if (_smartLabelMode == 'shift') { + _mode = SmartLabelMode.shift; + } + if (_smartLabelMode == 'hide') { + _mode = SmartLabelMode.hide; + } + if (_smartLabelMode == 'none') { + _mode = SmartLabelMode.none; + } + }); + } + + void _showSettingsPanel(SampleListModel model) { + double height = + (MediaQuery.of(context).size.height > MediaQuery.of(context).size.width) + ? 0.3 + : 0.4; + showRoundedModalBottomSheet( + dismissOnTap: false, + context: context, + radius: 12.0, + color: model.bottomSheetBackgroundColor, + builder: (context) => ScopedModelDescendant( + rebuildOnChange: false, + builder: (context, _, model) => Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 170, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: MediaQuery.of(context).size.height * height, + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 5), + child: Stack(children: [ + Container( + height: 40, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('Settings', + style: TextStyle( + color: model.textColor, + fontSize: 18, + letterSpacing: 0.34, + fontWeight: FontWeight.w500)), + IconButton( + icon: Icon( + Icons.close, + color: model.textColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets.fromLTRB(10, 50, 0, 0), + child: ListView( + children: [ + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Label Position ', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + padding: + const EdgeInsets.fromLTRB( + 20, 0, 0, 0), + height: 50, + width: 150, + child: Align( + alignment: + Alignment.bottomCenter, + child: Theme( + data: Theme.of(context) + .copyWith( + canvasColor: model + .bottomSheetBackgroundColor), + child: DropDown( + value: + _selectedPosition, + item: _labelPositon.map( + (String value) { + return DropdownMenuItem< + String>( + value: (value != + null) + ? value + : 'outside', + child: Text( + '$value', + style: TextStyle( + color: model + .textColor))); + }).toList(), + valueChanged: + (dynamic value) { + onLabelPositionChange( + value.toString()); + }), + ), + )) + ], + ), + ), + Container( + child: Row( + children: [ + Text('Smart label mode ', + style: TextStyle( + color: model.textColor, + fontSize: 16, + letterSpacing: 0.34, + fontWeight: + FontWeight.normal)), + Container( + padding: + const EdgeInsets.fromLTRB( + 20, 0, 0, 0), + height: 50, + width: 150, + child: Align( + alignment: + Alignment.bottomCenter, + child: Theme( + data: Theme.of(context) + .copyWith( + canvasColor: model + .bottomSheetBackgroundColor), + child: DropDown( + value: _smartLabelMode, + item: _modeList.map( + (String value) { + return DropdownMenuItem< + String>( + value: (value != + null) + ? value + : 'shift', + child: Text( + '$value', + style: TextStyle( + color: model + .textColor))); + }).toList(), + valueChanged: + (dynamic value) { + onSmartLabelModeChange( + value.toString(), + model); + }), + ), + )), + ], + ), + ), + ], + ), + ), + ]), + ))))))); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfFunnelChart getFunnelSmartLabelChart(bool isTileView, + [LabelPosition _labelPosition, SmartLabelMode _mode]) { + return SfFunnelChart( + smartLabelMode: isTileView ? SmartLabelMode.shift : _mode, + title: ChartTitle(text: isTileView ? '' : 'Tournament details'), + tooltipBehavior: TooltipBehavior( + enable: true, + ), + series: _getFunnelSeries( + isTileView, + _labelPosition, + ), + ); +} + +FunnelSeries<_FunnelData, String> _getFunnelSeries(bool isTileView, + [LabelPosition _labelPosition]) { + final List<_FunnelData> pieData = <_FunnelData>[ + _FunnelData('Finals', 2), + _FunnelData('Semifinals', 4), + _FunnelData('Quarter finals', 8), + _FunnelData('League matches', 16), + _FunnelData('Participated', 32), + _FunnelData('Eligible', 36), + _FunnelData('Applicants', 40), + ]; + return FunnelSeries<_FunnelData, String>( + width: '60%', + dataSource: pieData, + xValueMapper: (_FunnelData data, _) => data.xData, + yValueMapper: (_FunnelData data, _) => data.yData, + // textFieldMapper: (_FunnelData data, _) => data.xData, + // pointColorMapper: (_FunnelData data, _) => data.color, + dataLabelSettings: DataLabelSettings( + isVisible: true, + labelPosition: isTileView ? LabelPosition.outside : _labelPosition, + useSeriesColor: true)); +} + +class _FunnelData { + _FunnelData(this.xData, this.yData, [this.text, this.color]); + final String xData; + final num yData; + final String text; + final Color color; +} diff --git a/lib/samples/chart/home/axes_features_home.dart b/lib/samples/chart/home/axes_features_home.dart index 48745adf..13690070 100755 --- a/lib/samples/chart/home/axes_features_home.dart +++ b/lib/samples/chart/home/axes_features_home.dart @@ -27,9 +27,32 @@ class _SeriesFeaturesState extends State { i < model.controlList[model.selectedIndex].subItemList.length; i++) { if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { + String str = + getStatus(model.controlList[model.selectedIndex].subItemList[i]); tabs.add(Tab( - text: model - .controlList[model.selectedIndex].subItemList[i][0]?.category)); + child: Row( + children: [ + Text(model.controlList[model.selectedIndex].subItemList[i][0] + ?.category + .toString() + + (str != '' ? ' ' : '')), + Container( + height: 20, + width: 20, + decoration: BoxDecoration( + color: str == 'N' + ? Colors.green + : str == 'U' ? Colors.yellow : Colors.transparent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + str, + style: TextStyle(fontSize: 12), + ), + ), + ], + ))); } } return tabs; @@ -130,21 +153,55 @@ class _SeriesFeaturesState extends State { letterSpacing: 0.3), ), Container( - height: 30, - width: 30, - color: Colors.transparent, - child: Padding( - padding: - const EdgeInsets.fromLTRB( - 5, 0, 5, 5), - child: Image.asset( - 'images/fullscreen.png', - fit: BoxFit.contain, - height: 20, - width: 20, - color: model.listIconColor), - ), - ), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: model + .controlList[model + .selectedIndex] + .subItemList[i] + [position] + .status != + null + ? (model.controlList[model.selectedIndex].subItemList[i][position].status == + 'New' + ? Color.fromRGBO( + 101, 193, 0, 1) + : Color.fromRGBO( + 245, + 166, + 35, + 1)) + : Colors.transparent, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(10.0))), + padding: EdgeInsets.fromLTRB(6, 3, 6, 3), + child: Text((model.controlList[model.selectedIndex].subItemList[i][position].status != null ? model.controlList[model.selectedIndex].subItemList[i][position].status : ''), style: TextStyle(color: Colors.white))), + Padding( + padding: + EdgeInsets.only(left: 15), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: + model.listIconColor), + ), + ), + ], + )), ]), ), ), diff --git a/lib/samples/chart/home/axis_types.dart b/lib/samples/chart/home/axis_types.dart index c5b4cfd7..1c0efdda 100755 --- a/lib/samples/chart/home/axis_types.dart +++ b/lib/samples/chart/home/axis_types.dart @@ -27,9 +27,32 @@ class _AxisTypesState extends State { i < model.controlList[model.selectedIndex].subItemList.length; i++) { if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { + String str = getStatus(model + .controlList[model.selectedIndex].subItemList[i]); tabs.add(Tab( - text: model - .controlList[model.selectedIndex].subItemList[i][0]?.category)); + child: Row( + children: [ + Text(model.controlList[model.selectedIndex].subItemList[i][0] + ?.category + .toString() + + (str != '' ? ' ' : '')), + Container( + height: 20, + width: 20, + decoration: BoxDecoration( + color: str == 'N' + ? Color.fromRGBO(101,193,0,1) + : str == 'U' ? Color.fromRGBO(245,166,35,1) : Colors.transparent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + str, + style: TextStyle(fontSize: 12), + ), + ), + ], + ))); } } return tabs; @@ -137,21 +160,56 @@ class _AxisTypesState extends State { color: model.textColor, letterSpacing: 0.3), ), - Container( - height: 30, - width: 30, - color: Colors.transparent, - child: Padding( - padding: - const EdgeInsets.fromLTRB( - 5, 0, 5, 5), - child: Image.asset( - 'images/fullscreen.png', - fit: BoxFit.contain, - height: 20, - width: 20, - color: model.listIconColor), - ), + Container( + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: model + .controlList[model + .selectedIndex] + .subItemList[i] + [position] + .status != + null + ? (model.controlList[model.selectedIndex].subItemList[i][position].status == + 'New' + ? Color.fromRGBO( + 101, 193, 0, 1) + : Color.fromRGBO( + 245, + 166, + 35, + 1)) + : Colors.transparent, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(10.0))), + padding: EdgeInsets.fromLTRB(6, 3, 6, 3), + child: Text((model.controlList[model.selectedIndex].subItemList[i][position].status != null ? model.controlList[model.selectedIndex].subItemList[i][position].status : ''), style: TextStyle(color: Colors.white))), + Padding( + padding: + EdgeInsets.only(left: 15), + ), + Container( + height: 25, + width: 25, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: + model.listIconColor), + ), + ), + ], + ) ), ]), ), diff --git a/lib/samples/chart/home/cartesian_types.dart b/lib/samples/chart/home/cartesian_types.dart index c6a3d21d..88ad35f7 100755 --- a/lib/samples/chart/home/cartesian_types.dart +++ b/lib/samples/chart/home/cartesian_types.dart @@ -70,9 +70,32 @@ class _CartesianTypesState extends State i < model.controlList[model.selectedIndex].subItemList.length; i++) { if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { + String str = getStatus(model + .controlList[model.selectedIndex].subItemList[i]); tabs.add(Tab( - text: model - .controlList[model.selectedIndex].subItemList[i][0]?.category)); + child: Row( + children: [ + Text(model.controlList[model.selectedIndex].subItemList[i][0] + ?.category + .toString() + + (str != '' ? ' ' : '')), + Container( + height: 20, + width: 20, + decoration: BoxDecoration( + color: str == 'N' + ? Color.fromRGBO(101,193,0,1) + : str == 'U' ? Color.fromRGBO(245,166,35,1) : Colors.transparent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + str, + style: TextStyle(fontSize: 12), + ), + ), + ], + ))); } } return tabs; @@ -139,21 +162,55 @@ class _CartesianTypesState extends State letterSpacing: 0.3), ), Container( - height: 30, - width: 30, - color: Colors.transparent, - child: Padding( - padding: - const EdgeInsets.fromLTRB( - 5, 0, 5, 5), - child: Image.asset( - 'images/fullscreen.png', - fit: BoxFit.contain, - height: 20, - width: 20, - color: model.listIconColor), - ), - ), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: model + .controlList[model + .selectedIndex] + .subItemList[i] + [position] + .status != + null + ? (model.controlList[model.selectedIndex].subItemList[i][position].status == + 'New' + ? Color.fromRGBO( + 101, 193, 0, 1) + : Color.fromRGBO( + 245, + 166, + 35, + 1)) + : Colors.transparent, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(10.0))), + padding: EdgeInsets.fromLTRB(6, 3, 6, 3), + child: Text((model.controlList[model.selectedIndex].subItemList[i][position].status != null ? model.controlList[model.selectedIndex].subItemList[i][position].status : ''), style: TextStyle(color: Colors.white))), + Padding( + padding: + EdgeInsets.only(left: 15), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: + model.listIconColor), + ), + ), + ], + )), ]), ), ), @@ -191,3 +248,4 @@ class _CartesianTypesState extends State @override bool get wantKeepAlive => false; } + \ No newline at end of file diff --git a/lib/samples/chart/home/circular_types.dart b/lib/samples/chart/home/circular_types.dart index cc202bcc..cf1a4b38 100755 --- a/lib/samples/chart/home/circular_types.dart +++ b/lib/samples/chart/home/circular_types.dart @@ -70,9 +70,32 @@ class _CircularTypesState extends State i < model.controlList[model.selectedIndex].subItemList.length; i++) { if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { - tabs.add(Tab( - text: model - .controlList[model.selectedIndex].subItemList[i][0]?.category)); + String str = getStatus(model + .controlList[model.selectedIndex].subItemList[i]); + tabs.add(Tab( + child: Row( + children: [ + Text(model.controlList[model.selectedIndex].subItemList[i][0] + ?.category + .toString() + + (str != '' ? ' ' : '')), + Container( + height: 20, + width: 20, + decoration: BoxDecoration( + color: str == 'N' + ? Color.fromRGBO(101,193,0,1) + : str == 'U' ? Color.fromRGBO(245,166,35,1) : Colors.transparent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + str, + style: TextStyle(fontSize: 12), + ), + ), + ], + ))); } } return tabs; @@ -138,35 +161,73 @@ class _CircularTypesState extends State color: model.textColor, letterSpacing: 0.3), ), - Container( - height: 30, - width: 30, - color: Colors.transparent, - child: Padding( - padding: - const EdgeInsets.fromLTRB( - 5, 0, 5, 5), - child: Image.asset( - 'images/fullscreen.png', - fit: BoxFit.contain, - height: 20, - width: 20, - color: model.listIconColor), - ), - ), + Container( + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: model + .controlList[model + .selectedIndex] + .subItemList[i] + [position] + .status != + null + ? (model.controlList[model.selectedIndex].subItemList[i][position].status == + 'New' + ? Color.fromRGBO( + 101, 193, 0, 1) + : Color.fromRGBO( + 245, + 166, + 35, + 1)) + : Colors.transparent, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(10.0))), + padding: EdgeInsets.fromLTRB(6, 3, 6, 3), + child: Text((model.controlList[model.selectedIndex].subItemList[i][position].status != null ? model.controlList[model.selectedIndex].subItemList[i][position].status : ''), style: TextStyle(color: Colors.white))), + Padding( + padding: + EdgeInsets.only(left: 15), + ), + Container( + height: 25, + width: 25, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: + model.listIconColor), + ), + ), + ], + )), ]), ), ), - Padding( - padding: - const EdgeInsets.fromLTRB(5, 5, 5, 5), - child: SizedBox( - width: double.infinity, - height: 230, - child: model - .controlList[model.selectedIndex] - .subItemList[i][position] - .previewWidget, + InkWell( + onTap: () {}, + splashColor: Colors.grey.withOpacity(0.4), + child: Padding( + padding: + const EdgeInsets.fromLTRB(5, 5, 5, 5), + child: SizedBox( + width: double.infinity, + height: 230, + child: model + .controlList[model.selectedIndex] + .subItemList[i][position] + .previewWidget, + ), ), ), ], diff --git a/lib/samples/chart/home/dynamic_updates.dart b/lib/samples/chart/home/dynamic_updates.dart index 31feaf02..7776d9bd 100755 --- a/lib/samples/chart/home/dynamic_updates.dart +++ b/lib/samples/chart/home/dynamic_updates.dart @@ -26,9 +26,32 @@ class _DynamicUpdatesState extends State { for (int i = 0; i < model.controlList[model.selectedIndex].subItemList.length; i++) { - tabs.add(Tab( - text: model - .controlList[model.selectedIndex].subItemList[i][0].category)); + String str = getStatus(model + .controlList[model.selectedIndex].subItemList[i]); + tabs.add(Tab( + child: Row( + children: [ + Text(model.controlList[model.selectedIndex].subItemList[i][0] + ?.category + .toString() + + (str != '' ? ' ' : '')), + Container( + height: 20, + width: 20, + decoration: BoxDecoration( + color: str == 'N' + ? Color.fromRGBO(101,193,0,1) + : str == 'U' ? Color.fromRGBO(245,166,35,1) : Colors.transparent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + str, + style: TextStyle(fontSize: 12), + ), + ), + ], + ))); } return tabs; } @@ -135,22 +158,56 @@ class _DynamicUpdatesState extends State { color: model.textColor, letterSpacing: 0.3), ), - Container( - height: 30, - width: 30, - color: Colors.transparent, - child: Padding( - padding: - const EdgeInsets.fromLTRB( - 5, 0, 5, 5), - child: Image.asset( - 'images/fullscreen.png', - fit: BoxFit.contain, - height: 20, - width: 20, - color: model.listIconColor), - ), - ), + Container( + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: model + .controlList[model + .selectedIndex] + .subItemList[i] + [position] + .status != + null + ? (model.controlList[model.selectedIndex].subItemList[i][position].status == + 'New' + ? Color.fromRGBO( + 101, 193, 0, 1) + : Color.fromRGBO( + 245, + 166, + 35, + 1)) + : Colors.transparent, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(10.0))), + padding: EdgeInsets.fromLTRB(6, 3, 6, 3), + child: Text((model.controlList[model.selectedIndex].subItemList[i][position].status != null ? model.controlList[model.selectedIndex].subItemList[i][position].status : ''), style: TextStyle(color: Colors.white))), + Padding( + padding: + EdgeInsets.only(left: 15), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: + model.listIconColor), + ), + ), + ], + )), ]), ), ), diff --git a/lib/samples/chart/home/funnel_chart.dart b/lib/samples/chart/home/funnel_chart.dart new file mode 100644 index 00000000..9ee3e945 --- /dev/null +++ b/lib/samples/chart/home/funnel_chart.dart @@ -0,0 +1,181 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/helper.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class FunnelCharts extends StatefulWidget { + const FunnelCharts({Key key}) : super(key: key); + + @override + _SeriesFeaturesState createState() => _SeriesFeaturesState(); +} + +class _SeriesFeaturesState extends State { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + List getTabs(SampleListModel model) { + List tabs = []; + for (int i = 0; + i < model.controlList[model.selectedIndex].subItemList.length; + i++) { + if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { + tabs.add(Tab( + text: model + .controlList[model.selectedIndex].subItemList[i][0]?.category)); + } + } + return tabs; + } + + @override + // ignore: must_call_super + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) => Theme( + data: model.themeData, + child: SafeArea( + child: DefaultTabController( + length: + model.controlList[model.selectedIndex].subItemList.length, + child: Scaffold( + appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () => Navigator.pop(context, false), + ), + backgroundColor: model.backgroundColor, + title: Text( + model.controlList[model.selectedIndex].title.toString(), + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16.0, + color: Colors.white, + letterSpacing: 0.3)), + ), + body: TabBarView( + children: getTabViewChildrens(model), + ), + ), + ), + ))); + } + + List getTabViewChildrens(SampleListModel model) { + List tabChildren = []; + for (int i = 0; + i < model.controlList[model.selectedIndex].subItemList.length; + i++) { + tabChildren.add(ListView.builder( + cacheExtent: model + .controlList[model.selectedIndex].subItemList[i].length + .toDouble(), + addAutomaticKeepAlives: true, + itemCount: + model.controlList[model.selectedIndex].subItemList[i].length, + itemBuilder: (BuildContext context, int position) { + return Container( + color: model.slidingPanelColor, + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Column( + children: [ + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Card( + elevation: 2, + color: model.cardThemeColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(3.0), + ), + child: Column( + children: [ + InkWell( + splashColor: Colors.grey.withOpacity(0.4), + onTap: () { + Feedback.forLongPress(context); + onTapSampleItem( + context, + model.controlList[model.selectedIndex] + .subItemList[i][position]); + }, + child: Padding( + padding: + const EdgeInsets.fromLTRB(10, 5, 10, 5), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '${model.controlList[model.selectedIndex].subItemList[i][position].title}', + textAlign: TextAlign.left, + softWrap: true, + textScaleFactor: 1, + overflow: TextOverflow.fade, + style: TextStyle( + fontFamily: 'MontserratMedium', + fontSize: 16.0, + color: model.textColor, + letterSpacing: 0.3), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: model.listIconColor), + ), + ), + ]), + ), + ), + InkWell( + onTap: () {}, + splashColor: Colors.grey.withOpacity(0.4), + child: Padding( + padding: + const EdgeInsets.fromLTRB(5, 5, 5, 5), + child: SizedBox( + width: double.infinity, + height: 230, + child: model + .controlList[model.selectedIndex] + .subItemList[i][position] + .previewWidget, + ), + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ); + })); + } + return tabChildren; + } +} diff --git a/lib/samples/chart/home/legend_home.dart b/lib/samples/chart/home/legend_home.dart index 0c0d7104..452e5c62 100755 --- a/lib/samples/chart/home/legend_home.dart +++ b/lib/samples/chart/home/legend_home.dart @@ -27,9 +27,32 @@ class _SeriesFeaturesState extends State { i < model.controlList[model.selectedIndex].subItemList.length; i++) { if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { + String str = getStatus(model + .controlList[model.selectedIndex].subItemList[i]); tabs.add(Tab( - text: model - .controlList[model.selectedIndex].subItemList[i][0]?.category)); + child: Row( + children: [ + Text(model.controlList[model.selectedIndex].subItemList[i][0] + ?.category + .toString() + + (str != '' ? ' ' : '')), + Container( + height: 20, + width: 20, + decoration: BoxDecoration( + color: str == 'N' + ? Color.fromRGBO(101,193,0,1) + : str == 'U' ? Color.fromRGBO(245,166,35,1) : Colors.transparent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + str, + style: TextStyle(fontSize: 12), + ), + ), + ], + ))); } } return tabs; @@ -129,22 +152,56 @@ class _SeriesFeaturesState extends State { color: model.textColor, letterSpacing: 0.3), ), - Container( - height: 30, - width: 30, - color: Colors.transparent, - child: Padding( - padding: - const EdgeInsets.fromLTRB( - 5, 0, 5, 5), - child: Image.asset( - 'images/fullscreen.png', - fit: BoxFit.contain, - height: 20, - width: 20, - color: model.listIconColor), - ), - ), + Container( + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: model + .controlList[model + .selectedIndex] + .subItemList[i] + [position] + .status != + null + ? (model.controlList[model.selectedIndex].subItemList[i][position].status == + 'New' + ? Color.fromRGBO( + 101, 193, 0, 1) + : Color.fromRGBO( + 245, + 166, + 35, + 1)) + : Colors.transparent, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(10.0))), + padding: EdgeInsets.fromLTRB(6, 3, 6, 3), + child: Text((model.controlList[model.selectedIndex].subItemList[i][position].status != null ? model.controlList[model.selectedIndex].subItemList[i][position].status : ''), style: TextStyle(color: Colors.white))), + Padding( + padding: + EdgeInsets.only(left: 15), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: + model.listIconColor), + ), + ), + ], + )), ]), ), ), diff --git a/lib/samples/chart/home/other_features.dart b/lib/samples/chart/home/other_features.dart index 0aa69933..1a7b4e9a 100755 --- a/lib/samples/chart/home/other_features.dart +++ b/lib/samples/chart/home/other_features.dart @@ -27,9 +27,32 @@ class _SeriesFeaturesState extends State { i < model.controlList[model.selectedIndex].subItemList.length; i++) { if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { + String str = getStatus(model + .controlList[model.selectedIndex].subItemList[i]); tabs.add(Tab( - text: model - .controlList[model.selectedIndex].subItemList[i][0]?.category)); + child: Row( + children: [ + Text(model.controlList[model.selectedIndex].subItemList[i][0] + ?.category + .toString() + + (str != '' ? ' ' : '')), + Container( + height: 20, + width: 20, + decoration: BoxDecoration( + color: str == 'N' + ? Color.fromRGBO(101,193,0,1) + : str == 'U' ? Color.fromRGBO(245,166,35,1) : Colors.transparent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + str, + style: TextStyle(fontSize: 12), + ), + ), + ], + ))); } } return tabs; @@ -138,21 +161,55 @@ class _SeriesFeaturesState extends State { letterSpacing: 0.3), ), Container( - height: 30, - width: 30, - color: Colors.transparent, - child: Padding( - padding: - const EdgeInsets.fromLTRB( - 5, 0, 5, 5), - child: Image.asset( - 'images/fullscreen.png', - fit: BoxFit.contain, - height: 20, - width: 20, - color: model.listIconColor), - ), - ), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: model + .controlList[model + .selectedIndex] + .subItemList[i] + [position] + .status != + null + ? (model.controlList[model.selectedIndex].subItemList[i][position].status == + 'New' + ? Color.fromRGBO( + 101, 193, 0, 1) + : Color.fromRGBO( + 245, + 166, + 35, + 1)) + : Colors.transparent, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(10.0))), + padding: EdgeInsets.fromLTRB(6, 3, 6, 3), + child: Text((model.controlList[model.selectedIndex].subItemList[i][position].status != null ? model.controlList[model.selectedIndex].subItemList[i][position].status : ''), style: TextStyle(color: Colors.white))), + Padding( + padding: + EdgeInsets.only(left: 15), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: + model.listIconColor), + ), + ), + ], + )), ]), ), ), diff --git a/lib/samples/chart/home/pyramid_chart.dart b/lib/samples/chart/home/pyramid_chart.dart new file mode 100644 index 00000000..13295595 --- /dev/null +++ b/lib/samples/chart/home/pyramid_chart.dart @@ -0,0 +1,181 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/helper.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class PyramidFeatures extends StatefulWidget { + const PyramidFeatures({Key key}) : super(key: key); + + @override + _SeriesFeaturesState createState() => _SeriesFeaturesState(); +} + +class _SeriesFeaturesState extends State { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + List getTabs(SampleListModel model) { + List tabs = []; + for (int i = 0; + i < model.controlList[model.selectedIndex].subItemList.length; + i++) { + if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { + tabs.add(Tab( + text: model + .controlList[model.selectedIndex].subItemList[i][0]?.category)); + } + } + return tabs; + } + + @override + // ignore: must_call_super + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) => Theme( + data: model.themeData, + child: SafeArea( + child: DefaultTabController( + length: + model.controlList[model.selectedIndex].subItemList.length, + child: Scaffold( + appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () => Navigator.pop(context, false), + ), + backgroundColor: model.backgroundColor, + title: Text( + model.controlList[model.selectedIndex].title.toString(), + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16.0, + color: Colors.white, + letterSpacing: 0.3)), + ), + body: TabBarView( + children: getTabViewChildrens(model), + ), + ), + ), + ))); + } + + List getTabViewChildrens(SampleListModel model) { + List tabChildren = []; + for (int i = 0; + i < model.controlList[model.selectedIndex].subItemList.length; + i++) { + tabChildren.add(ListView.builder( + cacheExtent: model + .controlList[model.selectedIndex].subItemList[i].length + .toDouble(), + addAutomaticKeepAlives: true, + itemCount: + model.controlList[model.selectedIndex].subItemList[i].length, + itemBuilder: (BuildContext context, int position) { + return Container( + color: model.slidingPanelColor, + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Column( + children: [ + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Card( + elevation: 2, + color: model.cardThemeColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(3.0), + ), + child: Column( + children: [ + InkWell( + splashColor: Colors.grey.withOpacity(0.4), + onTap: () { + Feedback.forLongPress(context); + onTapSampleItem( + context, + model.controlList[model.selectedIndex] + .subItemList[i][position]); + }, + child: Padding( + padding: + const EdgeInsets.fromLTRB(10, 5, 10, 5), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '${model.controlList[model.selectedIndex].subItemList[i][position].title}', + textAlign: TextAlign.left, + softWrap: true, + textScaleFactor: 1, + overflow: TextOverflow.fade, + style: TextStyle( + fontFamily: 'MontserratMedium', + fontSize: 16.0, + color: model.textColor, + letterSpacing: 0.3), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: model.listIconColor), + ), + ), + ]), + ), + ), + InkWell( + onTap: () {}, + splashColor: Colors.grey.withOpacity(0.4), + child: Padding( + padding: + const EdgeInsets.fromLTRB(5, 5, 5, 5), + child: SizedBox( + width: double.infinity, + height: 230, + child: model + .controlList[model.selectedIndex] + .subItemList[i][position] + .previewWidget, + ), + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ); + })); + } + return tabChildren; + } +} diff --git a/lib/samples/chart/home/radial_gauge.dart b/lib/samples/chart/home/radial_gauge.dart new file mode 100644 index 00000000..52f241bc --- /dev/null +++ b/lib/samples/chart/home/radial_gauge.dart @@ -0,0 +1,193 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/helper.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:scoped_model/scoped_model.dart'; + +class RadialGaugeExamples extends StatefulWidget { + const RadialGaugeExamples({Key key}) : super(key: key); + + @override + _RadialGaugeExamplesState createState() => _RadialGaugeExamplesState(); +} + +class _RadialGaugeExamplesState extends State + with AutomaticKeepAliveClientMixin { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + // ignore: must_call_super + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) => Theme( + data: model.themeData, + child: SafeArea( + child: DefaultTabController( + length: + model.controlList[model.selectedIndex].subItemList.length, + child: Scaffold( + appBar: AppBar( + leading: IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () => Navigator.pop(context, false), + ), + backgroundColor: model.backgroundColor, + bottom: TabBar( + indicator: UnderlineTabIndicator( + borderSide: BorderSide( + width: 5.0, color: Color.fromRGBO(252, 220, 0, 1)), + ), + isScrollable: true, + tabs: getTabs(model), + ), + title: Text( + model.controlList[model.selectedIndex].title.toString(), + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16.0, + color: Colors.white, + letterSpacing: 0.3)), + ), + body: TabBarView( + children: getTabViewChildrens(model), + ), + ), + ), + ))); + } + + List getTabs(SampleListModel model) { + List tabs = []; + for (int i = 0; + i < model.controlList[model.selectedIndex].subItemList.length; + i++) { + if (model.controlList[model.selectedIndex].subItemList[i].length > 0) { + tabs.add(Tab( + text: model + .controlList[model.selectedIndex].subItemList[i][0]?.category)); + } + } + return tabs; + } + + List getTabViewChildrens(SampleListModel model) { + List tabChildren = []; + for (int i = 0; + i < model.controlList[model.selectedIndex].subItemList.length; + i++) { + tabChildren.add(ListView.builder( + cacheExtent: model + .controlList[model.selectedIndex].subItemList[i].length + .toDouble(), + addAutomaticKeepAlives: true, + itemCount: + model.controlList[model.selectedIndex].subItemList[i].length, + itemBuilder: (BuildContext context, int position) { + return Container( + color: model.slidingPanelColor, + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Column( + children: [ + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Card( + elevation: 2, + color: model.cardThemeColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(3.0), + ), + child: Column( + children: [ + InkWell( + splashColor: Colors.grey.withOpacity(0.4), + onTap: () { + Feedback.forLongPress(context); + onTapSampleItem( + context, + model.controlList[model.selectedIndex] + .subItemList[i][position]); + }, + child: Padding( + padding: + const EdgeInsets.fromLTRB(10, 5, 5, 5), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '${model.controlList[model.selectedIndex].subItemList[i][position].title}', + textAlign: TextAlign.left, + softWrap: true, + textScaleFactor: 1, + overflow: TextOverflow.fade, + style: TextStyle( + fontFamily: 'MontserratMedium', + fontSize: 16.0, + color: model.textColor, + letterSpacing: 0.3), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: model.listIconColor), + ), + ), + ]), + ), + ), + InkWell( + onTap: () {}, + splashColor: Colors.grey.withOpacity(0.4), + child: Padding( + padding: + const EdgeInsets.fromLTRB(5, 5, 5, 5), + child: SizedBox( + width: double.infinity, + height: 230, + child: model + .controlList[model.selectedIndex] + .subItemList[i][position] + .previewWidget, + ), + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ); + })); + } + return tabChildren; + } + + @override + bool get wantKeepAlive => false; +} \ No newline at end of file diff --git a/lib/samples/chart/home/user_interaction.dart b/lib/samples/chart/home/user_interaction.dart index a6521169..58beaaba 100755 --- a/lib/samples/chart/home/user_interaction.dart +++ b/lib/samples/chart/home/user_interaction.dart @@ -70,9 +70,32 @@ class _InteractionTypesState extends State for (int i = 0; i < model.controlList[model.selectedIndex].subItemList.length; i++) { - tabs.add(Tab( - text: model - .controlList[model.selectedIndex].subItemList[i][0].category)); + String str = getStatus(model + .controlList[model.selectedIndex].subItemList[i]); + tabs.add(Tab( + child: Row( + children: [ + Text(model.controlList[model.selectedIndex].subItemList[i][0] + ?.category + .toString() + + (str != '' ? ' ' : '')), + Container( + height: 20, + width: 20, + decoration: BoxDecoration( + color: str == 'N' + ? Color.fromRGBO(101,193,0,1) + : str == 'U' ? Color.fromRGBO(245,166,35,1) : Colors.transparent, + shape: BoxShape.circle, + ), + alignment: Alignment.center, + child: Text( + str, + style: TextStyle(fontSize: 12), + ), + ), + ], + ))); } return tabs; } @@ -138,21 +161,55 @@ class _InteractionTypesState extends State letterSpacing: 0.3), ), Container( - height: 30, - width: 30, - color: Colors.transparent, - child: Padding( - padding: - const EdgeInsets.fromLTRB( - 5, 0, 5, 5), - child: Image.asset( - 'images/fullscreen.png', - fit: BoxFit.contain, - height: 20, - width: 20, - color: model.listIconColor), - ), - ), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: model + .controlList[model + .selectedIndex] + .subItemList[i] + [position] + .status != + null + ? (model.controlList[model.selectedIndex].subItemList[i][position].status == + 'New' + ? Color.fromRGBO( + 101, 193, 0, 1) + : Color.fromRGBO( + 245, + 166, + 35, + 1)) + : Colors.transparent, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(10.0))), + padding: EdgeInsets.fromLTRB(6, 3, 6, 3), + child: Text((model.controlList[model.selectedIndex].subItemList[i][position].status != null ? model.controlList[model.selectedIndex].subItemList[i][position].status : ''), style: TextStyle(color: Colors.white))), + Padding( + padding: + EdgeInsets.only(left: 15), + ), + Container( + height: 30, + width: 30, + color: Colors.transparent, + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 5, 0, 5, 5), + child: Image.asset( + 'images/fullscreen.png', + fit: BoxFit.contain, + height: 20, + width: 20, + color: + model.listIconColor), + ), + ), + ], + )), ]), ), ), diff --git a/lib/samples/chart/pyramid_charts/default_pyramid_chart.dart b/lib/samples/chart/pyramid_charts/default_pyramid_chart.dart new file mode 100644 index 00000000..b6d0afd5 --- /dev/null +++ b/lib/samples/chart/pyramid_charts/default_pyramid_chart.dart @@ -0,0 +1,479 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/bottom_sheet.dart'; +import 'package:flutter_examples/widgets/customDropDown.dart'; +import 'package:flutter_examples/widgets/custom_button.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import '../../../widgets/checkbox.dart'; + +class PyramidDefault extends StatefulWidget { + final SubItemList sample; + const PyramidDefault(this.sample, {Key key}) : super(key: key); + + @override + _PyramidDefaultState createState() => _PyramidDefaultState(sample); +} + +class _PyramidDefaultState extends State { + final SubItemList sample; + _PyramidDefaultState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(PyramidDefault oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/circular_charts/pie_series/default_pie_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + final List _pyramidMode = + ['Linear', 'Surface'].toList(); + PyramidMode _selectedPyramidMode = PyramidMode.linear; + String _selectedMode; + _FrontPanelState(this.sample); + double gapRatio = 0; + bool explode = false; + @override + void initState() { + super.initState(); + gapRatio = 0; + _selectedMode = _pyramidMode.first; + _selectedPyramidMode = PyramidMode.linear; + } + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getDefaultPyramidChart(false, _selectedPyramidMode, gapRatio, explode)), + ), + floatingActionButton: Stack( + children: [ + Align( + alignment: Alignment.bottomLeft, + child: Padding( + padding: const EdgeInsets.fromLTRB(30, 50, 0, 0), + child: Container( + height: 50, + width: 250, + // child: InkWell( + // onTap: () => launch( + // 'https://data.worldbank.org/indicator/sp.rur.totl.zs'), + // child: Row( + // children: [ + // Text('Source: ', + // style: TextStyle( + // fontSize: 16, color: model.textColor)), + // Text('data.worldbank.org', + // style: TextStyle( + // fontSize: 14, color: Colors.blue)), + // ], + // ), + // ), + ), + ), + ), + Align( + alignment: Alignment.bottomRight, + child: FloatingActionButton( + heroTag: null, + onPressed: () { + _showSettingsPanel(model); + }, + child: Icon(Icons.graphic_eq, color: Colors.white), + backgroundColor: model.backgroundColor, + ), + ), + + ])); + }); + } + void onPyramidModeChange(String item) { + setState(() { + _selectedMode = item; + if (_selectedMode == 'Linear') { + _selectedPyramidMode = PyramidMode.linear; + } + else if (_selectedMode == 'Surface') { + _selectedPyramidMode = PyramidMode.surface; + } + }); + } + void _showSettingsPanel(SampleListModel model) { + double height = + (MediaQuery.of(context).size.height > MediaQuery.of(context).size.width) + ? 0.3 + : 0.4; + showRoundedModalBottomSheet( + dismissOnTap: false, + context: context, + radius: 12.0, + color: model.bottomSheetBackgroundColor, + builder: (context) => ScopedModelDescendant( + rebuildOnChange: false, + builder: (context, _, model) => Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 170, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: MediaQuery.of(context).size.height * height, + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 5), + child: Stack(children: [ + Container( + height: 40, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('Settings', + style: TextStyle( + color: model.textColor, + fontSize: 18, + letterSpacing: 0.34, + fontWeight: FontWeight.w500)), + IconButton( + icon: Icon( + Icons.close, + color: model.textColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets.fromLTRB(10, 50, 0, 0), + child: ListView( + children: [ + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Pyramid mode ', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + padding: + const EdgeInsets.fromLTRB( + 20, 0, 0, 0), + height: 50, + width: 150, + child: Align( + alignment: + Alignment.bottomCenter, + child: Theme( + data: Theme.of(context) + .copyWith( + canvasColor: model + .bottomSheetBackgroundColor), + child: DropDown( + value: _selectedMode, + item: _pyramidMode + .map( + (String value) { + return DropdownMenuItem< + String>( + value: (value != + null) + ? value + : 'Linear', + child: Text( + '$value', + style: TextStyle( + color: model + .textColor))); + }).toList(), + valueChanged: + (dynamic value) { + onPyramidModeChange( + value.toString()); + }), + ), + )) + ], + ), + ), + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Gap ratio ', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + child: Padding( + padding: + const EdgeInsets.fromLTRB( + 40, 0, 0, 0), + child: CustomButton( + minValue: 0, + maxValue: 0.5, + initialValue: + gapRatio, + onChanged: (val) => + setState(() { + gapRatio = val; + }), + step: 0.1, + horizontal: true, + loop: false, + padding: 0, + iconUp: + Icons.keyboard_arrow_up, + iconDown: + Icons.keyboard_arrow_down, + iconLeft: + Icons.keyboard_arrow_left, + iconRight: Icons + .keyboard_arrow_right, + iconUpRightColor: + model.textColor, + iconDownLeftColor: + model.textColor, + style: TextStyle( + fontSize: 20.0, + color: model.textColor), + ), + ), + ), + ], + ), + ), + Container( + child: Row( + children: [ + Text('Explode', + style: TextStyle( + color: model.textColor, + fontSize: 16, + letterSpacing: 0.34, + fontWeight: + FontWeight.normal)), + Padding( + padding: EdgeInsets.fromLTRB(40, 0, 0, 0) + ), + BottomSheetCheckbox( + activeColor: + model.backgroundColor, + switchValue: explode, + valueChanged: (value) { + setState(() { + explode = value; + }); + }, + ), + ], + ), + ), + ], + ), + ), + ]), + ))))))); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfPyramidChart getDefaultPyramidChart(bool isTileView, [PyramidMode _selectedPyramidMode, double gapRatio, bool explode]) { + return SfPyramidChart( + + smartLabelMode: SmartLabelMode.shift, + title: ChartTitle(text: isTileView ? '' : 'Comparison of calories'), + tooltipBehavior: TooltipBehavior(enable: true), + series: _getPyramidSeries(isTileView, _selectedPyramidMode, gapRatio, explode), + ); +} + +PyramidSeries<_PyramidData, String> _getPyramidSeries(bool isTileView, [PyramidMode selectedPyramidMode, double gapRatio, bool explode]) { + final List<_PyramidData> pieData = <_PyramidData>[ + _PyramidData('Walnuts', 654), + _PyramidData('Almonds', 575), + _PyramidData('Soybeans', 446), + _PyramidData('Black beans', 341), + _PyramidData('Mushrooms', 296), + _PyramidData('Avacado', 160), + ]; + return PyramidSeries<_PyramidData, String>( + dataSource: pieData, + height: '90%', + explode: isTileView ? false : explode, + gapRatio: isTileView ? 0 : gapRatio, + pyramidMode: isTileView ? PyramidMode.linear : selectedPyramidMode, + xValueMapper: (_PyramidData data, _) => data.xData, + yValueMapper: (_PyramidData data, _) => data.yData, + dataLabelSettings: DataLabelSettings(isVisible: true,)); +} + +class _PyramidData { + _PyramidData(this.xData, this.yData, [this.text]); + final String xData; + final num yData; + final String text; +} diff --git a/lib/samples/chart/pyramid_charts/pyramid_with_legend.dart b/lib/samples/chart/pyramid_charts/pyramid_with_legend.dart new file mode 100644 index 00000000..2376501b --- /dev/null +++ b/lib/samples/chart/pyramid_charts/pyramid_with_legend.dart @@ -0,0 +1,250 @@ +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class PyramidLegend extends StatefulWidget { + final SubItemList sample; + const PyramidLegend(this.sample, {Key key}) : super(key: key); + + @override + _PyramidLegendState createState() => _PyramidLegendState(sample); +} + +class _PyramidLegendState extends State { + final SubItemList sample; + _PyramidLegendState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(PyramidLegend oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/circular_charts/pie_series/default_pie_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + _FrontPanelState(this.sample); + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container(child: getLegendPyramidChart(false)), + )); + }); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfPyramidChart getLegendPyramidChart(bool isTileView) { + return SfPyramidChart( + onTooltipRender: (TooltipArgs args) { + List data; + String text; + text = args.dataPoints[args.pointIndex].y.toString(); + if (text.contains('.')) { + data = text.split('.'); + String newTe = + data[0].toString() + ' years ' + data[1].toString() + ' months'; + args.text = newTe; + } else { + args.text = text + ' years'; + } + }, + smartLabelMode: SmartLabelMode.none, + title: + ChartTitle(text: isTileView ? '' : 'Experience of employees in a team'), + legend: Legend(isVisible: true, overflowMode: LegendItemOverflowMode.wrap), + tooltipBehavior: TooltipBehavior(enable: true), + series: _getPyramidSeries(isTileView), + ); +} + +PyramidSeries<_PyramidData, String> _getPyramidSeries(bool isTileView) { + final List<_PyramidData> pieData = <_PyramidData>[ + _PyramidData('Ray', 7.3), + _PyramidData( + 'Michael', + 6.6, + ), + _PyramidData( + 'John ', + 3, + ), + _PyramidData( + 'Mercy', + 0.8, + ), + _PyramidData( + 'Tina ', + 1.4, + ), + _PyramidData( + 'Stephen', + 5.2, + ), + ]; + return PyramidSeries<_PyramidData, String>( + dataSource: pieData, + xValueMapper: (_PyramidData data, _) => data.xData, + yValueMapper: (_PyramidData data, _) => data.yData, + dataLabelSettings: DataLabelSettings( + isVisible: isTileView ? false : true, + labelPosition: LabelPosition.inside)); +} + +class _PyramidData { + _PyramidData(this.xData, this.yData, [this.text]); + final String xData; + final num yData; + final String text; +} diff --git a/lib/samples/chart/pyramid_charts/pyramid_with_smart_labels.dart b/lib/samples/chart/pyramid_charts/pyramid_with_smart_labels.dart new file mode 100644 index 00000000..5d94cc50 --- /dev/null +++ b/lib/samples/chart/pyramid_charts/pyramid_with_smart_labels.dart @@ -0,0 +1,490 @@ +import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:flutter_examples/widgets/bottom_sheet.dart'; +import 'package:flutter_examples/widgets/customDropDown.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class PyramidSmartLabels extends StatefulWidget { + final SubItemList sample; + const PyramidSmartLabels(this.sample, {Key key}) : super(key: key); + + @override + _PyramidSmartLabelState createState() => _PyramidSmartLabelState(sample); +} + +class _PyramidSmartLabelState extends State { + final SubItemList sample; + _PyramidSmartLabelState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(PyramidSmartLabels oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + toggleFrontLayer: false, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/circular_charts/pie_series/default_pie_chart.dart'); + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +class _FrontPanelState extends State { + final SubItemList sample; + _FrontPanelState(this.sample); + final List _labelPositon = ['outside', 'inside'].toList(); + LabelPosition _selectedLabelPosition = LabelPosition.outside; + String _selectedPosition; + + final List _modeList = ['shift', 'none', 'hide'].toList(); + String _smartLabelMode = 'shift'; + SmartLabelMode _mode = SmartLabelMode.shift; + + @override + void initState() { + super.initState(); + _selectedPosition = _labelPositon.first; + _selectedLabelPosition = LabelPosition.outside; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container( + child: getPyramidSmartLabelChart( + false, _selectedLabelPosition, _mode)), + ), + floatingActionButton: Stack(children: [ + Align( + alignment: Alignment.bottomLeft, + child: Padding( + padding: const EdgeInsets.fromLTRB(30, 50, 0, 0), + child: Container( + height: 50, + width: 250, + child: InkWell( + onTap: () => launch( + 'https://www.worldometers.info/world-population/population-by-country/'), + child: Row( + children: [ + Text('Source: ', + style: TextStyle( + fontSize: 16, color: model.textColor)), + Text('worldometers.com', + style: TextStyle( + fontSize: 14, color: Colors.blue)), + ], + ), + ), + ), + ), + ), + Align( + alignment: Alignment.bottomRight, + child: FloatingActionButton( + heroTag: null, + onPressed: () { + _showSettingsPanel(model); + }, + child: Icon(Icons.graphic_eq, color: Colors.white), + backgroundColor: model.backgroundColor, + ), + ), + ])); + }); + } + + void onLabelPositionChange(String item) { + setState(() { + _selectedPosition = item; + if (_selectedPosition == 'inside') { + _selectedLabelPosition = LabelPosition.inside; + } else if (_selectedPosition == 'outside') { + _selectedLabelPosition = LabelPosition.outside; + } + }); + } + + void onSmartLabelModeChange(String item, SampleListModel model) { + setState(() { + _smartLabelMode = item; + if (_smartLabelMode == 'shift') { + _mode = SmartLabelMode.shift; + } + if (_smartLabelMode == 'hide') { + _mode = SmartLabelMode.hide; + } + if (_smartLabelMode == 'none') { + _mode = SmartLabelMode.none; + } + }); + } + + void _showSettingsPanel(SampleListModel model) { + double height = + (MediaQuery.of(context).size.height > MediaQuery.of(context).size.width) + ? 0.3 + : 0.4; + showRoundedModalBottomSheet( + dismissOnTap: false, + context: context, + radius: 12.0, + color: model.bottomSheetBackgroundColor, + builder: (context) => ScopedModelDescendant( + rebuildOnChange: false, + builder: (context, _, model) => Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 170, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: MediaQuery.of(context).size.height * height, + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 5), + child: Stack(children: [ + Container( + height: 40, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('Settings', + style: TextStyle( + color: model.textColor, + fontSize: 18, + letterSpacing: 0.34, + fontWeight: FontWeight.w500)), + IconButton( + icon: Icon( + Icons.close, + color: model.textColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets.fromLTRB(10, 50, 0, 0), + child: ListView( + children: [ + Container( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Text('Label position ', + style: TextStyle( + fontSize: 16.0, + color: model.textColor)), + Container( + padding: + const EdgeInsets.fromLTRB( + 20, 0, 0, 0), + height: 50, + width: 150, + child: Align( + alignment: + Alignment.bottomCenter, + child: Theme( + data: Theme.of(context) + .copyWith( + canvasColor: model + .bottomSheetBackgroundColor), + child: DropDown( + value: + _selectedPosition, + item: _labelPositon.map( + (String value) { + return DropdownMenuItem< + String>( + value: (value != + null) + ? value + : 'outside', + child: Text( + '$value', + style: TextStyle( + color: model + .textColor))); + }).toList(), + valueChanged: + (dynamic value) { + onLabelPositionChange( + value.toString()); + }), + ), + )), + ], + ), + ), + Container( + child: Row( + children: [ + Text('Smart label mode ', + style: TextStyle( + color: model.textColor, + fontSize: 16, + letterSpacing: 0.34, + fontWeight: + FontWeight.normal)), + Container( + padding: + const EdgeInsets.fromLTRB( + 20, 0, 0, 0), + height: 50, + width: 150, + child: Align( + alignment: + Alignment.bottomCenter, + child: Theme( + data: Theme.of(context) + .copyWith( + canvasColor: model + .bottomSheetBackgroundColor), + child: DropDown( + value: _smartLabelMode, + item: _modeList.map( + (String value) { + return DropdownMenuItem< + String>( + value: (value != + null) + ? value + : 'shift', + child: Text( + '$value', + style: TextStyle( + color: model + .textColor))); + }).toList(), + valueChanged: + (dynamic value) { + onSmartLabelModeChange( + value.toString(), + model); + }), + ), + )), + ], + ), + ), + ], + ), + ), + ]), + ))))))); + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfPyramidChart getPyramidSmartLabelChart(bool isTileView, + [LabelPosition _labelPosition, SmartLabelMode _mode]) { + return SfPyramidChart( + onTooltipRender: (TooltipArgs args) { + final NumberFormat format = NumberFormat.decimalPattern(); + args.text = format.format(args.dataPoints[args.pointIndex].y).toString(); + }, + title: + ChartTitle(text: isTileView ? '' : 'Top 10 populated countries - 2019'), + tooltipBehavior: TooltipBehavior(enable: true), + smartLabelMode: isTileView ? SmartLabelMode.shift : _mode, + series: _getPyramidSeries( + isTileView, + _labelPosition, + ), + ); +} + +PyramidSeries<_PyramidData, String> _getPyramidSeries(bool isTileView, + [LabelPosition _labelPosition, + LabelIntersectAction _labelIntersectAction]) { + final List<_PyramidData> pieData = <_PyramidData>[ + _PyramidData('Mexico', 127575529, null, Color.fromRGBO(238, 238, 238, 1)), + _PyramidData('Russia ', 145872256, null, Color.fromRGBO(255, 240, 219, 1)), + _PyramidData( + 'Bangladesh', 163046161, null, Color.fromRGBO(255, 205, 96, 1)), + _PyramidData('Nigeria ', 200963599, null, Color.fromRGBO(73, 76, 162, 1)), + _PyramidData('Brazil', 211049527, null, Color.fromRGBO(0, 168, 181, 1)), + _PyramidData( + 'Pakistan ', 216565318, null, Color.fromRGBO(116, 180, 155, 1)), + _PyramidData( + 'Indonesia', 270625568, null, Color.fromRGBO(248, 177, 149, 1)), + _PyramidData('US', 329064917, null, Color.fromRGBO(246, 114, 128, 1)), + _PyramidData('India', 1366417754, null, Color.fromRGBO(192, 108, 132, 1)), + _PyramidData('China', 1433783686, null, Color.fromRGBO(53, 92, 125, 1)), + ]; + return PyramidSeries<_PyramidData, String>( + width: '60%', + dataSource: pieData, + xValueMapper: (_PyramidData data, _) => data.xData, + yValueMapper: (_PyramidData data, _) => data.yData, + textFieldMapper: (_PyramidData data, _) => data.xData, + pointColorMapper: (_PyramidData data, _) => data.color, + dataLabelSettings: DataLabelSettings( + isVisible: true, + labelPosition: isTileView ? LabelPosition.outside : _labelPosition, + useSeriesColor: true)); +} + +class _PyramidData { + _PyramidData(this.xData, this.yData, [this.text, this.color]); + final String xData; + final num yData; + final String text; + final Color color; +} diff --git a/lib/samples/chart/series_features/animation/dynamic_animation.dart b/lib/samples/chart/series_features/animation/dynamic_animation.dart new file mode 100644 index 00000000..4bcc82fc --- /dev/null +++ b/lib/samples/chart/series_features/animation/dynamic_animation.dart @@ -0,0 +1,633 @@ +import 'dart:async'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_examples/model/model.dart'; +import 'package:flutter_examples/widgets/bottom_sheet.dart'; +import 'package:flutter_examples/widgets/customDropDown.dart'; +import 'package:flutter_examples/widgets/flutter_backdrop.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class CartesianDynamicAnimation extends StatefulWidget { + final SubItemList sample; + const CartesianDynamicAnimation(this.sample, {Key key}) : super(key: key); + + @override + _CartesianDynamicAnimationState createState() => + _CartesianDynamicAnimationState(sample); +} + +class _CartesianDynamicAnimationState extends State { + final SubItemList sample; + _CartesianDynamicAnimationState(this.sample); + bool panelOpen; + final frontPanelVisible = ValueNotifier(true); + + @override + void initState() { + panelOpen = frontPanelVisible.value; + frontPanelVisible.addListener(_subscribeToValueNotifier); + super.initState(); + } + + void _subscribeToValueNotifier() => panelOpen = frontPanelVisible.value; + + @override + void dispose() { + super.dispose(); + } + + @override + void didUpdateWidget(CartesianDynamicAnimation oldWidget) { + super.didUpdateWidget(oldWidget); + frontPanelVisible.removeListener(_subscribeToValueNotifier); + frontPanelVisible.addListener(_subscribeToValueNotifier); + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + builder: (context, _, model) => SafeArea( + child: Backdrop( + needCloseButton: false, + panelVisible: frontPanelVisible, + sampleListModel: model, + frontPanelOpenPercentage: 0.28, + appBarAnimatedLeadingMenuIcon: AnimatedIcons.close_menu, + appBarActions: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.codeViewerIcon, + color: Colors.white), + onPressed: () { + launch( + 'https://github.com/syncfusion/flutter-examples/blob/master/lib/samples/chart/axis_features/handling_label_collision/handling_label_collision.dart'); + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: Container( + height: 40, + width: 40, + child: IconButton( + icon: Image.asset(model.informationIcon, + color: Colors.white), + onPressed: () { + if (frontPanelVisible.value) + frontPanelVisible.value = false; + else + frontPanelVisible.value = true; + }, + ), + ), + ), + ], + appBarTitle: AnimatedSwitcher( + duration: Duration(milliseconds: 1000), + child: Text(sample.title.toString())), + backLayer: BackPanel(sample), + frontLayer: FrontPanel(sample), + sideDrawer: null, + headerClosingHeight: 350, + titleVisibleOnPanelClosed: true, + borderRadius: BorderRadius.vertical( + top: Radius.circular(12), bottom: Radius.circular(0)), + ), + )); + } +} + +class FrontPanel extends StatefulWidget { + final SubItemList subItemList; + FrontPanel(this.subItemList); + + @override + _FrontPanelState createState() => _FrontPanelState(this.subItemList); +} + +List<_DynamicData> chartData = <_DynamicData>[ + _DynamicData('1', 45, Colors.yellow), + _DynamicData('2', 52, Colors.teal), + _DynamicData('3', 41, Colors.blue), + _DynamicData('4', 65, Colors.orange), + _DynamicData('5', 36, Colors.pink), + _DynamicData('6', 65, Colors.brown[300]), +]; + +class _FrontPanelState extends State { + final SubItemList sample; + _FrontPanelState(this.sample); + bool enableTooltip = false; + bool enableMarker = false; + bool enableDatalabel = false; + // List<_DynamicData> chartData; + int count = 0; + final List _seriesType = [ + 'Column', + 'Line', + 'Spline', + 'StepLine', + 'Scatter', + 'Bubble', + 'Bar', + 'Area' + ].toList(); + + String _selectedType = 'Column'; + + Timer timer; + + @override + Widget build(BuildContext context) { + chartData = getChartData(); + timer = Timer(Duration(seconds: 3), () { + setState(() { + chartData = getChartData(); + }); + }); + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.fromLTRB(5, 0, 5, 50), + child: Container( + child: getDynamicAnimationChart(false, _selectedType)), + ), + floatingActionButton: Stack( + children: [ + Align( + alignment: Alignment.bottomLeft, + child: Padding( + padding: const EdgeInsets.fromLTRB(30, 50, 0, 0), + child: Container( + height: 50, + width: 250, + child: InkWell( + onTap: () => launch( + 'https://en.wikipedia.org/wiki/List_of_men%27s_footballers_with_500_or_more_goals'), + ), + ), + ), + ), + Align( + alignment: Alignment.bottomRight, + child: FloatingActionButton( + heroTag: null, + onPressed: () { + _showSettingsPanel(model); + }, + child: Icon(Icons.graphic_eq, color: Colors.white), + backgroundColor: model.backgroundColor, + ), + ), + ], + )); + }); + } + + void onSeriesTypeChange(String item, SampleListModel model) { + setState(() { + _selectedType = item; + }); + } + + void _showSettingsPanel(SampleListModel model) { + showRoundedModalBottomSheet( + dismissOnTap: false, + context: context, + radius: 12.0, + color: model.bottomSheetBackgroundColor, + builder: (context) => ScopedModelDescendant( + rebuildOnChange: false, + builder: (context, _, model) => Padding( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 120, + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Container( + height: 150, + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 5), + child: Stack(children: [ + Container( + height: 40, + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('Settings', + style: TextStyle( + color: model.textColor, + fontSize: 18, + letterSpacing: 0.34, + fontWeight: FontWeight.w500)), + IconButton( + icon: Icon( + Icons.close, + color: model.textColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: + const EdgeInsets.fromLTRB(10, 50, 0, 0), + child: ListView( + children: [ + Container( + child: Row( + children: [ + Text('Chart type ', + style: TextStyle( + color: model.textColor, + fontSize: 16, + letterSpacing: 0.34, + fontWeight: + FontWeight.normal)), + Container( + padding: + const EdgeInsets.fromLTRB( + 20, 0, 0, 0), + height: 50, + width: 150, + child: Align( + alignment: + Alignment.bottomCenter, + child: Theme( + data: Theme.of(context) + .copyWith( + canvasColor: model + .bottomSheetBackgroundColor), + child: DropDown( + value: _selectedType, + item: _seriesType.map( + (String value) { + return DropdownMenuItem< + String>( + value: (value != + null) + ? value + : 'column', + child: Text( + '$value', + style: TextStyle( + color: model + .textColor))); + }).toList(), + valueChanged: + (dynamic value) { + onSeriesTypeChange( + value.toString(), + model); + }), + ), + )), + ], + ), + ), + ], + ), + ), + ]), + ))))))); + } + + List<_DynamicData> getChartData() { + if (count == 0) { + chartData = <_DynamicData>[ + _DynamicData('1', 76, Colors.yellow), + _DynamicData('2', 50, Colors.teal), + _DynamicData('3', 60, Colors.blue), + _DynamicData('4', 32, Colors.orange), + _DynamicData('5', 29, Colors.pink), + _DynamicData('6', 20, Colors.brown[300]), + ]; + count++; + } else if (count == 1) { + chartData = <_DynamicData>[ + _DynamicData('1', 36, Colors.yellow), + _DynamicData('2', 10, Colors.teal), + _DynamicData('3', 20, Colors.blue), + _DynamicData('4', 50, Colors.orange), + _DynamicData('5', 19, Colors.pink), + _DynamicData('6', 67, Colors.brown[300]), + ]; + count++; + } else if (count == 2) { + chartData = <_DynamicData>[ + _DynamicData('1', 40, Colors.yellow), + _DynamicData('2', 60, Colors.teal), + _DynamicData('3', 35, Colors.blue), + _DynamicData('4', 12, Colors.orange), + _DynamicData('5', 65, Colors.pink), + _DynamicData('6', 40, Colors.brown[300]), + ]; + count = 0; + } + if (timer != null) { + timer.cancel(); + } + return chartData; + } +} + +class BackPanel extends StatefulWidget { + final SubItemList sample; + + BackPanel(this.sample); + + @override + _BackPanelState createState() => _BackPanelState(sample); +} + +class _BackPanelState extends State { + final SubItemList sample; + GlobalKey _globalKey = GlobalKey(); + _BackPanelState(this.sample); + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + super.initState(); + // _selectedseriesType = _seriesTypes.first; + } + + _afterLayout(_) { + _getSizesAndPosition(); + } + + _getSizesAndPosition() { + final RenderBox renderBoxRed = _globalKey.currentContext.findRenderObject(); + final size = renderBoxRed.size; + final position = renderBoxRed.localToGlobal(Offset.zero); + double appbarHeight = 60; + BackdropState.frontPanelHeight = + position.dy + (size.height - appbarHeight) + 20; + } + + @override + Widget build(BuildContext context) { + return ScopedModelDescendant( + rebuildOnChange: true, + builder: (context, _, model) { + return Container( + color: model.backgroundColor, + child: Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 0, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + sample.title, + textAlign: TextAlign.left, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 28.0, + color: Colors.white, + letterSpacing: 0.53), + ), + Padding( + key: _globalKey, + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Text( + sample.description, + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 15.0, + color: Colors.white, + letterSpacing: 0.3, + height: 1.5), + ), + ), + ], + ), + ), + ); + }, + ); + } +} + +SfCartesianChart getDynamicAnimationChart(bool isTileView, + [String _selectedType]) { + return SfCartesianChart( + primaryXAxis: CategoryAxis( + majorGridLines: MajorGridLines(width: 0), + ), + primaryYAxis: NumericAxis( + axisLine: AxisLine(width: 0), + interval: 20, + maximum: 80, + majorTickLines: MajorTickLines(size: 0)), + series: getAnimationData(isTileView, isTileView ? 'Column' : _selectedType), + ); +} + +List> getAnimationData( + bool isTileView, String _selectedseriesType) { + if (_selectedseriesType == 'Line') { + return >[ + LineSeries<_DynamicData, String>( + dataSource: chartData, + color: Color.fromRGBO(0, 168, 181, 1), + width: 2, + xValueMapper: (_DynamicData sales, _) => sales.country, + yValueMapper: (_DynamicData sales, _) => sales.sales, + markerSettings: MarkerSettings( + isVisible: false, + height: 5, + width: 5, + color: Colors.white, + shape: DataMarkerType.circle, + borderWidth: 3, + borderColor: Colors.blue), + dataLabelSettings: DataLabelSettings( + color: Colors.blue, + alignment: ChartAlignment.near, + isVisible: false), + ) + ]; + } else if (_selectedseriesType == 'Column') { + return >[ + ColumnSeries<_DynamicData, String>( + dataSource: chartData, + color: Color.fromRGBO(0, 168, 181, 1), + xValueMapper: (_DynamicData sales, _) => sales.country, + yValueMapper: (_DynamicData sales, _) => sales.sales, + markerSettings: MarkerSettings( + isVisible: false, + height: 5, + width: 5, + color: Colors.white, + shape: DataMarkerType.circle, + borderWidth: 3, + borderColor: Colors.blue), + dataLabelSettings: DataLabelSettings( + color: Colors.blue, + alignment: ChartAlignment.near, + isVisible: false), + borderRadius: const BorderRadius.all(Radius.circular(20)), + ) + ]; + } else if (_selectedseriesType == 'Spline') { + return >[ + SplineSeries<_DynamicData, String>( + dataSource: chartData, + color: Color.fromRGBO(0, 168, 181, 1), + width: 2, + xValueMapper: (_DynamicData sales, _) => sales.country, + yValueMapper: (_DynamicData sales, _) => sales.sales, + markerSettings: MarkerSettings( + isVisible: false, + height: 5, + width: 5, + color: Colors.white, + shape: DataMarkerType.circle, + borderWidth: 3, + borderColor: Colors.blue), + dataLabelSettings: DataLabelSettings( + color: Colors.blue, + alignment: ChartAlignment.near, + isVisible: false), + ) + ]; + } else if (_selectedseriesType == 'Area') { + return >[ + AreaSeries<_DynamicData, String>( + dataSource: chartData, + color: Color.fromRGBO(0, 168, 181, 1), + xValueMapper: (_DynamicData sales, _) => sales.country, + yValueMapper: (_DynamicData sales, _) => sales.sales, + dataLabelSettings: DataLabelSettings( + color: Colors.blue, + alignment: ChartAlignment.near, + isVisible: false), + markerSettings: MarkerSettings( + isVisible: false, + height: 5, + width: 5, + color: Colors.white, + shape: DataMarkerType.circle, + borderWidth: 3, + borderColor: Colors.blue), + ) + ]; + } else if (_selectedseriesType == 'StepLine') { + return >[ + StepLineSeries<_DynamicData, String>( + dataSource: chartData, + width: 2, + color: Color.fromRGBO(0, 168, 181, 1), + xValueMapper: (_DynamicData sales, _) => sales.country, + yValueMapper: (_DynamicData sales, _) => sales.sales, + dataLabelSettings: DataLabelSettings( + color: Colors.blue, + alignment: ChartAlignment.center, + position: CartesianLabelPosition.auto, + isVisible: false), + markerSettings: MarkerSettings( + isVisible: false, + height: 5, + width: 5, + color: Colors.white, + shape: DataMarkerType.circle, + borderWidth: 3, + borderColor: Colors.blue), + ) + ]; + } else if (_selectedseriesType == 'Bar') { + return >[ + BarSeries<_DynamicData, String>( + dataSource: chartData, + color: Color.fromRGBO(0, 168, 181, 1), + xValueMapper: (_DynamicData sales, _) => sales.country, + yValueMapper: (_DynamicData sales, _) => sales.sales, + dataLabelSettings: DataLabelSettings( + color: Colors.blue, + alignment: ChartAlignment.center, + position: CartesianLabelPosition.auto, + isVisible: false), + borderRadius: const BorderRadius.all(Radius.circular(20)), + markerSettings: MarkerSettings( + isVisible: false, + height: 5, + width: 5, + color: Colors.white, + shape: DataMarkerType.circle, + borderWidth: 3, + borderColor: Colors.blue), + ) + ]; + } else if (_selectedseriesType == 'Scatter') { + return >[ + ScatterSeries<_DynamicData, String>( + dataSource: chartData, + width: 2, + xValueMapper: (_DynamicData sales, _) => sales.country, + yValueMapper: (_DynamicData sales, _) => sales.sales, + color: Color.fromRGBO(0, 168, 181, 1), + dataLabelSettings: DataLabelSettings( + color: Colors.blue, + alignment: ChartAlignment.center, + position: CartesianLabelPosition.auto, + isVisible: false), + markerSettings: MarkerSettings( + isVisible: false, + height: 10, + width: 10, + color: Colors.white, + shape: DataMarkerType.circle, + borderWidth: 3, + borderColor: Colors.blue), + ) + ]; + } else if (_selectedseriesType == 'Bubble') { + return >[ + BubbleSeries<_DynamicData, String>( + dataSource: chartData, + color: Color.fromRGBO(0, 168, 181, 1), + width: 2, + xValueMapper: (_DynamicData sales, _) => sales.country, + yValueMapper: (_DynamicData sales, _) => sales.sales, + sizeValueMapper: (_DynamicData sales, _) => sales.sales, + dataLabelSettings: DataLabelSettings( + color: Colors.blue, + alignment: ChartAlignment.center, + position: CartesianLabelPosition.auto, + isVisible: false), + markerSettings: MarkerSettings( + isVisible: false, + height: 5, + width: 5, + color: Colors.white, + shape: DataMarkerType.circle, + borderWidth: 3, + borderColor: Colors.blue), + ) + ]; + } + + return null; +} + +class _DynamicData { + _DynamicData(this.country, this.sales, this.pointColor); + final String country; + final double sales; + final Color pointColor; +} diff --git a/lib/samples/chart/series_features/animation/series_animation.dart b/lib/samples/chart/series_features/animation/series_animation.dart index 6ebef5a5..c0957e6a 100755 --- a/lib/samples/chart/series_features/animation/series_animation.dart +++ b/lib/samples/chart/series_features/animation/series_animation.dart @@ -190,7 +190,7 @@ SfCartesianChart getDefaultAnimationChart(bool isTileView) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Sales report'), legend: Legend(isVisible: isTileView ? false : true), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: CategoryAxis( majorGridLines: MajorGridLines(width: 0), edgeLabelPlacement: EdgeLabelPlacement.shift), diff --git a/lib/samples/chart/series_features/annotation/chart_with_annotation.dart b/lib/samples/chart/series_features/annotation/chart_with_annotation.dart index 8aa5b91e..fba06de6 100755 --- a/lib/samples/chart/series_features/annotation/chart_with_annotation.dart +++ b/lib/samples/chart/series_features/annotation/chart_with_annotation.dart @@ -209,7 +209,7 @@ SfCartesianChart getWatermarkAnnotationChart(bool isTileView) { return SfCartesianChart( title: ChartTitle( text: isTileView ? '' : 'UK social media reach, by platform'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: CategoryAxis( majorGridLines: MajorGridLines(width: 0), edgeLabelPlacement: EdgeLabelPlacement.shift), diff --git a/lib/samples/chart/series_features/annotation/chart_with_watermark.dart b/lib/samples/chart/series_features/annotation/chart_with_watermark.dart index e3a1a5a4..3b9f19d3 100755 --- a/lib/samples/chart/series_features/annotation/chart_with_watermark.dart +++ b/lib/samples/chart/series_features/annotation/chart_with_watermark.dart @@ -213,7 +213,7 @@ class _BackPanelState extends State { SfCartesianChart getDefaultAnnotationChart(bool isTileView,[Brightness currentTheme]) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, title: ChartTitle( text: isTileView ? '' @@ -237,7 +237,8 @@ SfCartesianChart getDefaultAnnotationChart(bool isTileView,[Brightness currentTh child: Text( '€ - \$ ', style: TextStyle( - color: currentTheme == Brightness.light ? Color.fromRGBO(0, 0, 0, 0.15) : Color.fromRGBO(255, 255, 255, 0.3), + color:Color.fromRGBO(216, 225, 227,1), + // color: currentTheme == Brightness.light ? Color.fromRGBO(0, 0, 0, 0.15) : Color.fromRGBO(255, 255, 255, 0.3), fontWeight: FontWeight.bold, fontSize: 80), ), diff --git a/lib/samples/chart/series_features/data_label/default_datalabels.dart b/lib/samples/chart/series_features/data_label/default_datalabels.dart index ba74d097..10700888 100755 --- a/lib/samples/chart/series_features/data_label/default_datalabels.dart +++ b/lib/samples/chart/series_features/data_label/default_datalabels.dart @@ -191,7 +191,7 @@ SfCartesianChart getDataLabelDefaultChart(bool isTileView, [bool performIntersectAction]) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Gross investments'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, legend: Legend(isVisible: isTileView ? false : true), primaryXAxis: NumericAxis( minimum: 2006, diff --git a/lib/samples/chart/series_features/empty_point/chart_with_empty_points.dart b/lib/samples/chart/series_features/empty_point/chart_with_empty_points.dart index 7ef64997..73bf6a2b 100755 --- a/lib/samples/chart/series_features/empty_point/chart_with_empty_points.dart +++ b/lib/samples/chart/series_features/empty_point/chart_with_empty_points.dart @@ -105,7 +105,7 @@ class _FrontPanelState extends State { @override void initState() { super.initState(); - _selectedMode = _emptyPointMode.first; + _selectedMode = _emptyPointMode.first; _selectedEmptyPointMode = EmptyPointMode.gap; } diff --git a/lib/samples/chart/series_features/marker/various_marker_shapes.dart b/lib/samples/chart/series_features/marker/various_marker_shapes.dart index 4c5b2e6c..bbfad49c 100755 --- a/lib/samples/chart/series_features/marker/various_marker_shapes.dart +++ b/lib/samples/chart/series_features/marker/various_marker_shapes.dart @@ -191,7 +191,7 @@ SfCartesianChart getMarkerDefaultChart(bool isTileView) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Vehicles crossed tollgate'), legend: Legend(isVisible: isTileView ? false : true), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: DateTimeAxis( majorGridLines: MajorGridLines(width: 0), dateFormat: DateFormat.Hm(), diff --git a/lib/samples/chart/series_features/sorting/sorting_options.dart b/lib/samples/chart/series_features/sorting/sorting_options.dart index b6b01912..82b9de57 100755 --- a/lib/samples/chart/series_features/sorting/sorting_options.dart +++ b/lib/samples/chart/series_features/sorting/sorting_options.dart @@ -448,7 +448,7 @@ SfCartesianChart getDefaultSortingChart(bool isTileView, [String _sortby, SortingOrder _sortingOrder]) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : "World's tallest buildings"), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: CategoryAxis(majorGridLines: MajorGridLines(width: 0)), primaryYAxis: NumericAxis( minimum: 500, diff --git a/lib/samples/chart/user_interactions/crosshair/chart_with_crosshair.dart b/lib/samples/chart/user_interactions/crosshair/chart_with_crosshair.dart index fc57c71a..5a98a433 100755 --- a/lib/samples/chart/user_interactions/crosshair/chart_with_crosshair.dart +++ b/lib/samples/chart/user_interactions/crosshair/chart_with_crosshair.dart @@ -382,11 +382,11 @@ class _BackPanelState extends State { SfCartesianChart getDefaultCrossHairChart(bool isTileView, [bool alwaysShow, CrosshairLineType lineType, dynamic randomData]) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: DateTimeAxis( majorGridLines: MajorGridLines(width: 0), edgeLabelPlacement: EdgeLabelPlacement.shift, - crosshairTooltip: InteractiveTooltip( + interactiveTooltip: InteractiveTooltip( enable: (isTileView || lineType == CrosshairLineType.both || lineType == CrosshairLineType.vertical) @@ -400,7 +400,7 @@ SfCartesianChart getDefaultCrossHairChart(bool isTileView, lineType: isTileView ? CrosshairLineType.both : lineType), primaryYAxis: NumericAxis( axisLine: AxisLine(width: 0), - crosshairTooltip: InteractiveTooltip( + interactiveTooltip: InteractiveTooltip( enable: (isTileView || lineType == CrosshairLineType.both || lineType == CrosshairLineType.horizontal) diff --git a/lib/samples/chart/user_interactions/selection/selection_modes.dart b/lib/samples/chart/user_interactions/selection/selection_modes.dart index e48afc84..ce726750 100755 --- a/lib/samples/chart/user_interactions/selection/selection_modes.dart +++ b/lib/samples/chart/user_interactions/selection/selection_modes.dart @@ -376,7 +376,7 @@ class _BackPanelState extends State { SfCartesianChart getDefaultSelectionChart(bool isTileView, [SelectionType _mode, bool enableMultiSelect]) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, title: ChartTitle(text: isTileView ? '' : 'Age distribution by country'), selectionType: _mode, selectionGesture: ActivationMode.singleTap, diff --git a/lib/samples/chart/user_interactions/tooltip/default_tooltip.dart b/lib/samples/chart/user_interactions/tooltip/default_tooltip.dart index 09bbf196..370b99a4 100755 --- a/lib/samples/chart/user_interactions/tooltip/default_tooltip.dart +++ b/lib/samples/chart/user_interactions/tooltip/default_tooltip.dart @@ -237,7 +237,7 @@ class _BackPanelState extends State { SfCartesianChart getDefaultTooltipChart(bool isTileView) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, title: ChartTitle(text: isTileView ? '' : 'Labour force'), legend: Legend(isVisible: isTileView ? false : true), primaryXAxis: NumericAxis( diff --git a/lib/samples/chart/user_interactions/trackball/chart_with_trackball.dart b/lib/samples/chart/user_interactions/trackball/chart_with_trackball.dart index de01cba1..8182c7cf 100755 --- a/lib/samples/chart/user_interactions/trackball/chart_with_trackball.dart +++ b/lib/samples/chart/user_interactions/trackball/chart_with_trackball.dart @@ -456,7 +456,7 @@ SfCartesianChart getDefaultTrackballChart(bool isTileView, [TrackballDisplayMode _mode, ChartAlignment _alignment, bool showAlways]) { return SfCartesianChart( title: ChartTitle(text: isTileView ? '' : 'Average sales per person'), - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: DateTimeAxis( majorGridLines: MajorGridLines(width: 0), edgeLabelPlacement: EdgeLabelPlacement.shift), diff --git a/lib/samples/chart/user_interactions/zooming_panning/pinch_zooming.dart b/lib/samples/chart/user_interactions/zooming_panning/pinch_zooming.dart index 56433245..9b2bf044 100755 --- a/lib/samples/chart/user_interactions/zooming_panning/pinch_zooming.dart +++ b/lib/samples/chart/user_interactions/zooming_panning/pinch_zooming.dart @@ -368,7 +368,7 @@ class _BackPanelState extends State { SfCartesianChart getDefaultPanningChart(bool isTileView, [ZoomMode _zoomModeType]) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: DateTimeAxis(majorGridLines: MajorGridLines(width: 0)), primaryYAxis: NumericAxis( axisLine: AxisLine(width: 0), diff --git a/lib/samples/chart/user_interactions/zooming_panning/selection_zooming.dart b/lib/samples/chart/user_interactions/zooming_panning/selection_zooming.dart index 628957e8..e7676c25 100755 --- a/lib/samples/chart/user_interactions/zooming_panning/selection_zooming.dart +++ b/lib/samples/chart/user_interactions/zooming_panning/selection_zooming.dart @@ -220,7 +220,7 @@ class _BackPanelState extends State { SfCartesianChart getDefaultZoomingChart(bool isTileView) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, legend: Legend(isVisible: isTileView ? false : true, opacity: 0.8), title: ChartTitle(text: isTileView ? '' : 'Heigth vs Weight'), zoomPanBehavior: zoomingBehavior, diff --git a/lib/samples/chart/user_interactions/zooming_panning/zooming_with_custom_buttons.dart b/lib/samples/chart/user_interactions/zooming_panning/zooming_with_custom_buttons.dart index e9415580..d4c458fe 100755 --- a/lib/samples/chart/user_interactions/zooming_panning/zooming_with_custom_buttons.dart +++ b/lib/samples/chart/user_interactions/zooming_panning/zooming_with_custom_buttons.dart @@ -370,7 +370,7 @@ class _BackPanelState extends State { SfCartesianChart getButtonZoomingChart(bool isTileView) { return SfCartesianChart( - plotAreaBorderColor: Colors.transparent, + plotAreaBorderWidth: 0, primaryXAxis: NumericAxis(majorGridLines: MajorGridLines(width: 0)), primaryYAxis: NumericAxis( axisLine: AxisLine(width: 0), majorTickLines: MajorTickLines(size: 0)), diff --git a/pubspec.yaml b/pubspec.yaml index bddaf3df..2b204255 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,8 +13,8 @@ dependencies: scoped_model: 1.0.1 flutter_gallery_assets: 0.1.8 url_launcher: ^5.0.3 - intl: ^0.15.7 - syncfusion_flutter_charts: ^1.0.0-beta.1 + intl: ^0.16.0 + syncfusion_flutter_charts: ^1.0.0-beta.5 dev_dependencies: flutter_test: