1bea425f1SIngo Weinhold /*
2bea425f1SIngo Weinhold * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3bea425f1SIngo Weinhold * Distributed under the terms of the MIT License.
4bea425f1SIngo Weinhold */
5bea425f1SIngo Weinhold
6bea425f1SIngo Weinhold #include "chart/LegendChartAxis.h"
7bea425f1SIngo Weinhold
8bea425f1SIngo Weinhold #include <limits.h>
9bea425f1SIngo Weinhold #include <stdio.h>
10bea425f1SIngo Weinhold
11bea425f1SIngo Weinhold #include <algorithm>
12bea425f1SIngo Weinhold #include <new>
13bea425f1SIngo Weinhold
14bea425f1SIngo Weinhold #include <Font.h>
15bea425f1SIngo Weinhold #include <View.h>
16bea425f1SIngo Weinhold
17bea425f1SIngo Weinhold #include "chart/ChartLegend.h"
18bea425f1SIngo Weinhold #include "chart/ChartAxisLegendSource.h"
19bea425f1SIngo Weinhold
20bea425f1SIngo Weinhold
21bea425f1SIngo Weinhold static const int32 kChartRulerDistance = 2;
22bea425f1SIngo Weinhold static const int32 kRulerSize = 3;
23bea425f1SIngo Weinhold static const int32 kRulerMarkSize = 3;
24bea425f1SIngo Weinhold static const int32 kRulerLegendDistance = 2;
25bea425f1SIngo Weinhold static const int32 kChartLegendDistance
26bea425f1SIngo Weinhold = kChartRulerDistance + kRulerSize + kRulerMarkSize + kRulerLegendDistance;
27bea425f1SIngo Weinhold
28bea425f1SIngo Weinhold
29bea425f1SIngo Weinhold
30bea425f1SIngo Weinhold struct LegendChartAxis::LegendInfo {
31bea425f1SIngo Weinhold ChartLegend* legend;
32bea425f1SIngo Weinhold double value;
33bea425f1SIngo Weinhold BSize size;
34bea425f1SIngo Weinhold
LegendInfoLegendChartAxis::LegendInfo35bea425f1SIngo Weinhold LegendInfo(ChartLegend* legend, double value, BSize size)
36bea425f1SIngo Weinhold :
37bea425f1SIngo Weinhold legend(legend),
38bea425f1SIngo Weinhold value(value),
39bea425f1SIngo Weinhold size(size)
40bea425f1SIngo Weinhold {
41bea425f1SIngo Weinhold }
42bea425f1SIngo Weinhold
~LegendInfoLegendChartAxis::LegendInfo43bea425f1SIngo Weinhold ~LegendInfo()
44bea425f1SIngo Weinhold {
45bea425f1SIngo Weinhold delete legend;
46bea425f1SIngo Weinhold }
47bea425f1SIngo Weinhold };
48bea425f1SIngo Weinhold
49bea425f1SIngo Weinhold
50bea425f1SIngo Weinhold float
_LegendPosition(double value,float legendSize,float totalSize,double scale)51bea425f1SIngo Weinhold LegendChartAxis::_LegendPosition(double value, float legendSize,
52bea425f1SIngo Weinhold float totalSize, double scale)
53bea425f1SIngo Weinhold {
54bea425f1SIngo Weinhold float position = (value - fRange.min) * scale - legendSize / 2;
55bea425f1SIngo Weinhold if (position + legendSize > totalSize)
56bea425f1SIngo Weinhold position = totalSize - legendSize;
57bea425f1SIngo Weinhold if (position < 0)
58bea425f1SIngo Weinhold position = 0;
59bea425f1SIngo Weinhold return position;
60bea425f1SIngo Weinhold }
61bea425f1SIngo Weinhold
62bea425f1SIngo Weinhold
63bea425f1SIngo Weinhold void
_FilterLegends(int32 totalSize,int32 spacing,float BSize::* sizeField)64bea425f1SIngo Weinhold LegendChartAxis::_FilterLegends(int32 totalSize, int32 spacing,
65bea425f1SIngo Weinhold float BSize::* sizeField)
66bea425f1SIngo Weinhold {
67bea425f1SIngo Weinhold // compute the min/max legend levels
68bea425f1SIngo Weinhold int32 legendCount = fLegends.CountItems();
69bea425f1SIngo Weinhold int32 minLevel = INT_MAX;
70bea425f1SIngo Weinhold int32 maxLevel = 0;
71bea425f1SIngo Weinhold
72bea425f1SIngo Weinhold for (int32 i = 0; i < legendCount; i++) {
73bea425f1SIngo Weinhold LegendInfo* info = fLegends.ItemAt(i);
74bea425f1SIngo Weinhold int32 level = info->legend->Level();
75bea425f1SIngo Weinhold if (level < minLevel)
76bea425f1SIngo Weinhold minLevel = level;
77bea425f1SIngo Weinhold if (level > maxLevel)
78bea425f1SIngo Weinhold maxLevel = level;
79bea425f1SIngo Weinhold }
80bea425f1SIngo Weinhold
81bea425f1SIngo Weinhold if (maxLevel <= 0)
82bea425f1SIngo Weinhold return;
83bea425f1SIngo Weinhold
84bea425f1SIngo Weinhold double rangeSize = fRange.max - fRange.min;
85bea425f1SIngo Weinhold if (rangeSize == 0)
86bea425f1SIngo Weinhold rangeSize = 1.0;
87bea425f1SIngo Weinhold double scale = (double)totalSize / rangeSize;
88bea425f1SIngo Weinhold
89bea425f1SIngo Weinhold // Filter out all higher level legends colliding with lower level or
90bea425f1SIngo Weinhold // preceeding same-level legends. We iterate backwards from the lower to
91bea425f1SIngo Weinhold // the higher levels
92*883b3e1dSMichael Lotz for (int32 level = std::max(minLevel, (int32)0); level <= maxLevel;) {
93bea425f1SIngo Weinhold legendCount = fLegends.CountItems();
94bea425f1SIngo Weinhold
95bea425f1SIngo Weinhold // get the first legend position/end
96bea425f1SIngo Weinhold LegendInfo* info = fLegends.ItemAt(0);
97bea425f1SIngo Weinhold float position = _LegendPosition(info->value, info->size.*sizeField,
98bea425f1SIngo Weinhold (float)totalSize, scale);;
99bea425f1SIngo Weinhold
100bea425f1SIngo Weinhold int32 previousEnd = (int32)ceilf(position + info->size.*sizeField);
101bea425f1SIngo Weinhold int32 previousLevel = info->legend->Level();
102bea425f1SIngo Weinhold
103bea425f1SIngo Weinhold for (int32 i = 1; (info = fLegends.ItemAt(i)) != NULL; i++) {
104bea425f1SIngo Weinhold float position = _LegendPosition(info->value, info->size.*sizeField,
105bea425f1SIngo Weinhold (float)totalSize, scale);;
106bea425f1SIngo Weinhold
107bea425f1SIngo Weinhold if (position - spacing < previousEnd
108bea425f1SIngo Weinhold && (previousLevel <= level
109bea425f1SIngo Weinhold || info->legend->Level() <= level)
110bea425f1SIngo Weinhold && std::max(previousLevel, info->legend->Level()) > 0) {
111bea425f1SIngo Weinhold // The item intersects with the previous one -- remove the
112bea425f1SIngo Weinhold // one at the higher level.
113bea425f1SIngo Weinhold if (info->legend->Level() >= previousLevel) {
114bea425f1SIngo Weinhold // This item is at the higher level -- remove it.
115bea425f1SIngo Weinhold delete fLegends.RemoveItemAt(i);
116bea425f1SIngo Weinhold i--;
117bea425f1SIngo Weinhold continue;
118bea425f1SIngo Weinhold }
119bea425f1SIngo Weinhold
120bea425f1SIngo Weinhold // The previous item is at the higher level -- remove it.
121bea425f1SIngo Weinhold delete fLegends.RemoveItemAt(i - 1);
122bea425f1SIngo Weinhold i--;
123bea425f1SIngo Weinhold }
124bea425f1SIngo Weinhold
125bea425f1SIngo Weinhold if (i == 0 && position < 0)
126bea425f1SIngo Weinhold position = 0;
127bea425f1SIngo Weinhold previousEnd = (int32)ceilf(position + info->size.*sizeField);
128bea425f1SIngo Weinhold previousLevel = info->legend->Level();
129bea425f1SIngo Weinhold }
130bea425f1SIngo Weinhold
131bea425f1SIngo Weinhold // repeat with the level as long as we've removed something
132bea425f1SIngo Weinhold if (legendCount == fLegends.CountItems())
133bea425f1SIngo Weinhold level++;
134bea425f1SIngo Weinhold }
135bea425f1SIngo Weinhold }
136bea425f1SIngo Weinhold
137bea425f1SIngo Weinhold
LegendChartAxis(ChartAxisLegendSource * legendSource,ChartLegendRenderer * legendRenderer)138bea425f1SIngo Weinhold LegendChartAxis::LegendChartAxis(ChartAxisLegendSource* legendSource,
139bea425f1SIngo Weinhold ChartLegendRenderer* legendRenderer)
140bea425f1SIngo Weinhold :
141bea425f1SIngo Weinhold fLegendSource(legendSource),
142bea425f1SIngo Weinhold fLegendRenderer(legendRenderer),
143bea425f1SIngo Weinhold fLocation(CHART_AXIS_BOTTOM),
144bea425f1SIngo Weinhold fRange(),
145bea425f1SIngo Weinhold fFrame(),
146bea425f1SIngo Weinhold fLegends(20, true),
147bea425f1SIngo Weinhold fHorizontalSpacing(20),
148bea425f1SIngo Weinhold fVerticalSpacing(10),
149bea425f1SIngo Weinhold fLayoutValid(false)
150bea425f1SIngo Weinhold {
151bea425f1SIngo Weinhold }
152bea425f1SIngo Weinhold
153bea425f1SIngo Weinhold
~LegendChartAxis()154bea425f1SIngo Weinhold LegendChartAxis::~LegendChartAxis()
155bea425f1SIngo Weinhold {
156bea425f1SIngo Weinhold }
157bea425f1SIngo Weinhold
158bea425f1SIngo Weinhold
159bea425f1SIngo Weinhold void
SetLocation(ChartAxisLocation location)160bea425f1SIngo Weinhold LegendChartAxis::SetLocation(ChartAxisLocation location)
161bea425f1SIngo Weinhold {
162bea425f1SIngo Weinhold if (location != fLocation) {
163bea425f1SIngo Weinhold fLocation = location;
164bea425f1SIngo Weinhold _InvalidateLayout();
165bea425f1SIngo Weinhold }
166bea425f1SIngo Weinhold }
167bea425f1SIngo Weinhold
168bea425f1SIngo Weinhold
169bea425f1SIngo Weinhold void
SetRange(const ChartDataRange & range)170bea425f1SIngo Weinhold LegendChartAxis::SetRange(const ChartDataRange& range)
171bea425f1SIngo Weinhold {
172bea425f1SIngo Weinhold if (range != fRange) {
173bea425f1SIngo Weinhold fRange = range;
174bea425f1SIngo Weinhold _InvalidateLayout();
175bea425f1SIngo Weinhold }
176bea425f1SIngo Weinhold }
177bea425f1SIngo Weinhold
178bea425f1SIngo Weinhold
179bea425f1SIngo Weinhold void
SetFrame(BRect frame)180bea425f1SIngo Weinhold LegendChartAxis::SetFrame(BRect frame)
181bea425f1SIngo Weinhold {
182bea425f1SIngo Weinhold if (frame != fFrame) {
183bea425f1SIngo Weinhold fFrame = frame;
184bea425f1SIngo Weinhold _InvalidateLayout();
185bea425f1SIngo Weinhold }
186bea425f1SIngo Weinhold }
187bea425f1SIngo Weinhold
188bea425f1SIngo Weinhold
189bea425f1SIngo Weinhold BSize
PreferredSize(BView * view,BSize maxSize)190314f0e01SIngo Weinhold LegendChartAxis::PreferredSize(BView* view, BSize maxSize)
191bea425f1SIngo Weinhold {
192314f0e01SIngo Weinhold // estimate the maximum legend count we might need
193314f0e01SIngo Weinhold float hSpacing, vSpacing;
194314f0e01SIngo Weinhold int32 maxLegends = _EstimateMaxLegendCount(view, maxSize, &hSpacing,
195314f0e01SIngo Weinhold &vSpacing);
196314f0e01SIngo Weinhold BSize spacing(hSpacing, vSpacing);
197314f0e01SIngo Weinhold if (maxLegends < 4)
198314f0e01SIngo Weinhold maxLegends = 4;
199314f0e01SIngo Weinhold
200314f0e01SIngo Weinhold // get the legends
201314f0e01SIngo Weinhold ChartLegend* legends[maxLegends];
202314f0e01SIngo Weinhold double values[maxLegends];
203314f0e01SIngo Weinhold
204314f0e01SIngo Weinhold int32 legendCount = fLegendSource->GetAxisLegends(fRange, legends, values,
205314f0e01SIngo Weinhold maxLegends);
206314f0e01SIngo Weinhold
207314f0e01SIngo Weinhold // get the sizes, delete the legends, and compute the preferred size
208314f0e01SIngo Weinhold float BSize::* sizeField;
209314f0e01SIngo Weinhold float BSize::* otherSizeField;
210bea425f1SIngo Weinhold if (fLocation == CHART_AXIS_LEFT || fLocation == CHART_AXIS_RIGHT) {
211314f0e01SIngo Weinhold sizeField = &BSize::height;
212314f0e01SIngo Weinhold otherSizeField = &BSize::width;
213bea425f1SIngo Weinhold } else {
214314f0e01SIngo Weinhold sizeField = &BSize::width;
215314f0e01SIngo Weinhold otherSizeField = &BSize::height;
216bea425f1SIngo Weinhold }
217bea425f1SIngo Weinhold
218314f0e01SIngo Weinhold BSize preferredSize;
219314f0e01SIngo Weinhold
220314f0e01SIngo Weinhold for (int32 i = 0; i < legendCount; i++) {
221314f0e01SIngo Weinhold ChartLegend* legend = legends[i];
222314f0e01SIngo Weinhold BSize size = fLegendRenderer->LegendSize(legend, view);
223314f0e01SIngo Weinhold delete legend;
224314f0e01SIngo Weinhold
225314f0e01SIngo Weinhold if (size.*sizeField > preferredSize.*sizeField)
226314f0e01SIngo Weinhold preferredSize.*sizeField = size.*sizeField;
227314f0e01SIngo Weinhold if (size.*otherSizeField > preferredSize.*otherSizeField)
228314f0e01SIngo Weinhold preferredSize.*otherSizeField = size.*otherSizeField;
229314f0e01SIngo Weinhold }
230314f0e01SIngo Weinhold
231314f0e01SIngo Weinhold // Suppose we want to have at least 2 legends.
232314f0e01SIngo Weinhold preferredSize.*sizeField
233314f0e01SIngo Weinhold = ceilf(preferredSize.*sizeField * 2 + spacing.*sizeField);
234314f0e01SIngo Weinhold preferredSize.*otherSizeField += kChartLegendDistance;
235314f0e01SIngo Weinhold
236314f0e01SIngo Weinhold return preferredSize;
237bea425f1SIngo Weinhold }
238bea425f1SIngo Weinhold
239bea425f1SIngo Weinhold
240bea425f1SIngo Weinhold void
Render(BView * view,BRect updateRect)241bea425f1SIngo Weinhold LegendChartAxis::Render(BView* view, BRect updateRect)
242bea425f1SIngo Weinhold {
243bea425f1SIngo Weinhold if (!_ValidateLayout(view))
244bea425f1SIngo Weinhold return;
245bea425f1SIngo Weinhold
246b8c273deSIngo Weinhold float valueDirection;
247b8c273deSIngo Weinhold float rulerDirection;
248b8c273deSIngo Weinhold float BSize::* sizeField;
249b8c273deSIngo Weinhold float BSize::* otherSizeField;
250b8c273deSIngo Weinhold float BPoint::* pointField;
251b8c273deSIngo Weinhold float BPoint::* otherPointField;
252b8c273deSIngo Weinhold
253b8c273deSIngo Weinhold switch (fLocation) {
254b8c273deSIngo Weinhold case CHART_AXIS_LEFT:
255b8c273deSIngo Weinhold case CHART_AXIS_RIGHT:
256b8c273deSIngo Weinhold valueDirection = -1;
257b8c273deSIngo Weinhold rulerDirection = fLocation == CHART_AXIS_LEFT ? -1 : 1;
258b8c273deSIngo Weinhold sizeField = &BSize::height;
259b8c273deSIngo Weinhold otherSizeField = &BSize::width;
260b8c273deSIngo Weinhold pointField = &BPoint::y;
261b8c273deSIngo Weinhold otherPointField = &BPoint::x;
262b8c273deSIngo Weinhold break;
263b8c273deSIngo Weinhold case CHART_AXIS_TOP:
264b8c273deSIngo Weinhold case CHART_AXIS_BOTTOM:
265b8c273deSIngo Weinhold valueDirection = 1;
266b8c273deSIngo Weinhold rulerDirection = fLocation == CHART_AXIS_TOP ? -1 : 1;
267b8c273deSIngo Weinhold sizeField = &BSize::width;
268b8c273deSIngo Weinhold otherSizeField = &BSize::height;
269b8c273deSIngo Weinhold pointField = &BPoint::x;
270b8c273deSIngo Weinhold otherPointField = &BPoint::y;
271b8c273deSIngo Weinhold break;
272b8c273deSIngo Weinhold default:
273b8c273deSIngo Weinhold return;
274b8c273deSIngo Weinhold }
275b8c273deSIngo Weinhold
276b8c273deSIngo Weinhold float totalSize = floorf(fFrame.Size().*sizeField) + 1;
277bea425f1SIngo Weinhold double rangeSize = fRange.max - fRange.min;
278bea425f1SIngo Weinhold if (rangeSize == 0)
279bea425f1SIngo Weinhold rangeSize = 1.0;
280bea425f1SIngo Weinhold double scale = (double)totalSize / rangeSize;
281bea425f1SIngo Weinhold
282bea425f1SIngo Weinhold // draw the ruler
283b8c273deSIngo Weinhold float rulerStart = fFrame.LeftBottom().*pointField;
284b8c273deSIngo Weinhold float rulerChartClosest = rulerDirection == 1
285b8c273deSIngo Weinhold ? fFrame.LeftTop().*otherPointField + kChartRulerDistance
286b8c273deSIngo Weinhold : fFrame.RightBottom().*otherPointField - kChartRulerDistance;
287b8c273deSIngo Weinhold float rulerEnd = fFrame.RightTop().*pointField;
288b8c273deSIngo Weinhold float rulerChartDistant = rulerChartClosest + rulerDirection * kRulerSize;
289bea425f1SIngo Weinhold
290bea425f1SIngo Weinhold rgb_color black = { 0, 0, 0, 255 };
291bea425f1SIngo Weinhold view->BeginLineArray(3 + fLegends.CountItems());
292b8c273deSIngo Weinhold BPoint first;
293b8c273deSIngo Weinhold first.*pointField = rulerStart;
294b8c273deSIngo Weinhold first.*otherPointField = rulerChartClosest;
295b8c273deSIngo Weinhold BPoint second = first;
296b8c273deSIngo Weinhold second.*otherPointField = rulerChartDistant;
297b8c273deSIngo Weinhold BPoint third = second;
298b8c273deSIngo Weinhold third.*pointField = rulerEnd;
299b8c273deSIngo Weinhold BPoint fourth = third;
300b8c273deSIngo Weinhold fourth.*otherPointField = rulerChartClosest;
301b8c273deSIngo Weinhold view->AddLine(first, second, black);
302b8c273deSIngo Weinhold view->AddLine(second, third, black);
303b8c273deSIngo Weinhold view->AddLine(third, fourth, black);
304bea425f1SIngo Weinhold
305bea425f1SIngo Weinhold // marks
306bea425f1SIngo Weinhold for (int32 i = 0; LegendInfo* info = fLegends.ItemAt(i); i++) {
307bea425f1SIngo Weinhold float position = (info->value - fRange.min) * scale;
308b8c273deSIngo Weinhold position = rulerStart + valueDirection * position;
309b8c273deSIngo Weinhold first.*pointField = position;
310b8c273deSIngo Weinhold first.*otherPointField = rulerChartDistant;
311b8c273deSIngo Weinhold second.*pointField = position;
312b8c273deSIngo Weinhold second.*otherPointField = rulerChartDistant
313b8c273deSIngo Weinhold + rulerDirection * kRulerMarkSize;
314b8c273deSIngo Weinhold view->AddLine(first, second, black);
315bea425f1SIngo Weinhold }
316bea425f1SIngo Weinhold view->EndLineArray();
317bea425f1SIngo Weinhold
318bea425f1SIngo Weinhold // draw the legends
319b8c273deSIngo Weinhold float legendRulerClosest = rulerChartDistant
320b8c273deSIngo Weinhold + rulerDirection * (kRulerMarkSize + kRulerLegendDistance);
321bea425f1SIngo Weinhold
322bea425f1SIngo Weinhold for (int32 i = 0; LegendInfo* info = fLegends.ItemAt(i); i++) {
323bea425f1SIngo Weinhold float position = _LegendPosition(info->value, info->size.*sizeField,
324bea425f1SIngo Weinhold (float)totalSize, scale);;
325bea425f1SIngo Weinhold
326b8c273deSIngo Weinhold first.*pointField = rulerStart
327b8c273deSIngo Weinhold + (valueDirection == 1
328b8c273deSIngo Weinhold ? position : -position - info->size.*sizeField);
329b8c273deSIngo Weinhold first.*otherPointField = rulerDirection == 1
330b8c273deSIngo Weinhold ? legendRulerClosest
331b8c273deSIngo Weinhold : legendRulerClosest - info->size.*otherSizeField;
332b8c273deSIngo Weinhold
333b8c273deSIngo Weinhold fLegendRenderer->RenderLegend(info->legend, view, first);
334bea425f1SIngo Weinhold }
335bea425f1SIngo Weinhold }
336bea425f1SIngo Weinhold
337bea425f1SIngo Weinhold
338bea425f1SIngo Weinhold void
_InvalidateLayout()339bea425f1SIngo Weinhold LegendChartAxis::_InvalidateLayout()
340bea425f1SIngo Weinhold {
341bea425f1SIngo Weinhold fLayoutValid = false;
342bea425f1SIngo Weinhold }
343bea425f1SIngo Weinhold
344bea425f1SIngo Weinhold
345bea425f1SIngo Weinhold bool
_ValidateLayout(BView * view)346bea425f1SIngo Weinhold LegendChartAxis::_ValidateLayout(BView* view)
347bea425f1SIngo Weinhold {
348bea425f1SIngo Weinhold if (fLayoutValid)
349bea425f1SIngo Weinhold return true;
350bea425f1SIngo Weinhold
351bea425f1SIngo Weinhold fLegends.MakeEmpty();
352bea425f1SIngo Weinhold
353bea425f1SIngo Weinhold int32 width = fFrame.IntegerWidth() + 1;
354bea425f1SIngo Weinhold int32 height = fFrame.IntegerHeight() + 1;
355bea425f1SIngo Weinhold
356bea425f1SIngo Weinhold // estimate the maximum legend count we might need
357314f0e01SIngo Weinhold int32 maxLegends = _EstimateMaxLegendCount(view, fFrame.Size(),
358314f0e01SIngo Weinhold &fHorizontalSpacing, &fVerticalSpacing);
359bea425f1SIngo Weinhold
360bea425f1SIngo Weinhold if (maxLegends == 0)
361bea425f1SIngo Weinhold return false;
362bea425f1SIngo Weinhold
363bea425f1SIngo Weinhold // get the legends
364bea425f1SIngo Weinhold ChartLegend* legends[maxLegends];
365bea425f1SIngo Weinhold double values[maxLegends];
366bea425f1SIngo Weinhold
367bea425f1SIngo Weinhold int32 legendCount = fLegendSource->GetAxisLegends(fRange, legends, values,
368bea425f1SIngo Weinhold maxLegends);
369bea425f1SIngo Weinhold if (legendCount == 0)
370bea425f1SIngo Weinhold return false;
371bea425f1SIngo Weinhold
372bea425f1SIngo Weinhold // create legend infos
373bea425f1SIngo Weinhold for (int32 i = 0; i < legendCount; i++) {
374bea425f1SIngo Weinhold ChartLegend* legend = legends[i];
375bea425f1SIngo Weinhold BSize size = fLegendRenderer->LegendSize(legend, view);
376bea425f1SIngo Weinhold LegendInfo* info = new(std::nothrow) LegendInfo(legend, values[i],
377bea425f1SIngo Weinhold size);
378bea425f1SIngo Weinhold if (info == NULL || !fLegends.AddItem(info)) {
379bea425f1SIngo Weinhold // TODO: Report error!
380bea425f1SIngo Weinhold delete info;
381bea425f1SIngo Weinhold for (int32 k = i; k < legendCount; k++)
382bea425f1SIngo Weinhold delete legends[k];
383bea425f1SIngo Weinhold return false;
384bea425f1SIngo Weinhold }
385bea425f1SIngo Weinhold }
386bea425f1SIngo Weinhold
387bea425f1SIngo Weinhold if (fLocation == CHART_AXIS_LEFT || fLocation == CHART_AXIS_RIGHT)
388bea425f1SIngo Weinhold _FilterLegends(height, fVerticalSpacing, &BSize::height);
389bea425f1SIngo Weinhold else
390bea425f1SIngo Weinhold _FilterLegends(width, fHorizontalSpacing, &BSize::width);
391bea425f1SIngo Weinhold
392bea425f1SIngo Weinhold fLayoutValid = true;
393bea425f1SIngo Weinhold return true;
394bea425f1SIngo Weinhold }
395314f0e01SIngo Weinhold
396314f0e01SIngo Weinhold
397314f0e01SIngo Weinhold int32
_EstimateMaxLegendCount(BView * view,BSize size,float * _hSpacing,float * _vSpacing)398314f0e01SIngo Weinhold LegendChartAxis::_EstimateMaxLegendCount(BView* view, BSize size,
399314f0e01SIngo Weinhold float* _hSpacing, float* _vSpacing)
400314f0e01SIngo Weinhold {
401314f0e01SIngo Weinhold // get the legend spacing
402314f0e01SIngo Weinhold fLegendRenderer->GetMinimumLegendSpacing(view, _hSpacing, _vSpacing);
403314f0e01SIngo Weinhold
404314f0e01SIngo Weinhold // estimate the maximum legend count we might need
405314f0e01SIngo Weinhold if (fLocation == CHART_AXIS_LEFT || fLocation == CHART_AXIS_RIGHT)
406b237fdf9SStephan Aßmus return (int32)((size.IntegerHeight() + 1) / (10 + *_vSpacing));
407b237fdf9SStephan Aßmus return (int32)((size.IntegerWidth() + 1) / (20 + *_hSpacing));
408314f0e01SIngo Weinhold }
409