| 3279 | |
| 3280 | template <typename T> |
| 3281 | double PlotHistogram2D(const char* label_id, const T* xs, const T* ys, int count, int x_bins, int y_bins, ImPlotRect range, const ImPlotSpec& spec) { |
| 3282 | |
| 3283 | // const bool cumulative = ImHasFlag(flags, ImPlotHistogramFlags_Cumulative); NOT SUPPORTED |
| 3284 | const bool density = ImHasFlag(spec.Flags, ImPlotHistogramFlags_Density); |
| 3285 | const bool outliers = !ImHasFlag(spec.Flags, ImPlotHistogramFlags_NoOutliers); |
| 3286 | const bool col_maj = ImHasFlag(spec.Flags, ImPlotHistogramFlags_ColMajor); |
| 3287 | |
| 3288 | IndexerIdx<T> indexer_x(xs,count,spec.Offset,Stride<T>(spec)); |
| 3289 | IndexerIdx<T> indexer_y(ys,count,spec.Offset,Stride<T>(spec)); |
| 3290 | |
| 3291 | if (count <= 0 || x_bins == 0 || y_bins == 0) |
| 3292 | return 0; |
| 3293 | |
| 3294 | if (range.X.Min == 0 && range.X.Max == 0) { |
| 3295 | ImMinMaxIndexer(indexer_x, count, &range.X.Min, &range.X.Min); |
| 3296 | } |
| 3297 | if (range.Y.Min == 0 && range.Y.Max == 0) { |
| 3298 | ImMinMaxIndexer(indexer_y, count, &range.Y.Min, &range.Y.Max); |
| 3299 | } |
| 3300 | |
| 3301 | double width, height; |
| 3302 | if (x_bins < 0) |
| 3303 | CalculateBins(indexer_x, count, x_bins, range.X, x_bins, width); |
| 3304 | else |
| 3305 | width = range.X.Size() / x_bins; |
| 3306 | if (y_bins < 0) |
| 3307 | CalculateBins(indexer_y, count, y_bins, range.Y, y_bins, height); |
| 3308 | else |
| 3309 | height = range.Y.Size() / y_bins; |
| 3310 | |
| 3311 | const int bins = x_bins * y_bins; |
| 3312 | |
| 3313 | ImPlotContext& gp = *GImPlot; |
| 3314 | ImVector<double>& bin_counts = gp.TempDouble1; |
| 3315 | bin_counts.resize(bins); |
| 3316 | |
| 3317 | for (int b = 0; b < bins; ++b) |
| 3318 | bin_counts[b] = 0; |
| 3319 | |
| 3320 | int counted = 0; |
| 3321 | double max_count = 0; |
| 3322 | for (int i = 0; i < count; ++i) { |
| 3323 | if (range.Contains(indexer_x[i], indexer_y[i])) { |
| 3324 | const int xb = ImClamp( (int)((indexer_x[i] - range.X.Min) / width) , 0, x_bins - 1); |
| 3325 | const int yb = ImClamp( (int)((indexer_y[i] - range.Y.Min) / height) , 0, y_bins - 1); |
| 3326 | const int b = yb * x_bins + xb; |
| 3327 | bin_counts[b] += 1.0; |
| 3328 | if (bin_counts[b] > max_count) |
| 3329 | max_count = bin_counts[b]; |
| 3330 | counted++; |
| 3331 | } |
| 3332 | } |
| 3333 | if (density) { |
| 3334 | double scale = 1.0 / ((outliers ? count : counted) * width * height); |
| 3335 | for (int b = 0; b < bins; ++b) |
| 3336 | bin_counts[b] *= scale; |
| 3337 | max_count *= scale; |
| 3338 | } |
no test coverage detected