@@ -48,29 +48,35 @@ PlotBuilder::PlotBuilder(const Data::DataTable &dataTable,
4848 initDimensionTrackers ();
4949
5050 std::size_t mainBucketSize{};
51- auto &&subBuckets = generateMarkers (mainBucketSize);
51+ std::size_t subBucketSize{};
52+ auto &&buckets = generateMarkers (mainBucketSize, subBucketSize);
5253
5354 if (!plot->getOptions ()->getChannels ().anyAxisSet ()) {
54- addSpecLayout (subBuckets );
55+ addSpecLayout (buckets );
5556 normalizeSizes ();
5657 }
5758 else {
5859 normalizeSizes ();
59- addAxisLayout (subBuckets, mainBucketSize, dataTable);
60+ addAxisLayout (buckets,
61+ mainBucketSize,
62+ subBucketSize,
63+ dataTable);
6064 }
6165
6266 normalizeColors ();
6367 calcLegendAndLabel (dataTable);
6468}
6569
66- void PlotBuilder::addAxisLayout (Buckets &subBuckets ,
70+ void PlotBuilder::addAxisLayout (Buckets &buckets ,
6771 const std::size_t &mainBucketSize,
72+ const std::size_t &subBucketSize,
6873 const Data::DataTable &dataTable)
6974{
70- linkMarkers (subBuckets);
71- addSeparation (subBuckets, mainBucketSize);
75+ linkMarkers (buckets, mainBucketSize, subBucketSize);
7276 calcAxises (dataTable);
73- addAlignment (subBuckets);
77+ addAlignment (buckets, plot->getOptions ()->subAxisType ());
78+ addAlignment (buckets.sort (&Marker::mainId),
79+ plot->getOptions ()->mainAxisType ());
7480}
7581
7682void PlotBuilder::initDimensionTrackers ()
@@ -82,7 +88,8 @@ void PlotBuilder::initDimensionTrackers()
8288 dataCube.combinedSizeOf (ch.dimensions ()).second );
8389}
8490
85- Buckets PlotBuilder::generateMarkers (std::size_t &mainBucketSize)
91+ Buckets PlotBuilder::generateMarkers (std::size_t &mainBucketSize,
92+ std::size_t &subBucketSize)
8693{
8794 const auto &mainIds (plot->getOptions ()->mainAxis ().dimensions ());
8895 auto subIds (plot->getOptions ()->subAxis ().dimensions ());
@@ -91,6 +98,7 @@ Buckets PlotBuilder::generateMarkers(std::size_t &mainBucketSize)
9198 subIds.split_by (mainIds);
9299
93100 mainBucketSize = dataCube.combinedSizeOf (mainIds).first ;
101+ subBucketSize = dataCube.combinedSizeOf (subIds).first ;
94102 plot->markers .reserve (dataCube.df ->get_record_count ());
95103 }
96104
@@ -201,13 +209,21 @@ void PlotBuilder::addSpecLayout(Buckets &buckets)
201209 }
202210}
203211
204- void PlotBuilder::linkMarkers (Buckets &buckets)
212+ void PlotBuilder::linkMarkers (Buckets &buckets,
213+ const std::size_t &mainBucketSize,
214+ const std::size_t &subBucketSize)
205215{
206216 auto &&hasMarkerConnection =
207217 linkMarkers (buckets.sort (&Marker::mainId),
208218 plot->getOptions ()->mainAxisType ());
219+ addSeparation (buckets,
220+ plot->getOptions ()->mainAxisType (),
221+ subBucketSize);
209222 std::ignore = linkMarkers (buckets.sort (&Marker::subId),
210223 plot->getOptions ()->subAxisType ());
224+ addSeparation (buckets,
225+ plot->getOptions ()->subAxisType (),
226+ mainBucketSize);
211227
212228 if (hasMarkerConnection
213229 && plot->getOptions ()->geometry .get () == ShapeType::line
@@ -493,67 +509,62 @@ void PlotBuilder::calcAxis(const Data::DataTable &dataTable,
493509 }
494510}
495511
496- void PlotBuilder::addAlignment (const Buckets &subBuckets) const
512+ void PlotBuilder::addAlignment (const Buckets &buckets,
513+ AxisId axisIndex) const
497514{
498- if (plot->getOptions ()->isSplit ()) return ;
515+ if (plot->getOptions ()->isSplit (axisIndex )) return ;
499516
500- auto &subAxisRange =
501- plot->axises .at (plot->getOptions ()->subAxisType ())
502- .measure .range ;
503- if (std::signbit (subAxisRange.min )
504- || std::signbit (subAxisRange.max ))
517+ auto &axisRange = plot->axises .at (axisIndex).measure .range ;
518+ if (std::signbit (axisRange.min ) || std::signbit (axisRange.max ))
505519 return ;
506520
507521 const auto &axisProps =
508- plot->getOptions ()->getChannels ().axisPropsAt (
509- plot->getOptions ()->subAxisType ());
522+ plot->getOptions ()->getChannels ().axisPropsAt (axisIndex);
510523
511524 if (axisProps.align == Base::Align::Type::none) return ;
512525
513526 if (axisProps.align == Base::Align::Type::center) {
514- auto &&halfSize = subAxisRange .size () / 2.0 ;
527+ auto &&halfSize = axisRange .size () / 2.0 ;
515528 if (!Math::Floating::is_zero (halfSize))
516- subAxisRange = {subAxisRange .min - halfSize,
517- subAxisRange .max - halfSize};
529+ axisRange = {axisRange .min - halfSize,
530+ axisRange .max - halfSize};
518531 }
519532
520- auto &&subAxis = plot->getOptions ()->subAxisType ();
521533 const Base::Align align{axisProps.align , {0.0 , 1.0 }};
522- for (auto &&bucket : subBuckets ) {
534+ for (auto &&bucket : buckets ) {
523535 Math::Range<> range;
524536
525537 for (auto &&[marker, idx] : bucket)
526538 if (marker.enabled )
527- range.include (marker.getSizeBy (subAxis ));
539+ range.include (marker.getSizeBy (axisIndex ));
528540
529541 auto &&transform = align.getAligned (range) / range;
530542
531543 for (auto &&[marker, idx] : bucket)
532- marker.setSizeBy (subAxis ,
533- marker.getSizeBy (subAxis ) * transform);
544+ marker.setSizeBy (axisIndex ,
545+ marker.getSizeBy (axisIndex ) * transform);
534546 }
535547}
536548
537- void PlotBuilder::addSeparation (const Buckets &subBuckets,
538- const std::size_t &mainBucketSize) const
549+ void PlotBuilder::addSeparation (const Buckets &buckets,
550+ AxisId axisIndex,
551+ const std::size_t &otherBucketSize) const
539552{
540- if (!plot->getOptions ()->isSplit ()) return ;
553+ if (!plot->getOptions ()->isSplit (axisIndex )) return ;
541554
542555 const auto &axisProps =
543- plot->getOptions ()->getChannels ().axisPropsAt (
544- plot->getOptions ()->subAxisType ());
556+ plot->getOptions ()->getChannels ().axisPropsAt (axisIndex);
545557 auto align = axisProps.align ;
546558
547- std::vector ranges{mainBucketSize , Math::Range<>{{}, {}}};
548- std::vector<bool > anyEnabled (mainBucketSize );
559+ std::vector ranges{otherBucketSize , Math::Range<>{{}, {}}};
560+ std::vector<bool > anyEnabled (otherBucketSize );
549561
550- auto &&subAxis = plot->getOptions ()->subAxisType ();
551- for (auto &&bucket : subBuckets)
562+ for (auto &&bucket : buckets)
552563 for (std::size_t i{}, prIx{}; auto &&[marker, idx] : bucket) {
553564 if (!marker.enabled ) continue ;
554565 (i += idx.itemId - std::exchange (prIx, idx.itemId )) %=
555566 ranges.size ();
556- ranges[i].include (marker.getSizeBy (subAxis ).size ());
567+ ranges[i].include (marker.getSizeBy (axisIndex ).size ());
557568 anyEnabled[i] = true ;
558569 }
559570
@@ -562,21 +573,20 @@ void PlotBuilder::addSeparation(const Buckets &subBuckets,
562573 if (anyEnabled[i]) max = max + ranges[i];
563574
564575 auto splitSpace =
565- plot->getStyle ()
566- .plot .getAxis (plot->getOptions ()->subAxisType ())
567- .spacing ->get (max.max , plot->getStyle ().calculatedSize ());
576+ plot->getStyle ().plot .getAxis (axisIndex).spacing ->get (max.max ,
577+ plot->getStyle ().calculatedSize ());
568578
569579 for (auto i = 1U ; i < ranges.size (); ++i)
570580 ranges[i] = ranges[i] + ranges[i - 1 ].max
571581 + (anyEnabled[i - 1 ] ? splitSpace : 0 );
572582
573- for (auto &&bucket : subBuckets )
583+ for (auto &&bucket : buckets )
574584 for (std::size_t i{}, prIx{}; auto &&[marker, idx] : bucket) {
575585 (i += idx.itemId - std::exchange (prIx, idx.itemId )) %=
576586 ranges.size ();
577- marker.setSizeBy (subAxis ,
587+ marker.setSizeBy (axisIndex ,
578588 Base::Align{align, ranges[i]}.getAligned (
579- marker.getSizeBy (subAxis )));
589+ marker.getSizeBy (axisIndex )));
580590 }
581591}
582592
0 commit comments