mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
The flux visualiser now uses a density map for better displaying when zoomed
out.
This commit is contained in:
@@ -13,8 +13,9 @@ DECLARE_COLOUR(FOREGROUND, 0, 0, 0);
|
||||
DECLARE_COLOUR(FLUX, 64, 64, 255);
|
||||
DECLARE_COLOUR(RECORD, 255, 255, 255);
|
||||
|
||||
const int BORDER = 10;
|
||||
const int BORDER = 4;
|
||||
const int MINIMUM_TICK_DISTANCE = 10;
|
||||
const double RENDER_LIMIT = 3000.0;
|
||||
|
||||
FluxViewerControl::FluxViewerControl(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
@@ -50,15 +51,48 @@ void FluxViewerControl::SetFlux(std::shared_ptr<const TrackFlux> flux)
|
||||
auto size = GetSize();
|
||||
_nanosecondsPerPixel = (double)_totalDuration / (double)size.GetWidth();
|
||||
|
||||
ResizeScrollbar();
|
||||
UpdateScale();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void FluxViewerControl::ResizeScrollbar()
|
||||
void FluxViewerControl::UpdateScale()
|
||||
{
|
||||
auto size = GetSize();
|
||||
nanoseconds_t thumbSize = size.GetWidth() * _nanosecondsPerPixel;
|
||||
_scrollbar->SetScrollbar(_scrollPosition/1000, thumbSize/1000, _totalDuration/1000, thumbSize/2000);
|
||||
|
||||
int totalPixels = (_totalDuration / _nanosecondsPerPixel) + 1;
|
||||
if ((totalPixels != _densityMap.size()) && (_nanosecondsPerPixel > RENDER_LIMIT))
|
||||
{
|
||||
_densityMap.resize(totalPixels);
|
||||
std::fill(_densityMap.begin(), _densityMap.end(), 0.0);
|
||||
|
||||
int i = 0;
|
||||
for (const auto& trackdata : _flux->trackDatas)
|
||||
{
|
||||
FluxmapReader fmr(*trackdata->fluxmap);
|
||||
while (!fmr.eof())
|
||||
{
|
||||
unsigned ticks;
|
||||
if (!fmr.findEvent(F_BIT_PULSE, ticks))
|
||||
break;
|
||||
|
||||
int fx = fmr.tell().ns() / _nanosecondsPerPixel;
|
||||
_densityMap.at(i + fx)++;
|
||||
}
|
||||
i += trackdata->fluxmap->duration() / _nanosecondsPerPixel;
|
||||
}
|
||||
|
||||
double max = *std::max_element(_densityMap.begin(), _densityMap.end());
|
||||
for (auto& d : _densityMap)
|
||||
d /= max;
|
||||
}
|
||||
}
|
||||
|
||||
static int interpolate(int lo, int hi, float factor)
|
||||
{
|
||||
float range = hi - lo;
|
||||
return lo + range*factor;
|
||||
}
|
||||
|
||||
void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
@@ -128,6 +162,20 @@ void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
tickCount++;
|
||||
}
|
||||
|
||||
if (x <= 0)
|
||||
dc.DrawText(
|
||||
fmt::format("{}us", (int)(_scrollPosition / 1000LL)),
|
||||
{ BORDER, t3y + ch2/2 }
|
||||
);
|
||||
|
||||
if ((x+fw) >= w)
|
||||
{
|
||||
wxString text = fmt::format(
|
||||
"{}us", (int)((_scrollPosition + (w * _nanosecondsPerPixel)) / 1000LL));
|
||||
auto size = dc.GetTextExtent(text);
|
||||
dc.DrawText(text, { w - size.GetWidth() - BORDER, t3y + ch2/2 });
|
||||
}
|
||||
|
||||
/* Sector blocks. */
|
||||
|
||||
for (const auto& sector : trackdata->sectors)
|
||||
@@ -155,7 +203,30 @@ void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
/* Flux chart. */
|
||||
|
||||
dc.SetPen(FLUX_PEN);
|
||||
dc.DrawLine({x, t4y}, {x+fw, t4y});
|
||||
if (_nanosecondsPerPixel > RENDER_LIMIT)
|
||||
{
|
||||
/* Draw using density map. */
|
||||
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
for (int fx = 0; fx < _densityMap.size(); fx++)
|
||||
{
|
||||
if (((x+fx) > 0) && ((x+fx) < w))
|
||||
{
|
||||
float density = _densityMap[fx];
|
||||
wxColour colour(
|
||||
interpolate(BACKGROUND_COLOUR.Red(), FLUX_COLOUR.Red(), density),
|
||||
interpolate(BACKGROUND_COLOUR.Green(), FLUX_COLOUR.Green(), density),
|
||||
interpolate(BACKGROUND_COLOUR.Blue(), FLUX_COLOUR.Blue(), density));
|
||||
wxBrush brush(colour);
|
||||
dc.SetBrush(brush);
|
||||
dc.DrawRectangle({x+fx, t4y - ch2}, {1, ch});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Draw discrete pulses. */
|
||||
|
||||
FluxmapReader fmr(*trackdata->fluxmap);
|
||||
while (!fmr.eof())
|
||||
{
|
||||
@@ -164,7 +235,8 @@ void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
fmr.getNextEvent(event, ticks);
|
||||
|
||||
int fx = fmr.tell().ns() / _nanosecondsPerPixel;
|
||||
|
||||
if (((x+fx) > 0) && ((x+fx) < w))
|
||||
{
|
||||
if (event & F_BIT_INDEX)
|
||||
{
|
||||
dc.SetPen(INDEX_SEPARATOR_PEN);
|
||||
@@ -176,6 +248,11 @@ void FluxViewerControl::OnPaint(wxPaintEvent&)
|
||||
dc.DrawLine({x+fx, t4y - ch2}, {x+fx, t4y + ch2});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dc.SetPen(FLUX_PEN);
|
||||
dc.DrawLine({x, t4y}, {x+fw, t4y});
|
||||
}
|
||||
|
||||
x += w;
|
||||
}
|
||||
@@ -193,7 +270,7 @@ void FluxViewerControl::OnMouseWheel(wxMouseEvent& event)
|
||||
_nanosecondsPerPixel *= 1.2;
|
||||
_scrollPosition -= x * _nanosecondsPerPixel;
|
||||
|
||||
ResizeScrollbar();
|
||||
UpdateScale();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
void SetFlux(std::shared_ptr<const TrackFlux> flux);
|
||||
|
||||
private:
|
||||
void ResizeScrollbar();
|
||||
void UpdateScale();
|
||||
|
||||
private:
|
||||
void OnPaint(wxPaintEvent&);
|
||||
@@ -34,6 +34,7 @@ private:
|
||||
nanoseconds_t _scrollPosition;
|
||||
nanoseconds_t _totalDuration;
|
||||
double _nanosecondsPerPixel;
|
||||
std::vector<float> _densityMap;
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user