-
Notifications
You must be signed in to change notification settings - Fork 36.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Qt] Add interactive mempool graph #8550
Conversation
ae05dfa
to
cb2b429
Compare
Concept ACK. Will test later. |
cb2b429
to
7650b31
Compare
Added the missing button PNGs now to git. This should fix the compile issue. |
Nice. Some people might want to see actual byte-size, weights, etc; probably will overflow the one-line-per-item paradigm quickly - maybe have a dropdown box to add stuff? |
Yes. Dropdown box could make sense. Adding a second graph below or on the right that just plots different data would probably also look good. |
src/qt/mempoolstats.cpp
Outdated
{ | ||
dynMemUsageValueItem->setPlainText(GUIUtil::formatBytes(vSamples.back().dynMemUsage)); | ||
txCountValueItem->setPlainText(QString::number(vSamples.back().txCount)); | ||
minFeeValueItem->setPlainText(QString::number(vSamples.back().minFeePerK)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Missing value. I think this is in satoshis. What about using BTC?
7650b31
to
0c6e36f
Compare
Switched to "Arial" as font and added a auto-size-adjustment. |
Nit: run optimize-pngs and mention the icons in assets_attribution? |
1944167
to
f62fae3
Compare
Optimized the pngs and added them to the assets attribution file. |
Concept ACK. |
Nit1: The graph window is always drawn on top of the main window, even when the main window is active. It makes it annoying to use the rest of the GUI while this is open. Nit2: The quantity labels for the Dynamic Memory Usage values on the left hand side of the graph are cramped and cut off some of the characters. See "500.00 KB" in the screenshot. It is like that for larger values once it gets into the 100MBs too. |
I'm not sure what I'm doing wrong but I've merged this and the graph is empty, and has been for an hour now... :-s i.e. Dynamic Memory Usage is stuck on 0 bytes, Amount of Txs also 0, MinRelayFee also zero. |
@rebroad: what does |
@jonasschnelli problem solved - I had blocksonly=1 in the config file!! It's working really nicely now - great job!! I love how it can be resized and the period of time changed without the graph resetting (unlike the network traffic graph!). Also, ACK |
Using images for basically-a-checkbox gives a non-native look on every system. It looks like we can just colour a QCheckBox? |
Rebase needed. Concept ACK Agree about checkboxes... |
f62fae3
to
d0d5c7d
Compare
Rebased on top of #8501 |
src/Makefile.qt.include
Outdated
@@ -234,6 +237,11 @@ RES_ICONS = \ | |||
qt/res/icons/bitcoin.ico \ | |||
qt/res/icons/bitcoin_testnet.ico \ | |||
qt/res/icons/bitcoin.png \ | |||
qt/res/icons/button_off.png \ | |||
qt/res/icons/button_on_blue.png \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonasschnelli What do you think about using QCheckBox
with setPallette()
as suggested by @luke-jr ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Checkboxes are appropriate for now.
But we should consider using non-standard UI elements to improve the look and feel. I know, developers hate this. :-)
But have a look at #5896. I think people liked it because the look and feel was different then just "Arial 12 and standard UI elements".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-standard UI elements ruin the look and feel...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure. That's probably a matter of taste.
The thing why I'd like to keep the non-standard UI elements is, that I'm using a QGraphicScene
at this point. Adding a QWidget
(checkbox) at this point breaks the flexibility of reusing the QGraphicScene
and draw it in any scale.
I think the checkbox could be different then the one thats currently used. And it probably should be draw internally and not use a PNG.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's a matter of taste is precisely why it should use standard UI elements. The standard element should do all the drawing. If the user doesn't like their standard widgets, they can change them.
src/main.cpp
Outdated
@@ -2837,6 +2844,9 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, | |||
for(unsigned int i=0; i < pblock->vtx.size(); i++) | |||
txChanged.push_back(std::make_tuple(pblock->vtx[i], pindexNew, i)); | |||
|
|||
// update mempool stats | |||
CStats::DefaultStats()->addMempoolSample(mempool.size(), mempool.DynamicMemoryUsage(), mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please do something with this long line? It is there ~3 times and does a simple thing - worth a better method to add a sample?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.. I think this line is reasonable? How would you improve it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass const ref. mempool only and do the rest in the method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the current layering concept. IMO its preferable that the stats.cpp
module has no knowledge over the txmempool.h
's classes, etc., I prefer to keep it as "dump" as possible.
034d89e
to
cb21388
Compare
cb21388
to
63fb116
Compare
Rebased. |
If it's a lot of work, feel free to leave "nice but not critical" features such as this out when compiling with Qt4. |
ACK with Qt5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm for some reason I'm getting this error on my system:
qt/mempoolstats.cpp: In member function ‘void MempoolStats::drawChart()’:
qt/mempoolstats.cpp:183:42: error: ‘ceil’ was not declared in this scope
maxValueSize = ceil(maxValueSize*0.11)*10; //use size steps of 10dip
^
qt/mempoolstats.cpp:256:108: error: ‘log10’ was not declared in this scope
int64_t dynMemUsagelog10Val = pow(10.0f, floor(log10(maxDynMemUsage*paddingTopSizeFactor-minDynMemUsage)));
^
qt/mempoolstats.cpp:256:109: error: ‘floor’ was not declared in this scope
int64_t dynMemUsagelog10Val = pow(10.0f, floor(log10(maxDynMemUsage*paddingTopSizeFactor-minDynMemUsage)));
^
qt/mempoolstats.cpp:256:110: error: ‘pow’ was not declared in this scope
int64_t dynMemUsagelog10Val = pow(10.0f, floor(log10(maxDynMemUsage*paddingTopSizeFactor-minDynMemUsage)));
^
I fixed it with this patch:
diff --git a/src/qt/mempoolstats.cpp b/src/qt/mempoolstats.cpp
index 139efa1a9..af33a655b 100644
--- a/src/qt/mempoolstats.cpp
+++ b/src/qt/mempoolstats.cpp
@@ -8,6 +8,7 @@
#include <qt/clientmodel.h>
#include <qt/guiutil.h>
#include <stats/stats.h>
+#include <math.h>
static const char *LABEL_FONT = "Arial";
static int LABEL_TITLE_SIZE = 22;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not need @jb55's patch on MacOS 10.13.2.
Although it can wait for a followup commit, I would prefer if more of the UI was built using interface builder (see #11950). That would it easier for other to improve the looks.
This should be easy for the header section above the chart and the duration toggles below. It's probably not realistic for the grid and X, Y axis and colored lines, although it would be nice if they can be styled using visual tools.
I left some inline comments, but didn't see any must-fix stuff.
The drawChart()
function is rather large. Some stuff needs to be drawn only once, other stuff maybe only when there's a resize. Maybe that can be split? It might be safer to move some of the calculations into their own functions and test those against boundary values.
@@ -0,0 +1,423 @@ | |||
// Copyright (c) 2016 The Bitcoin Core developers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: bump to 2018?
} | ||
|
||
// draw vertical grid | ||
int amountOfLinesV = 4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: numberOfLinesV
|
||
QPainterPath dynMemUsageGridPath(QPointF(currentX, bottom)); | ||
|
||
// draw horizontal grid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move grid drawing to a function?
|
||
if (!titleItem) | ||
{ | ||
// create labels (only once) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the once-only stuff to another function?
QCheckBox *cb0 = new QCheckBox("Dynamic Memory Usage"); | ||
cb0->setStyleSheet("background-color: rgb(255,255,255);"); | ||
dynMemUsageSwitch = scene->addWidget(cb0); | ||
connect(cb0, &QCheckBox::stateChanged, [cb0, this](){ drawDynMemUsage = cb0->isChecked(); drawChart(); }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the user interacting bits to another function?
Also, do these really need to get redrawn every time? I'm not worried about performance, just code complexity. Adding and removing UI elements where it's not needed might also make using the interface builder more difficult.
connect(model, SIGNAL(mempoolStatsDidUpdate()), this, SLOT(drawChart())); | ||
} | ||
|
||
void MempoolStats::drawChart() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to drawChartFrame()
? It draws a lot more than the chart.
allDataLabel->setPos((width()-totalWidth)/2.0+last10MinLabel->boundingRect().width()+lastHourLabel->boundingRect().width()+lastDayLabel->boundingRect().width()+30,height()-filterBottomPadding); | ||
|
||
// don't paint the grind/graph if there are no or only a signle sample | ||
if (vSamples.size() < 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drawEmptyChart()
{ | ||
noDataItem->setVisible(true); | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else {
drawChart(vSamples, ...)
}
This has been lingering for a long time. I would prefer if it makes it in, of course, it has tons of concept ACKs (the most of any open PR, according to bitcoinacks). But otherwise should we close and put this up for grabs? |
Although it would be really nice to have, this has been inactive for very long. |
@laanwj A rebased version of this seems to be in Bitcoin Knots. Should I open a new pull request using this rebased version? |
This looks very nice. @rebroad I would review/test it if you pick it up. |
Note that #8501 was updated after this, and in a conflicting way. In Knots, I'm using an older version of it. So there is some work to be done, but it sounds like a good idea since @jonasschnelli seems to have abandoned it. (If you're not up to merging #8501 with this, maybe it'd be fine to use the older version in Knots and the code can be updated later when the RPC interface is added) |
@hebasto I guess this isn't up for grabs anymore since it's been picked up again by jonasschnelli over on the GUI repo |
@hebasto This could still be up for grabs given that it was superior in various ways to the newer implementation - e.g. it could run in a separate window to the debug window - the timescales were changeable, and it also shows memory utilization, and fee filter. |
The "Up for grabs" label means "nobody's working on it", isn't it? |
Yes. If you wanted to handle it in a different way, you should have picked it up yourself. |
Or leave a suggestion on the pull that picked it up ;) |
Yes, it appears that no one is working on this - the fee graph is a different feature - related, but not the same. I think the UpForGrabs label ought to remain until someone is working on this particular graph. @luke-jr are you still rebasing this? |
A current rebase is here - rebroad@3ecfd95 |
Includes #8501
At the moment, the mempool graph is not very prominently placed (next to the debug window).

Features: