@@ -2216,57 +2216,121 @@ IMPLOT_INLINE void RenderPieSlice(ImDrawList& draw_list, const ImPlotPoint& cent
22162216}
22172217
22182218template <typename T>
2219- void PlotPieChart (const char * const label_ids[], const T* values, int count, double x, double y, double radius, const char * fmt, double angle0, ImPlotPieChartFlags flags) {
2220- IM_ASSERT_USER_ERROR (GImPlot->CurrentPlot != nullptr , " PlotPieChart() needs to be called between BeginPlot() and EndPlot()!" );
2221- ImDrawList & draw_list = *GetPlotDrawList ();
2219+ double PieChartSum (const T* values, int count, bool ignore_hidden) {
22222220 double sum = 0 ;
2223- for (int i = 0 ; i < count; ++i)
2224- sum += (double )values[i];
2225- const bool normalize = ImHasFlag (flags,ImPlotPieChartFlags_Normalize) || sum > 1.0 ;
2226- ImPlotPoint center (x,y);
2227- PushPlotClipRect ();
2221+ if (ignore_hidden) {
2222+ ImPlotContext& gp = *GImPlot;
2223+ ImPlotItemGroup& Items = *gp.CurrentItems ;
2224+ for (int i = 0 ; i < count; ++i) {
2225+ if (i >= Items.GetItemCount ())
2226+ break ;
2227+
2228+ ImPlotItem* item = Items.GetItemByIndex (i);
2229+ IM_ASSERT (item != nullptr );
2230+ if (item->Show ) {
2231+ sum += (double )values[i];
2232+ }
2233+ }
2234+ }
2235+ else {
2236+ for (int i = 0 ; i < count; ++i) {
2237+ sum += (double )values[i];
2238+ }
2239+ }
2240+ return sum;
2241+ }
2242+
2243+ template <typename T>
2244+ void PlotPieChartEx (const char * const label_ids[], const T* values, int count, ImPlotPoint center, double radius, double angle0, ImPlotPieChartFlags flags) {
2245+ ImDrawList& draw_list = *GetPlotDrawList ();
2246+
2247+ const bool ignore_hidden = ImHasFlag (flags, ImPlotPieChartFlags_IgnoreHidden);
2248+ const double sum = PieChartSum (values, count, ignore_hidden);
2249+ const bool normalize = ImHasFlag (flags, ImPlotPieChartFlags_Normalize) || sum > 1.0 ;
2250+
22282251 double a0 = angle0 * 2 * IM_PI / 360.0 ;
22292252 double a1 = angle0 * 2 * IM_PI / 360.0 ;
2230- ImPlotPoint Pmin = ImPlotPoint (x- radius,y- radius);
2231- ImPlotPoint Pmax = ImPlotPoint (x+ radius,y+ radius);
2253+ ImPlotPoint Pmin = ImPlotPoint (center. x - radius, center. y - radius);
2254+ ImPlotPoint Pmax = ImPlotPoint (center. x + radius, center. y + radius);
22322255 for (int i = 0 ; i < count; ++i) {
2233- double percent = normalize ? (double )values[i] / sum : (double )values[i];
2234- a1 = a0 + 2 * IM_PI * percent;
2235- if (BeginItemEx (label_ids[i], FitterRect (Pmin,Pmax))) {
2236- ImU32 col = GetCurrentItem ()->Color ;
2237- if (percent < 0.5 ) {
2238- RenderPieSlice (draw_list, center, radius, a0, a1, col);
2239- }
2240- else {
2241- RenderPieSlice (draw_list, center, radius, a0, a0 + (a1 - a0) * 0.5 , col);
2242- RenderPieSlice (draw_list, center, radius, a0 + (a1 - a0) * 0.5 , a1, col);
2256+ ImPlotItem* item = GetItem (label_ids[i]);
2257+
2258+ const double percent = normalize ? (double )values[i] / sum : (double )values[i];
2259+ const bool skip = sum <= 0.0 || (ignore_hidden && item != nullptr && !item->Show );
2260+ if (!skip)
2261+ a1 = a0 + 2 * IM_PI * percent;
2262+
2263+ if (BeginItemEx (label_ids[i], FitterRect (Pmin, Pmax))) {
2264+ if (sum > 0.0 ) {
2265+ ImU32 col = GetCurrentItem ()->Color ;
2266+ if (percent < 0.5 ) {
2267+ RenderPieSlice (draw_list, center, radius, a0, a1, col);
2268+ }
2269+ else {
2270+ RenderPieSlice (draw_list, center, radius, a0, a0 + (a1 - a0) * 0.5 , col);
2271+ RenderPieSlice (draw_list, center, radius, a0 + (a1 - a0) * 0.5 , a1, col);
2272+ }
22432273 }
22442274 EndItem ();
22452275 }
2246- a0 = a1;
2276+ if (!skip)
2277+ a0 = a1;
22472278 }
2279+ }
2280+
2281+ int PieChartFormatter (double value, char * buff, int size, void * data) {
2282+ const char * fmt = (const char *)data;
2283+ return snprintf (buff, size, fmt, value);
2284+ };
2285+
2286+ template <typename T>
2287+ void PlotPieChart (const char * const label_ids[], const T* values, int count, double x, double y, double radius, const char * fmt, double angle0, ImPlotPieChartFlags flags) {
2288+ PlotPieChart<T>(label_ids, values, count, x, y, radius, PieChartFormatter, (void *)fmt, angle0, flags);
2289+ }
2290+ #define INSTANTIATE_MACRO (T ) template IMPLOT_API void PlotPieChart<T>(const char * const label_ids[], const T* values, int count, double x, double y, double radius, const char * fmt, double angle0, ImPlotPieChartFlags flags);
2291+ CALL_INSTANTIATE_FOR_NUMERIC_TYPES ()
2292+ #undef INSTANTIATE_MACRO
2293+
2294+ template <typename T>
2295+ void PlotPieChart (const char * const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void * fmt_data, double angle0, ImPlotPieChartFlags flags) {
2296+ IM_ASSERT_USER_ERROR (GImPlot->CurrentPlot != nullptr , " PlotPieChart() needs to be called between BeginPlot() and EndPlot()!" );
2297+ ImDrawList& draw_list = *GetPlotDrawList ();
2298+
2299+ const bool ignore_hidden = ImHasFlag (flags, ImPlotPieChartFlags_IgnoreHidden);
2300+ const double sum = PieChartSum (values, count, ignore_hidden);
2301+ const bool normalize = ImHasFlag (flags, ImPlotPieChartFlags_Normalize) || sum > 1.0 ;
2302+ ImPlotPoint center (x, y);
2303+
2304+ PushPlotClipRect ();
2305+ PlotPieChartEx (label_ids, values, count, center, radius, angle0, flags);
22482306 if (fmt != nullptr ) {
2249- a0 = angle0 * 2 * IM_PI / 360.0 ;
2250- a1 = angle0 * 2 * IM_PI / 360.0 ;
2307+ double a0 = angle0 * 2 * IM_PI / 360.0 ;
2308+ double a1 = angle0 * 2 * IM_PI / 360.0 ;
22512309 char buffer[32 ];
22522310 for (int i = 0 ; i < count; ++i) {
22532311 ImPlotItem* item = GetItem (label_ids[i]);
2254- double percent = normalize ? (double )values[i] / sum : (double )values[i];
2255- a1 = a0 + 2 * IM_PI * percent;
2256- if (item->Show ) {
2257- ImFormatString (buffer, 32 , fmt, (double )values[i]);
2258- ImVec2 size = ImGui::CalcTextSize (buffer);
2259- double angle = a0 + (a1 - a0) * 0.5 ;
2260- ImVec2 pos = PlotToPixels (center.x + 0.5 * radius * cos (angle), center.y + 0.5 * radius * sin (angle),IMPLOT_AUTO,IMPLOT_AUTO);
2261- ImU32 col = CalcTextColor (ImGui::ColorConvertU32ToFloat4 (item->Color ));
2262- draw_list.AddText (pos - size * 0 .5f , col, buffer);
2312+ IM_ASSERT (item != nullptr );
2313+
2314+ const double percent = normalize ? (double )values[i] / sum : (double )values[i];
2315+ const bool skip = ignore_hidden && item != nullptr && !item->Show ;
2316+
2317+ if (!skip) {
2318+ a1 = a0 + 2 * IM_PI * percent;
2319+ if (item->Show ) {
2320+ fmt ((double )values[i], buffer, 32 , fmt_data);
2321+ ImVec2 size = ImGui::CalcTextSize (buffer);
2322+ double angle = a0 + (a1 - a0) * 0.5 ;
2323+ ImVec2 pos = PlotToPixels (center.x + 0.5 * radius * cos (angle), center.y + 0.5 * radius * sin (angle), IMPLOT_AUTO, IMPLOT_AUTO);
2324+ ImU32 col = CalcTextColor (ImGui::ColorConvertU32ToFloat4 (item->Color ));
2325+ draw_list.AddText (pos - size * 0 .5f , col, buffer);
2326+ }
2327+ a0 = a1;
22632328 }
2264- a0 = a1;
22652329 }
22662330 }
22672331 PopPlotClipRect ();
22682332}
2269- #define INSTANTIATE_MACRO (T ) template IMPLOT_API void PlotPieChart<T> (const char * const label_ids[], const T* values, int count, double x, double y, double radius, const char * fmt , double angle0, ImPlotPieChartFlags flags);
2333+ #define INSTANTIATE_MACRO (T ) template IMPLOT_API void PlotPieChart (const char * const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void * fmt_data , double angle0, ImPlotPieChartFlags flags);
22702334CALL_INSTANTIATE_FOR_NUMERIC_TYPES ()
22712335#undef INSTANTIATE_MACRO
22722336
0 commit comments