# Scale (lv_scale) (/widgets/scale)









<br />

<hr />

Overview [#overview]

Scale Widgets show linear or circular scales with configurable ranges, tick counts,
placement, labeling, and subsections ([Sections](/widgets/scale)) with custom styling.

Parts and Styles [#parts-and-styles]

The Scale Widget has the following three parts:

* <ApiLink name="LV_PART_MAIN" /> Main line --- the blue line in example image.
* <ApiLink name="LV_PART_ITEMS" /> Minor ticks --- the red minor ticks in example image.
* <ApiLink name="LV_PART_INDICATOR" /> Major ticks and their labels (if enabled) ---
  the green major ticks and pink labels in example image.

<img alt="Scale" src="__img0" />

Usage [#usage]

Mode [#mode]

When a Scale Widget is created, it starts out in MODE
<ApiLink name="LV_SCALE_MODE_HORIZONTAL_BOTTOM" />.  This makes the scale horizontal
with tick marks below the line.  If you need it to have a different shape, orientation
or tick position, use <ApiLink name="lv_scale_set_mode" display="lv_scale_set_mode(scale, mode)" />, where `mode` can
be any of these values:

* <ApiLink name="LV_SCALE_MODE_HORIZONTAL_TOP" />
* <ApiLink name="LV_SCALE_MODE_HORIZONTAL_BOTTOM" />
* <ApiLink name="LV_SCALE_MODE_VERTICAL_LEFT" />
* <ApiLink name="LV_SCALE_MODE_VERTICAL_RIGHT" />
* <ApiLink name="LV_SCALE_MODE_ROUND_INNER" />
* <ApiLink name="LV_SCALE_MODE_ROUND_OUTER" />

Setting range [#setting-range]

A Scale starts its life with a default numeric range of \[0..100] and a default
angular range of 270.  You can change these ranges with:

* <ApiLink name="lv_scale_set_range" display="lv_scale_set_range(scale, min, max)" />, and
* <ApiLink name="lv_scale_set_angle_range" display="lv_scale_set_angle_range(scale, angle_range)" />

where `min` and `max` will become the numeric low and high values for the Scale,
and `angle_range` is the angle between the low and high ends of the Scale.

Tick drawing order [#tick-drawing-order]

Normally ticks and their labels are drawn first and the main line is drawn next,
giving the ticks and their labels the appearance of being underneath the main line
when there is overlap.  You can reverse this sequence if you wish, making the ticks
and labels appear on top the main line, using
<ApiLink name="lv_scale_set_draw_ticks_on_top" display="lv_scale_set_draw_ticks_on_top(scale, true)" />.  (This effect can be
reversed by passing `false` instead.)

Example with with ticks and labels drawn *under* the main line (default):

<img alt="Scale Ticks Below" src="__img1" />

Example with ticks and labels drawn *on top of* the main line:

<img alt="Scale Ticks On Top" src="__img2" />

Configuring ticks [#configuring-ticks]

You configure the major and minor ticks of a Scale by calling 2 functions:

* <ApiLink name="lv_scale_set_total_tick_count" display="lv_scale_set_total_tick_count(scale, total_tick_count)" />, and
* <ApiLink name="lv_scale_set_major_tick_every" display="lv_scale_set_major_tick_every(scale, nth_tick)" />.

If you want labels to be drawn with the major ticks, call
<ApiLink name="lv_scale_set_label_show" display="lv_scale_set_label_show(scale, true)" />.  (Pass `false` to hide them again.)

By default, the labels shown are the numeric values of the scale at the major tick
points.  Can you specify different label content by calling
<ApiLink name="lv_scale_set_text_src" display="lv_scale_set_text_src(scale, custom_labels)" /> where `custom_labels` is an
array of string pointers.  Example:

```c title=" " lineNumbers=1
static char * custom_labels[3] = {"One", "Two", NULL};
```

Note that a `NULL` pointer is used to terminate the list.

The content of the buffers pointed to need to remain valid for the life of the Scale.

For a Scale in one of the `..._ROUND_...` modes, you can optionally get it to
rotate the major-tick labels to match the rotation of the major ticks using
<ApiLink name="lv_obj_set_style_transform_rotation" display="lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS, LV_PART_INDICATOR)" />.

Alternately, labels can be rotated by a fixed amount (for any Scale mode).  This
example rotates labels by 20 degrees:
<ApiLink name="lv_obj_set_style_transform_rotation" display="lv_obj_set_style_transform_rotation(scale, 200, LV_PART_INDICATOR)" />.

Or both of the above can be done at the same time:
<ApiLink name="lv_obj_set_style_transform_rotation" display="lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS + 200, LV_PART_INDICATOR)" />.

Some labels of the Scale might be drawn upside down (to match the tick) if the Scale includes a certain angle range.
If you don't want this, to automatically rotate the labels to keep them upright, an additional flag can be used.
Labels that would be upside down are then rotated 180°
<ApiLink name="lv_obj_set_style_transform_rotation" display="lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS | LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT, LV_PART_INDICATOR)" />.
Labels can also be moved a fixed distance in X and Y pixels using
<ApiLink name="lv_obj_set_style_translate_x" display="lv_obj_set_style_translate_x(scale, 10, LV_PART_INDICATOR)" />.

<Callout type="info">
  The major tick value is calculated with the <ApiLink name="lv_map" /> API (when not
  setting custom labels), this calculation takes into consideration the total
  number of ticks and the Scale range, so the label drawn can present rounding
  errors when the calculated value is a floating-point value.
</Callout>

The length of the ticks can be configured with the length Style property on the
<ApiLink name="LV_PART_INDICATOR" /> for major ticks and <ApiLink name="LV_PART_ITEMS" />
for minor ticks.  Example with local Style:
<ApiLink name="lv_obj_set_style_length" display="lv_obj_set_style_length(scale, 5, LV_PART_INDICATOR)" /> for major ticks
and <ApiLink name="lv_obj_set_style_length" display="lv_obj_set_style_length(scale, 5, LV_PART_ITEMS)" /> for minor ticks. The ticks can be
padded in either direction (outwards or inwards) for `..._ROUND_...` Scales only with:
<ApiLink name="lv_obj_set_style_radial_offset" display="lv_obj_set_style_radial_offset(scale, 5, LV_PART_INDICATOR)" /> for major ticks and
<ApiLink name="lv_obj_set_style_radial_offset" display="lv_obj_set_style_radial_offset(scale, 5, LV_PART_ITEMS)" /> for minor.
Using length and radial offset together allows total control of the tick position.

It is also possible to offset the labels from the major ticks (either positive or negative) using

<ApiLink name="lv_obj_set_style_pad_radial" display="lv_obj_set_style_pad_radial(scale, 5, LV_PART_INDICATOR)" />

Sections [#sections]

Sections make it possible for portions of a Scale to *convey meaning* by using
different Style properties to draw them (colors, line thicknesses, font, etc.).

A Section represents a sub-range of the Scale, whose Styles (like Cascading Style
Sheets) take precedence while drawing the PARTS (lines, arcs, ticks and labels) of
the Scale that are within the range of that Section.

If a PART of a Scale is within the range of 2 or more Sections (i.e. those Sections
overlap), the Style's properties belonging to the most recently added Section takes
precedence over the same style properties of other Section(s) that "involve" that
PART.

Creating Sections [#creating-sections]

A Section is created using <ApiLink name="lv_scale_add_section" display="lv_scale_add_section(scale)" />, which returns a
pointer to a <ApiLink name="lv_scale_section_t" /> object.  This creates a Section with
range \[0..0] and no Styles added to it, which ensures that Section will not be drawn
yet:  it needs both a range inside the Scale's range and at least one [Style](/common-widget-features/styles) added to it before it will be used in drawing the Scale.

Next, set the range using <ApiLink name="lv_scale_section_set_range" display="lv_scale_section_set_range(section, min, max)" />
where `min` and `max` are the Section's boundary values that should normally be
within the Scale's value range.  (If they are only partially within the Scale's
range, the Scale will only use that portion of the Section that overlaps the Scale's
range.  If a Section's range is not within the Scale's range at all, it will not be
used in drawing.  That can be useful to temporarily "disable" a Section, e.g.
<ApiLink name="lv_scale_section_set_range" display="lv_scale_section_set_range(section, 0, -1)" />.)

Data binding [#data-binding]

To get familiar with observers, subjects, and data bindings in general, visit the
[Observer](/main-modules/observer/observer) page.

This method of subscribing to an integer Subject affects a Section of a Scale Widget's integer
minimum or maximum values directly.  Note that this is a one-way binding (Subject ==> Widget)
as the Scale Section's boundaries are not interactive.

It supports only integer subjects.

* <ApiLink name="lv_scale_bind_section_min_value" display="lv_scale_bind_section_min_value(scale, section1, &subject)" />
* <ApiLink name="lv_scale_bind_section_max_value" display="lv_scale_bind_section_max_value(scale, section1, &subject)" />

Styling Sections [#styling-sections]

You set a Section's Style properties by creating a <ApiLink name="lv_style_t" /> object
for each "section" you want to appear different than the parent Scale.  Add style
properties as is documented in [Style Sheets](/common-widget-features/styles/style_sheets).

You attach each <ApiLink name="lv_style_t" /> object to each Section it will apply to using
<ApiLink name="lv_scale_section_set_style" display="lv_scale_section_set_style(section, PART, style_pointer)" />, where:

* `style_pointer` should point to the contents of a global or static variable (can
  be dynamically-allocated), since it needs to remain valid through the life of the
  Scale; and
* `PART` indicates which single [PART](/widgets/scale) of the
  parent Scale it will apply to, namely <ApiLink name="LV_PART_MAIN" />,
  <ApiLink name="LV_PART_ITEMS" /> or <ApiLink name="LV_PART_INDICATOR" />.

Unlike adding normal styles to Widgets, you cannot combine PARTs by bit-wise OR-ing
the PART values together to get the style to apply to more than one part.  However,
you can do something like this to accomplish the same thing:

```c title=" " lineNumbers=1
static lv_style_t  tick_style;
lv_style_init(&tick_style);
lv_style_set_line_color(&tick_style, lv_palette_darken(LV_PALETTE_RED, 3));
lv_scale_section_set_style(section, LV_PART_ITEMS, &tick_style);
lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style);
```

to get that one Style object to apply to both major and minor ticks.

<ApiLink name="lv_style_t" /> objects can be shared among Sections and among PARTs, but
unlike normal Styles added to a Widget, a Section can only have 1 style per PART.
Thus, doing this:

```c title=" " lineNumbers=1
lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style_1);
lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style_2);
```

replaces `tick_style_1` with `tick_style_2` for part
<ApiLink name="LV_PART_INDICATOR" /> rather than adding to it.

Useful Style Properties for Sections [#useful-style-properties-for-sections]

The Style properties that are used during Scale drawing (and are thus useful) are:

* For main line *when it is a straight line* (<ApiLink name="LV_PART_MAIN" />):

  :LV\_STYLE\_LINE\_WIDTH:         <ApiLink name="lv_style_set_line_width" />
  :LV\_STYLE\_LINE\_COLOR:         <ApiLink name="lv_style_set_line_color" />
  :LV\_STYLE\_LINE\_OPA:           <ApiLink name="lv_style_set_line_opa" />
* For main line *when it is an arc* (<ApiLink name="LV_PART_MAIN" />):

  :LV\_STYLE\_ARC\_WIDTH:          <ApiLink name="lv_style_set_arc_width" />
  :LV\_STYLE\_ARC\_COLOR:          <ApiLink name="lv_style_set_arc_color" />
  :LV\_STYLE\_ARC\_OPA:            <ApiLink name="lv_style_set_arc_opa" />
  :LV\_STYLE\_ARC\_ROUNDED:        <ApiLink name="lv_style_set_arc_rounded" />
  :LV\_STYLE\_ARC\_IMAGE\_SRC:      <ApiLink name="lv_style_set_arc_image_src" />
* For tick lines (<ApiLink name="LV_PART_ITEMS" /> and <ApiLink name="LV_PART_INDICATOR" />):

  :LV\_STYLE\_LINE\_WIDTH:         <ApiLink name="lv_style_set_line_width" />
  :LV\_STYLE\_LINE\_COLOR:         <ApiLink name="lv_style_set_line_color" />
  :LV\_STYLE\_LINE\_OPA:           <ApiLink name="lv_style_set_line_opa" />
* For labels on major ticks (<ApiLink name="LV_PART_INDICATOR" />)

  :LV\_STYLE\_TEXT\_COLOR:         <ApiLink name="lv_style_set_text_color" />
  :LV\_STYLE\_TEXT\_OPA:           <ApiLink name="lv_style_set_text_opa" />
  :LV\_STYLE\_TEXT\_LETTER\_SPACE:  <ApiLink name="lv_style_set_text_letter_space" />
  :LV\_STYLE\_TEXT\_FONT:          <ApiLink name="lv_style_set_text_font" />

Needles [#needles]

Needles are used to indicate a specific value for `..._ROUND_...` Scales only.
They can be lines or images and can be customized in terms of length, color, and
other properties.

Creating Needles [#creating-needles]

Create a [lv\_line](/widgets/line) or a [lv\_image](/widgets/image) Widget and then
attach it to the Scale as a needle with the appropriate function:

* <ApiLink name="lv_scale_set_line_needle_value" display="lv_scale_set_line_needle_value(scale, needle_line, needle_length, value)" />
* <ApiLink name="lv_scale_set_image_needle_value" display="lv_scale_set_image_needle_value(scale, needle_img, value)" />

Data binding [#data-binding-1]

To get familiar with observers, subjects, and data bindings in general, visit the
[Observer](/main-modules/observer/observer) page.

This method of subscribing to an integer Subject affects the needle value of a Scale
Widget directly.  Note that this is a one-way binding (Subject ==> Widget) so when
the subject changes, the Scale's needle will be updated too.

It supports only integer subjects.

* <ApiLink name="lv_scale_bind_line_needle_value" display="lv_scale_bind_line_needle_value(scale, needle_line, needle_length, &subject)" />
* <ApiLink name="lv_scale_bind_image_needle_value" display="lv_scale_bind_image_needle_value(scale, needle_img, &subject)" />

Events [#events]

No special events are sent by Scale Widgets.

In <ApiLink name="LV_EVENT_DRAW_TASK_ADDED" /> events, a major or minor line
draw descriptor's members `id1` and `id2` will be the tick index and
tick value, respectively. If the part is <ApiLink name="LV_PART_INDICATOR" />,
it is a major tick. If the part is <ApiLink name="LV_PART_ITEMS" /> it is a
minor tick.

<Callout type="info" title="Further Reading">
  Learn more about [Events](/common-widget-features/events) emitted by all Widgets.

  Learn more about [events](/common-widget-features/events).
</Callout>

Keys [#keys]

No *Keys* are processed by Scale Widgets.

<Callout type="info" title="Further Reading">
  Learn more about [Keys](/main-modules/indev/keypad).
</Callout>

Examples [#examples]

A simple horizontal scale [#a-simple-horizontal-scale]

<LvglExample name="lv_example_scale_1" path="widgets/scale/lv_example_scale_1" />

An vertical scale with section and custom styling [#an-vertical-scale-with-section-and-custom-styling]

<LvglExample name="lv_example_scale_2" path="widgets/scale/lv_example_scale_2" />

A simple round scale [#a-simple-round-scale]

<LvglExample name="lv_example_scale_3" path="widgets/scale/lv_example_scale_3" />

A round scale with section and custom styling [#a-round-scale-with-section-and-custom-styling]

<LvglExample name="lv_example_scale_4" path="widgets/scale/lv_example_scale_4" />

A scale with section and custom styling [#a-scale-with-section-and-custom-styling]

<LvglExample name="lv_example_scale_5" path="widgets/scale/lv_example_scale_5" />

A round scale with multiple needles, resembling a clock [#a-round-scale-with-multiple-needles-resembling-a-clock]

<LvglExample name="lv_example_scale_6" path="widgets/scale/lv_example_scale_6" />

Customizing scale major tick label color with `LV_EVENT_DRAW_TASK_ADDED` event [#customizing-scale-major-tick-label-color-with-lv_event_draw_task_added-event]

<LvglExample name="lv_example_scale_7" path="widgets/scale/lv_example_scale_7" />

A round scale with labels rotated and translated [#a-round-scale-with-labels-rotated-and-translated]

<LvglExample name="lv_example_scale_8" path="widgets/scale/lv_example_scale_8" />

A horizontal scale with labels rotated and translated [#a-horizontal-scale-with-labels-rotated-and-translated]

<LvglExample name="lv_example_scale_9" path="widgets/scale/lv_example_scale_9" />

A round scale style simulating a Heart Rate monitor [#a-round-scale-style-simulating-a-heart-rate-monitor]

<LvglExample name="lv_example_scale_10" path="widgets/scale/lv_example_scale_10" />

A round scale style simulating a sunset/sunrise widget [#a-round-scale-style-simulating-a-sunsetsunrise-widget]

<LvglExample name="lv_example_scale_11" path="widgets/scale/lv_example_scale_11" />

A round scale style simulating a compass [#a-round-scale-style-simulating-a-compass]

<LvglExample name="lv_example_scale_12" path="widgets/scale/lv_example_scale_12" />

Axis ticks and labels with scrolling on a chart [#axis-ticks-and-labels-with-scrolling-on-a-chart]

<LvglExample name="lv_example_chart_2" path="widgets/chart/lv_example_chart_2" />

API [#api]

[Scale (lv\_scale)](/widgets/scale)
