Creating a responsive scatter plot with flutter - flutter

I am trying to create a venn diagram of two elements from a scatter plot widget on package fl_chart.
scatterPlot(screenSize) {
return ListView(children: [
SizedBox(
width: 500,
height: 500,
child: ScatterChart(
ScatterChartData(
scatterSpots:
_createSpots(determineCircleLocation(screenSize), screenSize),
minX: 0,
minY: 0,
maxX: screenSize.width,
maxY: screenSize.height,
borderData: FlBorderData(show: false),
...
I have this problem that whenever I resize my window the scatter circles are moving - so if at a full screen it appeared that they had no intersection, when I resize the screen it appears like it has an intersection.
I was trying to wrap my plot in a SizedBox thinking that would stop the resizing side effects but it didn't.
Here's a demo of the problem
Is there a way to prevent this from happening?
While writing this I thought that by changing maxX and maxY to be some constants could help, but it resulted even worst outcome.

because we set a direct size (no matter in which size is it running) this problem happens.
You can check the window size, then update the dot's radius based on the window size.
(I calculated a number, then multiplied with radiuses).
Watch the video below. and check the code here:
LayoutBuilder(
builder: (context, constraints) {
final size = constraints.biggest.shortestSide;
final radiusMultiplier = size / 800;
return Padding(
padding: const EdgeInsets.only(right: 18.0),
child: ScatterChart(
ScatterChartData(
scatterSpots: [
ScatterSpot(5, 7, radius: 60 * radiusMultiplier,),
ScatterSpot(8, 4, radius: 20 * radiusMultiplier,),
ScatterSpot(3, 8, radius: 70 * radiusMultiplier),
],
minX: 1,
maxX: 10,
minY: 1,
maxY: 10,
)
),
);
},
)

Related

Flutter canvas RadialGradient understanding

I'm trying to create an effect like a heatmap point, so a circle with 2 or 3 colors on a gradient and then likely blurred.
final paint = Paint()
..shader = RadialGradient(
center: Alignment.center,
colors: <Color>[
Colors.green.withOpacity(0.2),
Colors.red.withOpacity(0.5),
Colors.blue.withOpacity(0.6)
],
stops: const [
0.3,
0.6,
1.0
]
).createShader(Rect.fromCircle(
center: const Offset(1.0,1.0),
radius: 10.0,
));
canvas.drawCircle(Offset(item[c][0].toDouble(), item[c][1].toDouble()), 8.0, paint);
However, whatever radius, Alignment, colors/opacity, shader center, stops I try, basically I just get a blue circle every time ?
I've also taken a look at the dartui RadialGradient (was after something like example 2), but I can't get that to work either.
I guess I'm missing something obvious, but can't see any Flutter examples of RadialGradient on canvas to compare to, any ideas what I'm misunderstanding ?

How to set InteractiveViewer initial zoom level

I am using InteractiveViewer to display a video. It is working properly.
But I want set initial zoom level.
Is there a way to do this?
return InteractiveViewer(
minScale: 1,
maxScale: 4,
constrained: false,
child: Container(
color: Colors.red,
width: 320,
height: 180,
child: widget.remoteVideoRenderer(),
),
);
I was able to do this, with varying levels of success, like so (credit to #pskink for pointing me in the right direction):
final viewTransformationController = TransformationController();
#override
void initState() {
final zoomFactor = 2.0;
final xTranslate = 300.0;
final yTranslate = 300.0;
viewTransformationController.value.setEntry(0, 0, zoomFactor);
viewTransformationController.value.setEntry(1, 1, zoomFactor);
viewTransformationController.value.setEntry(2, 2, zoomFactor);
viewTransformationController.value.setEntry(0, 3, -xTranslate);
viewTransformationController.value.setEntry(1, 3, -yTranslate);
super.initState();
}
#override
Widget build(BuildContext context) {
return InteractiveViewer(
transformationController: viewTransformationController,
minScale: 0.1,
maxScale: 6,
child: // ....
);
}
viewTransformationController.value is a 4x4 matrix that is applied to the view, it encodes the translations/rotations/scaling. The representation of these transformations in the matrix is probably documented somewhere (and/or just standard from projective/affine geometry), but I couldn't find them, so I just printed them out while zooming/panning until the roles of each entry became clear.
If you just set the zoom factor to 2 and don't translate, you'll be zoomed-in on the top-left corner of the widget.
Note that you cannot access the windows dimensions in the initState() method using MediaQuery.of(context), which is somewhat inconvenient if you want to e.g. zoom in on the middle of the window. I haven't found a good way to do that yet.
Base on Amos Joshua answer, if you want to always zoom center screen. I have this formula:
zoomFactor = 1, xTrans = 0, yTrans = 0
zoomFactor = 2, xTrans = w / 2, yTrans = h / 2
zoomFactor = 2.8, xTrans = (w / 2)(1 + 0.8), yTrans = (h / 2)(1 + 0.8)
Therefore:
zoomFactor = z, xTrans = (w / 2)(z - 1), yTrans = (h / 2)(z - 1)

Flutter - How to proportionally center a view (centered with multiplier offset)

I'm wondering if in Flutter there are any good ways of imitating the iOS Xcode constraint where you center a view inside another (say, vertically), and supply a multiplier such that instead of being exactly centered (50% of the way down the parent view), it's positioned at 30% down, or 70% down, or whatever.
(Rather than use a fixed margin from the top of the screen, I'd like to "float" a header view down by 20% of the screen height...)
FractionallySizedBox is enough by itself to handle such layout
FractionallySizedBox(
heightFactor: .5,
widthFactor: 1.0,
alignment: Alignment.topCenter,
child: child,
)
This will top center a widget taking helf the height of its parent and full width
All my FractionallySizedBox efforts have been unreliable, but here's a way that's proven far stabler for me - using LayoutBuilder and SizedBox as a spacer:
LayoutBuilder(builder: (context, constraints) => Column(
children: <Widget>[
SizedBox(height: (constraints.maxHeight - constraints.minHeight) * 0.2,),
myWidget
],
))
This way constraints give me the ability to calculate 20% of the parent height, and apply that as a spacing using a simple SizedBox.
Set in container of parent view
Container(alignment: Alignment.center, ...)
I found one way, but I'm not sure it's the neatest yet:
For vertical proportional centering:
Embed your layout inside a Center widget that is itself inside a FractionallySizedBox. Provided that FractionallySizedBox is at the top of the screen, by changing its heightFactor you effectively change the centering position caused by the Center widget.
new FractionallySizedBox(
heightFactor: someHeightFactor,
child: Center(
child: myChildWidget
),
);
i.e. if parentHeight = the height of the parent widget to this FractionallySizedBox, and parentY = the (absolute) y origin of that parent widget, then setting heightFactor = 0.6 would center your UI child inside a region measuring 0.6 * parentHeight, therefore with an absolute y center = parentY + 0.3 * parentHeight.
Horizontal proportional centering would be the same but using widthFactor on the FractionallySizedBox.
Use FractionallySizedBox to size a widget relative to all available space, and wrap it with a Container or Align to specify the alignment of it.
For example:
Container(
alignment: Alignment(0, -0.5),
child: FractionallySizedBox(
heightFactor: 0.5,
widthFactor: 0.8,
child: Container(color: Colors.blue),
),
)
This makes a blue box that's 50% of screen height and 80% of screen width, positioned at 25% down vertically.
Note, for the Alignment class, it takes in 2 parameters, for x and y axis alignment, ranges from -1 to +1. For example, (0,0) is center, (-1, -1) is top left corner, so here (0, -0.5) centers it horizontally and lifts it up half way vertically, resulting in 25% padding from the top.

Centering a layer on click using FramerJS

The goal is to move the button layer vertically upwards from the bottom the middle of the screen, whilst growing to a larger size. However, upon clicking the layer it does not move to the exact center. It moves up but shifts to the right. Why is this?
Code
bg = new BackgroundLayer
backgroundColor: "#f39c12"
button = new Layer
width: 100
height: 100
borderRadius: 100
backgroundColor: "white"
x: Align.center
y: Align.bottom(-100)
button.on Events.Click, ->
button.states.next()
button.states =
StateA:
width: 300
height: 300
borderRadius: 300
y: Align.center
The reason is that Align.center is something that is only calculated when you create the layer or a state. For that reason, adding x: Align.center to the state also doesn't work (as you might expect it to).
However, there is an easy way to do this, by setting the midX property of the state to Screen.midX. Full example:
bg = new BackgroundLayer
backgroundColor: "#f39c12"
button = new Layer
width: 100
height: 100
borderRadius: 100
backgroundColor: "white"
x: Align.center
y: Align.bottom(-100)
button.on Events.Click, ->
button.states.next()
button.states =
StateA:
width: 300
height: 300
borderRadius: 300
y: Align.center
midX: Screen.midX
Working prototype can be found here: https://framer.cloud/RsULi
When you enlarge the height and width of the button, the button will enlarge, but its x and y properties may not change as you expect.
Instead, try adjusting scale in StateA:
button.states =
StateA:
borderRadius: 300
y: Align.center
scale: 3

Fill color in circle in List box using another List box have color and may its muliple in c#.net

as you saw me how to draw circle using listbox now i want to fill color in List box each circle using another List box when color is defined ....it is multiple color also we can apply .. please help me in this.. in winforms in c#.net
Not sure if this is what you're asking, exactly, but you can use the same code as in the answer to your previous question, only use Graphics.FillEllipse instead of Graphics.DrawEllipse. This method uses a SolidBrush instead of a Pen.
Update: I think this is what you want. Take this line from your original answer:
e.Graphics.DrawEllipse(Pens.Blue, new Rectangle(1, 1+e.Index * 15, 100, 10));
and change it to this:
e.Graphics.FillEllipse(Brushes.Blue, new Rectangle(1, 1+e.Index * 15, 100, 10));
If you need to use different colors, you can use some variant of this:
SolidBrush brush;
Random rnd = new Random();
if (rnd.NextDouble() < 0.5)
{
brush = new SolidBrush(Color.Red);
}
else
{
brush = new SolidBrush(Color.Blue);
}
e.Graphics.FillEllipse(brush, new Rectangle(1, 1+e.Index * 15, 100, 10));
instead of using the Brushes enumeration.
Update 2: to draw a circle that is half one color and half another color, you'd want to use FillPie:
e.Graphics.FillPie(Brushes.Blue, new Rectangle(1, 1+e.Index * 15, 100, 10),
-90, 180);
e.Graphics.FillPie(Brushes.Red, new Rectangle(1, 1+e.Index * 15, 100, 10),
90, 180);