Engauge Digitizer 2
Loading...
Searching...
No Matches
Curve.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
7#include "Curve.h"
8#include "CurvesGraphs.h"
9#include "CurveStyle.h"
10#include "DocumentSerialize.h"
11#include "EngaugeAssert.h"
12#include "Logger.h"
13#include "MigrateToVersion6.h"
14#include "Point.h"
15#include "PointComparator.h"
16#include <QDataStream>
17#include <QDebug>
18#include <qmath.h>
19#include <QMultiMap>
20#include <QTextStream>
21#include <QXmlStreamReader>
22#include <QXmlStreamWriter>
23#include "Transformation.h"
24#include "Xml.h"
25
26const QString AXIS_CURVE_NAME ("Axes");
27const QString DEFAULT_GRAPH_CURVE_NAME ("Curve1");
28const QString DUMMY_CURVE_NAME ("dummy");
29const QString SCALE_CURVE_NAME ("Scale"); // Used for pre-version 6 input files
30const QString TAB_DELIMITER ("\t");
31
32// This has to be a multimap instead of a map since some users may mistakenly allow multiple points with the
33// same x coordinate in their functions even though that should not happen
34typedef QMultiMap<double, QString> XOrThetaToPointIdentifier;
35
36Curve::Curve(const QString &curveName,
37 const ColorFilterSettings &colorFilterSettings,
38 const CurveStyle &curveStyle) :
39 m_curveName (curveName),
40 m_colorFilterSettings (colorFilterSettings),
41 m_curveStyle (curveStyle)
42{
43}
44
45Curve::Curve (const Curve &curve) :
46 m_curveName (curve.curveName ()),
47 m_points (curve.points ()),
48 m_colorFilterSettings (curve.colorFilterSettings ()),
49 m_curveStyle (curve.curveStyle ())
50{
51}
52
53Curve::Curve (QDataStream &str)
54{
55 const int CONVERT_ENUM_TO_RADIUS = 6;
56 MigrateToVersion6 migrate;
57
58 qint32 int32, xScreen, yScreen;
59 double xGraph, yGraph;
60
61 str >> m_curveName;
62
63 // Scale bar points are handled as if they are axis points
64 if (m_curveName == SCALE_CURVE_NAME) {
65 m_curveName = AXIS_CURVE_NAME;
66 }
67
68 str >> int32;
69 m_curveStyle.setPointShape(migrate.pointShape (int32));
70 str >> int32;
71 m_curveStyle.setPointRadius(int32 + CONVERT_ENUM_TO_RADIUS);
72 str >> int32;
73 m_curveStyle.setPointLineWidth (int32);
74 str >> int32;
75 m_curveStyle.setPointColor(migrate.colorPalette (int32));
76 str >> int32; // Point interior color
77 str >> int32;
78 m_curveStyle.setLineWidth(int32);
79 str >> int32;
80 if (m_curveName == AXIS_CURVE_NAME) {
81 m_curveStyle.setLineColor(migrate.colorPalette (int32));
82 } else {
84 }
85 str >> int32;
86 m_curveStyle.setLineConnectAs(migrate.curveConnectAs (int32));
87
88 str >> int32;
89 int count = int32;
90 int ordinal = 0;
91 for (int i = 0; i < count; i++) {
92
93 str >> xScreen;
94 str >> yScreen;
95 str >> xGraph;
96 str >> yGraph;
97 if (m_curveName == AXIS_CURVE_NAME) {
98
99 // Axis point, with graph coordinates set by user and managed here
100 Point point (m_curveName,
101 QPointF (xScreen, yScreen),
102 QPointF (xGraph, yGraph),
103 ordinal++,
104 false);
105
106 addPoint(point);
107 } else {
108
109 // Curve point, with graph coordinates managed elsewhere
110 Point point (m_curveName,
111 QPointF (xScreen, yScreen));
112 point.setOrdinal (ordinal++);
113
114 addPoint(point);
115 }
116 }
117}
118
119Curve::Curve (QXmlStreamReader &reader)
120{
121 loadXml(reader);
122}
123
125{
126 m_curveName = curve.curveName ();
127 m_points = curve.points ();
128 m_colorFilterSettings = curve.colorFilterSettings ();
129 m_curveStyle = curve.curveStyle ();
130
131 return *this;
132}
133
134void Curve::addPoint (const Point &point)
135{
136 m_points.push_back (point);
137}
138
140{
141 return m_colorFilterSettings;
142}
143
144QString Curve::curveName () const
145{
146 return m_curveName;
147}
148
150{
151 return m_curveStyle;
152}
153
154void Curve::editPointAxis (const QPointF &posGraph,
155 const QString &identifier)
156{
157 // Search for the point with matching identifier
158 QList<Point>::iterator itr;
159 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
160
161 Point &point = *itr;
162 if (point.identifier () == identifier) {
163
164 point.setPosGraph (posGraph);
165 break;
166
167 }
168 }
169}
170
172 bool isY,
173 double x,
174 double y,
175 const QStringList &identifiers,
176 const Transformation &transformation)
177{
178 LOG4CPP_INFO_S ((*mainCat)) << "Curve::editPointGraph"
179 << " identifiers=" << identifiers.join(" ").toLatin1().data();
180
181 if (transformation.transformIsDefined()) {
182
183 // Search for the point with matching identifier
184 QList<Point>::iterator itr;
185 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
186
187 Point &point = *itr;
188
189 if (identifiers.contains (point.identifier ())) {
190
191 // Although one or more graph coordinates are specified, it is the screen coordinates that must be
192 // moved. This is because only the screen coordinates of the graph points are tracked (not the graph coordinates).
193 // So we compute posScreen and call Point::setPosScreen instead of Point::setPosGraph
194
195 // Get original graph coordinates
196 QPointF posScreen = point.posScreen ();
197 QPointF posGraph;
198 transformation.transformScreenToRawGraph (posScreen,
199 posGraph);
200
201 // Override one or both coordinates
202 if (isX) {
203 posGraph.setX (x);
204 }
205
206 if (isY) {
207 posGraph.setY (y);
208 }
209
210 // Set the screen coordinates
211 transformation.transformRawGraphToScreen(posGraph,
212 posScreen);
213
214 point.setPosScreen (posScreen);
215 }
216 }
217 }
218}
219
220void Curve::exportToClipboard (const QHash<QString, bool> &selectedHash,
221 const Transformation &transformation,
222 QTextStream &strCsv,
223 QTextStream &strHtml,
224 CurvesGraphs &curvesGraphs) const
225{
226 LOG4CPP_INFO_S ((*mainCat)) << "Curve::exportToClipboard"
227 << " hashCount=" << selectedHash.count();
228
229 // This method assumes Copy is only allowed when Transformation is valid
230
231 bool isFirst = true;
232 QList<Point>::const_iterator itr;
233 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
234
235 const Point &point = *itr;
236 if (selectedHash.contains (point.identifier ())) {
237
238 if (isFirst) {
239
240 // Insert headers to identify the points that follow
241 isFirst = false;
242 strCsv << "X" << TAB_DELIMITER << m_curveName << "\n";
243 strHtml << "<table>\n"
244 << "<tr><th>X</th><th>" << m_curveName << "</th></tr>\n";
245 }
246
247 // Default curve style
248 CurveStyle curveStyleDefault;
249 curveStyleDefault.setLineStyle(LineStyle::defaultAxesCurve());
250 curveStyleDefault.setPointStyle(PointStyle::defaultGraphCurve (curvesGraphs.numCurves ()));
251
252 // Check if this curve already exists from a previously exported point
253 if (curvesGraphs.curveForCurveName (m_curveName) == nullptr) {
254 Curve curve(m_curveName,
256 curveStyleDefault);
257 curvesGraphs.addGraphCurveAtEnd(curve);
258 }
259
260 // Start with screen coordinates
261 QPointF pos = point.posScreen();
262 if (transformation.transformIsDefined()) {
263
264 // Replace with graph coordinates which are almost always more useful
265 QPointF posGraph;
266 transformation.transformScreenToRawGraph(pos,
267 posGraph);
268 pos = posGraph;
269 }
270
271 // Add point to text going to clipboard
272 strCsv << pos.x() << TAB_DELIMITER << pos.y() << "\n";
273 strHtml << "<tr><td>" << pos.x() << "</td><td>" << pos.y() << "</td></tr>\n";
274
275 // Add point to list for undo/redo
276 curvesGraphs.curveForCurveName (m_curveName)->addPoint (point);
277 }
278 }
279
280 if (!isFirst) {
281 strHtml << "</table>\n";
282 }
283}
284
285bool Curve::isXOnly(const QString &pointIdentifier) const
286{
287 // Search for point with matching identifier
288 Points::const_iterator itr;
289 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
290 const Point &point = *itr;
291 if (pointIdentifier == point.identifier ()) {
292 return point.isXOnly();
293 }
294 }
295
296 ENGAUGE_ASSERT (false);
297
298 return false;
299}
300
301void Curve::iterateThroughCurvePoints (const Functor2wRet<const QString &, const Point&, CallbackSearchReturn> &ftorWithCallback) const
302{
303 QList<Point>::const_iterator itr;
304 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
305
306 const Point &point = *itr;
307
308 CallbackSearchReturn rtn = ftorWithCallback (m_curveName, point);
309
311 break;
312 }
313 }
314}
315
316void Curve::iterateThroughCurveSegments (const Functor2wRet<const Point&, const Point&, CallbackSearchReturn> &ftorWithCallback) const
317{
318 // Loop through Points. They are assumed to be already sorted by their ordinals, but we do NOT
319 // check the ordinal ordering since this could be called before, or while, the ordinal sorting is done
320 QList<Point>::const_iterator itr;
321 const Point *pointBefore = nullptr;
322 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
323
324 const Point &point = *itr;
325
326 if (pointBefore != nullptr) {
327
328 CallbackSearchReturn rtn = ftorWithCallback (*pointBefore,
329 point);
330
332 break;
333 }
334
335 }
336 pointBefore = &point;
337 }
338}
339
340void Curve::loadCurvePoints(QXmlStreamReader &reader)
341{
342 LOG4CPP_INFO_S ((*mainCat)) << "Curve::loadCurvePoints";
343
344 bool success = true;
345
346 while ((reader.tokenType() != QXmlStreamReader::EndElement) ||
347 (reader.name() != DOCUMENT_SERIALIZE_CURVE_POINTS)) {
348
349 QXmlStreamReader::TokenType tokenType = loadNextFromReader(reader);
350
351 if (reader.atEnd()) {
352 success = false;
353 break;
354 }
355
356 if (tokenType == QXmlStreamReader::StartElement) {
357
358 if (reader.name () == DOCUMENT_SERIALIZE_POINT) {
359
360 Point point (reader);
361 m_points.push_back (point);
362 }
363 }
364 }
365
366 if (!success) {
367 reader.raiseError(QObject::tr ("Cannot read curve data"));
368 }
369}
370
371void Curve::loadXml(QXmlStreamReader &reader)
372{
373 LOG4CPP_INFO_S ((*mainCat)) << "Curve::loadXml";
374
375 bool success = true;
376
377 QXmlStreamAttributes attributes = reader.attributes();
378
379 if (attributes.hasAttribute (DOCUMENT_SERIALIZE_CURVE_NAME)) {
380
381 setCurveName (attributes.value (DOCUMENT_SERIALIZE_CURVE_NAME).toString());
382
383 // Read until end of this subtree
384 while ((reader.tokenType() != QXmlStreamReader::EndElement) ||
385 (reader.name() != DOCUMENT_SERIALIZE_CURVE)){
386
387 QXmlStreamReader::TokenType tokenType = loadNextFromReader(reader);
388
389 if (reader.atEnd()) {
390 success = false;
391 break;
392 }
393
394 if (tokenType == QXmlStreamReader::StartElement) {
395
396 if (reader.name() == DOCUMENT_SERIALIZE_COLOR_FILTER) {
397 m_colorFilterSettings.loadXml(reader);
398 } else if (reader.name() == DOCUMENT_SERIALIZE_CURVE_POINTS) {
399 loadCurvePoints(reader);
400 } else if (reader.name() == DOCUMENT_SERIALIZE_CURVE_STYLE) {
401 m_curveStyle.loadXml(reader);
402 } else {
403 success = false;
404 break;
405 }
406 }
407
408 if (reader.hasError()) {
409 // No need to set success flag to indicate failure, which raises the error, since the error was already raised. Just
410 // need to exit the loop immediately
411 break;
412 }
413 }
414 } else {
415 success = false;
416 }
417
418 if (!success) {
419 reader.raiseError (QObject::tr ("Cannot read curve data"));
420 }
421}
422
423void Curve::movePoint (const QString &pointIdentifier,
424 const QPointF &deltaScreen)
425{
426 Point *point = pointForPointIdentifier (pointIdentifier);
427
428 QPointF posScreen = deltaScreen + point->posScreen ();
429 point->setPosScreen (posScreen);
430}
431
433{
434 return m_points.count ();
435}
436
437Point *Curve::pointForPointIdentifier (const QString pointIdentifier)
438{
439 Points::iterator itr;
440 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
441 Point &point = *itr;
442 if (pointIdentifier == point.identifier ()) {
443 return &point;
444 }
445 }
446
447 ENGAUGE_ASSERT (false);
448 return nullptr;
449}
450
451const Points Curve::points () const
452{
453 return m_points;
454}
455
456QPointF Curve::positionGraph (const QString &pointIdentifier) const
457{
458 QPointF posGraph;
459
460 // Search for point with matching identifier
461 Points::const_iterator itr;
462 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
463 const Point &point = *itr;
464 if (pointIdentifier == point.identifier ()) {
465 posGraph = point.posGraph ();
466 break;
467 }
468 }
469
470 return posGraph;
471}
472
473QPointF Curve::positionScreen (const QString &pointIdentifier) const
474{
475 QPointF posScreen;
476
477 // Search for point with matching identifier
478 Points::const_iterator itr;
479 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
480 const Point &point = *itr;
481 if (pointIdentifier == point.identifier ()) {
482 posScreen = point.posScreen ();
483 break;
484 }
485 }
486
487 return posScreen;
488}
489
490void Curve::printStream (QString indentation,
491 QTextStream &str) const
492{
493 str << indentation << "Curve=" << m_curveName << "\n";
494
495 indentation += INDENTATION_DELTA;
496
497 Points::const_iterator itr;
498 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
499 const Point &point = *itr;
500 point.printStream (indentation,
501 str);
502 }
503
504 m_colorFilterSettings.printStream (indentation,
505 str);
506 m_curveStyle.printStream (indentation,
507 str);
508}
509
510void Curve::removePoint (const QString &identifier)
511{
512 // Search for point with matching identifier
513 Points::iterator itr;
514 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
515 Point point = *itr;
516 if (point.identifier () == identifier) {
517 m_points.erase (itr);
518 break;
519 }
520 }
521}
522
523void Curve::saveXml(QXmlStreamWriter &writer) const
524{
525 LOG4CPP_INFO_S ((*mainCat)) << "Curve::saveXml";
526
527 writer.writeStartElement(DOCUMENT_SERIALIZE_CURVE);
528 writer.writeAttribute(DOCUMENT_SERIALIZE_CURVE_NAME, m_curveName);
529 m_colorFilterSettings.saveXml (writer,
530 m_curveName);
531 m_curveStyle.saveXml (writer,
532 m_curveName);
533
534 // Loop through points
535 writer.writeStartElement(DOCUMENT_SERIALIZE_CURVE_POINTS);
536 Points::const_iterator itr;
537 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
538 const Point &point = *itr;
539 point.saveXml (writer);
540 }
541 writer.writeEndElement();
542
543 writer.writeEndElement();
544}
545
546void Curve::setColorFilterSettings (const ColorFilterSettings &colorFilterSettings)
547{
548 m_colorFilterSettings = colorFilterSettings;
549}
550
551void Curve::setCurveName (const QString &curveName)
552{
553 m_curveName = curveName;
554
555 // Pass to member objects
556 QList<Point>::iterator itr;
557 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
558 Point &point = *itr;
559 point.setCurveName (curveName);
560 }
561}
562
563void Curve::setCurveStyle (const CurveStyle &curveStyle)
564{
565 m_curveStyle = curveStyle;
566}
567
568void Curve::updatePointOrdinals (const Transformation &transformation)
569{
570 CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
571
572 LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinals"
573 << " curve=" << m_curveName.toLatin1().data()
574 << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
575
576 // Make sure ordinals are properly ordered. Sorting is done afterward
577
578 if (curveConnectAs == CONNECT_AS_FUNCTION_SMOOTH ||
579 curveConnectAs == CONNECT_AS_FUNCTION_STRAIGHT) {
580
581 updatePointOrdinalsFunctions (transformation);
582
583 } else if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH ||
584 curveConnectAs == CONNECT_AS_RELATION_STRAIGHT) {
585
586 updatePointOrdinalsRelations ();
587
588 } else {
589
590 LOG4CPP_ERROR_S ((*mainCat)) << "Curve::updatePointOrdinals";
591 ENGAUGE_ASSERT (false);
592
593 }
594
595 qSort (m_points.begin(),
596 m_points.end(),
598}
599
600void Curve::updatePointOrdinalsFunctions (const Transformation &transformation)
601{
602 CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
603
604 LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinalsFunctions"
605 << " curve=" << m_curveName.toLatin1().data()
606 << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
607
608 // Get a map of x/theta values as keys with point identifiers as the values. This has to be a multimap since
609 // some users will have two (or maybe more) points with the same x coordinate, even though true functions should
610 // never have that happen
611 XOrThetaToPointIdentifier xOrThetaToPointIdentifier;
612 Points::iterator itr;
613 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
614 Point &point = *itr;
615
616 QPointF posGraph;
617 if (transformation.transformIsDefined()) {
618
619 // Transformation is available so use it
620 transformation.transformScreenToRawGraph (point.posScreen (),
621 posGraph);
622 } else {
623
624 // Transformation is not available so we just use the screen coordinates. Effectively, the
625 // transformation is the identity matrix
626 posGraph= point.posScreen();
627 }
628
629 xOrThetaToPointIdentifier.insert (posGraph.x(),
630 point.identifier());
631 }
632
633 // Every point in m_points must be in the map. Failure to perform this check will probably result in the assert
634 // below getting triggered
635 ENGAUGE_ASSERT (xOrThetaToPointIdentifier.count () == m_points.count ());
636
637 // Since m_points is a list (and therefore does not provide direct access to elements), we build a temporary map of
638 // point identifier to ordinal, by looping through the sorted x/theta values. Since QMap is used, the x/theta keys are sorted
639 QMap<QString, double> pointIdentifierToOrdinal;
640 int ordinal = 0;
641 XOrThetaToPointIdentifier::const_iterator itrX;
642 for (itrX = xOrThetaToPointIdentifier.begin(); itrX != xOrThetaToPointIdentifier.end(); itrX++) {
643
644 QString pointIdentifier = itrX.value();
645 pointIdentifierToOrdinal [pointIdentifier] = ordinal++;
646 }
647
648 // Override the old ordinal values
649 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
650 Point &point = *itr;
651
652 // Make sure point is in the map list. If this test is skipped then the square bracket operator
653 // will insert an entry with a zero ordinal, and the presence of multiple points with the same zero ordinal will
654 // cause problems downstream
655 ENGAUGE_ASSERT (pointIdentifierToOrdinal.contains (point.identifier()));
656
657 // Point is to be included since it is in the map list.
658 int ordinalNew = qFloor (pointIdentifierToOrdinal [point.identifier()]);
659 point.setOrdinal (ordinalNew);
660 }
661}
662
663void Curve::updatePointOrdinalsRelations ()
664{
665 CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
666
667 LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinalsRelations"
668 << " curve=" << m_curveName.toLatin1().data()
669 << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
670
671 // Keep the ordinal numbering, but make sure the ordinals are evenly spaced
672 Points::iterator itr;
673 int ordinal = 0;
674 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
675 Point &point = *itr;
676 point.setOrdinal (ordinal++);
677 }
678}
const QString AXIS_CURVE_NAME
CallbackSearchReturn
Return values for search callback methods.
@ CALLBACK_SEARCH_RETURN_INTERRUPT
Immediately terminate the current search.
const QString DUMMY_CURVE_NAME
@ COLOR_PALETTE_TRANSPARENT
QString curveConnectAsToString(CurveConnectAs curveConnectAs)
CurveConnectAs
@ CONNECT_AS_FUNCTION_STRAIGHT
@ CONNECT_AS_RELATION_STRAIGHT
@ CONNECT_AS_RELATION_SMOOTH
@ CONNECT_AS_FUNCTION_SMOOTH
QMultiMap< double, QString > XOrThetaToPointIdentifier
Definition Curve.cpp:34
const QString TAB_DELIMITER("\t")
const QString AXIS_CURVE_NAME
const QString SCALE_CURVE_NAME
const QString DEFAULT_GRAPH_CURVE_NAME
const QString DOCUMENT_SERIALIZE_COLOR_FILTER
const QString DOCUMENT_SERIALIZE_CURVE_NAME
const QString DOCUMENT_SERIALIZE_CURVE_STYLE
const QString DOCUMENT_SERIALIZE_POINT
const QString DOCUMENT_SERIALIZE_CURVE
const QString DOCUMENT_SERIALIZE_CURVE_POINTS
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) define ENGAUGE...
log4cpp::Category * mainCat
Definition Logger.cpp:14
const QString INDENTATION_DELTA
QList< Point > Points
Definition Points.h:13
QXmlStreamReader::TokenType loadNextFromReader(QXmlStreamReader &reader)
Load next token from xml reader.
Definition Xml.cpp:14
Color filter parameters for one curve. For a class, this is handled the same as LineStyle and PointSt...
static ColorFilterSettings defaultFilter()
Initial default for any Curve.
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
void saveXml(QXmlStreamWriter &writer, const QString &curveName) const
Save curve filter to stream.
void loadXml(QXmlStreamReader &reader)
Load curve filter to stream.
Container for LineStyle and PointStyle for one Curve.
Definition CurveStyle.h:19
void setLineColor(ColorPalette lineColor)
Set method for line color in specified curve.
void setPointRadius(int radius)
Set method for curve point radius.
LineStyle lineStyle() const
Get method for LineStyle.
void setPointLineWidth(int width)
Set method for curve point perimeter line width.
QString loadXml(QXmlStreamReader &reader)
Load from serialized xml. Returns the curve name.
void setLineConnectAs(CurveConnectAs curveConnectAs)
Set method for connect as method for lines in specified curve.
void setLineWidth(int width)
Set method for line width in specified curve.
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
void setPointStyle(const PointStyle &pointStyle)
Set method for PointStyle.
void saveXml(QXmlStreamWriter &writer, const QString &curveName) const
Serialize to xml.
void setPointColor(ColorPalette curveColor)
Set method curve point color in specified curve.
void setLineStyle(const LineStyle &lineStyle)
Set method for LineStyle.
void setPointShape(PointShape shape)
Set method for curve point shape in specified curve.
Container for one set of digitized Points.
Definition Curve.h:34
bool isXOnly(const QString &pointIdentifier) const
Determine if specified point has just x coordinate. Otherwise has just y coordinate,...
Definition Curve.cpp:285
void saveXml(QXmlStreamWriter &writer) const
Serialize curve.
Definition Curve.cpp:523
void movePoint(const QString &pointIdentifier, const QPointF &deltaScreen)
Translate the position of a point by the specified distance vector.
Definition Curve.cpp:423
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
Definition Curve.cpp:490
Curve & operator=(const Curve &curve)
Assignment constructor.
Definition Curve.cpp:124
CurveStyle curveStyle() const
Return the curve style.
Definition Curve.cpp:149
void exportToClipboard(const QHash< QString, bool > &selectedHash, const Transformation &transformation, QTextStream &strCsv, QTextStream &strHtml, CurvesGraphs &curvesGraphs) const
Export points in this Curve found in the specified point list.
Definition Curve.cpp:220
void setCurveStyle(const CurveStyle &curveStyle)
Set curve style.
Definition Curve.cpp:563
void updatePointOrdinals(const Transformation &transformation)
See CurveGraphs::updatePointOrdinals.
Definition Curve.cpp:568
void editPointAxis(const QPointF &posGraph, const QString &identifier)
Edit the graph coordinates of an axis point. This method does not apply to a graph point.
Definition Curve.cpp:154
ColorFilterSettings colorFilterSettings() const
Return the color filter.
Definition Curve.cpp:139
void removePoint(const QString &identifier)
Perform the opposite of addPointAtEnd.
Definition Curve.cpp:510
const Points points() const
Return a shallow copy of the Points.
Definition Curve.cpp:451
void setColorFilterSettings(const ColorFilterSettings &colorFilterSettings)
Set color filter.
Definition Curve.cpp:546
void addPoint(const Point &point)
Add Point to this Curve.
Definition Curve.cpp:134
void setCurveName(const QString &curveName)
Change the curve name.
Definition Curve.cpp:551
QString curveName() const
Name of this Curve.
Definition Curve.cpp:144
QPointF positionScreen(const QString &pointIdentifier) const
Return the position, in screen coordinates, of the specified Point.
Definition Curve.cpp:473
Curve(const QString &curveName, const ColorFilterSettings &colorFilterSettings, const CurveStyle &curveStyle)
Constructor from scratch.
Definition Curve.cpp:36
void iterateThroughCurvePoints(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback) const
Apply functor to Points on Curve.
Definition Curve.cpp:301
QPointF positionGraph(const QString &pointIdentifier) const
Return the position, in graph coordinates, of the specified Point.
Definition Curve.cpp:456
void iterateThroughCurveSegments(const Functor2wRet< const Point &, const Point &, CallbackSearchReturn > &ftorWithCallback) const
Apply functor to successive Points, as line segments, on Curve. This could be a bit slow.
Definition Curve.cpp:316
void editPointGraph(bool isX, bool isY, double x, double y, const QStringList &identifiers, const Transformation &transformation)
Edit the graph coordinates of one or more graph points. This method does not apply to an axis point.
Definition Curve.cpp:171
int numPoints() const
Number of points.
Definition Curve.cpp:432
Container for all graph curves. The axes point curve is external to this class.
Curve * curveForCurveName(const QString &curveName)
Return the axis or graph curve for the specified curve name.
int numCurves() const
Current number of graphs curves.
void addGraphCurveAtEnd(const Curve &curve)
Append new graph Curve to end of Curve list.
static LineStyle defaultAxesCurve()
Initial default for axes curve.
Definition LineStyle.cpp:68
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition LineStyle.cpp:63
Converts old (=pre version 6) enums to new (=version 6) enums, for reading of old document files.
CurveConnectAs curveConnectAs(int preVersion6) const
Line drawn between points.
ColorPalette colorPalette(int preVersion6) const
Color from color palette.
PointShape pointShape(int preVersion6) const
Point shape.
static PointStyle defaultGraphCurve(int index)
Initial default for index'th graph curve.
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition Point.h:26
void setOrdinal(double ordinal)
Set the ordinal used for ordering Points.
Definition Point.cpp:486
void setCurveName(const QString &curveName)
Update the point identifer to match the specified curve name.
Definition Point.cpp:471
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
Definition Point.cpp:409
void setPosScreen(const QPointF &posScreen)
Set method for position in screen coordinates.
Definition Point.cpp:510
QPointF posGraph(ApplyHasCheck applyHasCheck=KEEP_HAS_CHECK) const
Accessor for graph position. Skip check if copying one instance to another.
Definition Point.cpp:395
QPointF posScreen() const
Accessor for screen position.
Definition Point.cpp:404
QString identifier() const
Unique identifier for a specific Point.
Definition Point.cpp:268
void saveXml(QXmlStreamWriter &writer) const
Serialize to stream.
Definition Point.cpp:432
void setPosGraph(const QPointF &posGraph)
Set method for position in graph coordinates.
Definition Point.cpp:496
bool isXOnly() const
In DOCUMENT_AXES_POINTS_REQUIRED_4 modes, this is true/false if y/x coordinate is undefined.
Definition Point.cpp:286
Affine transformation between screen and graph coordinates, based on digitized axis points.
void transformRawGraphToScreen(const QPointF &pointRaw, QPointF &pointScreen) const
Transform from raw graph coordinates to linear cartesian graph coordinates, then to screen coordinate...
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18
#define LOG4CPP_ERROR_S(logger)
Definition convenience.h:12
Comparator for sorting Point class.