* Added a maximum size parameter to ChartAxis::PreferredSize(), specifying how
big the axis can maximally become. This helps to solve the chicken and egg problem that the axis can't compute a size without knowing what legends to use, which in turn requires knowing the size. * Reimplemented LegendChartAxis accordingly. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30527 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -288,13 +288,15 @@ printf("Chart::DoLayout(%f, %f)\n", size.width, size.height);
|
|||||||
int32 bottom = 0;
|
int32 bottom = 0;
|
||||||
|
|
||||||
if (fLeftAxis.axis != NULL)
|
if (fLeftAxis.axis != NULL)
|
||||||
left = fLeftAxis.axis->PreferredSize(this).IntegerWidth() + 1;
|
left = fLeftAxis.axis->PreferredSize(this, size).IntegerWidth() + 1;
|
||||||
if (fRightAxis.axis != NULL)
|
if (fRightAxis.axis != NULL)
|
||||||
right = fRightAxis.axis->PreferredSize(this).IntegerWidth() + 1;
|
right = fRightAxis.axis->PreferredSize(this, size).IntegerWidth() + 1;
|
||||||
if (fTopAxis.axis != NULL)
|
if (fTopAxis.axis != NULL)
|
||||||
top = fTopAxis.axis->PreferredSize(this).IntegerHeight() + 1;
|
top = fTopAxis.axis->PreferredSize(this, size).IntegerHeight() + 1;
|
||||||
if (fBottomAxis.axis != NULL)
|
if (fBottomAxis.axis != NULL) {
|
||||||
bottom = fBottomAxis.axis->PreferredSize(this).IntegerHeight() + 1;
|
bottom = fBottomAxis.axis->PreferredSize(this, size).IntegerHeight()
|
||||||
|
+ 1;
|
||||||
|
}
|
||||||
|
|
||||||
fChartFrame = BRect(left, top, width - right - 1, height - bottom - 1);
|
fChartFrame = BRect(left, top, width - right - 1, height - bottom - 1);
|
||||||
fRenderer->SetFrame(fChartFrame.InsetByCopy(1, 1));
|
fRenderer->SetFrame(fChartFrame.InsetByCopy(1, 1));
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public:
|
|||||||
virtual void SetLocation(ChartAxisLocation location) = 0;
|
virtual void SetLocation(ChartAxisLocation location) = 0;
|
||||||
virtual void SetRange(const ChartDataRange& range) = 0;
|
virtual void SetRange(const ChartDataRange& range) = 0;
|
||||||
virtual void SetFrame(BRect frame) = 0;
|
virtual void SetFrame(BRect frame) = 0;
|
||||||
virtual BSize PreferredSize(BView* view) = 0;
|
virtual BSize PreferredSize(BView* view, BSize maxSize) = 0;
|
||||||
virtual void Render(BView* view, BRect updateRect) = 0;
|
virtual void Render(BView* view, BRect updateRect) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -192,19 +192,53 @@ printf("LegendChartAxis::SetFrame((%f, %f) - (%f, %f))\n", frame.left, frame.top
|
|||||||
|
|
||||||
|
|
||||||
BSize
|
BSize
|
||||||
LegendChartAxis::PreferredSize(BView* view)
|
LegendChartAxis::PreferredSize(BView* view, BSize maxSize)
|
||||||
{
|
{
|
||||||
// TODO: Implement for real!
|
// estimate the maximum legend count we might need
|
||||||
BSize size = fLegendRenderer->MaximumLegendSize(view);
|
float hSpacing, vSpacing;
|
||||||
|
int32 maxLegends = _EstimateMaxLegendCount(view, maxSize, &hSpacing,
|
||||||
|
&vSpacing);
|
||||||
|
BSize spacing(hSpacing, vSpacing);
|
||||||
|
if (maxLegends < 4)
|
||||||
|
maxLegends = 4;
|
||||||
|
|
||||||
|
// get the legends
|
||||||
|
ChartLegend* legends[maxLegends];
|
||||||
|
double values[maxLegends];
|
||||||
|
|
||||||
|
int32 legendCount = fLegendSource->GetAxisLegends(fRange, legends, values,
|
||||||
|
maxLegends);
|
||||||
|
|
||||||
|
// get the sizes, delete the legends, and compute the preferred size
|
||||||
|
float BSize::* sizeField;
|
||||||
|
float BSize::* otherSizeField;
|
||||||
if (fLocation == CHART_AXIS_LEFT || fLocation == CHART_AXIS_RIGHT) {
|
if (fLocation == CHART_AXIS_LEFT || fLocation == CHART_AXIS_RIGHT) {
|
||||||
size.width += kChartLegendDistance;
|
sizeField = &BSize::height;
|
||||||
size.height = std::max(size.height * 4, 100.0f);
|
otherSizeField = &BSize::width;
|
||||||
} else {
|
} else {
|
||||||
size.width = std::max(size.width * 4, 100.0f);
|
sizeField = &BSize::width;
|
||||||
size.height += kChartLegendDistance;
|
otherSizeField = &BSize::height;
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
BSize preferredSize;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < legendCount; i++) {
|
||||||
|
ChartLegend* legend = legends[i];
|
||||||
|
BSize size = fLegendRenderer->LegendSize(legend, view);
|
||||||
|
delete legend;
|
||||||
|
|
||||||
|
if (size.*sizeField > preferredSize.*sizeField)
|
||||||
|
preferredSize.*sizeField = size.*sizeField;
|
||||||
|
if (size.*otherSizeField > preferredSize.*otherSizeField)
|
||||||
|
preferredSize.*otherSizeField = size.*otherSizeField;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Suppose we want to have at least 2 legends.
|
||||||
|
preferredSize.*sizeField
|
||||||
|
= ceilf(preferredSize.*sizeField * 2 + spacing.*sizeField);
|
||||||
|
preferredSize.*otherSizeField += kChartLegendDistance;
|
||||||
|
|
||||||
|
return preferredSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -331,15 +365,9 @@ printf("LegendChartAxis::_ValidateLayout()\n");
|
|||||||
int32 height = fFrame.IntegerHeight() + 1;
|
int32 height = fFrame.IntegerHeight() + 1;
|
||||||
printf(" width: %ld, height: %ld\n", width, height);
|
printf(" width: %ld, height: %ld\n", width, height);
|
||||||
|
|
||||||
fLegendRenderer->GetMinimumLegendSpacing(view, &fHorizontalSpacing,
|
|
||||||
&fVerticalSpacing);
|
|
||||||
|
|
||||||
// estimate the maximum legend count we might need
|
// estimate the maximum legend count we might need
|
||||||
int32 maxLegends;
|
int32 maxLegends = _EstimateMaxLegendCount(view, fFrame.Size(),
|
||||||
if (fLocation == CHART_AXIS_LEFT || fLocation == CHART_AXIS_RIGHT)
|
&fHorizontalSpacing, &fVerticalSpacing);
|
||||||
maxLegends = height / (10 + fVerticalSpacing);
|
|
||||||
else
|
|
||||||
maxLegends = width / (20 + fHorizontalSpacing);
|
|
||||||
|
|
||||||
printf(" max %ld legends\n", maxLegends);
|
printf(" max %ld legends\n", maxLegends);
|
||||||
if (maxLegends == 0)
|
if (maxLegends == 0)
|
||||||
@@ -387,3 +415,17 @@ printf(" failed to create legend info!\n");
|
|||||||
fLayoutValid = true;
|
fLayoutValid = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
LegendChartAxis::_EstimateMaxLegendCount(BView* view, BSize size,
|
||||||
|
float* _hSpacing, float* _vSpacing)
|
||||||
|
{
|
||||||
|
// get the legend spacing
|
||||||
|
fLegendRenderer->GetMinimumLegendSpacing(view, _hSpacing, _vSpacing);
|
||||||
|
|
||||||
|
// estimate the maximum legend count we might need
|
||||||
|
if (fLocation == CHART_AXIS_LEFT || fLocation == CHART_AXIS_RIGHT)
|
||||||
|
return (size.IntegerHeight() + 1) / (10 + *_vSpacing);
|
||||||
|
return (size.IntegerWidth() + 1) / (20 + *_hSpacing);
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public:
|
|||||||
virtual void SetLocation(ChartAxisLocation location);
|
virtual void SetLocation(ChartAxisLocation location);
|
||||||
virtual void SetRange(const ChartDataRange& range);
|
virtual void SetRange(const ChartDataRange& range);
|
||||||
virtual void SetFrame(BRect frame);
|
virtual void SetFrame(BRect frame);
|
||||||
virtual BSize PreferredSize(BView* view);
|
virtual BSize PreferredSize(BView* view, BSize maxSize);
|
||||||
virtual void Render(BView* view, BRect updateRect);
|
virtual void Render(BView* view, BRect updateRect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -34,6 +34,8 @@ private:
|
|||||||
private:
|
private:
|
||||||
void _InvalidateLayout();
|
void _InvalidateLayout();
|
||||||
bool _ValidateLayout(BView* view);
|
bool _ValidateLayout(BView* view);
|
||||||
|
int32 _EstimateMaxLegendCount(BView* view, BSize size,
|
||||||
|
float* _hSpacing, float* _vSpacing);
|
||||||
inline float _LegendPosition(double value, float legendSize,
|
inline float _LegendPosition(double value, float legendSize,
|
||||||
float totalSize, double scale);
|
float totalSize, double scale);
|
||||||
inline void _FilterLegends(int32 totalSize, int32 spacing,
|
inline void _FilterLegends(int32 totalSize, int32 spacing,
|
||||||
|
|||||||
Reference in New Issue
Block a user