| 1258 | } |
| 1259 | |
| 1260 | void Locator_Time(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data) { |
| 1261 | IM_ASSERT_USER_ERROR(vertical == false, "Cannot locate Time ticks on vertical axis!"); |
| 1262 | (void)vertical; |
| 1263 | // get units for level 0 and level 1 labels |
| 1264 | const ImPlotTimeUnit unit0 = GetUnitForRange(range.Size() / (pixels / 100)); // level = 0 (top) |
| 1265 | const ImPlotTimeUnit unit1 = ImClamp(unit0 + 1, 0, ImPlotTimeUnit_COUNT-1); // level = 1 (bottom) |
| 1266 | // get time format specs |
| 1267 | const ImPlotDateTimeSpec fmt0 = GetDateTimeFmt(TimeFormatLevel0, unit0); |
| 1268 | const ImPlotDateTimeSpec fmt1 = GetDateTimeFmt(TimeFormatLevel1, unit1); |
| 1269 | const ImPlotDateTimeSpec fmtf = GetDateTimeFmt(TimeFormatLevel1First, unit1); |
| 1270 | // min max times |
| 1271 | const ImPlotTime t_min = ImPlotTime::FromDouble(range.Min); |
| 1272 | const ImPlotTime t_max = ImPlotTime::FromDouble(range.Max); |
| 1273 | // maximum allowable density of labels |
| 1274 | const float max_density = 0.5f; |
| 1275 | // book keeping |
| 1276 | int last_major_offset = -1; |
| 1277 | // formatter data |
| 1278 | Formatter_Time_Data ftd; |
| 1279 | ftd.UserFormatter = formatter; |
| 1280 | ftd.UserFormatterData = formatter_data; |
| 1281 | if (unit0 != ImPlotTimeUnit_Yr) { |
| 1282 | // pixels per major (level 1) division |
| 1283 | const float pix_per_major_div = pixels / (float)(range.Size() / TimeUnitSpans[unit1]); |
| 1284 | // nominal pixels taken up by labels |
| 1285 | const float fmt0_width = GetDateTimeWidth(fmt0); |
| 1286 | const float fmt1_width = GetDateTimeWidth(fmt1); |
| 1287 | const float fmtf_width = GetDateTimeWidth(fmtf); |
| 1288 | // the maximum number of minor (level 0) labels that can fit between major (level 1) divisions |
| 1289 | const int minor_per_major = (int)(max_density * pix_per_major_div / fmt0_width); |
| 1290 | // the minor step size (level 0) |
| 1291 | const int step = GetTimeStep(minor_per_major, unit0); |
| 1292 | // generate ticks |
| 1293 | ImPlotTime t1 = FloorTime(ImPlotTime::FromDouble(range.Min), unit1); |
| 1294 | while (t1 < t_max) { |
| 1295 | // get next major |
| 1296 | const ImPlotTime t2 = AddTime(t1, unit1, 1); |
| 1297 | // add major tick |
| 1298 | if (t1 >= t_min && t1 <= t_max) { |
| 1299 | // minor level 0 tick |
| 1300 | ftd.Time = t1; ftd.Spec = fmt0; |
| 1301 | ticker.AddTick(t1.ToDouble(), true, 0, true, Formatter_Time, &ftd); |
| 1302 | // major level 1 tick |
| 1303 | ftd.Time = t1; ftd.Spec = last_major_offset < 0 ? fmtf : fmt1; |
| 1304 | ImPlotTick& tick_maj = ticker.AddTick(t1.ToDouble(), true, 1, true, Formatter_Time, &ftd); |
| 1305 | const char* this_major = ticker.GetText(tick_maj); |
| 1306 | if (last_major_offset >= 0 && TimeLabelSame(ticker.TextBuffer.Buf.Data + last_major_offset, this_major)) |
| 1307 | tick_maj.ShowLabel = false; |
| 1308 | last_major_offset = tick_maj.TextOffset; |
| 1309 | } |
| 1310 | // add minor ticks up until next major |
| 1311 | if (minor_per_major > 1 && (t_min <= t2 && t1 <= t_max)) { |
| 1312 | ImPlotTime t12 = AddTime(t1, unit0, step); |
| 1313 | while (t12 < t2) { |
| 1314 | float px_to_t2 = (float)((t2 - t12).ToDouble()/range.Size()) * pixels; |
| 1315 | if (t12 >= t_min && t12 <= t_max) { |
| 1316 | ftd.Time = t12; ftd.Spec = fmt0; |
| 1317 | ticker.AddTick(t12.ToDouble(), false, 0, px_to_t2 >= fmt0_width, Formatter_Time, &ftd); |
nothing calls this directly
no test coverage detected