Используя Wt, библиотеку C для веб-разработки, я пытаюсь загрузить файл .wav, а затем распечатать его значения на диаграмме. Есть ли способ сделать это динамически, другими словами, добавить точки на уже созданную диаграмму?
Wt динамические диаграммы и графики
Ответы (2)
Да, есть способ сделать это. Однажды я написал код для отслеживания использования памяти и печати этой информации на диаграмме, как на вкладке «Производительность» диспетчера задач Windows. Я использовал поток повышения, чтобы постоянно обновлять его. Вот некоторый код, который может направить вас в правильном направлении с вашей проблемой с диаграммой.
Вам понадобится WCartesianChart
Wt::Chart::WCartesianChart* _chart_memory_display;
Теперь инициализация для диаграмм на самом деле довольно сложна. Я написал функцию для этого. ПРИМЕЧАНИЕ. Здесь используется #define PERFORMANCE_HISTORY 100 — это объем данных, хранящихся на диаграмме, насколько мне известно, ограничений нет, мне нужны только последние 100 точек.
Wt::Chart::WCartesianChart* CreateCartesianChart(WContainerWidget* parent)
{
WStandardItemModel *model = new WStandardItemModel(PERFORMANCE_HISTORY, 2, parent);
//Create the scatter plot.
Wt::Chart::WCartesianChart* chart = new Wt::Chart::WCartesianChart(parent);
//Give the chart an empty model to fill with data
chart->setModel(model);
//Set which column holds X data
chart->setXSeriesColumn(0);
//Get the axes
Wt::Chart::WAxis& x_axis = chart->axis(Wt::Chart::Axis::XAxis);
Wt::Chart::WAxis& y1_axis = chart->axis(Wt::Chart::Axis::Y1Axis);
Wt::Chart::WAxis& y2_axis = chart->axis(Wt::Chart::Axis::Y2Axis);
//Modify axes attributes
x_axis.setRange(0, PERFORMANCE_HISTORY);
x_axis.setGridLinesEnabled(true);
x_axis.setLabelInterval(PERFORMANCE_HISTORY / 10);
y1_axis.setRange(0, 100);
y1_axis.setGridLinesEnabled(true);
y1_axis.setLabelInterval(10);
y2_axis.setRange(0, 100);
y2_axis.setVisible(true);
y2_axis.setLabelInterval(10);
//Set chart type
chart->setType(Wt::Chart::ChartType::ScatterPlot);
// Typically, for mathematical functions, you want the axes to cross at the 0 mark:
chart->axis(Wt::Chart::Axis::XAxis).setLocation(Wt::Chart::AxisValue::ZeroValue);
chart->axis(Wt::Chart::Axis::Y1Axis).setLocation(Wt::Chart::AxisValue::ZeroValue);
chart->axis(Wt::Chart::Axis::Y2Axis).setLocation(Wt::Chart::AxisValue::ZeroValue);
// Add the lines
Wt::Chart::WDataSeries s(1, Wt::Chart::SeriesType::LineSeries);
chart->addSeries(s);
//Size the display size of the chart, has no effect on scale
chart->resize(300, 300);
return chart;
}
По сути, диаграммам WT нужна модель и ряд данных, чтобы быть готовыми к приему данных. Я настоятельно рекомендую прочитать документацию обо всем, что вы не узнаете в этой функции, мне потребовалось некоторое время, чтобы собрать все воедино. Кроме того, загляните в галерею виджетов WT, в ней есть диаграммы и образцы кода.
Теперь, для собственно обновления, я написал еще одну функцию.
void UpdateChartDisplay(Wt::WAbstractItemModel* data_model, double data)
{
//Update the old data
for(unsigned int i = 0; i < PERFORMANCE_HISTORY; i++)
{
//Move all data back one index
data_model->setData(i, 0, i);
data_model->setData(i, 1, data_model->data(i+1, 1));
}
//Get the last index of the data
int insertion_point = PERFORMANCE_HISTORY - 1;
//Insert new data at the last index
data_model->setData(insertion_point, 0, insertion_point);
data_model->setData(insertion_point, 1, data);
}
Теперь data_model — это просто модель обновляемой диаграммы,
_chart_memory_display->model()
двойное вхождение — это сами данные, которые добавляются к диаграмме. У меня есть поток повышения, вызывающий эту функцию каждую секунду, передавая новые данные, он выглядит точно так же, как диспетчер задач при работе. Я не уверен, пытаетесь ли вы обновить его динамически или просто заполнить его данными, но я надеюсь, что это поможет и поставит вас на правильный путь!
Я думаю, что когда у вас есть модель и вы обновляете эту модель, график автоматически обновляется как представление.
Создайте свою собственную модель и сделайте там свою бизнес-логику. Пусть Wt обрабатывает представление графика.