Coverage Report

Created: 2026-06-13 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwps/src/lib/WKSChart.h
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2
/* libwps
3
 * Version: MPL 2.0 / LGPLv2.1+
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * Major Contributor(s):
10
 * Copyright (C) 2006, 2007 Andrew Ziem
11
 * Copyright (C) 2004 Marc Maurer (uwog@uwog.net)
12
 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
13
 *
14
 * For minor contributions see the git repository.
15
 *
16
 * Alternatively, the contents of this file may be used under the terms
17
 * of the GNU Lesser General Public License Version 2.1 or later
18
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
19
 * applicable instead of those above.
20
 */
21
22
/*
23
 * Structure to store and construct a chart
24
 *
25
 */
26
27
#ifndef WKS_CHART
28
#  define WKS_CHART
29
30
#include <iostream>
31
#include <vector>
32
#include <map>
33
34
#include "libwps_internal.h"
35
36
#include "WPSEntry.h"
37
#include "WPSFont.h"
38
#include "WPSGraphicStyle.h"
39
40
namespace WKSChartInternal
41
{
42
class SubDocument;
43
}
44
/** a class used to store a chart associated to a spreadsheet .... */
45
class WKSChart
46
{
47
  friend class WKSChartInternal::SubDocument;
48
public:
49
  //! a cell position
50
  struct Position
51
  {
52
    //! constructor
53
    explicit Position(Vec2i pos=Vec2i(-1,-1), librevenge::RVNGString const &sheetName="")
54
10.4M
      : m_pos(pos)
55
10.4M
      , m_sheetName(sheetName)
56
10.4M
      , m_sheetId(-1)
57
10.4M
    {
58
10.4M
    }
59
    //! return true if the position is valid
60
    bool valid() const
61
3.10M
    {
62
3.10M
      return m_pos[0]>=0 && m_pos[1]>=0 && (!m_sheetName.empty() || m_sheetId>=0);
63
3.10M
    }
64
    //! return true if the position is valid
65
    bool valid(Position const &maxPos) const
66
1.56M
    {
67
1.56M
      return valid() && maxPos.valid() && maxPos.m_pos[0]>=m_pos[0] && maxPos.m_pos[1]>=m_pos[1];
68
1.56M
    }
69
    //! return the cell name
70
    librevenge::RVNGString getCellName() const;
71
    //! operator<<
72
    friend std::ostream &operator<<(std::ostream &o, Position const &pos);
73
    //! operator==
74
    bool operator==(Position const &pos) const
75
176k
    {
76
176k
      return m_pos==pos.m_pos && m_sheetName==pos.m_sheetName && m_sheetId==pos.m_sheetId;
77
176k
    }
78
    //! operator!=
79
    bool operator!=(Position const &pos) const
80
176k
    {
81
176k
      return !(operator==(pos));
82
176k
    }
83
    //! the cell column and row
84
    Vec2i m_pos;
85
    //! the cell sheet name
86
    librevenge::RVNGString m_sheetName;
87
    /** the cell sheet id
88
      \note can be used temporary if the sheet name is not known when reading a position,
89
      but you must before sending a chart, go through such positions to set the final
90
      spreadsheet name
91
     */
92
    int m_sheetId;
93
  };
94
  //! a axis in a chart
95
  struct Axis
96
  {
97
    //! the axis content
98
    enum Type { A_None, A_Numeric, A_Logarithmic, A_Sequence, A_Sequence_Skip_Empty };
99
    //! constructor
100
    Axis();
101
    //! destructor
102
    ~Axis();
103
    //! add content to the propList
104
    void addContentTo(int coord, librevenge::RVNGPropertyList &propList) const;
105
    //! add style to the propList
106
    void addStyleTo(librevenge::RVNGPropertyList &propList) const;
107
    //! operator<<
108
    friend std::ostream &operator<<(std::ostream &o, Axis const &axis);
109
    //! the sequence type
110
    Type m_type;
111
    //! automatic scaling (or manual)
112
    bool m_automaticScaling;
113
    //! the minimum, maximum scaling(if manual)
114
    Vec2f m_scaling;
115
    //! show or not the grid
116
    bool m_showGrid;
117
    //! show or not the label
118
    bool m_showLabel;
119
    //! the label range if defined
120
    Position m_labelRanges[2];
121
122
    //! show or not the title/subtitle
123
    bool m_showTitle;
124
    //! the title cell range
125
    Position m_titleRange;
126
    //! the title label
127
    librevenge::RVNGString m_title;
128
    //! the subtitle label
129
    librevenge::RVNGString m_subTitle;
130
    //! the graphic style
131
    WPSGraphicStyle m_style;
132
  };
133
  //! a legend in a chart
134
  struct Legend
135
  {
136
    //! constructor
137
    Legend()
138
114k
      : m_show(false)
139
114k
      , m_autoPosition(true)
140
114k
      , m_relativePosition(WPSBorder::RightBit)
141
114k
      , m_position(0,0)
142
114k
      , m_font()
143
114k
      , m_style()
144
114k
    {
145
114k
    }
146
    //! add content to the propList
147
    void addContentTo(librevenge::RVNGPropertyList &propList) const;
148
    //! add style to the propList
149
    void addStyleTo(librevenge::RVNGPropertyList &propList) const;
150
    //! operator<<
151
    friend std::ostream &operator<<(std::ostream &o, Legend const &legend);
152
    //! show or not the legend
153
    bool m_show;
154
    //! automatic position
155
    bool m_autoPosition;
156
    //! the automatic position libwps::LeftBit|...
157
    int m_relativePosition;
158
    //! the position in points
159
    Vec2f m_position;
160
    //! the font
161
    WPSFont m_font;
162
    //! the graphic style
163
    WPSGraphicStyle m_style;
164
  };
165
  //! a serie in a chart
166
  struct Serie
167
  {
168
    //! the series type
169
    enum Type { S_Area, S_Bar, S_Bubble, S_Circle, S_Column, S_Gantt, S_Line, S_Radar, S_Ring, S_Scatter, S_Stock, S_Surface };
170
    //! the point type
171
    enum PointType
172
    {
173
      P_None=0, P_Automatic, P_Square, P_Diamond, P_Arrow_Down,
174
      P_Arrow_Up, P_Arrow_Right, P_Arrow_Left, P_Bow_Tie, P_Hourglass,
175
      P_Circle, P_Star, P_X, P_Plus, P_Asterisk,
176
      P_Horizontal_Bar, P_Vertical_Bar
177
    };
178
    //! constructor
179
    Serie();
180
15.5k
    Serie(Serie const &)=default;
181
    Serie(Serie &&)=default;
182
    Serie &operator=(Serie const &)=default;
183
1.89M
    Serie &operator=(Serie &&)=default;
184
    //! destructor
185
    virtual ~Serie();
186
    //! return true if the serie style is 1D
187
    bool is1DStyle() const
188
757k
    {
189
757k
      return m_type==S_Line || m_type==S_Radar || (m_type==S_Scatter && m_pointType==P_None);
190
757k
    }
191
    //! set the primary color
192
    void setPrimaryColor(WPSColor const &color, float opacity = 1, bool force1D=false)
193
194k
    {
194
194k
      if (force1D || is1DStyle())
195
2.44k
        m_style.m_lineColor=color;
196
191k
      else
197
191k
        m_style.setSurfaceColor(color, opacity);
198
194k
    }
199
    //! set the primary pattern
200
    void setPrimaryPattern(WPSGraphicStyle::Pattern const &pattern, bool force1D=false);
201
    //! set the secondary color
202
    void setSecondaryColor(WPSColor const &color)
203
196k
    {
204
196k
      if (!is1DStyle())
205
194k
        m_style.m_lineColor=color;
206
196k
    }
207
    //! return true if the serie is valid
208
    bool valid() const
209
154k
    {
210
154k
      return m_ranges[0].valid(m_ranges[0]);
211
154k
    }
212
    //! add content to the propList
213
    void addContentTo(librevenge::RVNGPropertyList &propList) const;
214
    //! add style to the propList
215
    void addStyleTo(librevenge::RVNGPropertyList &propList) const;
216
    //! returns a string corresponding to a series type
217
    static std::string getSerieTypeName(Type type);
218
    //! operator<<
219
    friend std::ostream &operator<<(std::ostream &o, Serie const &series);
220
    //! the type
221
    Type m_type;
222
    //! the data range
223
    Position m_ranges[2];
224
    //! use or not the secondary y axis
225
    bool m_useSecondaryY;
226
    //! the label font
227
    WPSFont m_font;
228
    //! the label ranges if defined(unused)
229
    Position m_labelRanges[2];
230
    //! the legend range if defined
231
    Position m_legendRange;
232
    //! the legend name if defined
233
    librevenge::RVNGString m_legendText;
234
    //! the graphic style
235
    WPSGraphicStyle m_style;
236
    //! the point type
237
    PointType m_pointType;
238
  };
239
  //! a text zone a chart
240
  struct TextZone
241
  {
242
    //! the text type
243
    enum Type { T_Title, T_SubTitle, T_Footer };
244
    //! the text content type
245
    enum ContentType { C_Cell, C_Text };
246
247
    //! constructor
248
    explicit TextZone(Type type);
249
103k
    TextZone(TextZone const &)=default;
250
    //! destructor
251
    ~TextZone();
252
    //! returns true if the textbox is valid
253
    bool valid() const
254
23.1k
    {
255
23.1k
      if (!m_show) return false;
256
22.7k
      if (m_contentType==C_Cell)
257
194
        return m_cell.valid();
258
22.5k
      if (m_contentType!=C_Text)
259
0
        return false;
260
22.5k
      for (auto const &e : m_textEntryList)
261
22.5k
      {
262
22.5k
        if (e.valid()) return true;
263
22.5k
      }
264
23
      return false;
265
22.5k
    }
266
    //! add content to the propList
267
    void addContentTo(librevenge::RVNGPropertyList &propList) const;
268
    //! add to the propList
269
    void addStyleTo(librevenge::RVNGPropertyList &propList) const;
270
    //! operator<<
271
    friend std::ostream &operator<<(std::ostream &o, TextZone const &zone);
272
    //! the zone type
273
    Type m_type;
274
    //! the content type
275
    ContentType m_contentType;
276
    //! true if the zone is visible
277
    bool m_show;
278
    //! the position in the zone
279
    Vec2f m_position;
280
    //! the cell position ( or title and subtitle)
281
    Position m_cell;
282
    //! the text entry (or the list of text entry)
283
    std::vector<WPSEntry> m_textEntryList;
284
    //! the zone format
285
    WPSFont m_font;
286
    //! the graphic style
287
    WPSGraphicStyle m_style;
288
  };
289
290
  //! the constructor
291
  explicit WKSChart(Vec2f const &dim=Vec2f());
292
  //! the destructor
293
  virtual ~WKSChart();
294
  //! send the chart to the listener
295
  void sendChart(WKSContentListenerPtr &listener, librevenge::RVNGSpreadsheetInterface *interface) const;
296
  //! send the zone content (called when the zone is of text type)
297
  virtual void sendContent(TextZone const &zone, WPSListenerPtr &listener) const=0;
298
299
  //! set the grid color
300
  void setGridColor(WPSColor const &color)
301
39.0k
  {
302
39.0k
    m_gridColor=color;
303
39.0k
  }
304
  //! return an axis (corresponding to a coord)
305
  Axis &getAxis(int coord);
306
  //! return an axis (corresponding to a coord)
307
  Axis const &getAxis(int coord) const;
308
309
  //! returns the legend
310
  Legend const &getLegend() const
311
0
  {
312
0
    return m_legend;
313
0
  }
314
  //! returns the legend
315
  Legend &getLegend()
316
89.6k
  {
317
89.6k
    return m_legend;
318
89.6k
  }
319
320
  //! return a serie
321
  Serie *getSerie(int id, bool create);
322
  //! returns the list of defined series
323
  std::map<int, Serie> const &getIdSerieMap() const
324
30.0k
  {
325
30.0k
    return m_serieMap;
326
30.0k
  }
327
  //! returns a textzone content
328
  TextZone *getTextZone(TextZone::Type type, bool create=false);
329
330
protected:
331
  //! sends a textzone content
332
  void sendTextZoneContent(TextZone::Type type, WPSListenerPtr listener) const;
333
334
public:
335
  //! the chart dimension in point
336
  Vec2f m_dimension;
337
  //! the chart type (if no series)
338
  Serie::Type m_type;
339
  //! a flag to know if the data are stacked or not
340
  bool m_dataStacked;
341
  //! a flag to know if the data are percent stacked or not
342
  bool m_dataPercentStacked;
343
  //! a flag to know if the data are vertical (for bar)
344
  bool m_dataVertical;
345
  //! a flag to know if the graphic is 3D
346
  bool m_is3D;
347
  //! a flag to know if real 3D or 2D-extended
348
  bool m_is3DDeep;
349
350
  // main
351
352
  //! the chart style
353
  WPSGraphicStyle m_style;
354
  //! the chart name
355
  librevenge::RVNGString m_name;
356
357
  // plot area
358
359
  //! the plot area dimension in percent
360
  WPSBox2f m_plotAreaPosition;
361
  //! the ploat area style
362
  WPSGraphicStyle m_plotAreaStyle;
363
364
  // legend
365
366
  //! the legend dimension in percent
367
  WPSBox2f m_legendPosition;
368
369
  //! floor
370
  WPSGraphicStyle m_floorStyle;
371
  //! wall
372
  WPSGraphicStyle m_wallStyle;
373
374
protected:
375
  //! the grid color
376
  WPSColor m_gridColor;
377
  //! the x,y,y-second,z and a bad axis
378
  Axis m_axis[5];
379
  //! the legend
380
  Legend m_legend;
381
  //! the list of series
382
  std::map<int, Serie> m_serieMap;
383
  //! a map text zone type to text zone
384
  std::map<TextZone::Type, TextZone> m_textZoneMap;
385
private:
386
  explicit WKSChart(WKSChart const &orig) = delete;
387
  WKSChart &operator=(WKSChart const &orig) = delete;
388
};
389
390
#endif
391
/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */