Skip to content

Commit

Permalink
Merge branch 'axis_refactor_v12b' into axis_refactor_v12d
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/chart/generator/plotbuilder.cpp
  • Loading branch information
schaumb committed Dec 6, 2024
2 parents 72ef2bf + 3fa1330 commit 8a54384
Show file tree
Hide file tree
Showing 23 changed files with 132 additions and 180 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## [Unreleased]

### Fixed

- Fix invalid read/write when animation is contiguous (onFinish callback calls setKeyframe).
- Waterfall chart preset not aligned.
- Split chart count negative values too.

### Changed

- Separate Channel properties to AxisChannel properties at config.
Expand Down
9 changes: 6 additions & 3 deletions docs/assets/javascripts/mdchart.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ class MdChart {
this.id = id
}

async createFromConfig(snippets) {
this.create(await loadAnimations(snippets))
}

async create(snippets) {
const animations = await loadAnimations(snippets)
let chart = Promise.resolve()
for (let i = 0; i < animations.length; i++) {
for (let i = 0; i < snippets.length; i++) {
const number = i + 1
chart = this.animate(('0' + number).slice(-2), animations[i], chart)
chart = this.animate(('0' + number).slice(-2), snippets[i], chart)
}
}

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/assets/snippet.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ Promise.all([mdChartLoaded, dataLoaded, configLoaded]).then((results) => {
const config = results[2].default
const MdChart = results[0].default
const mdchart = new MdChart(data, 'tutorial')
mdchart.create(config)
mdchart.createFromConfig(config)
})
18 changes: 9 additions & 9 deletions src/apps/weblib/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,25 +267,25 @@ void Interface::setAnimControlValue(ObjectRegistryHandle chart,
const char *value)
{
auto &&chartPtr = getChart(chart);
auto &ctrl = chartPtr->getAnimControl();
auto &&ctrl = chartPtr->getAnimControl();

if (path == "seek") { ctrl.seek(value); }
if (path == "seek") { ctrl->seek(value); }
else if (path == "cancel") {
ctrl.cancel();
ctrl->cancel();
}
else if (path == "stop") {
ctrl.stop();
ctrl->stop();
}
else if (auto &&set_accessor =
Refl::Access::getAccessor<::Anim::Control::Option>(
path)
.set) {
set_accessor(ctrl.getOptions(), value);
set_accessor(ctrl->getOptions(), value);
}
else {
throw std::logic_error("invalid animation command");
}
ctrl.update();
ctrl->update();
}

const char *Interface::getAnimControlValue(ObjectRegistryHandle chart,
Expand All @@ -294,12 +294,12 @@ const char *Interface::getAnimControlValue(ObjectRegistryHandle chart,
thread_local std::string res;

auto &&chartPtr = getChart(chart);
auto &ctrl = chartPtr->getAnimControl();
auto &&ctrl = chartPtr->getAnimControl();

if (auto &&get_accessor =
Refl::Access::getAccessor<::Anim::Control::Option>(path)
.get) {
res = get_accessor(ctrl.getOptions());
res = get_accessor(ctrl->getOptions());
}
else
throw std::logic_error("invalid animation command");
Expand Down Expand Up @@ -396,7 +396,7 @@ void Interface::update(ObjectRegistryHandle chart, double timeInMSecs)
std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::duration<double, std::milli>{timeInMSecs});

widget->getChart().getAnimControl().update(
widget->getChart().getAnimControl()->update(
::Anim::TimePoint{nanoSecs});
}

Expand Down
2 changes: 1 addition & 1 deletion src/apps/weblib/ts-api/plugins/presetconfigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const presetConfigs = {
waterfall: {
channels: {
x: { set: [{ name: 'x' }] },
y: { set: [{ name: 'y' }, { name: 'x' }], align: 'stretch' },
y: { set: [{ name: 'y' }, { name: 'x' }] },
label: { set: [{ name: 'y' }] },
color: { set: [{ name: 'y' }] }
}
Expand Down
8 changes: 4 additions & 4 deletions src/base/geom/rect.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ struct Rect

void setHSize(const Math::Range<> &range)
{
setLeft(range.getMin());
setRight(range.getMax());
setLeft(range.min);
setRight(range.max);
}

void setVSize(const Math::Range<> &range)
{
setBottom(range.getMin());
setTop(range.getMax());
setBottom(range.min);
setTop(range.max);
}

[[nodiscard]] Rect bottomHalf() const
Expand Down
69 changes: 21 additions & 48 deletions src/base/math/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,6 @@ template <std::floating_point T = double> struct Range
constexpr static auto less = Floating::less;
constexpr static auto is_zero = Floating::is_zero;

constexpr static Range<T> Raw(const T &min, const T &max)
{
Range<T> range;
range.min = min;
range.max = max;
return range;
}

constexpr Range() :
min(std::numeric_limits<T>::max()),
max(std::numeric_limits<T>::lowest())
{}

Range(const T &x, const T &y) :
min(std::min(x, y, less)),
max(std::max(x, y, less))
{}

[[nodiscard]] bool isReal() const
{
return min != std::numeric_limits<T>::max()
Expand All @@ -52,7 +34,7 @@ template <std::floating_point T = double> struct Range
min = std::min(min, value, less);
}

void include(const Range<T> &range)
void include(const Range &range)
{
include(range.min);
include(range.max);
Expand All @@ -63,7 +45,7 @@ template <std::floating_point T = double> struct Range
return !less(value, min) && !less(max, value);
}

[[nodiscard]] bool includes(const Range<T> &range) const
[[nodiscard]] bool includes(const Range &range) const
{
return !less(range.max, min) && !less(max, range.min);
}
Expand All @@ -79,57 +61,57 @@ template <std::floating_point T = double> struct Range
return value * size() + min;
}

[[nodiscard]] Range<T> scale(const Range<T> &range) const
[[nodiscard]] Range scale(const Range &range) const
{
return Range<T>(scale(range.min), scale(range.max));
return {scale(range.min), scale(range.max)};
}

[[nodiscard]] T normalize(const T &value) const
{
return is_zero(max) ? 0 : value / max;
}

[[nodiscard]] Range<T> normalize(const Range<T> &range) const
[[nodiscard]] Range normalize(const Range &range) const
{
return Range<T>(normalize(range.min), normalize(range.max));
return {normalize(range.min), normalize(range.max)};
}

bool operator==(const Range<T> &other) const
bool operator==(const Range &other) const
{
return min == other.min && max == other.max;
}

Range<T> operator+(double shift) const
Range operator+(double shift) const
{
return Range<T>(min + shift, max + shift);
return {min + shift, max + shift};
}

Range<T> operator+(const Range<T> &other) const
Range operator+(const Range &other) const
{
return Range<T>(min + other.min, max + other.max);
return {min + other.min, max + other.max};
}

Range<T> operator-(double shift) const
Range operator-(double shift) const
{
return Range<T>(min - shift, max - shift);
return {min - shift, max - shift};
}

Range<T> operator*(double factor) const
Range operator*(double factor) const
{
return Range<T>(min * factor, max * factor);
return {min * factor, max * factor};
}

Range<T> operator/(double factor) const
Range operator/(double factor) const
{
return Range<T>(min / factor, max / factor);
return {min / factor, max / factor};
}

Range<T> operator*(const Transform &transf)
Range operator*(const Transform &transf)
{
return *this * transf.factor + transf.shift;
}

Transform operator/(const Range<T> range)
Transform operator/(const Range range)
{
auto factor = range.size() != 0 ? size() / range.size() : 0;
auto shift = min - range.min * factor;
Expand All @@ -140,17 +122,8 @@ template <std::floating_point T = double> struct Range

[[nodiscard]] T size() const { return max - min; }

[[nodiscard]] T getMin() const { return min; }
[[nodiscard]] T getMax() const { return max; }

consteval static auto members()
{
return std::tuple{&Range::min, &Range::max};
}

protected:
T min;
T max;
T min{std::numeric_limits<T>::max()};
T max{std::numeric_limits<T>::lowest()};
};

}
Expand Down
2 changes: 1 addition & 1 deletion src/base/math/segmentedfunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ template <typename T, class CRTP> struct SegmentedFunction
});
return interpolate(it->value,
std::next(it)->value,
Range{it->pos, std::next(it)->pos}.rescale(pos));
Range<>{it->pos, std::next(it)->pos}.rescale(pos));
}

protected:
Expand Down
56 changes: 24 additions & 32 deletions src/chart/generator/axis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ MeasureAxis::MeasureAxis(const Math::Range<> &interval,
const std::string_view &unit,
const std::optional<double> &step) :
enabled(true),
range(interval.isReal() ? interval : Math::Range<>::Raw({}, {})),
range(interval.isReal() ? interval : Math::Range<>{{}, {}}),
series(std::move(series)),
unit(std::string{unit}),
step(step ? *step : Math::Renard::R5().ceil(range.size() / 5.0))
Expand All @@ -120,7 +120,7 @@ MeasureAxis::MeasureAxis(const Math::Range<> &interval,
double MeasureAxis::origo() const
{
if (range.size() == 0) return 0;
return -range.getMin() / range.size();
return -range.min / range.size();
}

MeasureAxis interpolate(const MeasureAxis &op0,
Expand All @@ -140,13 +140,12 @@ MeasureAxis interpolate(const MeasureAxis &op0,

if (auto s0Zero = is_zero(s0), s1Zero = is_zero(s1);
s0Zero && s1Zero) {
res.range = Math::Range<>::Raw(
Math::interpolate(op0.range.getMin(),
op1.range.getMin(),
factor),
Math::interpolate(op0.range.getMax(),
op1.range.getMax(),
factor));
res.range = {Math::interpolate(op0.range.min,
op1.range.min,
factor),
Math::interpolate(op0.range.max,
op1.range.max,
factor)};
res.step = interpolate(op0.step, op1.step, factor);
}
else if (s1Zero) {
Expand All @@ -157,18 +156,16 @@ MeasureAxis interpolate(const MeasureAxis &op0,
0.0,
factor);

res.range = Math::Range<>::Raw(op1.range.middle()
- middleAt * size,
res.range = {op1.range.middle() - middleAt * size,
op1.range.middle()
+ (factor == 1.0 ? 0.0 : (1 - middleAt) * size));
+ (factor == 1.0 ? 0.0 : (1 - middleAt) * size)};

auto step = op0.step.get() / s0 * size;
auto max = std::copysign(MAX, step);

res.step = interpolate(op0.step,
Anim::Interpolated{max},
Math::Range<>::Raw(op0.step.get(), max)
.rescale(step));
Math::Range<>{op0.step.get(), max}.rescale(step));
}
else if (s0Zero) {
auto size = factor == 0.0 ? MAX : s1 / factor;
Expand All @@ -177,18 +174,16 @@ MeasureAxis interpolate(const MeasureAxis &op0,
op1.range.rescale(op0.range.middle()),
factor);

res.range = Math::Range<>::Raw(op0.range.middle()
- middleAt * size,
res.range = {op0.range.middle() - middleAt * size,
op0.range.middle()
+ (factor == 0.0 ? 0.0 : (1 - middleAt) * size));
+ (factor == 0.0 ? 0.0 : (1 - middleAt) * size)};

auto step = op1.step.get() / s1 * size;
auto max = std::copysign(MAX, step);

res.step = interpolate(op1.step,
Anim::Interpolated{max},
Math::Range<>::Raw(op1.step.get(), max)
.rescale(step));
Math::Range<>{op1.step.get(), max}.rescale(step));
}
else {
auto s0Inv = 1 / s0;
Expand All @@ -199,15 +194,14 @@ MeasureAxis interpolate(const MeasureAxis &op0,

const auto size = is_zero(interp) ? MAX : 1 / interp;

res.range = Math::Range<>::Raw(
Math::interpolate(op0.range.getMin() * s0Inv,
op1.range.getMin() * s1Inv,
res.range = {Math::interpolate(op0.range.min * s0Inv,
op1.range.min * s1Inv,
factor)
* size,
Math::interpolate(op0.range.max * s0Inv,
op1.range.max * s1Inv,
factor)
* size,
Math::interpolate(op0.range.getMax() * s0Inv,
op1.range.getMax() * s1Inv,
factor)
* size);
* size};

auto step = Math::interpolate(op0.step.get() * s0Inv,
op1.step.get() * s1Inv,
Expand All @@ -218,19 +212,17 @@ MeasureAxis interpolate(const MeasureAxis &op0,
op0sign == std::signbit(op1.step.get()))
res.step = interpolate(op0.step,
op1.step,
Math::Range<>::Raw(op0.step.get(), op1.step.get())
Math::Range<>{op0.step.get(), op1.step.get()}
.rescale(step));
else if (auto max = std::copysign(MAX, step);
op0sign == std::signbit(step))
res.step = interpolate(op0.step,
Anim::Interpolated{max},
Math::Range<>::Raw(op0.step.get(), max)
.rescale(step));
Math::Range<>{op0.step.get(), max}.rescale(step));
else
res.step = interpolate(op1.step,
Anim::Interpolated{max},
Math::Range<>::Raw(op1.step.get(), max)
.rescale(step));
Math::Range<>{op1.step.get(), max}.rescale(step));
}

res.unit = interpolate(op0.unit, op1.unit, factor);
Expand Down
Loading

0 comments on commit 8a54384

Please sign in to comment.