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,
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 {
83 m_curveStyle.setLineColor(COLOR_PALETTE_TRANSPARENT);
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 LOG4CPP_ERROR_S ((*mainCat)) << "Curve::isXOnly encountered unknown indentifier "
297 << pointIdentifier.toLatin1().data();
298 ENGAUGE_ASSERT (false);
299
300 return false;
301}
302
303void Curve::iterateThroughCurvePoints (const Functor2wRet<const QString &, const Point&, CallbackSearchReturn> &ftorWithCallback) const
304{
305 QList<Point>::const_iterator itr;
306 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
307
308 const Point &point = *itr;
309
310 CallbackSearchReturn rtn = ftorWithCallback (m_curveName, point);
311
313 break;
314 }
315 }
316}
317
318void Curve::iterateThroughCurveSegments (const Functor2wRet<const Point&, const Point&, CallbackSearchReturn> &ftorWithCallback) const
319{
320 // Loop through Points. They are assumed to be already sorted by their ordinals, but we do NOT
321 // check the ordinal ordering since this could be called before, or while, the ordinal sorting is done
322 QList<Point>::const_iterator itr;
323 const Point *pointBefore = nullptr;
324 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
325
326 const Point &point = *itr;
327
328 if (pointBefore != nullptr) {
329
330 CallbackSearchReturn rtn = ftorWithCallback (*pointBefore,
331 point);
332
334 break;
335 }
336
337 }
338 pointBefore = &point;
339 }
340}
341
342void Curve::loadCurvePoints(QXmlStreamReader &reader)
343{
344 LOG4CPP_INFO_S ((*mainCat)) << "Curve::loadCurvePoints";
345
346 bool success = true;
347
348 while ((reader.tokenType() != QXmlStreamReader::EndElement) ||
349 (reader.name() != DOCUMENT_SERIALIZE_CURVE_POINTS)) {
350
351 QXmlStreamReader::TokenType tokenType = loadNextFromReader(reader);
352
353 if (reader.atEnd()) {
354 success = false;
355 break;
356 }
357
358 if (tokenType == QXmlStreamReader::StartElement) {
359
360 if (reader.name () == DOCUMENT_SERIALIZE_POINT) {
361
362 Point point (reader);
363 m_points.push_back (point);
364 }
365 }
366 }
367
368 if (!success) {
369 reader.raiseError(QObject::tr ("Cannot read curve data"));
370 }
371}
372
373void Curve::loadXml(QXmlStreamReader &reader)
374{
375 LOG4CPP_INFO_S ((*mainCat)) << "Curve::loadXml";
376
377 bool success = true;
378
379 QXmlStreamAttributes attributes = reader.attributes();
380
381 if (attributes.hasAttribute (DOCUMENT_SERIALIZE_CURVE_NAME)) {
382
383 setCurveName (attributes.value (DOCUMENT_SERIALIZE_CURVE_NAME).toString());
384
385 // Read until end of this subtree
386 while ((reader.tokenType() != QXmlStreamReader::EndElement) ||
387 (reader.name() != DOCUMENT_SERIALIZE_CURVE)){
388
389 QXmlStreamReader::TokenType tokenType = loadNextFromReader(reader);
390
391 if (reader.atEnd()) {
392 success = false;
393 break;
394 }
395
396 if (tokenType == QXmlStreamReader::StartElement) {
397
398 if (reader.name() == DOCUMENT_SERIALIZE_COLOR_FILTER) {
399 m_colorFilterSettings.loadXml(reader);
400 } else if (reader.name() == DOCUMENT_SERIALIZE_CURVE_POINTS) {
401 loadCurvePoints(reader);
402 } else if (reader.name() == DOCUMENT_SERIALIZE_CURVE_STYLE) {
403 m_curveStyle.loadXml(reader);
404 } else {
405 success = false;
406 break;
407 }
408 }
409
410 if (reader.hasError()) {
411 // No need to set success flag to indicate failure, which raises the error, since the error was already raised. Just
412 // need to exit the loop immediately
413 break;
414 }
415 }
416 } else {
417 success = false;
418 }
419
420 if (!success) {
421 reader.raiseError (QObject::tr ("Cannot read curve data"));
422 }
423}
424
425void Curve::movePoint (const QString &pointIdentifier,
426 const QPointF &deltaScreen)
427{
428 Point *point = pointForPointIdentifier (pointIdentifier);
429
430 QPointF posScreen = deltaScreen + point->posScreen ();
431 point->setPosScreen (posScreen);
432}
433
435{
436 return m_points.count ();
437}
438
439Point *Curve::pointForPointIdentifier (const QString pointIdentifier)
440{
441 Points::iterator itr;
442 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
443 Point &point = *itr;
444 if (pointIdentifier == point.identifier ()) {
445 return &point;
446 }
447 }
448
449 LOG4CPP_ERROR_S ((*mainCat)) << "Curve::pointForPointIdentifier encountered unknown indentifier "
450 << pointIdentifier.toLatin1().data();
451 ENGAUGE_ASSERT (false);
452 return nullptr;
453}
454
455const Points Curve::points () const
456{
457 return m_points;
458}
459
460QPointF Curve::positionGraph (const QString &pointIdentifier) const
461{
462 QPointF posGraph;
463
464 // Search for point with matching identifier
465 Points::const_iterator itr;
466 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
467 const Point &point = *itr;
468 if (pointIdentifier == point.identifier ()) {
469 posGraph = point.posGraph ();
470 break;
471 }
472 }
473
474 return posGraph;
475}
476
477QPointF Curve::positionScreen (const QString &pointIdentifier) const
478{
479 QPointF posScreen;
480
481 // Search for point with matching identifier
482 Points::const_iterator itr;
483 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
484 const Point &point = *itr;
485 if (pointIdentifier == point.identifier ()) {
486 posScreen = point.posScreen ();
487 break;
488 }
489 }
490
491 return posScreen;
492}
493
494void Curve::printStream (QString indentation,
495 QTextStream &str) const
496{
497 str << indentation << "Curve=" << m_curveName << "\n";
498
499 indentation += INDENTATION_DELTA;
500
501 Points::const_iterator itr;
502 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
503 const Point &point = *itr;
504 point.printStream (indentation,
505 str);
506 }
507
508 m_colorFilterSettings.printStream (indentation,
509 str);
510 m_curveStyle.printStream (indentation,
511 str);
512}
513
514void Curve::removePoint (const QString &identifier)
515{
516 // Search for point with matching identifier
517 Points::iterator itr;
518 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
519 Point point = *itr;
520 if (point.identifier () == identifier) {
521 m_points.erase (itr);
522 break;
523 }
524 }
525}
526
527void Curve::saveXml(QXmlStreamWriter &writer) const
528{
529 LOG4CPP_INFO_S ((*mainCat)) << "Curve::saveXml";
530
531 writer.writeStartElement(DOCUMENT_SERIALIZE_CURVE);
532 writer.writeAttribute(DOCUMENT_SERIALIZE_CURVE_NAME, m_curveName);
533 m_colorFilterSettings.saveXml (writer,
534 m_curveName);
535 m_curveStyle.saveXml (writer,
536 m_curveName);
537
538 // Loop through points
539 writer.writeStartElement(DOCUMENT_SERIALIZE_CURVE_POINTS);
540 Points::const_iterator itr;
541 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
542 const Point &point = *itr;
543 point.saveXml (writer);
544 }
545 writer.writeEndElement();
546
547 writer.writeEndElement();
548}
549
554
555void Curve::setCurveName (const QString &curveName)
556{
557 m_curveName = curveName;
558
559 // Pass to member objects
560 QList<Point>::iterator itr;
561 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
562 Point &point = *itr;
563 point.setCurveName (curveName);
564 }
565}
566
568{
569 m_curveStyle = curveStyle;
570}
571
572void Curve::updatePointOrdinals (const Transformation &transformation)
573{
574 CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
575
576 LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinals"
577 << " curve=" << m_curveName.toLatin1().data()
578 << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
579
580 // Make sure ordinals are properly ordered. Sorting is done afterward
581
582 if (curveConnectAs == CONNECT_AS_FUNCTION_SMOOTH ||
583 curveConnectAs == CONNECT_AS_FUNCTION_STRAIGHT) {
584
585 updatePointOrdinalsFunctions (transformation);
586
587 } else if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH ||
588 curveConnectAs == CONNECT_AS_RELATION_STRAIGHT) {
589
590 updatePointOrdinalsRelations ();
591
592 } else {
593
594 LOG4CPP_ERROR_S ((*mainCat)) << "Curve::updatePointOrdinals encountered unexpected connection configuration";
595 ENGAUGE_ASSERT (false);
596
597 }
598
599 std::sort (m_points.begin(),
600 m_points.end(),
602}
603
604void Curve::updatePointOrdinalsFunctions (const Transformation &transformation)
605{
606 CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
607
608 LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinalsFunctions"
609 << " curve=" << m_curveName.toLatin1().data()
610 << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
611
612 // Get a map of x/theta values as keys with point identifiers as the values. This has to be a multimap since
613 // some users will have two (or maybe more) points with the same x coordinate, even though true functions should
614 // never have that happen
615 XOrThetaToPointIdentifier xOrThetaToPointIdentifier;
616 Points::iterator itr;
617 for (itr = m_points.begin (); itr != m_points.end (); itr++) {
618 Point &point = *itr;
619
620 QPointF posGraph;
621 if (transformation.transformIsDefined()) {
622
623 // Transformation is available so use it
624 transformation.transformScreenToRawGraph (point.posScreen (),
625 posGraph);
626 } else {
627
628 // Transformation is not available so we just use the screen coordinates. Effectively, the
629 // transformation is the identity matrix
630 posGraph= point.posScreen();
631 }
632
633 xOrThetaToPointIdentifier.insert (posGraph.x(),
634 point.identifier());
635 }
636
637 // Every point in m_points must be in the map. Failure to perform this check will probably result in the assert
638 // below getting triggered
639 ENGAUGE_ASSERT (xOrThetaToPointIdentifier.count () == m_points.count ());
640
641 // Since m_points is a list (and therefore does not provide direct access to elements), we build a temporary map of
642 // point identifier to ordinal, by looping through the sorted x/theta values. Since QMap is used, the x/theta keys are sorted
643 QMap<QString, double> pointIdentifierToOrdinal;
644 int ordinal = 0;
645 XOrThetaToPointIdentifier::const_iterator itrX;
646 for (itrX = xOrThetaToPointIdentifier.begin(); itrX != xOrThetaToPointIdentifier.end(); itrX++) {
647
648 QString pointIdentifier = itrX.value();
649 pointIdentifierToOrdinal [pointIdentifier] = ordinal++;
650 }
651
652 // Override the old ordinal values
653 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
654 Point &point = *itr;
655
656 // Make sure point is in the map list. If this test is skipped then the square bracket operator
657 // will insert an entry with a zero ordinal, and the presence of multiple points with the same zero ordinal will
658 // cause problems downstream
659 ENGAUGE_ASSERT (pointIdentifierToOrdinal.contains (point.identifier()));
660
661 // Point is to be included since it is in the map list.
662 int ordinalNew = qFloor (pointIdentifierToOrdinal [point.identifier()]);
663 point.setOrdinal (ordinalNew);
664 }
665}
666
667void Curve::updatePointOrdinalsRelations ()
668{
669 CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
670
671 LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinalsRelations"
672 << " curve=" << m_curveName.toLatin1().data()
673 << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
674
675 // Keep the ordinal numbering, but make sure the ordinals are evenly spaced
676 Points::iterator itr;
677 int ordinal = 0;
678 for (itr = m_points.begin(); itr != m_points.end(); itr++) {
679 Point &point = *itr;
680 point.setOrdinal (ordinal++);
681 }
682}
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.
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.
Container for LineStyle and PointStyle for one Curve.
Definition CurveStyle.h:19
LineStyle lineStyle() const
Get method for LineStyle.
void setPointStyle(const PointStyle &pointStyle)
Set method for PointStyle.
void setLineStyle(const LineStyle &lineStyle)
Set method for LineStyle.
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:527
void movePoint(const QString &pointIdentifier, const QPointF &deltaScreen)
Translate the position of a point by the specified distance vector.
Definition Curve.cpp:425
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:494
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:567
void updatePointOrdinals(const Transformation &transformation)
See CurveGraphs::updatePointOrdinals.
Definition Curve.cpp:572
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:514
const Points points() const
Return a shallow copy of the Points.
Definition Curve.cpp:455
void setColorFilterSettings(const ColorFilterSettings &colorFilterSettings)
Set color filter.
Definition Curve.cpp:550
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:555
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:477
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:303
QPointF positionGraph(const QString &pointIdentifier) const
Return the position, in graph coordinates, of the specified Point.
Definition Curve.cpp:460
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:318
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:434
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 identifier 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.