Ich bin dabei, ein kleines Statistik-Tool zu programmieren. Ich möchte dabei im Programm auch einfache Diagramme darstellen (Wert pro Zeit, 1-n Kurven pro Diagramm). Natürlich fiel mir dafür als erstes Qwt ein, was selbiges wohl ausreichend beherrscht.
Was ich jedoch auch brauche, ist der Export von Diagrammen in ein webtaugliches Format - vorzugsweise PNG. Per google hab ich rausgefunden, dass man Qwt Diagramme zumindest ins SVG Format exportieren kann.
Wie siehts mit PNG aus? Traumhaft wäre noch, wenn man einzelne Kurven als einzelne, transparente PNGs exportieren könnte, so dass ich diese im HTML übereinander legen kann und bei Klick ein/ausblenden kann.
Ist sowas mit Qwt denkbar, oder, falls nein, kennt jemand eine alternative Library mit der ich so etwas umsetzen könnte? (graphviz..?) Selbige sollte unter windows, linux und mac verfügbar sein.
Frage 2:
Zusätzlich zu normalen Kurven im X/Y Diagramm bräuchte ich noch Markierungen. Zum einen senkrechte Striche, die ein bestimmtes Ereignis kennzeichnen, sowie einen farblich(hintergrund) markierten Bereich im Diagramm, der einen besonderen Zeitraum kennzeichnet.
Das sollte mit Qwt möglich sein, oder?
Frage zu Qwt
Ja die nennt sich "Qt"kennt jemand eine alternative Library mit der ich so etwas umsetzen könnte?
In Qt kannst du ja jedes beliebige Widget in ein von Qt unterstütztes Graphikformat (u.a. auch png) exportieren (s. http://doc.trolltech.com/4.5/qpixmap.html#grabWidget). Daher hast du also folgende Möglichkeiten:
* du erstellst mit Qwt ein Diagramm, welches genau deinen Wünschen entsprechend aussieht (z.B. ohne Achsen, Hintergrundfarbe usw.) und erstellst daraus via QPixmap direkt eine PNG
* du erstellst die Graphik gleich selbst (QPainter auf QPixmap, siehe http://www.qtforum.de/forum/viewtopic.php?t=8826)
Also http://qwt.sourceforge.net/plot.png zeigt ja solche "Cursors" (senkrechte Linien). Ich habe gerade keine Qwt-Installation, aber findest du dies nicht in den Beispielen? Ob sich die Hintergrundfarbe zwischen zwei Cursors auch verstellen lässt, weiss ich nicht.bräuchte ich noch Markierungen. Zum einen senkrechte Striche, die ein bestimmtes Ereignis kennzeichnen, sowie einen farblich(hintergrund) markierten Bereich im Diagramm, der einen besonderen Zeitraum kennzeichnet.
hth..
Das Diagramm direkt mit Qt zu zeichnen, hatte ich mir auch schon überlegt. Habe in diese Richtung allerdings noch nie was mit Qt gemacht, und weiß nicht wie (un-?)komfortabel das Zeichen mit immer unterschiedlicher Achsenskalierung in Qt ist.
Dass ich die Qwt Diagramme direkt mit Qt exportieren kann, wusste ich nicht, und erleichtert die Sache wohl erheblich, ich denke so werd ichs probieren
Dass ich die Qwt Diagramme direkt mit Qt exportieren kann, wusste ich nicht, und erleichtert die Sache wohl erheblich, ich denke so werd ichs probieren
a)
Mit Qt Bordmitteln kannst Du einen Screenshot von Deinem Plot Widget erzeugen - das mag für viele Zwecke genügen. Besser ist es aber Dein Diagramm mit QwtPlot::print auf ein QImage rendern. Das Image kannst Du dann als PNG ( oder jedes andere Raster Bildformat ) speichern.
z.B:
QImage image(1000, 1000, ...);
image.fill(Qt::transparent);
plot->print(image, ...);
image.save(...);
b)
Markierungen nennen sich in Qwt "überrachenderweise" Marker (QwtPlotMarker). Das bode Beispiel zeigt Marker in Form von vertikalen Linien.
c)
Um Intervalle durch einen farbigen Hintergrund darzustellen würde ich ein eigenes Plot Item implementieren. Schau Dir mal das cpuplot Beispiel an. Da ist so ein Background Item implementiert.
HTH,
Uwe
Mit Qt Bordmitteln kannst Du einen Screenshot von Deinem Plot Widget erzeugen - das mag für viele Zwecke genügen. Besser ist es aber Dein Diagramm mit QwtPlot::print auf ein QImage rendern. Das Image kannst Du dann als PNG ( oder jedes andere Raster Bildformat ) speichern.
z.B:
QImage image(1000, 1000, ...);
image.fill(Qt::transparent);
plot->print(image, ...);
image.save(...);
b)
Markierungen nennen sich in Qwt "überrachenderweise" Marker (QwtPlotMarker). Das bode Beispiel zeigt Marker in Form von vertikalen Linien.
c)
Um Intervalle durch einen farbigen Hintergrund darzustellen würde ich ein eigenes Plot Item implementieren. Schau Dir mal das cpuplot Beispiel an. Da ist so ein Background Item implementiert.
HTH,
Uwe
Grml, eben nen langen Text getippt, und dann aus versehen gelöscht.
Kurzfassung: Habe Probleme, Flächen im Diagramm zu markieren
Ansatz: eigenes Plotitem dass ein Rechteck zeichnet. Dem Plotitem wird die Start-Sekunde im Diagramm sowie die End-Sekunde mitgegeben, dazwischen soll auf der ganzen Höhe das Diagramms ein farbiges Rechteck gemalt werden.
Position/Breite des Rechtecks stimmt, nur die Höhe macht er mir immer auf 4 Pixel, und ich weiß nicht warum.
[edit] Hab alle Probleme nun gelöst, das Widget funktioniert wies soll. Der Übersichtlichkeit wegen habe ich den alten Text entfernt und den fertigen Code gepostet, falls jemand ein solches Widget mal brauchen könnte:
Header:
Impl:
updateLegend() ist copy & paste von QPlotCurve. Da ich für meinen Fall weder Symbol noch Linestyle konfigurieren muss, gibts dafür keine Optionen. Einfach in qwt_plot_curve.cpp nachschauen, dort ist Symbol & Linestyle implementiert.
Kurzfassung: Habe Probleme, Flächen im Diagramm zu markieren
Ansatz: eigenes Plotitem dass ein Rechteck zeichnet. Dem Plotitem wird die Start-Sekunde im Diagramm sowie die End-Sekunde mitgegeben, dazwischen soll auf der ganzen Höhe das Diagramms ein farbiges Rechteck gemalt werden.
Position/Breite des Rechtecks stimmt, nur die Höhe macht er mir immer auf 4 Pixel, und ich weiß nicht warum.
[edit] Hab alle Probleme nun gelöst, das Widget funktioniert wies soll. Der Übersichtlichkeit wegen habe ich den alten Text entfernt und den fertigen Code gepostet, falls jemand ein solches Widget mal brauchen könnte:
Header:
Code: Alles auswählen
//******************************************************
// class AreaMarker
//******************************************************
class AreaMarker: public QwtPlotItem
{
public:
AreaMarker(const QString& title, const QColor& color, int startSec, int endSec);
virtual int rtti() const { return QwtPlotItem::Rtti_PlotUserItem; }
void updateLegend(QwtLegend *legend) const;
virtual void draw(QPainter* p, const QwtScaleMap& xMap,
const QwtScaleMap& yMap, const QRect& rect) const;
// get
int getStart() { return startSec; }
int getEnd() { return endSec; }
// set
int setStart(int to) { startSec = to ; return 0; }
int setEnd(int to) { endSec = to; return 0; }
private:
QColor color;
int startSec;
int endSec;
};
Code: Alles auswählen
//******************************************************
// class AreaMarker
//******************************************************
// ctor
//******************************************************
AreaMarker::AreaMarker(const QString& title, const QColor& color, int startSec, int endSec)
: QwtPlotItem(title), color(color), startSec(startSec), endSec(endSec)
{
startSec = endSec = 0;
setItemAttribute(Legend, true);
}
//******************************************************
// draw
//******************************************************
void AreaMarker::draw(QPainter* p, const QwtScaleMap& xMap,
const QwtScaleMap& /*yMap*/, const QRect& rect) const
{
QRect areaRect;
areaRect.setX(xMap.transform(startSec));
areaRect.setY(rect.y());
areaRect.setHeight(rect.height());
areaRect.setWidth(xMap.transform(endSec) - xMap.transform(startSec));
p->save();
p->setBrush(QBrush(color, Qt::SolidPattern));
p->setOpacity(0.3);
p->setPen(QPen(Qt::NoPen));
p->drawRect(areaRect);
p->restore();
}
//******************************************************
// update legend
//******************************************************
void AreaMarker::updateLegend(QwtLegend *legend) const
{
if ( !legend )
return;
QwtPlotItem::updateLegend(legend);
QWidget *widget = legend->find(this);
if ( !widget || !widget->inherits("QwtLegendItem") )
return;
QwtLegendItem *legendItem = (QwtLegendItem *)widget;
#if QT_VERSION < 0x040000
const bool doUpdate = legendItem->isUpdatesEnabled();
#else
const bool doUpdate = legendItem->updatesEnabled();
#endif
legendItem->setUpdatesEnabled(false);
const int policy = legend->displayPolicy();
if (policy == QwtLegend::FixedIdentifier)
{
int mode = legend->identifierMode();
if (mode & QwtLegendItem::ShowLine)
legendItem->setCurvePen(QPen(color));
if (mode & QwtLegendItem::ShowText)
legendItem->setText(title());
else
legendItem->setText(QwtText());
legendItem->setIdentifierMode(mode);
}
else if (policy == QwtLegend::AutoIdentifier)
{
int mode = 0;
legendItem->setCurvePen(QPen(color));
mode |= QwtLegendItem::ShowLine;
if (!title().isEmpty())
{
legendItem->setText(title());
mode |= QwtLegendItem::ShowText;
}
else
{
legendItem->setText(QwtText());
}
legendItem->setIdentifierMode(mode);
}
legendItem->setUpdatesEnabled(doUpdate);
legendItem->update();
}