| 1220 | } |
| 1221 | |
| 1222 | void Locator_Time(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data) { |
| 1223 | IM_ASSERT_USER_ERROR(vertical == false, "Cannot locate Time ticks on vertical axis!"); |
| 1224 | (void)vertical; |
| 1225 | // get units for level 0 and level 1 labels |
| 1226 | const ImPlotTimeUnit unit0 = GetUnitForRange(range.Size() / (pixels / 100)); // level = 0 (top) |
| 1227 | const ImPlotTimeUnit unit1 = ImClamp(unit0 + 1, 0, ImPlotTimeUnit_COUNT-1); // level = 1 (bottom) |
| 1228 | // get time format specs |
| 1229 | const ImPlotDateTimeSpec fmt0 = GetDateTimeFmt(TimeFormatLevel0, unit0); |
| 1230 | const ImPlotDateTimeSpec fmt1 = GetDateTimeFmt(TimeFormatLevel1, unit1); |
| 1231 | const ImPlotDateTimeSpec fmtf = GetDateTimeFmt(TimeFormatLevel1First, unit1); |
| 1232 | // min max times |
| 1233 | const ImPlotTime t_min = ImPlotTime::FromDouble(range.Min); |
| 1234 | const ImPlotTime t_max = ImPlotTime::FromDouble(range.Max); |
| 1235 | // maximum allowable density of labels |
| 1236 | const float max_density = 0.5f; |
| 1237 | // book keeping |
| 1238 | int last_major_offset = -1; |
| 1239 | // formatter data |
| 1240 | Formatter_Time_Data ftd; |
| 1241 | ftd.UserFormatter = formatter; |
| 1242 | ftd.UserFormatterData = formatter_data; |
| 1243 | if (unit0 != ImPlotTimeUnit_Yr) { |
| 1244 | // pixels per major (level 1) division |
| 1245 | const float pix_per_major_div = pixels / (float)(range.Size() / TimeUnitSpans[unit1]); |
| 1246 | // nominal pixels taken up by labels |
| 1247 | const float fmt0_width = GetDateTimeWidth(fmt0); |
| 1248 | const float fmt1_width = GetDateTimeWidth(fmt1); |
| 1249 | const float fmtf_width = GetDateTimeWidth(fmtf); |
| 1250 | // the maximum number of minor (level 0) labels that can fit between major (level 1) divisions |
| 1251 | const int minor_per_major = (int)(max_density * pix_per_major_div / fmt0_width); |
| 1252 | // the minor step size (level 0) |
| 1253 | const int step = GetTimeStep(minor_per_major, unit0); |
| 1254 | // generate ticks |
| 1255 | ImPlotTime t1 = FloorTime(ImPlotTime::FromDouble(range.Min), unit1); |
| 1256 | while (t1 < t_max) { |
| 1257 | // get next major |
| 1258 | const ImPlotTime t2 = AddTime(t1, unit1, 1); |
| 1259 | // add major tick |
| 1260 | if (t1 >= t_min && t1 <= t_max) { |
| 1261 | // minor level 0 tick |
| 1262 | ftd.Time = t1; ftd.Spec = fmt0; |
| 1263 | ticker.AddTick(t1.ToDouble(), true, 0, true, Formatter_Time, &ftd); |
| 1264 | // major level 1 tick |
| 1265 | ftd.Time = t1; ftd.Spec = last_major_offset < 0 ? fmtf : fmt1; |
| 1266 | ImPlotTick& tick_maj = ticker.AddTick(t1.ToDouble(), true, 1, true, Formatter_Time, &ftd); |
| 1267 | const char* this_major = ticker.GetText(tick_maj); |
| 1268 | if (last_major_offset >= 0 && TimeLabelSame(ticker.TextBuffer.Buf.Data + last_major_offset, this_major)) |
| 1269 | tick_maj.ShowLabel = false; |
| 1270 | last_major_offset = tick_maj.TextOffset; |
| 1271 | } |
| 1272 | // add minor ticks up until next major |
| 1273 | if (minor_per_major > 1 && (t_min <= t2 && t1 <= t_max)) { |
| 1274 | ImPlotTime t12 = AddTime(t1, unit0, step); |
| 1275 | while (t12 < t2) { |
| 1276 | float px_to_t2 = (float)((t2 - t12).ToDouble()/range.Size()) * pixels; |
| 1277 | if (t12 >= t_min && t12 <= t_max) { |
| 1278 | ftd.Time = t12; ftd.Spec = fmt0; |
| 1279 | ticker.AddTick(t12.ToDouble(), false, 0, px_to_t2 >= fmt0_width, Formatter_Time, &ftd); |
nothing calls this directly
no test coverage detected