60
63
//// psChart Chart(dynamic_cast<psChart>(viewport->parent()));
66
//-------------------------------------------------------------- sChartScales ---
68
void sChartScales::RestoreSettings (sCluster::sPtr C)
72
sPhysRangeNode::sPtr R;
73
V=C->GetAttr("ScaleX.Variable");
74
if( V.IsCorrect() ) X.Name=V->Value();
75
V=C->GetAttr("ScaleY.Variable");
76
if( V.IsCorrect() ) Y.Name=V->Value();
78
R=C->GetAttr("ScaleX.Range");
79
if( R.IsCorrect() ) X.Range=(sPhysRange)(*R);
80
R=C->GetAttr("ScaleY.Range");
81
if( R.IsCorrect() ) Y.Range=(sPhysRange)(*R);
86
void sChartScales::StoreSettings (sCluster::sPtr C) const
89
C << attr("ScaleX.Variable",X.Name)
90
<< attr("ScaleX.Range",X.Range)
91
<< attr("ScaleY.Variable",Y.Name)
92
<< attr("ScaleY.Range",Y.Range);
63
96
//----------------------------------------------------------------- sMargins ---
65
98
sMargins::sMargins (int top ,int bottom ,int left ,int right)
96
129
//--------------------------------------------------------------- sAxis ---
131
sAxis::sAxis (bool upside_down)
100
134
,MultiplierExponent(0)
137
,LabelsArranged(false)
138
,LabelsOverlap(false)
105
141
Title.setDocumentMargin(0);
106
142
MinorTicks.Length=(MajorTicks.Length+1) / 2;
143
SetRange(sPhysRange(0,10,sUnits()));
147
void sAxis::SetPenWidth (int width)
150
SetOffset((PenWidth+1)/2);
110
154
int sAxis::Value2Offset (real value)
112
return ( (Range.To > Range.From)
113
? Round((value-Range.From)/(Range.To-Range.From)*NominalSize)
157
return Round((value-Range().From)/(Range().To-Range().From)*Size());
119
164
void sAxis::Arrange (const QFontMetrics & font_metrics)
124
166
MultiplierExponent=0;
125
MultiplierExponent=3*Round(log10( max(fabs(Range.From),fabs(Range.To))
167
MultiplierExponent=3*Round(log10( max(fabs(Range().From),fabs(Range().To))
127
169
Multiplier=power10(MultiplierExponent);
128
170
MajorTicks.Interval
129
= Multiplier * power10(Round(log10(
130
(Range.To-Range.From)/Multiplier/Labels.MaxAmount)-1.5)
171
= Multiplier * power10(Round( -1.0 + log10(
172
(Range().To-Range().From)/Multiplier/Labels.MaxAmount
132
174
MinorTicks.Interval=MajorTicks.Interval / 10;
133
ArrangeLabels(font_metrics,LabelsOverlap);
134
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
176
if( ArrangeLabels(font_metrics) ){
177
RANet::Log.Put(sLog::Debug,"Graph"
178
,sString("sAxis::Arrange: success in step #")<<1 );
135
180
MajorTicks.Interval*=2.0;
136
181
MinorTicks.Interval=MajorTicks.Interval / 2;
137
ArrangeLabels(font_metrics,LabelsOverlap);
138
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
182
if( ArrangeLabels(font_metrics) ){
183
RANet::Log.Put(sLog::Debug,"Graph"
184
,sString("sAxis::Arrange: success in step #")<<2 );
139
186
MajorTicks.Interval*=2.5;
140
187
MinorTicks.Interval=MajorTicks.Interval / 5;
141
ArrangeLabels(font_metrics,LabelsOverlap);
142
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
188
if( ArrangeLabels(font_metrics) ){
189
RANet::Log.Put(sLog::Debug,"Graph"
190
,sString("sAxis::Arrange: success in step #")<<3 );
143
192
MajorTicks.Interval*=2.0;
144
193
MinorTicks.Interval=MajorTicks.Interval / 10;
145
ArrangeLabels(font_metrics,LabelsOverlap);
146
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
194
if( ArrangeLabels(font_metrics) ){
195
RANet::Log.Put(sLog::Debug,"Graph"
196
,sString("sAxis::Arrange: success in step #")<<4 );
147
198
MajorTicks.Interval*=2.0;
148
199
MinorTicks.Interval=MajorTicks.Interval / 2;
149
ArrangeLabels(font_metrics,LabelsOverlap);
150
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
200
if( ArrangeLabels(font_metrics) ){
201
RANet::Log.Put(sLog::Debug,"Graph"
202
,sString("sAxis::Arrange: success in step #")<<5 );
151
204
MajorTicks.Interval*=2.5;
152
205
MinorTicks.Interval=MajorTicks.Interval / 5;
153
ArrangeLabels(font_metrics,LabelsOverlap);
154
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
206
if( ArrangeLabels(font_metrics) ){
207
RANet::Log.Put(sLog::Debug,"Graph"
208
,sString("sAxis::Arrange: success in step #")<<6 );
155
210
MajorTicks.Interval*=2.0;
156
211
MinorTicks.Interval=MajorTicks.Interval / 10;
157
ArrangeLabels(font_metrics,LabelsOverlap);
158
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
212
if( ArrangeLabels(font_metrics) ){
213
RANet::Log.Put(sLog::Debug,"Graph"
214
,sString("sAxis::Arrange: success in step #")<<7 );
159
216
MajorTicks.Interval*=2.0;
160
217
MinorTicks.Interval=MajorTicks.Interval / 2;
161
ArrangeLabels(font_metrics,LabelsOverlap);
162
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
218
if( ArrangeLabels(font_metrics) ){
219
RANet::Log.Put(sLog::Debug,"Graph"
220
,sString("sAxis::Arrange: success in step #")<<8 );
163
222
MajorTicks.Interval*=2.5;
164
223
MinorTicks.Interval=MajorTicks.Interval / 5;
165
ArrangeLabels(font_metrics,LabelsOverlap);
166
if( LabelsOverlap || (Labels.List.size() > Labels.MaxAmount) ){
167
TRACE("sAxis::Arrange - no success !!!!!!!!!!!!!!!!!!!!!!");
224
if( ArrangeLabels(font_metrics) ){
225
RANet::Log.Put(sLog::Debug,"Graph"
226
,sString("sAxis::Arrange: success in step #")<<9 );
170
// TRACE("sAxis::Arrange - success in eigth try");
228
RANet::Log.Put(sLog::Debug,"Graph"
229
,sString("sAxis::Arrange: no success !!!!!!!!!!!!!!!!!"));
173
// TRACE("sAxis::Arrange - success in seventh try");
176
// TRACE("sAxis::Arrange - success in sixth try");
179
// TRACE("sAxis::Arrange - success in fifth try");
182
// TRACE("sAxis::Arrange - success in fourth try");
185
TRACE("sAxis::Arrange - success in third try");
188
TRACE("sAxis::Arrange - success in second try");
191
TRACE("sAxis::Arrange - success in first try");
194
MinorTicks.Start=Round(Range.From/MinorTicks.Interval+0.499)*MinorTicks.Interval;
239
if(MultiplierExponent)
240
RANet::Log.Put(sLog::Debug,"Graph"
241
,sString(" MultiplierExponent=")<<MultiplierExponent
243
// RANet::Log.Put(sLog::Debug,"Graph"
244
// ,sString("sAxis::Arrange: LabelsArranged=")+(LabelsArranged ? "Y" : "N")
245
// +sString(" LabelsOverlap=")+(LabelsOverlap ? "Y" : "N")
224
280
digits=-Round(log10(MajorTicks.Interval/Multiplier)-0.499);
226
282
tick=MajorTicks.Start;
227
while( tick < Range.To + PixelValue()){ /*! @todo{bug} Infinite cycling if Interval is too small */
283
while( tick < Range().To + PixelValue() ){
228
284
LabelText.setNum(double((tick-Shift)/Multiplier),'f',digits);
229
285
Labels.List.push_back(sLabel(LabelText));
230
286
tick+=MajorTicks.Interval;
288
if( NumOfMajorTicks > 1000*(int)Labels.MaxAmount ){
289
RANet::Log.Put(sLog::Debug,"Graph"
290
,sString("cycling in sAxis::PrearrangeLabels: ")+Variable
291
+" Range().From="+sString::FromReal(Range().From,12)
292
+" Range().To="+sString::FromReal(Range().To,12)
293
+" MajorTicks.Interval="+sString::FromReal(MajorTicks.Interval,12)
294
+" MajorTicks.Start="+sString::FromReal(MajorTicks.Start,12)
295
// +" ="+sString::FromReal()
300
LabelsArranged = ! Labels.List.empty()
301
&& (Labels.List.size() <= Labels.MaxAmount);
302
// RANet::Log.Put(sLog::Debug,"Graph",sString("Prearranged ")+Variable
303
// +" Labels.List.size()="+sString::FromInteger(Labels.List.size())
304
// +" MajorTicks.Start="+sString::FromReal(MajorTicks.Start,15)
305
// +" MinorTicks.Start="+sString::FromReal(MinorTicks.Start,15)
306
// +" MajorTicks.Interval="+sString::FromReal(MajorTicks.Interval,15)
307
// +" MinorTicks.Interval="+sString::FromReal(MinorTicks.Interval,15)
308
// +" LabelsArranged="+sString::FromInteger(LabelsArranged)
235
313
QString sAxis::TitleText ()
315
sPhysValue U(Unit());
238
316
int Exp=MultiplierExponent;
322
sString UnitsText(U.Text(HTML,Laconic));
241
323
sString ShiftText;
242
/*! @todo{Units} make Prefix and Exp (and Shift?) specific for scale units */
243
// UnitsText=sMetricPrefix::Symbol(MultiplierExponent) + "<i>1</i>";
245
/*! @todo{Units} set Variable for scales */
324
sString VarText(Variable);
325
if( ! Unit().IsPowerOfTen() ){
326
RANet::Log.Put(sLog::Debug,"Graph",sString("TitleText: not a power of ten: ")+Unit().Text());
329
if( VarText.Empty() ){
330
VarText = sString("<i>") + VarText + "</i>";
248
332
if( Shift > fabs(PixelValue()) ){
249
333
if( Variable.Empty() ){
332
424
Pen.setWidth(PenWidth);
333
425
painter->setPen(Pen);
334
426
painter->drawLine( Origin.x() , Origin.y()
335
, Origin.x()+NominalSize , Origin.y());
427
, Origin.x()+Size() , Origin.y());
336
428
painter->drawLine( OppositeOrigin.x() , OppositeOrigin.y()
337
, OppositeOrigin.x()+NominalSize , OppositeOrigin.y() );
338
tick_value=MinorTicks.Start;
339
while( tick_value < Range.To + PixelValue() ){
340
tick_pos=Origin.x()+Value2Offset(tick_value);
341
painter->drawLine(tick_pos ,Origin.y()
342
,tick_pos ,Origin.y() + MinorTicks.Length);
343
painter->drawLine(tick_pos ,OppositeOrigin.y()
344
,tick_pos ,OppositeOrigin.y() - MinorTicks.Length);
345
tick_value+=MinorTicks.Interval;
347
tick_value=MajorTicks.Start;
348
while( tick_value < Range.To + PixelValue() ){
349
tick_pos=Origin.x()+Value2Offset(tick_value);
350
painter->drawLine(tick_pos ,Origin.y()
351
,tick_pos ,Origin.y() + MajorTicks.Length);
352
painter->drawLine(tick_pos ,OppositeOrigin.y()
353
,tick_pos ,OppositeOrigin.y() - MajorTicks.Length);
354
tick_value+=MajorTicks.Interval;
429
, OppositeOrigin.x()+Size() , OppositeOrigin.y() );
430
if( LabelsArranged ){
431
tick_value=MinorTicks.Start;
432
while( tick_value < Range().To + PixelValue() ){
433
// RANet::Log.Put(sLog::Debug,"Graph",sString("min tick ")+sString::FromReal(tick_value,15));
434
if( tick_value >= Range().From ){
435
tick_pos=Origin.x()+Value2Offset(tick_value);
436
painter->drawLine(tick_pos ,Origin.y()
437
,tick_pos ,Origin.y() + MinorTicks.Length);
438
painter->drawLine(tick_pos ,OppositeOrigin.y()
439
,tick_pos ,OppositeOrigin.y() - MinorTicks.Length);
441
tick_value+=MinorTicks.Interval;
443
// RANet::Log.Put(sLog::Debug,"Graph",sString("min ticks done "));
444
tick_value=MajorTicks.Start;
445
while( tick_value < Range().To + PixelValue() ){
446
tick_pos=Origin.x()+Value2Offset(tick_value);
447
painter->drawLine(tick_pos ,Origin.y()
448
,tick_pos ,Origin.y() + MajorTicks.Length);
449
painter->drawLine(tick_pos ,OppositeOrigin.y()
450
,tick_pos ,OppositeOrigin.y() - MajorTicks.Length);
451
tick_value+=MajorTicks.Interval;
454
// RANet::Log.Put(sLog::Debug,"Graph",sString("ticks done "));
356
455
painter->restore();
357
for( list<sLabel>::iterator label_index = Labels.List.begin() ;
358
label_index != Labels.List.end() ;
360
painter->drawText(label_index->Rect
361
,Qt::AlignHCenter|Qt::AlignTop
456
if( LabelsArranged && ! LabelsOverlap ){
457
for( list<sLabel>::iterator label_index = Labels.List.begin() ;
458
label_index != Labels.List.end() ;
460
painter->drawText(label_index->Rect
461
,Qt::AlignHCenter|Qt::AlignTop
365
466
painter->translate( TitleArea.topLeft() );
366
467
Title.drawContents(painter);
367
468
painter->restore();
469
// RANet::Log.Put(sLog::Debug,"Graph","-------------------X-drawn----------------");
370
472
//--------------------------------------------------------------- sY_Axis ---
373
void sY_Axis::ArrangeLabels (const QFontMetrics & font_metrics
374
,bool & LabelsOverlap)
475
bool sY_Axis::ArrangeLabels (const QFontMetrics & font_metrics)
421
529
Pen.setWidth(PenWidth);
422
530
painter->setPen(Pen);
423
531
painter->drawLine( Origin.x() , Origin.y()
424
, Origin.x() , Origin.y()-NominalSize );
532
, Origin.x() , Origin.y()-Size() );
425
533
painter->drawLine( OppositeOrigin.x() , OppositeOrigin.y()
426
, OppositeOrigin.x() , OppositeOrigin.y()-NominalSize );
427
tick_value=MinorTicks.Start;
428
while( tick_value < Range.To + PixelValue() ){
429
tick_pos=Origin.y()-Value2Offset(tick_value);
430
painter->drawLine(Origin.x() ,tick_pos
431
,Origin.x() - MinorTicks.Length ,tick_pos);
432
painter->drawLine(OppositeOrigin.x() ,tick_pos
433
,OppositeOrigin.x() + MinorTicks.Length ,tick_pos);
434
tick_value+=MinorTicks.Interval;
436
tick_value=MajorTicks.Start;
437
while( tick_value < Range.To + PixelValue() ){
438
tick_pos=Origin.y()-Value2Offset(tick_value);
439
painter->drawLine(Origin.x() ,tick_pos
440
,Origin.x() - MajorTicks.Length ,tick_pos);
441
painter->drawLine(OppositeOrigin.x() ,tick_pos
442
,OppositeOrigin.x() + MajorTicks.Length ,tick_pos);
443
tick_value+=MajorTicks.Interval;
534
, OppositeOrigin.x() , OppositeOrigin.y()-Size() );
535
if( LabelsArranged ){
536
tick_value=MinorTicks.Start;
537
while( tick_value < Range().To + PixelValue() ){
538
if( tick_value >= Range().From ){
539
tick_pos=Origin.y()-Value2Offset(tick_value);
540
painter->drawLine(Origin.x() ,tick_pos
541
,Origin.x() - MinorTicks.Length ,tick_pos);
542
painter->drawLine(OppositeOrigin.x() ,tick_pos
543
,OppositeOrigin.x() + MinorTicks.Length ,tick_pos);
545
tick_value+=MinorTicks.Interval;
547
tick_value=MajorTicks.Start;
548
while( tick_value < Range().To + PixelValue() ){
549
tick_pos=Origin.y()-Value2Offset(tick_value);
550
painter->drawLine(Origin.x() ,tick_pos
551
,Origin.x() - MajorTicks.Length ,tick_pos);
552
painter->drawLine(OppositeOrigin.x() ,tick_pos
553
,OppositeOrigin.x() + MajorTicks.Length ,tick_pos);
554
tick_value+=MajorTicks.Interval;
445
557
painter->restore();
446
for( list<sLabel>::iterator label_index = Labels.List.begin() ;
447
label_index != Labels.List.end() ;
449
painter->drawText(label_index->Rect
450
,Qt::AlignVCenter|Qt::AlignRight
558
if( LabelsArranged && ! LabelsOverlap ){
559
for( list<sLabel>::iterator label_index = Labels.List.begin() ;
560
label_index != Labels.List.end() ;
562
painter->drawText(label_index->Rect
563
,Qt::AlignVCenter|Qt::AlignRight
454
568
painter->translate( TitleArea.topLeft() );
455
569
painter->rotate(-90);
456
570
Title.drawContents(painter);
457
571
painter->restore();
572
// RANet::Log.Put(sLog::Debug,"Graph","-------------------Y-drawn----------------");
460
575
//----------------------------------------------------------- sChartViewport ---
593
QPoint sChartViewport::Value2Offset (rcsPoint point)
595
return QPoint( NominalOrigin.x()
596
+Round( NominalSize.width()*( (point.X-TheScale.From.X)
597
/(TheScale.To.X-TheScale.From.X)) )
599
+Round( NominalSize.height()*( (TheScale.To.Y-point.Y)
600
/(TheScale.To.Y-TheScale.From.Y)) ) );
604
sPoint sChartViewport::Offset2Value (const QPoint & position)
606
return sPoint( TheScale.From.X
607
+(position.x()-NominalOrigin.x())*(TheScale.To.X-TheScale.From.X)
610
-(position.y()-NominalOrigin.y())*(TheScale.To.Y-TheScale.From.Y)
611
/NominalSize.height() );
725
QPoint sChartViewport::Tr (sPhysPair point) const
727
return QPoint( XAxis->Tr(point.X) , YAxis->Tr(point.Y) );
731
QPoint sChartViewport::Tr (rcsPoint point) const
733
return QPoint( XAxis->Tr(point.X) , YAxis->Tr(point.Y) );
737
sPhysPair sChartViewport::Tr (QPoint point) const
739
return sPhysPair( XAxis->Tr(point.x()) , YAxis->Tr(point.y()) );
615
743
void sChartViewport::ZoomOut ()
619
sScale NewScale(TheScale);
620
OldRangeX = TheScale.To.X - TheScale.From.X;
621
OldRangeY = TheScale.To.Y - TheScale.From.Y;
622
NewScale.From.X -= 0.5*(ZoomOutFactor-1.0)*OldRangeX;
623
NewScale.To.X += 0.5*(ZoomOutFactor-1.0)*OldRangeX;
624
NewScale.From.Y -= 0.5*(ZoomOutFactor-1.0)*OldRangeY;
625
NewScale.To.Y += 0.5*(ZoomOutFactor-1.0)*OldRangeY;
626
ScaleHistory.push(TheScale);
745
ScalesHistory.push(ChartScales());
746
XAxis->SetRange( - 0.5*(ZoomOutFactor-1.0)*NominalSize.width()
747
, 0.5*(ZoomOutFactor+1.0)*NominalSize.width() );
748
YAxis->SetRange( 0.5*(ZoomOutFactor+1.0)*NominalSize.height()
749
, - 0.5*(ZoomOutFactor-1.0)*NominalSize.height() );
750
emit ScalesChanged();
631
754
void sChartViewport::RescaleBack ()
633
if( ! ScaleHistory.empty() ){
634
SetScale(ScaleHistory.top());
756
if( ! ScalesHistory.empty() ){
757
SetChartScales(ScalesHistory.top());
640
763
void sChartViewport::RescaleToShowAll ()
644
ScaleHistory.push(TheScale);
645
B=BoundariesForAllObjects();
647
B.X=sRange(0.0,10.0);
649
B.Y=sRange(0.0,10.0);
650
if( B.X.To < B.X.From )
652
if( B.Y.To < B.Y.From )
656
TheScale.From.X = B.X.From - 0.05*S;
657
TheScale.To.X = B.X.To + 0.05*S;
661
TheScale.From.Y = B.Y.From - 0.05*S;
662
TheScale.To.Y = B.Y.To + 0.05*S;
765
sBoundaries B( BoundariesForAllObjects() );
766
// RANet::Log.Put(sLog::Debug,"Graph"
767
// ,sString("Boundaries: X: ")+B.X.Text()+" Y: "+B.Y.Text());
768
ScalesHistory.push(ChartScales());
769
XAxis->SetRange(sPhysRange( B.X.From() - 0.05*B.X.Size()
770
, B.X.To() + 0.05*B.X.Size() ));
771
YAxis->SetRange(sPhysRange( B.Y.From() - 0.05*B.Y.Size()
772
, B.Y.To() + 0.05*B.Y.Size() ));
773
emit ScalesChanged();
668
777
sBoundaries sChartViewport::BoundariesForAllObjects ()
779
RANet::Log.OpenBlock(sLog::Debug,"sChartViewport::BoundariesForAllObjects");
780
int NumberOfVisibleGraphObjects = 0;
782
sBoundaries B_of_the_first;
670
783
sBoundaries TotalB;
785
TotalB = sBoundaries( sPhysRange(real_nan,real_nan,_Unitsless_)
786
, sPhysRange(real_nan,real_nan,_Unitsless_) );
672
787
sNet2TreeEvolution::psItem I = Evolution->FirstVisible();
674
// s2DVisibleObject::sPtr NodePtr(I->AttrValue());
675
/*! @todo{patch} заплатка */
676
sCurve::sPtr NodePtr(I->AttrValue());
677
if( NodePtr.IsCorrect() ){
678
B= NodePtr->Boundaries();
679
if( !B.X.Undefined ){
680
if( TotalB.X.Undefined ){
681
TotalB.X.From=B.X.From;
683
TotalB.X.Undefined=false;
685
if( TotalB.X.From > B.X.From )
686
TotalB.X.From=B.X.From;
687
if( TotalB.X.To < B.X.To )
691
if( !B.Y.Undefined ){
692
if( TotalB.Y.Undefined ){
693
TotalB.Y.From=B.Y.From;
695
TotalB.Y.Undefined=false;
697
if( TotalB.Y.From > B.Y.From )
698
TotalB.Y.From=B.Y.From;
699
if( TotalB.Y.To < B.Y.To )
789
if( psGraphObject O = dynamic_cast<psGraphObject>
790
(I->AttrValue().operator ->()) ){
791
sBoundaries BB(sPhysRange(XAxis->Scale().Unit().Units())
792
,sPhysRange(YAxis->Scale().Unit().Units())
794
NumberOfVisibleGraphObjects++;
796
RANet::Log.Put(sLog::Debug,"sChartViewport::BoundariesForAllObjects"
797
,sString("O->Boundaries: X: ")+B.X.Text()+" Y:"+B.Y.Text());
798
if( NumberOfVisibleGraphObjects == 1 ){
802
if( ! B.X.From().IsNaN() && ! B.X.To().IsNaN()
803
&& ! B.Y.From().IsNaN() && ! B.Y.To().IsNaN() ){
806
if( TotalB.X.From().IsNaN() ){
811
if( TotalB.Y.From().IsNaN() ){
816
}else if( ! B.X.From().IsNaN() && ! B.X.To().IsNaN() ){
818
if( TotalB.X.From().IsNaN() ){
823
}else if( ! B.Y.From().IsNaN() && ! B.Y.To().IsNaN() ){
825
if( TotalB.Y.From().IsNaN() ){
831
}catch(rxRAlgebra){};
832
RANet::Log.Put(sLog::Debug,"sChartViewport::BoundariesForAllObjects"
833
,sString("BB.X: ")+BB.X.Text()+" BB.Y:"+BB.Y.Text());
834
RANet::Log.Put(sLog::Debug,"sChartViewport::BoundariesForAllObjects"
835
,sString("TotalB.X: ")+TotalB.X.Text()+" TotalB.Y:"+TotalB.Y.Text());
704
837
I=I->NextVisible();
839
if( NumberOfVisibleGraphObjects == 0 ){
840
TotalB = sBoundaries(XAxis->PhysRange(),YAxis->PhysRange());
841
}else if( NumberOfVisibleGraphObjects == 1 ){
842
TotalB = B_of_the_first;
844
if( TotalB.X.From().IsInf() ){
845
TotalB.X = sPhysRange(XAxis->PhysRange().From(),TotalB.X.To());
846
}else if( TotalB.X.To().IsInf() ){
847
TotalB.X = sPhysRange(TotalB.X.From() ,XAxis->PhysRange().To());
848
}else if( TotalB.Y.From().IsInf() ){
849
TotalB.Y = sPhysRange(YAxis->PhysRange().From(),TotalB.Y.To());
850
}else if( TotalB.Y.To().IsInf() ){
851
TotalB.Y = sPhysRange(TotalB.Y.From() ,YAxis->PhysRange().To());
854
RANet::Log.Put(sLog::Debug,"sChartViewport::BoundariesForAllObjects"
855
,sString("TotalB: X: ")+TotalB.X.Text()+" Y: "+TotalB.Y.Text());
856
RANet::Log.CloseBlock(sLog::Debug,"sChartViewport::BoundariesForAllObjects");
718
869
sNet2TreeEvolution::psItem I = Evolution->FirstVisible();
720
// s2DVisibleObject::sPtr NodePtr(I->AttrValue());
721
// if( NodePtr.IsCorrect() ){
722
// sCurve::sPtr CurvePtr(NodePtr);
723
sCurve::sPtr CurvePtr(I->AttrValue());
724
if( CurvePtr.IsCorrect() ){
725
(*DrawProc)(&painter,this,I);
727
if( true /*sMark*/ ){
728
// поиск принадлежности среди предков по эволюции
871
// if( /*psCurve O =*/ dynamic_cast<psCurve>
872
// (I->AttrValue().operator ->()) ){
873
// (*DrawProc)(&painter,this,I);
874
// }else if( true /*sMark*/ ){
875
// //поиск принадлежности среди предков по эволюции
877
psGraphObject Object(dynamic_cast<psGraphObject>
878
(I->AttrValue().operator ->()));
880
psAppearance ObjectAppearance(Object->Appearance);
881
for( list<pcfDrawProc>::const_iterator i = DrawProcCollection.begin()
882
; i != DrawProcCollection.end()
884
if( (*i)(&painter,this,Object,ObjectAppearance) ) break;
731
887
I=I->NextVisible();
733
QPen Pen=painter.pen();
734
Pen.setStyle(Qt::DotLine);
736
painter.drawLine(Value2Offset(sPoint(TheScale.From.X,TheReference.Y))
737
,Value2Offset(sPoint(TheScale.To.X ,TheReference.Y)));
738
painter.drawLine(Value2Offset(sPoint(TheReference.X,TheScale.From.Y))
739
,Value2Offset(sPoint(TheReference.X,TheScale.To.Y)));
890
QPoint R(Tr(TheReference));
891
QPen Pen=painter.pen();
892
Pen.setStyle(Qt::DotLine);
894
painter.drawLine(0 ,R.y() ,size().width() ,R.y());
895
painter.drawLine(R.x() ,0 ,R.x() ,size().height());
896
}catch(rxRAlgebra){};
743
900
void sChartViewport::keyPressEvent (QKeyEvent * event)
791
948
if( MouseOperationType == MovingInitialPoint ){
792
949
MouseOperationStarted=false;
793
950
SetReference(event->pos());
794
emit CursorPositionChanged(Offset2Value(event->pos())
951
emit CursorPositionChanged(event->pos());
797
953
}else if( MouseOperationType == MovingFrame ){
798
954
if( (event->pos() == MouseOperationStartPosition)
799
&& ! ScaleHistory.empty() ){
955
&& ! ScalesHistory.empty() ){
802
958
}else if( MouseOperationType == Zooming ){
803
959
ZoomRect->hide();
804
960
if( (ZoomRect->width() > 2) && (ZoomRect->height() > 2) ){
806
S.From=Offset2Value(QPoint(ZoomRect->pos().x()
807
,ZoomRect->pos().y() + ZoomRect->height()));
808
S.To= Offset2Value(QPoint(ZoomRect->pos().x() + ZoomRect->width()
809
,ZoomRect->pos().y() ));
810
ScaleHistory.push(TheScale);
961
ScalesHistory.push(ChartScales());
962
XAxis->SetRange( ZoomRect->pos().x()
963
, ZoomRect->pos().x() + ZoomRect->width() );
964
YAxis->SetRange( ZoomRect->pos().y() + ZoomRect->height()
965
, ZoomRect->pos().y() );
966
emit ScalesChanged();
814
969
// if( Shift.Contains(ssCtrl) ){
954
1126
(*(MyAction->DoIt))(TreeItem,sPoint(event->pos().x(),event->pos().y()));
955
1127
Evolution->Update();
1132
void sChartViewport::OnCursorPositionChanged (QPoint cursor)
1134
sPhysPair Cursor(XAxis->Tr(cursor.x())
1135
,YAxis->Tr(cursor.y()));
1136
emit CursorPositionChanged(Cursor ,Reference()
1137
,XAxis->Variable ,YAxis->Variable);
959
1140
//-------------------------------------------------------------- sChart ---
961
1142
sChart::~sChart ()
963
1144
if( Viewport ){ delete Viewport; Viewport=NULL; };
1145
if( XAxis ){ delete XAxis; XAxis=NULL; };
1146
if( YAxis ){ delete YAxis; YAxis=NULL; };
966
1149
sChart::sChart (psNet2TreeEvolution evolution
967
1150
,QWidget * parent)
969
,Viewport( new sChartViewport(evolution,this) )
1152
,XAxis( new sX_Axis )
1153
,YAxis( new sY_Axis )
1154
,Viewport( new sChartViewport(XAxis,YAxis,evolution,this) )
970
1155
// ,Margins(10,30,60,10)
971
1156
,Margins(10,40,70,10)
973
1158
// setContextMenuPolicy(Qt::DefaultContextMenu);
974
1159
setStyleSheet("QFrame {background: white; border: 1px solid grey}");
976
connect(Viewport,SIGNAL(ScaleChanged()),this,SLOT(UpdateAxes()));
977
connect(Viewport,SIGNAL(CursorPositionChanged(sPoint,sPoint))
978
,this ,SLOT(OnCursorMove(sPoint,sPoint)));
1161
connect(Viewport,SIGNAL(ScalesChanged()),this,SLOT(UpdateAxes()));
1162
connect(Viewport ,SIGNAL(CursorPositionChanged(sPhysPair,sPhysPair
1164
,this ,SIGNAL(CursorPositionChanged(sPhysPair,sPhysPair
1165
,sString,sString)));
981
1168
A = new QAction(QIcon(":/RAGUI/icons/zoomout.png") ,tr("Zoom out") ,this);
1040
1263
void sChart::EditScales ()
1042
sSetScalesDlg D(parentWidget());
1043
D.field_OrdinateMetricPrefix->setCurrentIndex(Y_Axis.MultiplierExponent/3 + 8);
1044
D.field_OrdinateFrom->setValue(Viewport->Scale().Y().From / Y_Axis.Multiplier);
1045
D.field_OrdinateTo->setValue(Viewport->Scale().Y().To / Y_Axis.Multiplier);
1046
D.field_AbscissMetricPrefix->setCurrentIndex(X_Axis.MultiplierExponent/3 + 8);
1047
D.field_AbscissFrom->setValue(Viewport->Scale().X().From / X_Axis.Multiplier);
1048
D.field_AbscissTo->setValue(Viewport->Scale().X().To / X_Axis.Multiplier);
1265
sScalesDlg D(parentWidget());
1266
D.fldAbscissVariableName->setText(ToQString(XAxis->Variable));
1267
D.fldOrdinateVariableName->setText(ToQString(YAxis->Variable));
1268
D.fldAbscissRange->SetValue(XAxis->PhysRange());
1269
D.fldOrdinateRange->SetValue(YAxis->PhysRange());
1049
1270
if( D.exec() ){
1050
int OrdinateExp = (D.field_OrdinateMetricPrefix->currentIndex()-8)*3;
1051
int AbscissExp = (D.field_AbscissMetricPrefix->currentIndex()-8)*3;
1052
Viewport->ChangeScale(sScale(sPoint(D.field_AbscissFrom->value()
1053
*power10(AbscissExp)
1054
,D.field_OrdinateFrom->value()
1055
*power10(OrdinateExp))
1056
,sPoint(D.field_AbscissTo->value()
1057
*power10(AbscissExp)
1058
,D.field_OrdinateTo->value()
1059
*power10(OrdinateExp)) ));
1271
Viewport->ChangeChartScales(sChartScales
1272
(sChartScale(FromQString(D.fldAbscissVariableName->text().simplified())
1273
,D.fldAbscissRange->Value())
1274
,sChartScale(FromQString(D.fldOrdinateVariableName->text().simplified())
1275
,D.fldOrdinateRange->Value())
1075
1292
int AxisLinewidth = 1;
1077
X_Axis.Range=Viewport->Scale().X();
1078
Y_Axis.Range=Viewport->Scale().Y();
1079
1294
Viewport->SetNominalSize(ViewportNominalSize);
1080
X_Axis.NominalSize=ViewportNominalSize.width();
1081
Y_Axis.NominalSize=ViewportNominalSize.height();
1295
XAxis->SetSize(ViewportNominalSize.width());
1296
YAxis->SetSize(ViewportNominalSize.height());
1083
X_Axis.PenWidth=AxisLinewidth;
1084
Y_Axis.PenWidth=AxisLinewidth;
1085
X_Axis.Origin=QPoint( TopLeft.x()
1298
XAxis->SetPenWidth(AxisLinewidth);
1299
YAxis->SetPenWidth(AxisLinewidth);
1300
XAxis->Origin=QPoint( TopLeft.x()
1086
1301
, TopLeft.y() + ViewportNominalSize.height() );
1087
X_Axis.OppositeOrigin=QPoint( TopLeft.x() , TopLeft.y() );
1088
Y_Axis.Origin=QPoint( X_Axis.Origin.x() , X_Axis.Origin.y() );
1089
Y_Axis.OppositeOrigin=QPoint(TopLeft.x() + ViewportNominalSize.width()
1302
XAxis->OppositeOrigin=QPoint( TopLeft.x() , TopLeft.y() );
1303
YAxis->Origin=QPoint( XAxis->Origin.x() , XAxis->Origin.y() );
1304
YAxis->OppositeOrigin=QPoint(TopLeft.x() + ViewportNominalSize.width()
1090
1305
,TopLeft.y() + ViewportNominalSize.height() );
1092
1307
Viewport->resize(ViewportNominalSize.width() - AxisLinewidth
1096
1311
Viewport->move(Margins.Left() + (AxisLinewidth+1)/2
1097
1312
,Margins.Top() + (AxisLinewidth+1)/2 );
1099
X_Axis.Arrange(fontMetrics());
1100
Y_Axis.Arrange(fontMetrics());
1314
XAxis->Arrange(fontMetrics());
1315
YAxis->Arrange(fontMetrics());
1101
1316
setMinimumSize(40 + Margins.Left() + Margins.Right()
1102
1317
,40 + Margins.Top() + Margins.Bottom() );
1107
void sChart::OnCursorMove (sPoint cursor
1108
,sPoint reference_point)
1110
emit CursorPositionChanged(cursor,reference_point);
1119
if( X_Axis.MultiplierExponent != 0 )
1120
((ExpText = "×10<sup>") << X_Axis.MultiplierExponent ) += "</sup> ";
1121
if( X_Axis.PixelValue() / X_Axis.Multiplier < 0.999 ){
1122
digits=-Round(log10(X_Axis.PixelValue() / X_Axis.Multiplier)-0.499);
1124
X.setNum(double(cursor.X / X_Axis.Multiplier),'f',digits);
1125
DX.setNum(double((cursor.X - reference_point.X) / X_Axis.Multiplier),'f',digits);
1126
X = VarX + "= " + X + sString2QString(ExpText);
1127
DX = QString::fromUtf8("Δ<sub>") + VarX + QString::fromUtf8("</sub>= ") + DX
1128
+ sString2QString(ExpText);
1131
if( Y_Axis.MultiplierExponent != 0 )
1132
((ExpText = "×10<sup>") << Y_Axis.MultiplierExponent ) += "</sup> ";
1134
if( Y_Axis.PixelValue() / Y_Axis.Multiplier < 0.999 ){
1135
digits=-Round(log10(Y_Axis.PixelValue() / Y_Axis.Multiplier)-0.499);
1137
Y.setNum(double(cursor.Y / Y_Axis.Multiplier),'f',digits);
1138
DY.setNum(double((cursor.Y - reference_point.Y) / Y_Axis.Multiplier),'f',digits);
1139
Y = VarY + "= " + Y + sString2QString(ExpText);
1140
DY = QString::fromUtf8("Δ<sub>") + VarY + QString::fromUtf8("</sub>= ") + DY
1141
+ sString2QString(ExpText);
1142
emit CursorInfo(X,DX,Y,DY);
1145
1321
//------------------------------------------------------------------------------
1146
1322
}; //namespace RA