mutex, move series creation to chart, remove unused functions
This commit is contained in:
parent
03b0591371
commit
966db4f4e1
@ -21,12 +21,7 @@ class ChartWidget : public QListWidgetItem {
|
|||||||
void addData(const char* seriesName, const point_t* points, int count);
|
void addData(const char* seriesName, const point_t* points, int count);
|
||||||
|
|
||||||
QChartView* getView() const { return view; }
|
QChartView* getView() const { return view; }
|
||||||
QChart* getChart() const { return chart; }
|
|
||||||
QList<QAbstractSeries*> getSeries() const { return chart->series(); }
|
QList<QAbstractSeries*> getSeries() const { return chart->series(); }
|
||||||
QValueAxis* getX() const { return x; }
|
|
||||||
QValueAxis* getY() const { return y; }
|
|
||||||
const chart_spec_t& getSpec() const { return spec; }
|
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -36,7 +31,7 @@ class ChartWidget : public QListWidgetItem {
|
|||||||
chart_spec_t spec;
|
chart_spec_t spec;
|
||||||
int decimateState = 0;
|
int decimateState = 0;
|
||||||
|
|
||||||
mutable QMutex mutex;
|
QMutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ContextMenu : public QMenu {
|
class ContextMenu : public QMenu {
|
||||||
|
@ -21,8 +21,6 @@ class SpecDialog : public QDialog {
|
|||||||
|
|
||||||
static SpecDialog* getInstance();
|
static SpecDialog* getInstance();
|
||||||
static void close();
|
static void close();
|
||||||
|
|
||||||
QStringList getList() const { return series->stringList(); }
|
|
||||||
chart_spec_t getSpec() const;
|
chart_spec_t getSpec() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
struct axis_spec_t {
|
struct axis_spec_t {
|
||||||
@ -19,4 +20,5 @@ struct chart_spec_t {
|
|||||||
struct {
|
struct {
|
||||||
axis_spec_t x, y;
|
axis_spec_t x, y;
|
||||||
} axis;
|
} axis;
|
||||||
|
QList<QString> series;
|
||||||
};
|
};
|
@ -38,6 +38,14 @@ ChartWidget::ChartWidget(QWidget* parent, const chart_spec_t& spec) : QListWidge
|
|||||||
chart->addAxis(x, Qt::AlignBottom);
|
chart->addAxis(x, Qt::AlignBottom);
|
||||||
chart->addAxis(y, Qt::AlignLeft);
|
chart->addAxis(y, Qt::AlignLeft);
|
||||||
|
|
||||||
|
for (const QString& title : spec.series) {
|
||||||
|
QLineSeries* series = new QLineSeries(view);
|
||||||
|
series->setName(title);
|
||||||
|
chart->addSeries(series);
|
||||||
|
series->attachAxis(x);
|
||||||
|
series->attachAxis(y);
|
||||||
|
}
|
||||||
|
|
||||||
view->setRenderHint(QPainter::Antialiasing);
|
view->setRenderHint(QPainter::Antialiasing);
|
||||||
view->setChart(chart);
|
view->setChart(chart);
|
||||||
view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
@ -61,6 +69,8 @@ ChartWidget::~ChartWidget() {
|
|||||||
void ChartWidget::addData(const char* seriesName, const point_t* points, int count) {
|
void ChartWidget::addData(const char* seriesName, const point_t* points, int count) {
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
std::cout << "locked: " << locker.isLocked() << std::endl;
|
||||||
|
|
||||||
QString name(seriesName);
|
QString name(seriesName);
|
||||||
|
|
||||||
double minX = spec.keep_all ? x->min() : std::numeric_limits<double>::max();
|
double minX = spec.keep_all ? x->min() : std::numeric_limits<double>::max();
|
||||||
@ -74,10 +84,12 @@ void ChartWidget::addData(const char* seriesName, const point_t* points, int cou
|
|||||||
if (count >= spec.keep_limit) {
|
if (count >= spec.keep_limit) {
|
||||||
((QLineSeries*)series)->clear();
|
((QLineSeries*)series)->clear();
|
||||||
} else if (((QLineSeries*)series)->count() + count > spec.keep_limit) {
|
} else if (((QLineSeries*)series)->count() + count > spec.keep_limit) {
|
||||||
|
std::cout << "count: " << count << ", size: " << ((QLineSeries*)series)->count() << ", remove: " << ((QLineSeries*)series)->count() - (spec.keep_limit - count) << std::endl;
|
||||||
((QLineSeries*)series)->removePoints(0, ((QLineSeries*)series)->count() - (spec.keep_limit - count));
|
((QLineSeries*)series)->removePoints(0, ((QLineSeries*)series)->count() - (spec.keep_limit - count));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (QPointF point : ((QLineSeries*)series)->points()) {
|
std::cout << "starting min/max" << std::endl;
|
||||||
|
for (const QPointF& point : ((QLineSeries*)series)->points()) {
|
||||||
if (spec.axis.x.auto_limit) {
|
if (spec.axis.x.auto_limit) {
|
||||||
minX = MIN(minX, point.x());
|
minX = MIN(minX, point.x());
|
||||||
maxX = MAX(maxX, point.x());
|
maxX = MAX(maxX, point.x());
|
||||||
@ -87,8 +99,12 @@ void ChartWidget::addData(const char* seriesName, const point_t* points, int cou
|
|||||||
maxY = MAX(maxY, point.y());
|
maxY = MAX(maxY, point.y());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << "got min/max" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "start adding" << std::endl;
|
||||||
|
QList<QPointF> newPoints;
|
||||||
|
|
||||||
for (int i = spec.keep_all ? 0 : MAX(0, count - spec.keep_limit); i < count; i++) {
|
for (int i = spec.keep_all ? 0 : MAX(0, count - spec.keep_limit); i < count; i++) {
|
||||||
if (decimateState >= spec.decimate)
|
if (decimateState >= spec.decimate)
|
||||||
decimateState = 0;
|
decimateState = 0;
|
||||||
@ -104,19 +120,20 @@ void ChartWidget::addData(const char* seriesName, const point_t* points, int cou
|
|||||||
maxY = MAX(maxY, points[i].y);
|
maxY = MAX(maxY, points[i].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
*((QLineSeries*)series) << QPointF(points[i].x, points[i].y);
|
newPoints.append(QPointF(points[i].x, points[i].y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "adding" << std::endl;
|
||||||
|
((QLineSeries*)series)->append(newPoints);
|
||||||
|
|
||||||
if (spec.axis.x.auto_limit)
|
if (spec.axis.x.auto_limit)
|
||||||
x->setRange(minX, maxX);
|
x->setRange(MIN(x->min(), minX), MAX(x->max(), maxX));
|
||||||
if (spec.axis.y.auto_limit)
|
if (spec.axis.y.auto_limit)
|
||||||
y->setRange(minY, maxY);
|
y->setRange(MIN(y->min(), minY), MAX(y->max(), maxY));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view->update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChartWidget::clear() {
|
void ChartWidget::clear() {
|
||||||
@ -128,7 +145,6 @@ void ChartWidget::clear() {
|
|||||||
x->setRange(spec.axis.x.min, spec.axis.x.max);
|
x->setRange(spec.axis.x.min, spec.axis.x.max);
|
||||||
y->setRange(spec.axis.y.min, spec.axis.y.max);
|
y->setRange(spec.axis.y.min, spec.axis.y.max);
|
||||||
decimateState = 0;
|
decimateState = 0;
|
||||||
view->update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextMenu::ContextMenu(QWidget* parent, ChartWidget* chartWidget) : QMenu(parent) {
|
ContextMenu::ContextMenu(QWidget* parent, ChartWidget* chartWidget) : QMenu(parent) {
|
||||||
|
@ -85,15 +85,6 @@ void MainWindow::on_action_Add_triggered() {
|
|||||||
|
|
||||||
ui->graphsListWidget->addItem(chart);
|
ui->graphsListWidget->addItem(chart);
|
||||||
ui->graphsListWidget->setItemWidget(chart, chart->getView());
|
ui->graphsListWidget->setItemWidget(chart, chart->getView());
|
||||||
|
|
||||||
for (QString title : dialog->getList()) {
|
|
||||||
QLineSeries* series = new QLineSeries();
|
|
||||||
series->setName(title);
|
|
||||||
chart->getChart()->addSeries(series);
|
|
||||||
for (QAbstractAxis* axis : chart->getChart()->axes()) {
|
|
||||||
series->attachAxis(axis);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_action_Load_triggered() {
|
void MainWindow::on_action_Load_triggered() {
|
||||||
|
@ -48,6 +48,7 @@ chart_spec_t SpecDialog::getSpec() const {
|
|||||||
.keep_limit = ui->keep->value(),
|
.keep_limit = ui->keep->value(),
|
||||||
.decimate = ui->decimate->value(),
|
.decimate = ui->decimate->value(),
|
||||||
.axis = {.x = {.label = ui->xTitle->text(), .auto_limit = ui->xAutoRange->isChecked(), .min = ui->xMin->value(), .max = ui->xMax->value()},
|
.axis = {.x = {.label = ui->xTitle->text(), .auto_limit = ui->xAutoRange->isChecked(), .min = ui->xMin->value(), .max = ui->xMax->value()},
|
||||||
.y = {.label = ui->yTitle->text(), .auto_limit = ui->yAutoRange->isChecked(), .min = ui->yMin->value(), .max = ui->yMax->value()}}};
|
.y = {.label = ui->yTitle->text(), .auto_limit = ui->yAutoRange->isChecked(), .min = ui->yMin->value(), .max = ui->yMax->value()}},
|
||||||
|
.series = series->stringList()};
|
||||||
}
|
}
|
||||||
} // namespace Graph::GUI
|
} // namespace Graph::GUI
|
104
test/test.py
104
test/test.py
@ -4,33 +4,40 @@ import requests
|
|||||||
from math import sin
|
from math import sin
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pyaudio
|
from argparse import ArgumentParser
|
||||||
|
# import pyaudio
|
||||||
|
|
||||||
def sine():
|
def sine(args):
|
||||||
x = 0.0
|
x = 0.0
|
||||||
while True:
|
while True:
|
||||||
requests.get(f"http://localhost:8080/add?chart=0&series=R1&x={x}&y={sin(x)}")
|
try:
|
||||||
|
requests.get(f"http://{args.address}:{args.port}/add?chart={args.chart}&series={args.series}&x={x}&y={sin(x)}")
|
||||||
x += 0.01
|
x += 0.01
|
||||||
sleep(0.01)
|
sleep(0.01)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
break
|
||||||
|
|
||||||
def sine_array():
|
def sine_array(args):
|
||||||
start = 0
|
start = 0
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
x = np.linspace(start, start+0.5, 100)
|
x = np.linspace(start, start+0.5, 100)
|
||||||
y = np.sin(x)
|
y = np.sin(x)
|
||||||
|
|
||||||
start += 0.5
|
start += 0.5
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"chart": 0,
|
"chart": args.chart,
|
||||||
"series": "R1",
|
"series": args.series,
|
||||||
"points": [ {"x": i[0], "y":i[1]} for i in zip(x,y) ]
|
"points": [ {"x": i[0], "y":i[1]} for i in zip(x,y) ]
|
||||||
}
|
}
|
||||||
|
|
||||||
r = requests.post("http://0.0.0.0:8080/add", json=data, headers={"Connection":"close"})
|
r = requests.post(f"http://{args.address}:{args.port}/add", json=data)
|
||||||
sleep(0.25)
|
sleep(0.25)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
break
|
||||||
|
|
||||||
def star():
|
def star(args):
|
||||||
points = [
|
points = [
|
||||||
(2,2),
|
(2,2),
|
||||||
(3,0),
|
(3,0),
|
||||||
@ -40,43 +47,52 @@ def star():
|
|||||||
(2,2)
|
(2,2)
|
||||||
]
|
]
|
||||||
for point in points:
|
for point in points:
|
||||||
requests.get(f"http://localhost:8080/add?chart=0&series=R1&x={point[0]}&y={point[1]}")
|
requests.get(f"http://{args.address}:{args.port}/add?chart={args.chart}&series={args.series}&x={point[0]}&y={point[1]}")
|
||||||
|
|
||||||
|
# def audio():
|
||||||
|
# p = pyaudio.PyAudio()
|
||||||
|
# stream = p.open(
|
||||||
|
# input=True,
|
||||||
|
# input_device_index=0,
|
||||||
|
# format=pyaudio.paInt16,
|
||||||
|
# channels=1,
|
||||||
|
# rate=44100,
|
||||||
|
# frames_per_buffer=1024
|
||||||
|
# )
|
||||||
|
# stream.start_stream()
|
||||||
|
# while True:
|
||||||
|
# try:
|
||||||
|
# data = stream.read(1024, False)
|
||||||
|
# requests.post(
|
||||||
|
# "http://0.0.0.0:8080/add",
|
||||||
|
# json={
|
||||||
|
# "chart": 0,
|
||||||
|
# "series": "audio",
|
||||||
|
# "points": [ {"x": i, "y": v} for (i, v) in enumerate(data) ]
|
||||||
|
# },
|
||||||
|
# headers={"Connection":"close"})
|
||||||
|
# except KeyboardInterrupt:
|
||||||
|
# break
|
||||||
|
|
||||||
def audio():
|
# stream.stop_stream()
|
||||||
p = pyaudio.PyAudio()
|
# stream.close()
|
||||||
stream = p.open(
|
# p.terminate()
|
||||||
input=True,
|
|
||||||
input_device_index=0,
|
|
||||||
format=pyaudio.paInt16,
|
|
||||||
channels=1,
|
|
||||||
rate=44100,
|
|
||||||
frames_per_buffer=1024
|
|
||||||
)
|
|
||||||
stream.start_stream()
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
data = stream.read(1024, False)
|
|
||||||
requests.post(
|
|
||||||
"http://0.0.0.0:8080/add",
|
|
||||||
json={
|
|
||||||
"chart": 0,
|
|
||||||
"series": "audio",
|
|
||||||
"points": [ {"x": i, "y": v} for (i, v) in enumerate(data) ]
|
|
||||||
},
|
|
||||||
headers={"Connection":"close"})
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
break
|
|
||||||
|
|
||||||
stream.stop_stream()
|
|
||||||
stream.close()
|
|
||||||
p.terminate()
|
|
||||||
|
|
||||||
def main():
|
|
||||||
#sine()
|
|
||||||
# sine_array()
|
|
||||||
#star()
|
|
||||||
audio()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
parser = ArgumentParser()
|
||||||
|
parser.add_argument("-t", action="store", dest="test", help="test type", type=str, choices=["sine", "sine_array", "star"], required=False, default="sin")
|
||||||
|
parser.add_argument("-n", action="store", dest="num", help="sin_array size/iteration", type=int, required=False, default=100)
|
||||||
|
parser.add_argument("-d", action="store", dest="delay", help="delay between iteration", type=float, required=False, default=0.25)
|
||||||
|
parser.add_argument("-c", action="store", dest="chart", help="chart id", type=int, required=True)
|
||||||
|
parser.add_argument("-s", action="store", dest="series", help="series name", type=str, required=True)
|
||||||
|
parser.add_argument("-p", action="store", dest="port", help="server port", type=int, required=False, default=8080)
|
||||||
|
parser.add_argument("-a", action="store", dest="address", help="server address", type=str, required=False, default="localhost")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
if args.test == "sine":
|
||||||
|
sine(args)
|
||||||
|
elif args.test == "sine_array":
|
||||||
|
sine_array(args)
|
||||||
|
elif args.test == "star":
|
||||||
|
star(args)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user