This file is indexed.

/usr/include/Wt/Chart/WAxis is in libwt-dev 3.3.6+dfsg-1.1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
// This may look like C code, but it's really -*- C++ -*-
/*
 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
 *
 * See the LICENSE file for terms of use.
 */
#ifndef CHART_WAXIS_H_
#define CHART_WAXIS_H_

#include <Wt/Chart/WChartGlobal>
#include <Wt/WDateTime>
#include <Wt/WFont>
#include <Wt/WPen>
#include <Wt/WSignal>
#include <Wt/WString>
#include <Wt/WTransform>

#include <boost/any.hpp>
#ifndef WT_TARGET_JAVA
#include <boost/function.hpp>
#endif
#include <boost/unordered_map.hpp>
#include <cfloat>

namespace Wt {

  namespace Chart {

class WAbstractChartImplementation;

/*! \brief Enumeration that indicates a chart axis.
 *
 * \sa WCartesianChart::axis(Axis)
 *
 * \ingroup charts
 */
enum Axis {
  XAxis = 0,             //!< X axis.
  YAxis = 1,             //!< First Y axis (== Y1Axis).
  Y1Axis = YAxis,        //!< First Y axis (== YAxis).
  Y2Axis = 2,            //!< Second Y Axis.
  OrdinateAxis = YAxis,  //!< Ordinate axis (== Y1Axis for a 2D plot).
  XAxis_3D = 0,          //!< X axis on 3D chart.
  YAxis_3D = 3,          //!< Y axis on 3D chart.
  ZAxis_3D = 1 /* = Y */ //!< Z axis on 3D chart.
};

/*! \brief Enumeration that indicates a logical location for an axis.
 *
 * The location is dependent on the values of the other axis.
 *
 * \sa WAxis::setLocation(AxisValue)
 *
 * \ingroup charts
 */
enum AxisValue {
  MinimumValue = 0x1,  //!< At the minimum value.
  MaximumValue = 0x2,  //!< At the maximum value.
  ZeroValue = 0x4,     //!< At the zero value (if displayed).
  BothSides = 0x8      //!< At both sides (MinimumValue and MaximumValue).
};

/*! \brief Axis configuration.
 * 
 * This describes the configuration of an axis determining how
 * it should be drawn. To be passed into getLabelTicks().
 */
struct AxisConfig {
  AxisConfig()
    : side(MinimumValue), zoomLevel(1)
  { }

  AxisValue side; //!< The side the axis is drawn on, should be MinimumValue, MaximumValue, or ZeroValue
  int zoomLevel; //!< The zoom level. Different axis labels can be drawn depending on the zoom level. These are requested by WCartesianChart in powers of 2 (1, 2, 4, 8,...)
};

/*! \brief Enumeration that indicates which way the axis ticks point.
 *
 * \sa WAxis::setTickDirection(TickDirection)
 */
enum TickDirection {
  Outwards, //!< Towards of the outside of the chart.
  Inwards   //!< Pointing inwards to the chart.
};

// for < 3.0.1 compatibility
typedef AxisValue AxisLocation;

W_DECLARE_OPERATORS_FOR_FLAGS(AxisValue)

/*! \brief Enumeration that indicates a scale for an axis.
 *
 * The scale determines how values are mapped onto an axis.
 *
 * \sa WAxis::setScale(AxisScale scale)
 *
 * \ingroup charts
 */
enum AxisScale {
  /*! A category scale is set as the scale for the X axis in a \link
   * Chart::CategoryChart CategoryChart\endlink, and is only
   * applicable there. It lists all values, evenly spaced, and
   * consecutively in the order of the model. The categories are
   * converted to numbers using their ordinal (first category = 0,
   * second = 1, ...).
   */
  CategoryScale = 0,

  /*! A linear scale is the default scale for all axes, except for the
   * X scale in a CategoryScale. It maps values in a linear
   * fashion on the axis.
   */
  LinearScale = 1,

  /*! A logarithmic scale is useful for plotting values with of a
   * large range, but only works for positive values.
   */
  LogScale = 2,

  /*! A date scale is a special linear scale, which is useful for the
   * X axis in a ScatterPlot, when the X series contain dates (of type
   * WDate). The dates are converted to numbers, as Julian Days.
   */
  DateScale = 3,

  /*! A datetime scale is a special linear scale, which is useful for
   * the X axis in a ScatterPlot, when the X series contain timedates
   * (of type WDateTime). The dates are converted to numbers, as the
   * number of seconds since the Unix Epoch (midnight Coordinated
   * Universal Time (UTC) of January 1, 1970).
   */
  DateTimeScale = 4
};

/*! \class WAxis Wt/Chart/WAxis Wt/Chart/WAxis
 *  \brief Class which represents an axis of a cartesian chart.
 *
 * A cartesian chart has two or three axes: an X axis (\link
 * Chart::XAxis XAxis\endlink), a Y axis (\link Chart::YAxis
 * YAxis\endlink) and optionally a second Y axis (\link Chart::Y2Axis
 * Y2Axis\endlink). Each of the up to three axes in a cartesian
 * chart has a unique id() that identifies which of these three axes
 * it is in the enclosing chart().
 *
 * Use setVisible() to change the visibility of an axis,
 * setGridLinesEnabled() to show grid lines for an axis. The pen
 * styles for rendering the axis or grid lines may be changed using
 * setPen() and setGridLinesPen(). A margin between the axis and the
 * main plot area may be configured using setMargin().
 *
 * By default, the axis will automatically adjust its range so that
 * all data will be visible. You may manually specify a range using
 * setMinimum(), setMaximum or setRange(). The interval between labels
 * is by default automatically adjusted depending on the axis length
 * and the range, but may be manually specified using
 * setLabelInterval().
 *
 * The axis has support for being "broken", to support displaying data
 * with a few outliers which would otherwise swamp the chart. This is
 * not done automatically, but instead you need to use setBreak() to
 * specify the value range that needs to be omitted from the axis. The
 * omission is rendered in the axis and in bars that cross the break.
 *
 * The labels are shown using a "%.4g" format string for numbers, and
 * a suitable format for \link Chart::DateScale DateScale\endlink or
 * \link Chart::DateTimeScale DateTimeScale\endlink scales, based on
 * heuristics. The format may be customized using
 * setLabelFormat(). The angle of the label text may be changed using
 * setLabelAngle(). By default, all labels are printed horizontally.
 * 
 * \sa WCartesianChart
 *
 * \ingroup charts
 */
class WT_API WAxis
{
public:
  /*! \brief Constant which indicates automatic minimum calculation.
   *
   * \sa setMinimum()
   */
  static const double AUTO_MINIMUM;

  /*! \brief Constant which indicates automatic maximum calculation
   *
   * \sa setMaximum()
   */
  static const double AUTO_MAXIMUM;

  /*! \brief Destructor
   */
  virtual ~WAxis();

  /*! \brief Returns the axis id.
   *
   * \sa chart(), WCartesianChart::axis()
   */
  Axis id() const { return axis_; }

  /*! \brief Sets whether this axis is visible.
   *
   * Changes whether the axis is displayed, including ticks and
   * labels. The rendering of the grid lines is controlled seperately
   * by setGridLinesEnabled().
   *
   * The default value is true for the X axis and first Y axis, but false
   * for the second Y axis.
   *
   * \sa setGridLinesEnabled().
   */
  void setVisible(bool visible);

  /*! \brief Returns whether this axis is visible.
   *
   * \sa setVisible()
   */
  bool isVisible() const { return visible_; }

  /*! \brief Sets the axis location.
   *
   * Configures the location of the axis, relative to values on the
   * other axis (i.e. Y values for the X axis, and X values for the
   * Y axis).
   *
   * The default value is Chart::MinimumValue.
   *
   * \sa location()
   */
  void setLocation(AxisValue value);

  /*! \brief Returns the axis location.
   *
   * \sa setLocation()
   */
  AxisValue location() const { return location_; }

  /*! \brief Sets the scale of the axis.
   *
   * For the X scale in a \link Chart::CategoryChart
   * CategoryChart\endlink, the scale should be left unchanged to
   * \link Chart::CategoryScale CategoryScale\endlink.
   *
   * For all other axes, the default value is \link Chart::LinearScale
   * LinearScale\endlink, but this may be changed to \link
   * Chart::LogScale LogScale\endlink or \link Chart::DateScale
   * DateScale\endlink. \link Chart::DateScale DateScale\endlink is
   * only useful for the X axis in a ScatterPlot which contains WDate
   * values.
   *
   * \sa scale()
   */
  void setScale(AxisScale scale);

  /*! \brief Returns the scale of the axis.
   *
   * \sa setScale()
   */
  AxisScale scale() const { return scale_; }

  /*! \brief Sets the minimum value displayed on the axis.
   *
   * By default, the minimum and maximum values are determined
   * automatically so that all the data can be displayed.
   *
   * The numerical value corresponding to a data point is 
   * defined by it's AxisScale type.
   *
   * \sa setMaximum(), setAutoLimits()
   */
  void setMinimum(double minimum);

  /*! \brief Returns the minimum value displayed on the axis.
   *
   * This returned the minimum value that was set using setMinimum(),
   * or otherwise the automatically calculated (and rounded) minimum.
   *
   * The numerical value corresponding to a data point is defined by
   * it's AxisScale type.
   *
   * \sa setMinimum(), setAutoLimits(), setRoundLimits()
   */
  double minimum() const;

  /*! \brief Sets the maximum value for the axis displayed on the axis.
   *
   * By default, the minimum and maximum values are determined
   * automatically so that all the data can be displayed.
   *
   * The numerical value corresponding to a data point is 
   * defined by it's AxisScale type.
   *
   * \sa setMinimum(), setAutoLimits()
   */
  void setMaximum(double maximum);

  /*! \brief Returns the maximum value displayed on the axis.
   *
   * This returned the maximum value that was set using setMaximum(),
   * or otherwise the automatically calculated (and rounded) maximum.
   *
   * The numerical value corresponding to a data point is defined by
   * it's AxisScale type.
   *
   * \sa setMaximum(), setAutoLimits(), setRoundLimits()
   */
  double maximum() const;

  /*! \brief Sets the axis range (minimum and maximum values) manually.
   *
   * Specifies both minimum and maximum value for the axis. This
   * automatically disables automatic range calculation.
   *
   * The numerical value corresponding to a data point is defined by
   * it's AxisScale type.
   *
   * \sa setMinimum(), setMaximum()
   */
  void setRange(double minimum, double maximum);

  /*! \brief Sets the axis resolution.
   *
   * Specifies the axis resolution, in case maximum-minimum <
   * resolution minimum and maximum are modified so the maximum -
   * minimum = resolution
   *
   * The default resolution is 0, which uses a built-in epsilon.
   *
   * \sa resolution()
   */
  void setResolution(double resolution);

  /*! \brief Returns the axis resolution.
   *
   * \sa setResolution()
   */
  double resolution() const { return resolution_; }

  /*! \brief Let the minimum and/or maximum be calculated from the
   *         data.
   *
   * Using this method, you can indicate that you want to have
   * automatic limits, rather than limits set manually using
   * setMinimum() or setMaximum().
   *
   * \p locations can be Chart::MinimumValue and/or Chart::MaximumValue.
   *
   * The default value is Chart::MinimumValue | Chart::MaximumValue.
   */
  void setAutoLimits(WFlags<AxisValue> locations);

  /*! \brief Returns the limits that are calculated automatically.
   *
   * This returns the limits (Chart::MinimumValue and/or
   * Chart::MaximumValue) that are calculated automatically from the
   * data, rather than being specified manually using setMinimum()
   * and/or setMaximum().
   *
   * \sa setAutoLimits()
   */
  WFlags<AxisValue> autoLimits() const;

  /*! \brief Specifies whether limits should be rounded.
   *
   * When enabling rounding, this has the effect of rounding down the
   * minimum value, or rounding up the maximum value, to the nearest
   * label interval.
   *
   * By default, rounding is enabled for an auto-calculated limited,
   * and disabled for a manually specifed limit.
   *
   * \sa setAutoLimits()
   */
  void setRoundLimits(WFlags<AxisValue> locations);

  /*! \brief Returns whether limits should be rounded.
   *
   * \sa setRoundLimits()
   */
  WFlags<AxisValue> roundLimits() const { return roundLimits_; }

  /*! \brief Specifies a range that needs to be omitted from the axis.
   *
   * This is useful to display data with a few outliers which would
   * otherwise swamp the chart. This is not done automatically, but
   * instead you need to use setBreak() to specify the value range
   * that needs to be omitted from the axis. The omission is rendered
   * in the axis and in BarSeries that cross the break.
   *
   * \note This feature is incompatible with the interactive features
   *       of WCartesianChart.
   */
  void setBreak(double minimum, double maximum);

  /*! \brief Sets the label interval.
   *
   * Specifies the interval for displaying labels (and ticks) on the axis.
   * The default value is 0.0, and indicates that the interval should be
   * computed automatically.
   *
   * The unit for the label interval is in logical units (i.e. the same as
   * minimum or maximum).
   *
   * \sa setLabelFormat()
   */
  void setLabelInterval(double labelInterval);

  /*! \brief Returns the label interval.
   *
   * \sa setLabelInterval()
   */
  double labelInterval() const { return labelInterval_; }

  /*! \brief Sets a point to be included as one of the labels (if possible).
   *
   * The given point will be included as one of the labels, by adjusting
   * the minimum value on the axis, if that minimum is auto-computed. This
   * is only applicable to a Linear scale axis.
   *
   * The default value is 0.0.
   *
   * \sa setRoundLimits()
   */
  void setLabelBasePoint(double point);

  /*! \brief Returns the base point for labels.
   *
   * \sa setLabelBasePoint()
   */
  double labelBasePoint() const { return labelBasePoint_; }

  /*! \brief Sets the label format.
   *
   * Sets a format string which is used to format values, both for the
   * axis labels as well as data series values
   * (see WDataSeries::setLabelsEnabled()).
   *
   * For an axis with a \link Chart::LinearScale LinearScale\endlink
   * or \link Chart::LogScale LogScale\endlink scale, the format string
   * must be a format string that is accepted by snprintf() and which
   * formats one double. If the format string is an empty string,
   * then WLocale::toString() is used.
   *
   * For an axis with a \link Chart::DateScale DateScale\endlink
   * scale, the format string must be a format string accepted by
   * WDate::toString(), to format a date. If the format string is an
   * empty string, a suitable format is chosen based on heuristics.
   *
   * For an axis with a \link Chart::DateTimeScale
   * DateTimeScale\endlink scale, the format string must be a format
   * string accepted by WDateTime::toString(), to format a date. If
   * the format string is an empty string, a suitable format is chosen
   * based on heuristics.
   *
   * The default value is "%.4g" for a numeric axis, and a suitable
   * format for date(time) scales based on a heuristic taking into
   * account the current axis range.
   *
   * \sa labelFormat()
   */
  void setLabelFormat(const WString& format);

  /*! \brief Returns the label format string.
   *
   * \sa setLabelFormat()
   */
  WString labelFormat() const;

  /*! \brief Sets the label angle.
   *
   * Sets the angle used for displaying the labels (in degrees). A 0 angle
   * corresponds to horizontal text.
   *
   * The default value is 0.0.
   *
   * \sa labelAngle()
   */
  void setLabelAngle(double angle);

  /*! \brief Returns the label angle.
   *
   * \sa setLabelAngle()
   */
  double labelAngle() const { return labelAngle_; }

  /*! \brief Sets the title orientation
   *
   * Sets the orientation used for displaying the title.
   *
   * The default value is Horizontal
   *
   * \sa titleOrientation()
   */
  void setTitleOrientation(const Orientation& orientation);

  /*! \brief Returns the title orientation.
   *
   * \sa setTitleOrientation()
   */
  const Orientation& titleOrientation() const { return titleOrientation_; }

  /*! \brief Sets whether gridlines are displayed for this axis.
   *
   * When <i>enabled</i>, gird lines are drawn for each tick on this axis,
   * using the gridLinesPen().
   *
   * Unlike all other visual aspects of an axis, rendering of the
   * gridlines is not controlled by setDisplayEnabled().
   *
   * \sa setGridLinesPen(), isGridLinesEnabled()
   */
  void setGridLinesEnabled(bool enabled);

  /*! \brief Returns whether gridlines are displayed for this axis.
   *
   * \sa setGridLinesEnabled()
   */
  bool isGridLinesEnabled() const { return gridLines_; }

  /*! \brief Changes the pen used for rendering the axis and ticks.
   *
   * The default value is a black pen of 0 width.
   *
   * \sa setGridLinesPen().
   */
  void setPen(const WPen& pen);

  /*! \brief Returns the pen used for rendering the axis and ticks.
   *
   * \sa setPen()
   */
  const WPen& pen() const { return pen_; }

  /*! \brief Changes the pen used for rendering labels for this axis
   *
   * The default value is a black pen of 0 width.
   *
   * \sa setGridLinesPen().
   * \sa setPen().
   * \sa WCartesianChart::setTextPen()
   */
  void setTextPen(const WPen& pen);

  /*! \brief Returns the pen used for rendering labels for this axis
   *
   * \sa setTextPen()
   */
  const WPen& textPen() const { return textPen_; }

  /*! \brief Changes the pen used for rendering the grid lines.
   *
   * The default value is a gray pen of 0 width.
   *
   * \sa setPen(), gridLinesPen().
   */
  void setGridLinesPen(const WPen& pen);

  /*! \brief Returns the pen used for rendering the grid lines.
   *
   * \sa setGridLinesPen()
   */
  const WPen& gridLinesPen() const { return gridLinesPen_; }

  /*! \brief Sets the margin between the axis and the plot area.
   *
   * The margin is defined in pixels.
   *
   * The default value is 0.
   *
   * \sa margin()
   */
  void setMargin(int pixels);

  /*! \brief Returns the margin between the axis and the plot area.
   *
   * \sa setMargin()
   */
  int margin() const { return margin_; }

  /*! \brief Sets the axis title.
   *
   * The default title is empty.
   *
   * \sa title()
   */
  void setTitle(const WString& title);

  /*! \brief Returns the axis title.
   *
   * \sa setTitle()
   */
  const WString& title() const { return title_; }

  /*! \brief Sets the axis title font.
   *
   * The default title font is a 12 point Sans Serif font.
   *
   * \sa titleFont()
   */
  void setTitleFont(const WFont& titleFont);

  /*! \brief Returns the axis title font.
   *
   * \sa setTitleFont()
   */
  const WFont& titleFont() const { return titleFont_; }

  /*! \brief Sets the offset from the axis for the title label.
   */
  void setTitleOffset(double offset) { titleOffset_ = offset; }

  /*! \brief Returns the title offset.
   */
  double titleOffset() const { return titleOffset_; }

  /*! \brief Sets the axis label font.
   *
   * The default label font is a 10 point Sans Serif font.
   *
   * \sa labelFont()
   */
  void setLabelFont(const WFont& labelFont);

  /*! \brief Returns the axis label font.
   *
   * \sa setLabelFont()
   */
  const WFont& labelFont() const { return labelFont_; }

  /*! \brief Returns the label for a value.
   *
   * This returns the label text that corresponds to a given value.
   *
   * The default implementation uses the labelFormat() to properly represent
   * the value.
   */
  virtual WString label(double u) const;

  /*! \brief Set the range to zoom to on this axis.
   *
   * The minimum is the lowest value to be displayed, and
   * the maximum is the highest value to be displayed.
   *
   * If the difference between minimum and maximum is less
   * than minimumZoomRange(), the zoom range will be made
   * more narrow around the center of minimum and maximum.
   *
   * If the given minimum is larger than the given maximum, the
   * two values are swapped.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \note This is only implemented for the X and first Y axis. It has no effect on the second Y axis.
   */
  void setZoomRange(double minimum, double maximum);

  /*! \brief Get the zoom range minimum for this axis.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \sa setZoomRange()
   */
  double zoomMinimum() const;

  /*! \brief Get the zoom range maximum for this axis.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \sa setZoomRange()
   */
  double zoomMaximum() const;

  /*! \brief A signal triggered when the zoom range is changed on the client side.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \note If you want to use this signal, you must connect a signal listener
   *       before the chart is rendered.
   */
  Signal<double, double>& zoomRangeChanged() { return zoomRangeChanged_; }

  /*! \brief Sets the zoom level for this axis.
   *
   * Only applies to a WCartesianChart in interactive mode.
   * The zoom level should be >= 1 and smaller than maxZoom()
   *
   * \note This is only implemented for the X and first Y axis. It has no effect on the second Y axis.
   *
   * \deprecated Use setZoomRange() instead.
   */
  void setZoom(double zoom);

  /*! \brief Get the zoom level for this axis.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \see setZoom()
   *
   * \deprecated Use zoomMinimum() and zoomMaximum() instead.
   */
  double zoom() const;
  
  /*! \brief Sets the maximum zoom level for this axis.
   *
   * Only applies to a WCartesianChart in interactive mode.
   * The zoom level should be >= 1 (1 = no zoom).
   *
   * \note This is only implemented for the X and first Y axis. It has no effect on the second Y axis.
   *
   * \deprecated Use setMinimumZoomRange(double) instead
   */
  void setMaxZoom(double maxZoom);

  /*! \brief Get the maximum zoom level for this axis.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \see setMaxZoom()
   *
   * \deprecated Use minimumZoomRange() instead
   */
  double maxZoom() const;

  /*! \brief Sets the minimum zoom range for this axis.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * This range is the smallest difference there can be between
   * zoomMinimum() and zoomMaximum().
   *
   * \note This is only implemented for the X and first Y axis. It has no effect on the second Y axis.
   */
  void setMinimumZoomRange(double size);

  /*! \brief Get the minimum zoom range for this axis.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \sa setMinimumZoomRange()
   */
  double minimumZoomRange() const;

  /*! \brief Sets the value to pan to for this axis.
   *
   * This sets the leftmost (horizontal axis)
   * or bottom (vertical axis) value to be displayed on the chart.
   *
   * Note that if this would cause the chart to go out of bounds,
   * the panning of the chart will be automatically adjusted.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \note This is only implemented for the X and first Y axis. It has no effect on the second Y axis.
   *
   * \note If the pan position has been changed on the client side, this may not reflect the actual pan position.
   *
   * \deprecated Use setZoomRange() instead.
   */
  void setPan(double pan);

  /*! \brief Get the value to pan to for this axis, when pan is enabled on the chart.
   *
   * Only applies to a WCartesianChart in interactive mode.
   *
   * \sa setPan()
   *
   * \deprecated Use zoomMinimum() instead.
   */
  double pan() const;

  /*! \brief Sets the padding between the chart area and this axis.
   *
   * \sa padding()
   */
  void setPadding(int padding);

  /*! \brief Returns the padding between the chart area and this axis.
   * 
   * \sa setPadding()
   */
  int padding() const { return padding_; }

  /*! \brief Sets the direction that the axis ticks should point to.
   *
   * If set to Outwards, the axis ticks will point outside of
   * the chart, and the labels will be on the outside.
   *
   * If set to Inwards, the axis ticks will point inside of
   * the chart, and the labels will be on the inside. Also,
   * the padding() will be set to 25.
   *
   * \sa tickDirection()
   * \sa setPadding()
   */
  void setTickDirection(TickDirection direction);

  /*! \brief Gets the direction that the axis ticks point to.
   *
   * \sa setTickDirection()
   */
  TickDirection tickDirection() const { return tickDirection_; }

  /*! \brief Enables soft clipping of axis labels.
   *
   * This is set to \c false by for a 3D chart and to \c true for a 2D
   * chart.
   *
   * This setting determines how labels should be clipped in case not
   * the entire axis is visible due to clipping. "Hard" clipping is
   * done by the paint device and may truncate labels. "Soft" clipping
   * will determine if the corresponding tick is visible, and draw the
   * label (unclipped), preventing labels from being truncated. For a
   * 2D chart, this feature is only relevant when \link
   * WCartesianChart::setZoomEnabled zoom is enabled \endlink on a
   * WCartesianChart.
   * <table>
   * <tr style="vertical-align:top"><td>
   * \image html WAxis-partialLabelClipping-disabled.png "Soft clipping enabled (slower)."
   * This is the default for WCartesianChart. The tick for 0 is visible, and the 0 is shown
   * completely. The tick for 01/01/86 is not visible, so its label is not shown.
   * </td><td>
   * \image html WAxis-partialLabelClipping-enabled.png "Soft clipping disabled (faster)."
   * The tick of the 0 is visible, but the 0 is shown partially. Also, the tick of 01/01/86 is not
   * visible, but the label is partially shown.
   * </td></tr>
   * </table>
   */
  void setSoftLabelClipping(bool enabled);

  /*! \brief Returns whether soft label clipping is enabled
   *
   * \sa setSoftLabelCLipping()
   */
  bool softLabelClipping() const { return !partialLabelClipping_; }

  int segmentCount() const { return (int)segments_.size(); }

  double segmentMargin() const { return segmentMargin_; }

  bool prepareRender(Orientation orientation, double length) const;

  void render(WPainter& painter,
	      WFlags<AxisProperty> properties,
	      const WPointF& axisStart,
	      const WPointF& axisEnd,
	      double tickStart, double tickEnd, double labelPos,
	      WFlags<AlignmentFlag> labelFlags,
	      const WTransform &transform = WTransform(),
	      AxisValue side = MinimumValue) const {
    std::vector<WPen> pens;
    std::vector<WPen> textPens;
    render(painter, properties, axisStart, axisEnd, tickStart, tickEnd, labelPos, labelFlags, transform, side, pens, textPens);
  }

  void render(WPainter& painter,
	      WFlags<AxisProperty> properties,
	      const WPointF& axisStart,
	      const WPointF& axisEnd,
	      double tickStart, double tickEnd, double labelPos,
	      WFlags<AlignmentFlag> labelFlags,
	      const WTransform &transform,
	      AxisValue side,
	      std::vector<WPen> pens,
	      std::vector<WPen> textPens) const;

  std::vector<double> gridLinePositions(AxisConfig config) const;

  /*! \brief Set whether this axis should be inverted.
   *
   * When inverted, the axis will be drawn in the opposite direction, e.g.
   * if normally, the low values are on the left and high values on the right,
   * when inverted, the low values will be on the right and high values on the left.
   */
  void setInverted(bool inverted = true);

  /*! \brief Get whether this axis is inverted.
   *
   * \sa setInverted()
   */
  bool inverted() const { return inverted_; }

#ifndef WT_TARGET_JAVA
  /*! \brief A label transform function.
   *
   * The label transform is a function from double to double.
   *
   * \sa WAxis::setLabelTransform()
   */
  typedef boost::function<double (double)> LabelTransform;
#else
  /*! \brief A label transform function.
   *
   * The label transform is a function from double to double.
   *
   * \sa WAxis::setLabelTransform()
   */
  class LabelTransform {
  public:
    /*! \brief Apply the label transform.
     */
    virtual double apply(double d) const = 0;
  };
private:
  class IdentityLabelTransform : public LabelTransform {
  public:
    virtual double apply(double d) const {
      return d;
    }
  };
public:
#endif

  /*! \brief Set the transform function to apply to a given side.
   *
   * The label transform must be a function from double to double,
   * and will be applied on the double value of the model coordinate
   * of every axis tick.
   *
   * The label transform will not move the position of the axis
   * ticks, only change the labels displayed at the ticks.
   *
   * This can be useful in combination with a location() set to
   * BothSides, to show different labels on each side.
   *
   * If DateScale or DateTimeScale are used, the double value will be
   * in seconds since the Epoch (00:00:00 UTC, January 1, 1970).
   *
   * Only MinimumValue, ZeroValue and MaximumValue are accepted for
   * side. If you set a label transform for another side, the label
   * transform will not be used.
   *
   * The label transform will not be used if the scale() is CategoryScale.
   */
  void setLabelTransform(const LabelTransform& transform, AxisValue side);

  /*! \brief Get the label transform configured for the given side.
   *
   * If no transform is configured for the given side, the identity
   * function is returned.
   *
   * \sa setLabelTransform()
   */
  LabelTransform labelTransform(AxisValue side) const;

  void renderLabel(WPainter& painter,
		   const WString& text, const WPointF& p,
		   WFlags<AlignmentFlag> flags,
		   double angle, int margin, WTransform transform,
		   const WPen& pen) const;

  void setRenderMirror(bool enable) { renderingMirror_ = enable; }
  double calcTitleSize(WPaintDevice *device, Orientation orientation) const;
  double calcMaxTickLabelSize(WPaintDevice *device, Orientation orientation) const;

protected:
  /*! \brief Represents a Date time unit
   */
  enum DateTimeUnit { Seconds, Minutes, Hours, Days, Months, Years };
  
  /*! \brief Represents a label/tick on the axis.
   */
  struct WT_API TickLabel {
    /*! \brief Enumeration for a tick type */
    enum TickLength { Zero, Short, Long };

    /*! \brief Position on the axis. */
    double u;

    /*! \brief Tick length */
    TickLength tickLength;

    /*! \brief Label text */
    WString    label;

    /*! \brief Creates a label tick. */
    TickLabel(double v, TickLength length, const WString& l = WString());
  };

  WAxis();

  /*! \brief Returns the label (and ticks) information for this axis.
   */
  virtual void getLabelTicks(std::vector<TickLabel>& ticks, int segment, AxisConfig config) const;

  /*! \brief Returns the Date format 
   */
  virtual WString autoDateFormat(const WDateTime& dt, DateTimeUnit unit, bool atTick) const;

private:

  WAbstractChartImplementation *chart_;
  Axis             axis_;
  bool             visible_;
  AxisValue        location_;
  AxisScale        scale_;
  double           resolution_;
  double           labelInterval_;
  double           labelBasePoint_;
  WString          labelFormat_;
  bool             defaultLabelFormat_;
  bool             gridLines_;
  WPen             pen_, gridLinesPen_;
  int              margin_;
  double           labelAngle_;
  WString          title_;
  WFont            titleFont_, labelFont_;
  WFlags<AxisValue> roundLimits_;
  double           segmentMargin_;
  double           titleOffset_;
  WPen             textPen_;
  Orientation      titleOrientation_;
  double	   maxZoom_;
  double	   minimumZoomRange_;
  double           zoomMin_;
  double           zoomMax_;
  bool 		   zoomRangeDirty_;
  int              padding_;
  TickDirection    tickDirection_;
  bool             partialLabelClipping_;
  bool		   inverted_;
  boost::unordered_map<AxisValue, LabelTransform > labelTransforms_;

  // for 3D charts, don't call update when the labelangle is tempor. changed
  bool             renderingMirror_;

  Signal<double, double> zoomRangeChanged_;

  struct Segment {
    double minimum, maximum;
    mutable double renderMinimum, renderMaximum, renderLength, renderStart;
    mutable DateTimeUnit dateTimeRenderUnit;
    mutable int dateTimeRenderInterval;

    Segment();
    Segment(const Segment &other); // Explicit copy constructor for JWt
  };

  std::vector<Segment> segments_;

  mutable double renderInterval_;
  mutable double fullRenderLength_; // Render length including padding

  void init(WAbstractChartImplementation* chart, Axis axis);
  void update();

  template <typename T>
  bool set(T& m, const T& v);

  void computeRange(const Segment& segment) const;

  double getValue(const boost::any& v) const;
  static double getDateValue(const boost::any& value);

  double calcAutoNumLabels(Orientation orientation, const Segment& s) const;
  WString defaultDateTimeFormat(const Segment& s) const;

  double mapFromDevice(double d) const;
  double mapToDevice(const boost::any &value) const;
  double mapToDevice(const boost::any& value, int segment) const;
  double mapToDevice(double value) const;
  double mapToDevice(double value, int segment) const;
  // Check whether the given point is within the limits of this axis
  bool isOnAxis(double d) const;

  // The smallest value that is shown on the chart, including padding
  // (smaller than minimum())
  double drawnMinimum() const;

  // The largest value that is shown on the chart, including padding
  // (larger than maximum())
  double drawnMaximum() const;

  long long getDateNumber(Wt::WDateTime dt) const;
  void setZoomRangeFromClient(double minimum, double maximum);

  bool hasLabelTransformOnSide(AxisValue side) const;

  friend class WCartesianChart;
  friend class WCartesian3DChart;
  friend class WChart2DRenderer;
  friend class WAxisSliderWidget;
  friend class LineSeriesRenderer;
};

template <typename T>
bool WAxis::set(T& m, const T& v)
{
  if (m != v) {
    m = v;
    update();
    return true;
  } else
    return false;
}

  }
}

#endif // CHART_WAXIS_H_