Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 43 additions & 47 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,38 @@ guide in the documentation says what to change in your code.

## [Unreleased]

### Changed
- The badge names the CoolProp and CoolPlot versions by default
(`BrandingSettings.versions=True`), below the equation of state, so a
chart says what drew it. Specs saved before hold `"versions": false`
and keep their badge; `{"references": "none", "versions": False}`
draws a chart without badge.
- `cycle_states`, `state`, `state_at` and `mix` say which way `units=`
works: on `cycle_states` it converts the states returned (as dicts),
on the others it only sets the units of the input and the StatePoint
returned stays in SI units. The how-to on units explains why (#33).
## [1.5.0] - 2026-11-03

### Added
- coolplot-core 1.5 composes and writes the badge of the branding when it
holds text lines only (references, versions, lines of your own): the
compose record takes the source lines as `"sources"`, the scene record
carries the badge, and the SVG and PDF writers draw it as the Python SVG
writer does. A branded chart without logo or watermark therefore takes
the native path; one with pictures still takes Python. The bridge
refuses a badge for a core older than 1.5, so the Python composer draws
it, with a warning.
- The plotly backend and the JavaScript writer (`scene_page`) draw the
badge of text lines too; only a logo or a watermark is left out, with a
warning. `PdfRenderer` draws it through coolplot-core 1.5, also on a
chart with a logo or a watermark, which it leaves out with a warning.
- Theme "coolpack": the look of the log(p),h-diagrams of CoolPack (DTU,
"Refrigeration Utilities", late 1990s). Times on white with a dense
light grey grid (major and minor ticks), a black saturation curve, red
isotherms, blue isentropes, green isochores and navy lines of constant
quality in the colours of the 16 colour Windows palette, every label in
the colour of its line, no legend. Purple isobars and magenta
isenthalps for the other charts. coolplot-core has the same preset.
- Documentation: a theme catalog with every theme on a log(p)-h and a T-s
chart, its isoline colours as seen with each kind of colour vision
deficiency and in greyscale, contrast and separation numbers, and why
its colours are what they are. Pictures and numbers are generated when
the documentation is built.
- Documentation: "Colour and accessibility", the rules the themes are
measured against (WCAG 2.2 AA, the colour science literature), who they
are for, and how the default colours were chosen.
- Gallery example "A CoolPack chart, for old times' sake": the R290 chart
of the CoolPack tutorial with its one stage cycle, in the new theme.
- `Chart.add_line` and `Chart.remove_line` (issue #32): single lines of
constant value drawn on top of the families, each with its own name,
legend entry, label and style, such as a highlighted isotherm among
Expand All @@ -27,7 +47,7 @@ guide in the documentation says what to change in your code.
style a line takes its family's at twice the width. The lines are
stored in `DiagramSpec.lines` (`coolplot.LineSpec`, the spec record's
`lines`), drawn with the scene roles `line` and `line_label`, and
composed the same by coolplot-core 1.6; an older core leaves charts
composed the same by coolplot-core 1.5; an older core leaves charts
with single lines to the Python composer.
- The critical point and the triple point can be marked with a dot in the
colour of the saturation curve: `diagram.marked_points = ("critical",
Expand All @@ -36,7 +56,7 @@ guide in the documentation says what to change in your code.
chart is not drawn, and the axes are widened a little to show the dots
whole. Mixtures and pseudo-pure blends mark the critical point only.
The spec record holds `marked_points` only when it is set, so records
of 1.5 read as before.
of 1.4 read as before.
- A saturation scale just inside the frame, right of the vertical axis
(#39): `diagram.saturation_scale = True`, or `{"step": 10, "Q": 0}`
for a tick every 10 K at the bubble points of a blend. Next to a
Expand All @@ -53,10 +73,10 @@ guide in the documentation says what to change in your code.
saturation scale and cycles, and are left out where they do not fit,
as near the critical point. `LabelSettings.dome` is written to the
record only when true.
- coolplot-core 1.6 composes the marked points, the saturation scale and
- coolplot-core 1.5 composes the marked points, the saturation scale and
the labels inside the dome; the compose record carries their states as
`"points"`, `"scale"` and `"dome"` of the domain. The bridge refuses
any of them for a core older than 1.6, so the Python composer draws
any of them for a core older than 1.5, so the Python composer draws
them, with a warning.
- Example `examples/co2_phase_diagram.py`: a full phase diagram of CO2 on
the p-T chart. CoolPlot draws the vapour pressure curve; the example
Expand All @@ -67,39 +87,6 @@ guide in the documentation says what to change in your code.
melting line of the ices from CoolProp and the sublimation line of ice
Ih from IAPWS R14-08 (2011).

## [1.5.0] - 2026-10-30

### Added
- coolplot-core 1.5 composes and writes the badge of the branding when it
holds text lines only (references, versions, lines of your own): the
compose record takes the source lines as `"sources"`, the scene record
carries the badge, and the SVG and PDF writers draw it as the Python SVG
writer does. A branded chart without logo or watermark therefore takes
the native path; one with pictures still takes Python. The bridge
refuses a badge for a core older than 1.5, so the Python composer draws
it, with a warning.
- The plotly backend and the JavaScript writer (`scene_page`) draw the
badge of text lines too; only a logo or a watermark is left out, with a
warning. `PdfRenderer` draws it through coolplot-core 1.5, also on a
chart with a logo or a watermark, which it leaves out with a warning.
- Theme "coolpack": the look of the log(p),h-diagrams of CoolPack (DTU,
"Refrigeration Utilities", late 1990s). Times on white with a dense
light grey grid (major and minor ticks), a black saturation curve, red
isotherms, blue isentropes, green isochores and navy lines of constant
quality in the colours of the 16 colour Windows palette, every label in
the colour of its line, no legend. Purple isobars and magenta
isenthalps for the other charts. coolplot-core has the same preset.
- Documentation: a theme catalog with every theme on a log(p)-h and a T-s
chart, its isoline colours as seen with each kind of colour vision
deficiency and in greyscale, contrast and separation numbers, and why
its colours are what they are. Pictures and numbers are generated when
the documentation is built.
- Documentation: "Colour and accessibility", the rules the themes are
measured against (WCAG 2.2 AA, the colour science literature), who they
are for, and how the default colours were chosen.
- Gallery example "A CoolPack chart, for old times' sake": the R290 chart
of the CoolPack tutorial with its one stage cycle, in the new theme.

### Changed
- Every chart names the equation of state of its fluid by default:
`BrandingSettings.references` is "short" instead of "none", so the
Expand Down Expand Up @@ -128,6 +115,15 @@ guide in the documentation says what to change in your code.
is gone: the company chart of Clean Heat Partners shows the same
(logo, references, versions, a line of text and a watermark) on a real
chart.
- The badge names the CoolProp and CoolPlot versions by default
(`BrandingSettings.versions=True`), below the equation of state, so a
chart says what drew it. Specs saved before hold `"versions": false`
and keep their badge; `{"references": "none", "versions": False}`
draws a chart without badge.
- `cycle_states`, `state`, `state_at` and `mix` say which way `units=`
works: on `cycle_states` it converts the states returned (as dicts),
on the others it only sets the units of the input and the StatePoint
returned stays in SI units. The how-to on units explains why (#33).

### Removed
- Theme "classic" (and `coolplot.style.CLASSIC`). Its idea, a colour per
Expand Down
2 changes: 1 addition & 1 deletion cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Catch2 is fetched for the tests; set FETCHCONTENT_SOURCE_DIR_CATCH2 to a
# local checkout to build offline.
cmake_minimum_required(VERSION 3.16)
project(coolplot_core VERSION 1.6.0 LANGUAGES CXX)
project(coolplot_core VERSION 1.5.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down
6 changes: 3 additions & 3 deletions cpp/include/coolplot/compose.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
//
// {"spec": <chart spec>,
// "domain": {"tp_box": [T_min, T_max, p_min, p_max], "ranges_SI": {key: [min, max]},
// "points": {name: {key: value}} (optional, since 1.6),
// "scale": [[saturation_SI, axis_SI], ...] (optional, since 1.6)},
// "points": {name: {key: value}} (optional, since 1.5),
// "scale": [[saturation_SI, axis_SI], ...] (optional, since 1.5)},
// "curves": [{"request": {"item_id", "key", "value_SI", "points", "labels", "anchor_SI"}, "curve": <curve record>}],
// (anchor_SI, since 1.1: the saturation temperature or pressure the line passes through when its
// family is placed by saturation states, null otherwise; the label shows it. Since 1.6 the curves
// family is placed by saturation states, null otherwise; the label shows it. Since 1.5 the curves
// of the single lines of the spec come here too, with the item id "line/<name>")
// "cycles": [{"states": {"1": {key: value}}, "chains": [[{key: value}, ...]]}],
// "plot_size_pt": [width, height] or null,
Expand Down
8 changes: 4 additions & 4 deletions cpp/tests/data/make_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def main():
restyled.set_line_style("Q", color="#7a3cc8", dash="dotted")
compose_case("compose_r290_ph_restyled_dome", restyled)

# Single lines (1.6): a highlighted isotherm and quality line in the
# Single lines (1.5): a highlighted isotherm and quality line in the
# style of their families, a line of each axis quantity, one with its own
# style and text, one without a label; labels in the colour of the lines
single = PropertyDiagram("R290", "ph", tp_limits="ACHP", settings="interactive")
Expand Down Expand Up @@ -216,15 +216,15 @@ def main():


def marked_point_cases():
"""The critical and triple points marked with a dot (1.6), the axes widened to show the triple points whole."""
"""The critical and triple points marked with a dot (1.5), the axes widened to show the triple points whole."""
water = PropertyDiagram("Water", "Ts", tp_limits=[None, None, None, None], settings="interactive")
water.set_lines("p", num=5, labels=True)
water.marked_points = ("critical", "triple")
compose_case("compose_rails_water_ts_marked_points", water)


def saturation_scale_cases():
"""The saturation scale (1.6): T_sat on a pressure axis with a cycle, p_sat on a temperature axis, crowded."""
"""The saturation scale (1.5): T_sat on a pressure axis with a cycle, p_sat on a temperature axis, crowded."""
r290 = PropertyDiagram("R290", "ph", tp_limits="ACHP", settings="interactive")
r290.set_default_lines(labels=True)
r290.add_cycle("heat pump", [{"p": 3.0, "T": 0.0}, {"p": 15.0, "via": "compression", "eta_is": 0.7},
Expand Down Expand Up @@ -328,7 +328,7 @@ def badge_cases():


def dome_label_cases():
"""Labels inside the dome (1.6): isotherms of a p-h chart with a cycle and the scale, isobars of a T-s chart,
"""Labels inside the dome (1.5): isotherms of a p-h chart with a cycle and the scale, isobars of a T-s chart,
the sloped isotherms of a blend in edge mode."""
r290 = PropertyDiagram("R290", "ph", tp_limits="ACHP", settings="interactive")
r290.set_default_lines(labels=True)
Expand Down
2 changes: 1 addition & 1 deletion cpp/tests/test_svg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ TEST_CASE("The C ABI composes, writes SVG and reports errors", "[svg][capi]") {
CHECK(std::string(error).find("not valid JSON") != std::string::npos);
coolplot_free(error);
CHECK(coolplot_compose(nullptr, &scene_json, nullptr) == 1);
CHECK(std::string(coolplot_version()) == "1.6.0");
CHECK(std::string(coolplot_version()) == "1.5.0");
}

TEST_CASE("The writers ignore the C locale", "[svg][pdf][locale]") {
Expand Down
4 changes: 2 additions & 2 deletions docs/how_to/branding.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ plot area and, if you like, a faint picture behind the lines.

Since 1.5 every chart names its equation of state by default
(`references="short"`), so a chart never reaches a reader without its
source, and since 1.6 the versions of CoolProp and CoolPlot that drew it
(`versions=True`, "CoolProp 8.0.0, CoolPlot 1.6.0"). To draw a chart
source, and the versions of CoolProp and CoolPlot that drew it
(`versions=True`, "CoolProp 8.0.0, CoolPlot 1.5.0"). To draw a chart
without the badge:

```python
Expand Down
6 changes: 3 additions & 3 deletions docs/how_to/isolines.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ is in {doc}`../reference/tables`.

## Single lines

Since 1.6 `add_line` draws one line of constant value on top of the
Since 1.5 `add_line` draws one line of constant value on top of the
families, for a design temperature or the pressure at which a relief
valve or burst disk opens. Each line has a name, shows in the legend and
is independent of the families: `set_lines` and `set_default_lines`
Expand Down Expand Up @@ -72,7 +72,7 @@ values decide, as they did then.

## Mark the critical and triple points

Since 1.6 a chart of a fluid can mark the critical point and the triple
Since 1.5 a chart of a fluid can mark the critical point and the triple
point with a dot in the colour of the saturation curve:

```python
Expand Down Expand Up @@ -102,7 +102,7 @@ follows `set_line_style("saturation", ...)`.

## A saturation scale next to the axis

Since 1.6 a chart with pressure on the vertical axis can show the
Since 1.5 a chart with pressure on the vertical axis can show the
saturation temperature at each pressure on a scale just inside the frame,
right of the axis; a chart with temperature on the vertical axis shows the
saturation pressure at each temperature:
Expand Down
2 changes: 1 addition & 1 deletion docs/how_to/labels.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ n-th line), `digits`, `show_units`, `tick_digits`.

## Labels inside the dome

Since 1.6 each labelled line that runs through the two-phase region can
Since 1.5 each labelled line that runs through the two-phase region can
carry two more labels inside the dome, one just right of the bubble line
and one just left of the dew line, as on the printed refrigerant charts:

Expand Down
18 changes: 9 additions & 9 deletions docs/reference/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ One record describes a property diagram and a psychrometric chart alike;
`symbols`, "unicode" (the default: rho, deg C and m3 written with
their own characters) or "ascii"; a `labels` record without it was
written before 1.4 and reads as "ascii", so it draws as before. Since
1.6 `labels` may hold `dome`, `true` for labels inside the dome; it is
1.5 `labels` may hold `dome`, `true` for labels inside the dome; it is
written only when true, so a record without it reads as `false`.
* `isolines`: one entry per family, in drawing order. `values_SI` lists
explicit values; `anchor` (since 1.1) places the lines through
Expand Down Expand Up @@ -123,21 +123,21 @@ One record describes a property diagram and a psychrometric chart alike;
0 and 1, or 100 % relative humidity) whatever lines are set, `false`
hides it, `null` leaves it to the values of the family. A record of 1.1
has no such field and reads as `null`, so it draws as it did.
* `lines` (since 1.6): single lines of constant `key` at `value_SI`,
* `lines` (since 1.5): single lines of constant `key` at `value_SI`,
each under its own `name` (`coolplot.spec.LineSpec`). `key` is a
quantity with a family in the diagram, or one of its two axes: such a
line is straight and spans the plot, and the axes widen to show it.
`label` is `true` (the value), `false` (none) or a text; `line_style`
`null` takes the family's style at twice the width (the colour of the
saturation curve for an axis quantity). The key is left out when a
chart has no single lines, so records of 1.5 read as they were; a
coolplot-core older than 1.6 is not asked to compose a spec with lines.
* `marked_points` (since 1.6, charts of a fluid only): the special states
chart has no single lines, so records of 1.4 read as they were; a
coolplot-core older than 1.5 is not asked to compose a spec with lines.
* `marked_points` (since 1.5, charts of a fluid only): the special states
marked with a dot, `"critical"` and or `"triple"` (the two ends of the
saturation curve at the triple point). A point outside the chart's T-p
box is not drawn. The key is left out when nothing is marked, so a
record of 1.5 reads as it was.
* `saturation_scale` (since 1.6, charts of a fluid with pressure or
record of 1.4 reads as it was.
* `saturation_scale` (since 1.5, charts of a fluid with pressure or
temperature on the vertical axis): `{"step_SI": 10.0, "Q": 1.0}`
draws a scale of saturation temperatures next to a pressure axis, or
of saturation pressures next to a temperature axis, with a tick every
Expand Down Expand Up @@ -249,7 +249,7 @@ an item in place:
| `cycle/<name>/states` | the markers of all states of a cycle, in ascending state number |
| `cycle/<name>/number/<n>` | the number of state n |
| `process/<name>/line`, `process/<name>/points` | a legacy process |
| `line/<name>` | a single line (1.6), also the item id of its curve request |
| `line/<name>` | a single line (1.5), also the item id of its curve request |
| `line/<name>/label` | its label |

Groups collect what is styled and toggled together (`iso/T`,
Expand All @@ -260,7 +260,7 @@ and 1, relative humidity 100 %), `quality` (the other lines of the
boundary family), `isoline_label`, `label_tick` (since 1.2: the short
line on the frame where a line with an outer rail label leaves, id
`iso/<key>/<value>/tick`, in the group of the labels), `cycle`, `process`, `state_points`,
`state_number`, `annotation`, and since 1.6 `line` and `line_label` (a
`state_number`, `annotation`, and since 1.5 `line` and `line_label` (a
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
single line and its label, in the groups `line/<name>` and
`line/<name>/label`). Z order: isolines 1,
saturation 2, single lines 3, labels 4, cycles and processes 5, state
Expand Down
Loading
Loading