mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-26 08:01:51 +08:00
#31 [Gui] Arbitrary values viewer: fixed performance problem, added icons for chart types
This commit is contained in:
parent
3608ec1a56
commit
87bc825980
@ -55,13 +55,16 @@
|
||||
#include <QAction>
|
||||
#include <QActionGroup>
|
||||
#include <QColor>
|
||||
#include <QComboBox>
|
||||
#include <QGraphicsScene>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QResizeEvent>
|
||||
#include <QSettings>
|
||||
#include <QSpinBox>
|
||||
#include <QSplitter>
|
||||
#include <QToolBar>
|
||||
#include <QVariant>
|
||||
@ -77,37 +80,77 @@
|
||||
EASY_CONSTEXPR int ChartBound = 2; ///< Top and bottom bounds for chart
|
||||
EASY_CONSTEXPR int ChartBounds = ChartBound << 1;
|
||||
|
||||
template <size_t window_size>
|
||||
std::vector<QPointF> gauss(const std::vector<QPointF>& _points)
|
||||
void gaussFilter(std::vector<QPointF>& _points, int _windowSize, const std::atomic_bool& _interrupt)
|
||||
{
|
||||
if (_points.size() < 3)
|
||||
return _points;
|
||||
if (_points.size() < 3 || _windowSize < 3 || _interrupt.load(std::memory_order_acquire))
|
||||
return;
|
||||
|
||||
std::vector<QPointF> out;
|
||||
out.reserve(_points.size());
|
||||
|
||||
for (size_t i = 0, size = _points.size(); i < size; ++i)
|
||||
{
|
||||
if (_interrupt.load(std::memory_order_acquire))
|
||||
return;
|
||||
|
||||
const auto next = i + 1;
|
||||
if (next < window_size)
|
||||
qreal sum = 0;
|
||||
|
||||
if (static_cast<int>(next) < _windowSize)
|
||||
{
|
||||
qreal sum = 0;
|
||||
for (size_t j = 0; j <= i; ++j)
|
||||
sum += _points[j].y();
|
||||
sum /= i + 1;
|
||||
out.emplace_back(_points[i].x(), sum);
|
||||
}
|
||||
else
|
||||
{
|
||||
qreal sum = 0;
|
||||
for (size_t j = next - window_size; j <= i; ++j)
|
||||
for (size_t j = next - _windowSize; j <= i; ++j)
|
||||
sum += _points[j].y();
|
||||
sum /= window_size;
|
||||
out.emplace_back(_points[i].x(), sum);
|
||||
sum /= _windowSize;
|
||||
}
|
||||
|
||||
out.emplace_back(_points[i].x(), sum);
|
||||
}
|
||||
|
||||
return out;
|
||||
_points = std::move(out);
|
||||
}
|
||||
|
||||
void medianFilter(std::vector<QPointF>& _points, int _windowSize, const std::atomic_bool& _interrupt)
|
||||
{
|
||||
if (_points.size() < 3 || _windowSize < 3 || _interrupt.load(std::memory_order_acquire))
|
||||
return;
|
||||
|
||||
const auto windowSizeHalf = _windowSize >> 1;
|
||||
|
||||
std::vector<QPointF> out;
|
||||
out.reserve(_points.size());
|
||||
|
||||
std::vector<qreal> window(static_cast<size_t>(_windowSize));
|
||||
|
||||
for (size_t i = 0, size = _points.size(); i < size; ++i)
|
||||
{
|
||||
if (_interrupt.load(std::memory_order_acquire))
|
||||
return;
|
||||
|
||||
const auto next = i + 1;
|
||||
if (next < windowSizeHalf)
|
||||
{
|
||||
int k = 0;
|
||||
for (int j = static_cast<int>(next) - windowSizeHalf; k < _windowSize; ++j, ++k)
|
||||
window[k] = _points[abs(j)].y();
|
||||
}
|
||||
else
|
||||
{
|
||||
int k = 0;
|
||||
for (size_t j = next - windowSizeHalf; k < _windowSize; ++j, ++k)
|
||||
window[k] = _points[j].y();
|
||||
}
|
||||
|
||||
std::sort(window.begin(), window.end());
|
||||
out.emplace_back(_points[i].x(), window[windowSizeHalf]);
|
||||
}
|
||||
|
||||
_points = std::move(out);
|
||||
}
|
||||
|
||||
void getChartPoints(const ArbitraryValuesCollection& _collection, Points& _points, qreal& _minValue, qreal& _maxValue)
|
||||
@ -599,7 +642,9 @@ ArbitraryValuesChartItem::ArbitraryValuesChartItem()
|
||||
, m_workerMinDuration(0)
|
||||
, m_maxDuration(0)
|
||||
, m_minDuration(0)
|
||||
, m_filterWindowSize(8)
|
||||
, m_chartType(ChartType::Regular)
|
||||
, m_filterType(FilterType::None)
|
||||
{
|
||||
}
|
||||
|
||||
@ -760,6 +805,8 @@ void ArbitraryValuesChartItem::onImageUpdated()
|
||||
{
|
||||
m_maxValue = m_workerMaxValue;
|
||||
m_minValue = m_workerMinValue;
|
||||
m_maxDuration = m_workerMaxDuration;
|
||||
m_minDuration = m_workerMinDuration;
|
||||
}
|
||||
|
||||
void ArbitraryValuesChartItem::drawGrid(QPainter& _painter, int _width, int _height) const
|
||||
@ -1235,7 +1282,29 @@ void ArbitraryValuesChartItem::updateComplexityImageAsync(QRectF _boundingRect,
|
||||
|
||||
if (drawApproximateLine)
|
||||
{
|
||||
p.drawPolyline(averages.data(), static_cast<int>(averages.size()));
|
||||
// drawPolyLine() with 2 pixel width is VERY slow! Do not use it!
|
||||
//p.drawPolyline(averages.data(), static_cast<int>(averages.size()));
|
||||
|
||||
// Draw polyline
|
||||
{
|
||||
QPointF p1 = averages.front();
|
||||
|
||||
auto averages_it = averages.begin();
|
||||
for (++averages_it; averages_it != averages.end(); ++averages_it)
|
||||
{
|
||||
if (isReady())
|
||||
return;
|
||||
|
||||
const QPointF& p2 = *averages_it;
|
||||
const auto dx = fabs(p2.x() - p1.x()), dy = fabs(p2.y() - p1.y());
|
||||
if (dx > 1 || dy > 1)
|
||||
p.drawLine(p1, p2);
|
||||
else
|
||||
continue;
|
||||
|
||||
p1 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
auto color = profiler_gui::darken(c.color, 0.65f);
|
||||
if (profiler_gui::alpha(color) < 0xc0)
|
||||
@ -1265,13 +1334,31 @@ void ArbitraryValuesChartItem::updateComplexityImageAsync(QRectF _boundingRect,
|
||||
pen.setWidth(2);
|
||||
p.setPen(pen);
|
||||
|
||||
//averages = std::move(gauss<8>(averages));
|
||||
switch (m_filterType)
|
||||
{
|
||||
case FilterType::Median:
|
||||
medianFilter(averages, m_filterWindowSize, m_bReady);
|
||||
break;
|
||||
|
||||
case FilterType::Gauss:
|
||||
gaussFilter(averages, m_filterWindowSize, m_bReady);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (isReady())
|
||||
return;
|
||||
|
||||
QPainterPath pp;
|
||||
pp.moveTo(averages.front());
|
||||
const size_t step = std::max(averages.size() / (size_t)40, (size_t)1);
|
||||
for (size_t k = 3 * step; k < averages.size(); k += 4 * step)
|
||||
{
|
||||
if (isReady())
|
||||
return;
|
||||
|
||||
pp.cubicTo(averages[k - 2 * step], averages[k - 1 * step], averages[k]);
|
||||
}
|
||||
|
||||
@ -1309,12 +1396,44 @@ void ArbitraryValuesChartItem::update(const ArbitraryValuesCollection* _selected
|
||||
|
||||
void ArbitraryValuesChartItem::setChartType(ChartType _chartType)
|
||||
{
|
||||
if (m_chartType != _chartType)
|
||||
if (m_chartType == _chartType)
|
||||
return;
|
||||
|
||||
cancelImageUpdate();
|
||||
m_chartType = _chartType;
|
||||
updateImage();
|
||||
}
|
||||
|
||||
void ArbitraryValuesChartItem::setFilterType(FilterType _filterType)
|
||||
{
|
||||
if (m_filterType == _filterType)
|
||||
return;
|
||||
|
||||
if (m_chartType == ChartType::Regular)
|
||||
{
|
||||
cancelImageUpdate();
|
||||
m_chartType = _chartType;
|
||||
updateImage();
|
||||
m_filterType = _filterType;
|
||||
return;
|
||||
}
|
||||
|
||||
cancelImageUpdate();
|
||||
m_filterType = _filterType;
|
||||
updateImage();
|
||||
}
|
||||
|
||||
void ArbitraryValuesChartItem::setFilterWindowSize(int _size)
|
||||
{
|
||||
if (m_filterWindowSize == _size)
|
||||
return;
|
||||
|
||||
if (m_chartType == ChartType::Regular || m_filterType == FilterType::None)
|
||||
{
|
||||
m_filterWindowSize = _size;
|
||||
return;
|
||||
}
|
||||
|
||||
cancelImageUpdate();
|
||||
m_filterWindowSize = _size;
|
||||
updateImage();
|
||||
}
|
||||
|
||||
ChartType ArbitraryValuesChartItem::chartType() const
|
||||
@ -1322,6 +1441,16 @@ ChartType ArbitraryValuesChartItem::chartType() const
|
||||
return m_chartType;
|
||||
}
|
||||
|
||||
FilterType ArbitraryValuesChartItem::filterType() const
|
||||
{
|
||||
return m_filterType;
|
||||
}
|
||||
|
||||
int ArbitraryValuesChartItem::filterWindowSize() const
|
||||
{
|
||||
return m_filterWindowSize;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GraphicsChart::GraphicsChart(QWidget* _parent)
|
||||
@ -1378,11 +1507,31 @@ void GraphicsChart::setChartType(ChartType _chartType)
|
||||
m_slider->setVisible(_chartType != ChartType::Complexity && !m_bBindMode);
|
||||
}
|
||||
|
||||
void GraphicsChart::setFilterType(FilterType _filterType)
|
||||
{
|
||||
m_chartItem->setFilterType(_filterType);
|
||||
}
|
||||
|
||||
void GraphicsChart::setFilterWindowSize(int _size)
|
||||
{
|
||||
m_chartItem->setFilterWindowSize(_size);
|
||||
}
|
||||
|
||||
ChartType GraphicsChart::chartType() const
|
||||
{
|
||||
return m_chartItem->chartType();
|
||||
}
|
||||
|
||||
FilterType GraphicsChart::filterType() const
|
||||
{
|
||||
return m_chartItem->filterType();
|
||||
}
|
||||
|
||||
int GraphicsChart::filterWindowSize() const
|
||||
{
|
||||
return m_chartItem->filterWindowSize();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum class ArbitraryColumns : uint8_t
|
||||
@ -1493,6 +1642,10 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
||||
, m_splitter(new QSplitter(Qt::Horizontal, this))
|
||||
, m_treeWidget(new QTreeWidget(this))
|
||||
, m_chart(new GraphicsChart(this))
|
||||
, m_filterBoxLabel(new QLabel(tr(" Approx filter:"), this))
|
||||
, m_filterComboBox(new QComboBox(this))
|
||||
, m_filterWindowLabel(new QLabel(tr(" Window size:"), this))
|
||||
, m_filterWindowPicker(new QSpinBox(this))
|
||||
, m_boldItem(nullptr)
|
||||
{
|
||||
m_splitter->setHandleWidth(1);
|
||||
@ -1502,6 +1655,15 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
||||
m_splitter->setStretchFactor(0, 1);
|
||||
m_splitter->setStretchFactor(1, 1);
|
||||
|
||||
m_filterWindowPicker->setRange(3, 25);
|
||||
m_filterWindowPicker->setSingleStep(1);
|
||||
m_filterWindowPicker->setValue(8);
|
||||
|
||||
m_filterComboBox->addItem(tr("None"));
|
||||
m_filterComboBox->addItem(tr("Gauss"));
|
||||
m_filterComboBox->addItem(tr("Median"));
|
||||
m_filterComboBox->setCurrentIndex(0);
|
||||
|
||||
auto tb = new QToolBar(this);
|
||||
tb->setIconSize(applicationIconsSize());
|
||||
|
||||
@ -1512,16 +1674,24 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
||||
auto actionGroup = new QActionGroup(this);
|
||||
actionGroup->setExclusive(true);
|
||||
|
||||
action = new QAction(tr("Regular chart"), actionGroup);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(true);
|
||||
connect(action, &QAction::triggered, this, &This::onRegularChartTypeChecked);
|
||||
tb->addAction(action);
|
||||
auto actionRegulatChart = new QAction(QIcon(imagePath("yx-chart")), tr("Regular chart"), actionGroup);
|
||||
actionRegulatChart->setCheckable(true);
|
||||
actionRegulatChart->setChecked(true);
|
||||
tb->addAction(actionRegulatChart);
|
||||
|
||||
action = new QAction(tr("Complexity chart"), actionGroup);
|
||||
action->setCheckable(true);
|
||||
connect(action, &QAction::triggered, this, &This::onComplexityChartTypeChecked);
|
||||
tb->addAction(action);
|
||||
auto actionComplexityChart = new QAction(QIcon(imagePath("big-o-chart")), tr("Complexity chart"), actionGroup);
|
||||
actionComplexityChart->setCheckable(true);
|
||||
tb->addAction(actionComplexityChart);
|
||||
|
||||
auto filtersWidget = new QWidget(this);
|
||||
auto filtersLay = new QHBoxLayout(filtersWidget);
|
||||
filtersLay->setContentsMargins(0, 0, 0, 0);
|
||||
filtersLay->addWidget(m_filterBoxLabel);
|
||||
filtersLay->addWidget(m_filterComboBox);
|
||||
filtersLay->addWidget(m_filterWindowLabel);
|
||||
filtersLay->addWidget(m_filterWindowPicker);
|
||||
|
||||
tb->addWidget(filtersWidget);
|
||||
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@ -1557,6 +1727,24 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
|
||||
|
||||
loadSettings();
|
||||
|
||||
m_filterComboBox->setCurrentIndex(int_cast(m_chart->filterType()));
|
||||
m_filterWindowPicker->setValue(m_chart->filterWindowSize());
|
||||
|
||||
m_filterBoxLabel->setVisible(m_chart->chartType() == ChartType::Complexity);
|
||||
m_filterComboBox->setVisible(m_chart->chartType() == ChartType::Complexity);
|
||||
m_filterWindowLabel->setVisible(m_chart->chartType() == ChartType::Complexity && m_chart->filterType() != FilterType::None);
|
||||
m_filterWindowPicker->setVisible(m_chart->chartType() == ChartType::Complexity && m_chart->filterType() != FilterType::None);
|
||||
|
||||
if (m_chart->chartType() == ChartType::Complexity)
|
||||
actionComplexityChart->setChecked(true);
|
||||
else
|
||||
actionRegulatChart->setChecked(true);
|
||||
|
||||
connect(actionRegulatChart, &QAction::triggered, this, &This::onRegularChartTypeChecked);
|
||||
connect(actionComplexityChart, &QAction::triggered, this, &This::onComplexityChartTypeChecked);
|
||||
connect(m_filterComboBox, Overload<int>::of(&QComboBox::currentIndexChanged), this, &This::onFilterComboBoxChanged);
|
||||
connect(m_filterWindowPicker, Overload<int>::of(&QSpinBox::valueChanged), this, &This::onFilterWindowSizeChanged);
|
||||
|
||||
rebuild();
|
||||
}
|
||||
|
||||
@ -1722,6 +1910,12 @@ void ArbitraryValuesWidget::onRegularChartTypeChecked(bool _checked)
|
||||
return;
|
||||
|
||||
m_chart->setChartType(ChartType::Regular);
|
||||
|
||||
m_filterWindowPicker->hide();
|
||||
m_filterWindowLabel->hide();
|
||||
m_filterComboBox->hide();
|
||||
m_filterBoxLabel->hide();
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
@ -1731,9 +1925,44 @@ void ArbitraryValuesWidget::onComplexityChartTypeChecked(bool _checked)
|
||||
return;
|
||||
|
||||
m_chart->setChartType(ChartType::Complexity);
|
||||
|
||||
m_filterBoxLabel->show();
|
||||
m_filterComboBox->show();
|
||||
m_filterWindowLabel->setVisible(m_filterComboBox->currentIndex() != 0);
|
||||
m_filterWindowPicker->setVisible(m_filterComboBox->currentIndex() != 0);
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void ArbitraryValuesWidget::onFilterComboBoxChanged(int _index)
|
||||
{
|
||||
switch (_index)
|
||||
{
|
||||
case 1:
|
||||
m_filterWindowLabel->show();
|
||||
m_filterWindowPicker->show();
|
||||
m_chart->setFilterType(FilterType::Gauss);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_filterWindowLabel->show();
|
||||
m_filterWindowPicker->show();
|
||||
m_chart->setFilterType(FilterType::Median);
|
||||
break;
|
||||
|
||||
default:
|
||||
m_filterWindowLabel->hide();
|
||||
m_filterWindowPicker->hide();
|
||||
m_chart->setFilterType(FilterType::None);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ArbitraryValuesWidget::onFilterWindowSizeChanged(int _size)
|
||||
{
|
||||
m_chart->setFilterWindowSize(_size);
|
||||
}
|
||||
|
||||
void ArbitraryValuesWidget::buildTree(profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId)
|
||||
{
|
||||
m_treeWidget->clear();
|
||||
@ -1920,6 +2149,18 @@ void ArbitraryValuesWidget::loadSettings()
|
||||
if (!state.isEmpty())
|
||||
m_splitter->restoreState(state);
|
||||
|
||||
auto value = settings.value("chart/filterWindow");
|
||||
if (!value.isNull())
|
||||
m_chart->setFilterWindowSize(value.toInt());
|
||||
|
||||
value = settings.value("chart/filter");
|
||||
if (!value.isNull())
|
||||
m_chart->setFilterType(static_cast<FilterType>(value.toInt()));
|
||||
|
||||
value = settings.value("chart/type");
|
||||
if (!value.isNull())
|
||||
m_chart->setChartType(static_cast<ChartType>(value.toInt()));
|
||||
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
@ -1929,5 +2170,8 @@ void ArbitraryValuesWidget::saveSettings()
|
||||
settings.beginGroup("ArbitraryValuesWidget");
|
||||
settings.setValue("hsplitter/geometry", m_splitter->saveGeometry());
|
||||
settings.setValue("hsplitter/state", m_splitter->saveState());
|
||||
settings.setValue("chart/type", static_cast<int>(m_chart->chartType()));
|
||||
settings.setValue("chart/filter", static_cast<int>(m_chart->filterType()));
|
||||
settings.setValue("chart/filterWindow", m_chart->filterWindowSize());
|
||||
settings.endGroup();
|
||||
}
|
||||
|
@ -88,6 +88,13 @@ enum class ChartType : uint8_t
|
||||
Complexity ///< Complexity chart; X axis = value, Y axis = duration
|
||||
};
|
||||
|
||||
enum class FilterType : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
Gauss,
|
||||
Median,
|
||||
};
|
||||
|
||||
enum class ComplexityType : uint8_t
|
||||
{
|
||||
Constant = 0, ///< O(1)
|
||||
@ -195,7 +202,9 @@ class ArbitraryValuesChartItem : public GraphicsImageItem
|
||||
profiler::timestamp_t m_workerMinDuration;
|
||||
profiler::timestamp_t m_maxDuration;
|
||||
profiler::timestamp_t m_minDuration;
|
||||
int m_filterWindowSize;
|
||||
ChartType m_chartType;
|
||||
FilterType m_filterType;
|
||||
|
||||
public:
|
||||
|
||||
@ -216,7 +225,12 @@ public:
|
||||
void update(Collections _collections);
|
||||
void update(const ArbitraryValuesCollection* _selected);
|
||||
void setChartType(ChartType _chartType);
|
||||
void setFilterType(FilterType _filterType);
|
||||
void setFilterWindowSize(int _size);
|
||||
|
||||
ChartType chartType() const;
|
||||
FilterType filterType() const;
|
||||
int filterWindowSize() const;
|
||||
|
||||
private:
|
||||
|
||||
@ -263,7 +277,12 @@ public:
|
||||
void update(Collections _collections);
|
||||
void update(const ArbitraryValuesCollection* _selected);
|
||||
void setChartType(ChartType _chartType);
|
||||
void setFilterType(FilterType _filterType);
|
||||
void setFilterWindowSize(int _size);
|
||||
|
||||
ChartType chartType() const;
|
||||
FilterType filterType() const;
|
||||
int filterWindowSize() const;
|
||||
|
||||
private slots:
|
||||
|
||||
@ -318,6 +337,10 @@ class ArbitraryValuesWidget : public QWidget
|
||||
class QSplitter* m_splitter;
|
||||
QTreeWidget* m_treeWidget;
|
||||
GraphicsChart* m_chart;
|
||||
class QLabel* m_filterBoxLabel;
|
||||
class QComboBox* m_filterComboBox;
|
||||
class QLabel* m_filterWindowLabel;
|
||||
class QSpinBox* m_filterWindowPicker;
|
||||
ArbitraryTreeWidgetItem* m_boldItem;
|
||||
|
||||
public:
|
||||
@ -342,6 +365,8 @@ private slots:
|
||||
void onCollectionsTimeout();
|
||||
void onRegularChartTypeChecked(bool _checked);
|
||||
void onComplexityChartTypeChecked(bool _checked);
|
||||
void onFilterComboBoxChanged(int _index);
|
||||
void onFilterWindowSizeChanged(int _size);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -41,3 +41,4 @@ default/arrow-up-hover.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/arrow-up-disabled.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/arrow-left.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/arrow-right.svg - Icon made by Freepik from www.flaticon.com
|
||||
default/yx.svg - Icon made by Freepik from www.flaticon.com
|
||||
|
21
profiler_gui/images/default/big-o.svg
Normal file
21
profiler_gui/images/default/big-o.svg
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="300.000000pt" height="142.000000pt" viewBox="0 0 300.000000 142.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<g transform="translate(0.000000,142.000000) scale(0.100000,-0.100000)" stroke="none">
|
||||
<path fill="#484848" d="M652 1345 c-107 -47 -280 -191 -368 -309 -57 -76 -127 -220 -150
|
||||
-311 -25 -96 -25 -279 0 -360 37 -123 110 -221 197 -266 297 -151 792 86 986
|
||||
472 162 325 103 708 -121 774 -224 67 -491 -91 -630 -372 -40 -82 -42 -93 -10
|
||||
-93 15 0 46 11 69 25 35 20 51 41 95 125 59 112 121 189 174 214 76 36 195 7
|
||||
263 -65 18 -19 44 -61 59 -94 24 -52 29 -76 32 -177 7 -180 -35 -331 -133
|
||||
-478 -223 -335 -638 -372 -789 -70 -47 94 -59 163 -54 290 11 252 141 470 368
|
||||
620 90 59 113 90 68 90 -13 -1 -38 -7 -56 -15z"/>
|
||||
<path fill="#f44336" d="M2850 839 c-14 -12 -52 -35 -85 -52 -52 -27 -71 -31 -140 -31 -69 -1
|
||||
-96 5 -200 42 -66 24 -148 46 -183 49 -82 8 -173 -17 -252 -68 l-60 -39 0 -96
|
||||
0 -96 31 27 c18 14 59 40 93 58 53 27 71 31 141 31 69 1 96 -5 200 -42 66 -24
|
||||
148 -46 183 -49 82 -8 173 17 252 68 l60 39 0 90 c0 49 -3 90 -7 90 -5 -1 -19
|
||||
-10 -33 -21z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
16
profiler_gui/images/default/yx.svg
Normal file
16
profiler_gui/images/default/yx.svg
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 395.304 395.304" style="enable-background:new 0 0 395.304 395.304;" xml:space="preserve">
|
||||
<g>
|
||||
<polygon fill="#484848" points="392.152,341.5 392.152,326.5 65.652,326.5 65.652,0 50.652,0 50.652,326.5 21.152,326.5 21.152,341.5
|
||||
50.652,341.5 50.652,371 65.652,371 65.652,341.5 "/>
|
||||
<path fill="#f44336" d="M229.731,307.947c37.193,0,71.676-30.068,97.096-84.667c24.571-52.773,38.103-122.773,38.103-197.105h-15
|
||||
c0,72.19-13.034,139.941-36.701,190.774c-22.818,49.008-52.472,75.998-83.498,75.998s-60.68-26.99-83.498-75.998
|
||||
c-23.667-50.833-36.701-118.584-36.701-190.774h-15c0,74.332,13.532,144.332,38.103,197.105
|
||||
C158.056,277.879,192.539,307.947,229.731,307.947z"/>
|
||||
<polygon fill="#f44336" points="393.455,365.304 382.849,354.696 373.152,364.393 363.455,354.696 352.849,365.304 362.545,375 352.849,384.696
|
||||
363.455,395.304 373.152,385.607 382.849,395.304 393.455,384.696 383.759,375 "/>
|
||||
<polygon fill="#f44336" points="31.849,11.696 22.152,21.393 12.455,11.696 1.849,22.304 11.545,32 1.849,41.696 12.455,52.304 42.455,22.304 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -47,5 +47,7 @@
|
||||
<file alias="arrow-down">images/default/arrow-down.svg</file>
|
||||
<file alias="arrow-down-hover">images/default/arrow-down-hover.svg</file>
|
||||
<file alias="arrow-down-disabled">images/default/arrow-down-disabled.svg</file>
|
||||
<file alias="yx-chart">images/default/yx.svg</file>
|
||||
<file alias="big-o-chart">images/default/big-o.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user