Skip to content

Commit

Permalink
Voronoi diagram on chart
Browse files Browse the repository at this point in the history
.. The diagram now displays on a chart, but there are a few issues.
   Will work through them as more testing done.
  • Loading branch information
liversedge committed Sep 30, 2021
1 parent 4f005d4 commit 70ed4e3
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 11 deletions.
21 changes: 18 additions & 3 deletions contrib/voronoi/Voronoi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,21 @@
Voronoi::Voronoi()
{
// old controls essentially in main.c
triangulate = 0;
plot = 0;
debug = 0;
//
// the original source was written in such a way that you could
// update the "plotting functions" (line, circle etc) with your
// own code to implement a plot.
//
// we have adapted the "line" function to record lines in the
// output vector, so we can draw them on a plot
//
// testing has suggested that these kinds of diagrams only work
// well when there are lots of cells ie, running kmeans with
// 30 or even 100 clusters.
//
triangulate = 0; // tesselate (we don't support this)
plot = 1; // call "plotting functions" - we use this
debug = 0; // set to 1 to get lots of debug

// malloc lists are maintained and zapped in constructors
freeinit(&sfl, sizeof(Site));
Expand Down Expand Up @@ -98,6 +110,7 @@ Voronoi::run(QRectF /* boundingRect */)

// was done in main.c previously
geominit();
plotinit();

// now into the original sources
Site *newsite, * bot, * top, * temp, * p, * v ;
Expand Down Expand Up @@ -755,11 +768,13 @@ Voronoi::myalloc(unsigned n)
void
Voronoi::openpl(void)
{
output.clear();
}

void
Voronoi::line(float ax, float ay, float bx, float by)
{
output << QLineF(QPointF(ax,ay), QPointF(bx,by));
}

void
Expand Down
5 changes: 5 additions & 0 deletions contrib/voronoi/Voronoi.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <QList>
#include <QRectF>
#include <QPointF>
#include <QLineF>

#ifndef __VDEFS_H
#define __VDEFS_H 1
Expand Down Expand Up @@ -76,6 +77,9 @@ class Voronoi {
void addSite(QPointF point);
void run(QRectF boundingRect);

// the output is a vector of lines to draw
QList<QLineF> &lines() { return output; }

private:

// original global variables
Expand All @@ -99,6 +103,7 @@ class Voronoi {
// refactoring to Qt containers
QList<void *> malloclist; // keep tabs on all the malloc'ed memory
QList<Site*> sites;
QList<QLineF> output;

/*** implicit parameters: nsites, sqrt_nsites, xmin, xmax, ymin, ymax,
: deltax, deltay (can all be estimates).
Expand Down
2 changes: 1 addition & 1 deletion src/Charts/GenericChart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ GenericChart::finaliseChart()
}

// did we have a voronoi diagram?
if (p.voronoix.count() >= 2) newPlots[i].plot->addVoronoi(p.voronoix, p.voronoiy);
if (p.voronoix.count() >= 2) newPlots[i].plot->addVoronoi(p.name, p.voronoix, p.voronoiy);
}

// set axis
Expand Down
56 changes: 56 additions & 0 deletions src/Charts/GenericLines.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 Mark Liversedge ([email protected])
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <QChart>
#include "GenericLines.h"

GenericLines::GenericLines(GenericPlot *plot) : QGraphicsItem(NULL), plot(plot), curve(NULL)
{
}

GenericLines::~GenericLines() {}

void
GenericLines::paint(QPainter*painter, const QStyleOptionGraphicsItem *, QWidget*)
{
if (curve == NULL) return;

QPen pen(Qt::lightGray);
painter->setPen(pen);

painter->setClipRect(plot->qchart->plotArea());

foreach(QLineF line, lines) {
QPointF from = plot->qchart->mapToPosition(line.p1(), curve);
QPointF to = plot->qchart->mapToPosition(line.p2(), curve);

painter->drawLine(from, to);
}
}

void
GenericLines::prepare()
{
prepareGeometryChange();
}

QRectF GenericLines::boundingRect() const
{
// we cover the entire plot area generally
return plot->qchart->plotArea();
}
56 changes: 56 additions & 0 deletions src/Charts/GenericLines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 Mark Liversedge ([email protected])
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef _GC_GenericLines_h
#define _GC_GenericLines_h 1

#include <QPointF>
#include <QtCharts>
#include <QGraphicsItem>

#include "GenericPlot.h"

// for painting lines on a chart
class GenericLines : public QGraphicsItem
{

Q_INTERFACES(QGraphicsItem)

public:

GenericLines(GenericPlot *);
~GenericLines();

void setCurve(QAbstractSeries *curve) { this->curve=curve; }
void setLines(QList<QLineF> lines) { this->lines = lines; update(); }

void paint(QPainter*, const QStyleOptionGraphicsItem *, QWidget*);
QRectF boundingRect() const;

void prepare();
private:

// lines to draw
QList<QLineF> lines;
GenericPlot *plot;

QAbstractSeries *curve;

};

#endif
61 changes: 58 additions & 3 deletions src/Charts/GenericPlot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
#include "ChartSpace.h"
#include "UserChartOverviewItem.h"

#include "Voronoi.h"
#include "GenericLines.h"

#include <limits>

// used to format dates/times on axes
Expand All @@ -47,6 +50,7 @@ GenericPlot::GenericPlot(QWidget *parent, Context *context, QGraphicsItem *item)
barseries=NULL;
stackbarseries=NULL;
percentbarseries=NULL;
voronoidiagram=NULL;
bottom=left=true;

mainLayout = new QVBoxLayout(this);
Expand Down Expand Up @@ -316,12 +320,11 @@ GenericPlot::addAnnotation(AnnotationType, QString string, QColor color)
}

void
GenericPlot::addVoronoi(QVector<double>x, QVector<double>y)
GenericPlot::addVoronoi(QString name, QVector<double>x, QVector<double>y)
{
vname = name;
vx = x;
vy = y;

fprintf(stderr, "generic plot: add voronoi diagram\n"); fflush(stderr);
}

void
Expand Down Expand Up @@ -456,6 +459,8 @@ GenericPlot::plotAreaChanged()
bool
GenericPlot::initialiseChart(QString title, int type, bool animate, int legpos, double scale)
{
clearVoronoi();

// if we changed the type, all series must go
if (charttype != type) {
qchart->removeAllSeries();
Expand All @@ -466,6 +471,7 @@ GenericPlot::initialiseChart(QString title, int type, bool animate, int legpos,
percentbarseries=NULL;
}


foreach(QLabel *label, labels) delete label;
labels.clear();

Expand Down Expand Up @@ -919,6 +925,9 @@ GenericPlot::finaliseChart()
{
if (!qchart) return;

// remove voronoix if present
clearVoronoi();

// clear ALL axes
foreach(QAbstractAxis *axis, qchart->axes(Qt::Vertical)) {
qchart->removeAxis(axis);
Expand Down Expand Up @@ -1246,6 +1255,9 @@ GenericPlot::finaliseChart()
// add labels after legend items
foreach(QLabel *label, labels) legend->addLabel(label);

// add voronoi if need to
plotVoronoi();

plotAreaChanged(); // make sure get updated before paint
}

Expand Down Expand Up @@ -1357,3 +1369,46 @@ GenericPlot::seriesColor(QAbstractSeries* series)
default: return GColor(CPLOTMARKER);
}
}

void
GenericPlot::plotVoronoi()
{
// if there is one there already, lets remove it
clearVoronoi();

if (vx.count() < 2) return;

Voronoi v;
for(int i=0; i<vx.count(); i++) v.addSite(QPointF(vx[i],vy[i]));
v.run(QRectF());

#if 0
// how many lines?
fprintf(stderr, "voronoi diagram curve '%s' has %d lines\n", vname.toStdString().c_str(),v.lines().count()); fflush(stderr);

foreach(QLineF line, v.lines()) {
fprintf(stderr, "from %f,%f to %f,%f\n", line.p1().x(), line.p1().y(), line.p2().x(), line.p2().y());
}
#endif

// create a new diagram
voronoidiagram = new GenericLines(this);
voronoidiagram->setCurve(curves.value(vname,NULL));
voronoidiagram->setLines(v.lines());

chartview->scene()->addItem(voronoidiagram);
voronoidiagram->update();
}

void
GenericPlot::clearVoronoi()
{
if (voronoidiagram) {
voronoidiagram->setCurve(NULL);
voronoidiagram->setLines(QList<QLineF>());
voronoidiagram->prepare();
chartview->scene()->removeItem(voronoidiagram);
//delete voronoidiagram; // CRASH!
voronoidiagram = NULL;
}
}
14 changes: 13 additions & 1 deletion src/Charts/GenericPlot.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class GenericPlot;
class GenericLegend;
class GenericSelectTool;
class GenericAxisInfo;
class GenericLines; // draw lines

// the chart
class ChartSpace;
Expand All @@ -72,6 +73,7 @@ class GenericPlot : public QWidget {
static QString gl_timeformat;

friend class GenericSelectTool;
friend class GenericLines;
friend class GenericLegend;

GenericPlot(QWidget *parent, Context *context, QGraphicsItem *item);
Expand Down Expand Up @@ -107,7 +109,7 @@ class GenericPlot : public QWidget {
// adding annotations
void addAnnotation(AnnotationType, QAbstractSeries*, double yvalue); // LINE
void addAnnotation(AnnotationType, QString, QColor=QColor(Qt::gray)); // LABEL
void addVoronoi(QVector<double>, QVector<double>); // VORONOI
void addVoronoi(QString name, QVector<double>, QVector<double>); // VORONOI

// configure axis, after curves added
bool configureAxis(QString name, bool visible, int align, double min, double max,
Expand All @@ -119,13 +121,20 @@ class GenericPlot : public QWidget {
// do we want to see this series?
void setSeriesVisible(QString name, bool visible);

// adding and clearing a voronoi diagram from the chart
void clearVoronoi();
void plotVoronoi();

// watching scene events and managing interaction
void seriesClicked(QAbstractSeries*series, GPointF point);
bool eventHandler(int eventsource, void *obj, QEvent *event);
void barsetHover(bool status, int index, QBarSet *barset);
void plotAreaChanged();
void pieHover(QPieSlice *slice, bool state);

// access structures
QAbstractSeries *curve(QString name) { return curves.value(name, NULL); }

protected:

// legend and selector need acces to these
Expand Down Expand Up @@ -153,7 +162,10 @@ class GenericPlot : public QWidget {

// annotations
QList<QLabel *> labels;

QString vname;
QVector<double> vx, vy; //voronoi digram
GenericLines *voronoidiagram; // draws the lines on the chart

private:
Context *context;
Expand Down
6 changes: 5 additions & 1 deletion src/Charts/UserChart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ UserChart::setRide(const RideItem *item)
// clear old annotations for this series
annotations.clear();

// any old voronoi diagram centers
series.voronoix.clear();
series.voronoiy.clear();

// re-create program (may be edited)
if (series.user1 != NULL) delete static_cast<UserChartData*>(series.user1);
series.user1 = new UserChartData(context, this, series.string1, rangemode);
Expand Down Expand Up @@ -534,7 +538,7 @@ UserChart::annotateVoronoi(QVector<double>x, QVector<double>y)
UserChartData *ucd = static_cast<UserChartData*>(seriesinfo[i].user1);
if (ucd->program == from) {
seriesinfo[i].voronoix = x;
seriesinfo[i].voronoiy = x;
seriesinfo[i].voronoiy = y;
}
}
}
Expand Down
Loading

0 comments on commit 70ed4e3

Please sign in to comment.