I've been playing around with the CatmullRomSpline class from Flutter the past few days. Drawing points with is trivial, however, I've been looking for information on interpolating between two sets of values and haven't had much luck.
to give a better overview here is the first plot of offsets: 
This is the next plot of offsets that I would like to morph/animate to:
Here is the code I have so far:
import 'dart:ui';
import 'package:curves/data.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'models/price_plot.dart';
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Home(),
);
}
}
class Home extends StatefulWidget {
const Home({
Key? key,
}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
late Animation<List<Offset>> animation;
late AnimationController controller;
List<Offset> controlPoints = [];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
controlPoints = buildControlPoints(hourItems);
setState(() {});
});
}
List<Offset> buildControlPoints(List<List<double>> items) {
final max = items.map((x) => x.last).fold<double>(
items.first.last,
math.max,
);
final min = items.map((x) => x.last).fold<double>(
items.first.last,
math.min,
);
final range = max - min;
final priceMap = {
for (var v in items)
v.last: ((max - v.last) / range) * MediaQuery.of(context).size.height,
};
final pricePlots =
priceMap.entries.map((e) => PricePlot(e.value.toInt(), e.key)).toList();
return controlPoints = List.generate(
pricePlots.length,
(index) {
return Offset(
calculateXOffset(
MediaQuery.of(context).size.width, pricePlots, index),
pricePlots[index].yAxis.toDouble(),
);
},
).toList();
}
double calculateXOffset(double width, List<PricePlot> list, int index) {
if (index == (list.length - 1)) {
return width;
}
return index == 0 ? 0 : width ~/ list.length * (index + 1);
}
void _startAnimation() {
controller.stop();
controller.reset();
controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("App"),
),
body: Stack(
children: [
CustomPaint(
painter: SplinePainter(controlPoints),
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
),
FloatingActionButton(onPressed: () {
_startAnimation();
})
],
),
);
}
}
class SplinePainter extends CustomPainter {
final List<Offset> items;
SplinePainter(this.items);
@override
void paint(Canvas canvas, Size size) {
canvas.drawPaint(Paint()..color = Colors.white);
if (items.isEmpty) {
return;
}
final spline = CatmullRomSpline(items);
final bezierPaint = Paint()
..strokeCap = StrokeCap.round
..strokeWidth = 2
..color = Colors.blue;
canvas.drawPoints(
PointMode.points,
spline.generateSamples(tolerance: 1e-17).map((e) => e.value).toList(),
bezierPaint,
);
}
@override
bool shouldRepaint(SplinePainter oldDelegate) => true;
}

not coding in your environment but I would try:
lets have
p0[n0]andp1[n1]control points for your curveslet
n = max(n0,n1)resample the less sampled curve to
npointslinearly interpolate between corresponding curve points
where
tis linear parameter in range<0.0,1.0>So to animate just render
p[n]witht=0.0wait a bit, increasetby small amount render again and so on until you hitt=1.0...If you share your control point I would make a simple C++ example and grab a GIF animation but without I would need to extract the points from image which is a problem as you did not mark control point in your plot... and the extraction is much more work than the resampling and animation itself...
After your comments and looking at the link of yours its obvious you do not have 2 datasets but just one and just changing the sampling rate ...
So I taken the more dense data you provided and create second set by skipping points ... so booth sets covering the same time interval just have different number of points but still uniformly sampled...
Putting all together I created a small C++/VCL example of doing this:
You can ignore most of the stuff, the only important parts of code are functions:
the first just obtains point on piecewise cubic curve
p[n]with parametert=<0.0,n>. The other one uses the first function to obtain corresponding points on both curve and linearly interpolate between them with parametert=<0.0,1.0>to render interpolated curve.The function
void draw();render the graph and animate the interpolation parameter ... its called in timer with 100ms interval...Beware my data is just 1D array of
x,ycoordinates son0,n1are twice the number of points !!!Here preview:
The graph transition in the link of yours adds also animation of scale and scroll of time (x axis) but that is just a matter of changing view parameters ...