Skip to content

Commit

Permalink
refactor to use Edge struct
Browse files Browse the repository at this point in the history
  • Loading branch information
sandsmark committed Mar 2, 2016
1 parent 03e70ee commit 5d72f65
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 61 deletions.
102 changes: 49 additions & 53 deletions hivewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void HiveWidget::setNodes(const QMultiMap<QString, QString> &nodes)
update();
}

void HiveWidget::setEdges(const QMultiMap<QString, QString> &edges)
void HiveWidget::setEdges(const QList<Edge> &edges)
{
m_edges = edges;
calculate();
Expand All @@ -50,18 +50,21 @@ void HiveWidget::paintEvent(QPaintEvent *)
painter.drawPoint(m_positions[node]);
}

// Draw underlying edges first
painter.setPen(Qt::NoPen);
for (const Edge &edge : m_edgePaths) {
if (edge.first == m_closest) {

for (const Edge &edge : m_edges) {
if (edge.source == m_closest) {
continue;
}
painter.setBrush(edge.brush);
painter.drawPath(edge.path);
}

// Draw active edges on top
painter.setBrush(m_nodeColors[m_closest]);
for (const Edge &edge : m_edgePaths) {
if (edge.first != m_closest) {
for (const Edge &edge : m_edges) {
if (edge.source != m_closest) {
continue;
}
painter.drawPath(edge.path);
Expand All @@ -74,15 +77,19 @@ void HiveWidget::paintEvent(QPaintEvent *)
painter.drawText(m_positions[m_closest], m_closest);

penColor.setAlpha(128);
for (const QString &otherNode : m_edges.values(m_closest)) {
QColor ellipseColor = m_nodeColors[otherNode];
for (const Edge &edge : m_edges) {
if (edge.source != m_closest) {
continue;
}

QColor ellipseColor = m_nodeColors[edge.target];
ellipseColor.setAlpha(128);
painter.setPen(Qt::NoPen);
painter.setBrush(ellipseColor);
painter.drawEllipse(m_positions[otherNode].x() - 5, m_positions[otherNode].y() - 5, 10, 10);
painter.drawEllipse(m_positions[edge.target].x() - 5, m_positions[edge.target].y() - 5, 10, 10);

painter.setPen(penColor);
painter.drawText(m_positions[otherNode], otherNode);
painter.drawText(m_positions[edge.target], edge.target);
}
}

Expand Down Expand Up @@ -116,7 +123,6 @@ void HiveWidget::calculate()
timer.start();
m_positions.clear();
m_nodeColors.clear();
m_edgePaths.clear();

if (m_nodes.isEmpty() || m_edges.isEmpty()) {
return;
Expand Down Expand Up @@ -166,51 +172,41 @@ void HiveWidget::calculate()
} else if (m_edges.count() > 100) {
lineAlpha = 64;
}
for (QString node : m_positions.keys()) {
if (!m_edges.contains(node)) {
continue;
}

for (const QString &otherNode : m_edges.values(node)) {
Edge edge;

const double nodeX = m_positions[node].x();
const double nodeY = m_positions[node].y();
const double otherX = m_positions[otherNode].x();
const double otherY = m_positions[otherNode].y();

double magnitude = hypot(nodeX - cx, nodeY - cy);
double otherMagnitude = hypot(otherX - cx, otherY - cy);
double averageRadians = atan2(((nodeY - cy) + (otherY - cy))/2, ((nodeX - cx) + (otherX - cx))/2);

double averageMagnitude;
if (m_scaleEdgeMax) {
averageMagnitude = qMax(magnitude, otherMagnitude);
} else {
averageMagnitude = (magnitude + otherMagnitude) / 2;
}

QPointF controlPoint(cos(averageRadians) * averageMagnitude + cx, sin(averageRadians) * averageMagnitude + cy);

QLinearGradient gradient(m_positions[node], m_positions[otherNode]);
QColor color = m_nodeColors[node];
color.setAlpha(lineAlpha);
gradient.setColorAt(0, color);
color.setAlpha(lineAlpha / 2);
gradient.setColorAt(0.5, color);
color = m_nodeColors[otherNode];
color.setAlpha(lineAlpha / 3);
gradient.setColorAt(1, color);
edge.brush = QBrush(gradient);

QPainterPath path;
path.moveTo(m_positions[node]);
path.quadTo(controlPoint, m_positions[otherNode]);
edge.first = node;
edge.second = otherNode;
edge.path = stroker.createStroke(path);
m_edgePaths.append(edge);
for (Edge &edge : m_edges) {
const double nodeX = m_positions[edge.source].x();
const double nodeY = m_positions[edge.source].y();
const double otherX = m_positions[edge.target].x();
const double otherY = m_positions[edge.target].y();

double magnitude = hypot(nodeX - cx, nodeY - cy);
double otherMagnitude = hypot(otherX - cx, otherY - cy);
double averageRadians = atan2(((nodeY - cy) + (otherY - cy))/2, ((nodeX - cx) + (otherX - cx))/2);

double averageMagnitude;
if (m_scaleEdgeMax) {
averageMagnitude = qMax(magnitude, otherMagnitude);
} else {
averageMagnitude = (magnitude + otherMagnitude) / 2;
}

QPointF controlPoint(cos(averageRadians) * averageMagnitude + cx, sin(averageRadians) * averageMagnitude + cy);

QLinearGradient gradient(m_positions[edge.source], m_positions[edge.target]);
QColor color = m_nodeColors[edge.source];
color.setAlpha(lineAlpha);
gradient.setColorAt(0, color);
color.setAlpha(lineAlpha / 2);
gradient.setColorAt(0.5, color);
color = m_nodeColors[edge.target];
color.setAlpha(lineAlpha / 3);
gradient.setColorAt(1, color);
edge.brush = QBrush(gradient);

QPainterPath path;
path.moveTo(m_positions[edge.source]);
path.quadTo(controlPoint, m_positions[edge.target]);
edge.path = stroker.createStroke(path);
}
qDebug() << "calculating took" << timer.restart() << "ms";
}
13 changes: 8 additions & 5 deletions hivewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
#include <QMultiMap>

struct Edge {
QString first;
QString second;
QString source;
QString target;
QPainterPath path;
QBrush brush;

bool operator==(const Edge &other) {
return (source == other.source && target == other.target);
}
};

class HiveWidget : public QOpenGLWidget
Expand All @@ -20,7 +24,7 @@ class HiveWidget : public QOpenGLWidget
~HiveWidget();

void setNodes(const QMultiMap<QString, QString> &nodes);
void setEdges(const QMultiMap<QString, QString> &edges);
void setEdges(const QList<Edge> &edges);

protected:
virtual void paintEvent(QPaintEvent *);
Expand All @@ -31,9 +35,8 @@ class HiveWidget : public QOpenGLWidget
void calculate();

QMultiMap<QString, QString> m_nodes;
QMultiMap<QString, QString> m_edges;
QList<Edge> m_edges;

QList<Edge> m_edgePaths;
QMap<QString, QColor> m_nodeColors;
QMap<QString, QColor> m_colors;
QMap<QString, QPoint> m_positions;
Expand Down
9 changes: 6 additions & 3 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,15 @@ int main(int argc, char *argv[])
}
}

QMultiMap<QString, QString> edges;
QList<Edge> edges;
for (int i=0; i<50; i++) {
QString nodeA = createNode();
QString nodeB = createNode();
if (edges.value(nodeA) != nodeB && nodeGroups[nodeA] != nodeGroups[nodeB]) {
edges.insert(nodeA, nodeB);
Edge edge;
edge.source = nodeA;
edge.target = nodeB;
if (!edges.contains(edge)) {
edges.append(edge);
}
}

Expand Down

0 comments on commit 5d72f65

Please sign in to comment.