I have a requirement to extend my plot band outside the graph and give a shape. Need to achieve the portion marked in the attached screenshot. using highchart android wrapper. While searching for the solution, I found the jsfiddle I would like to do the same thing using the android wrapper; I am using highchart library of version 6.1.4
targetimage
Link : https://jsfiddle.net/BlackLabel/e52smy16/
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
const renderCustomPlotBand = function(chart) {
let ren = chart.renderer,
customOptions = chart.yAxis[0].options.customPlotBand,
from = customOptions.from,
to = customOptions.to,
xEnd = chart.plotLeft + chart.plotSizeX,
xBeginig = chart.plotLeft - 40,
point1 = [xEnd, chart.yAxis[0].toPixels(from)],
point2 = [xBeginig, chart.yAxis[0].toPixels(from)],
point3 = [xBeginig, chart.yAxis[0].toPixels(to)],
point4 = [xEnd, chart.yAxis[0].toPixels(to)],
textWidth = chart;
if (customOptions.enabled) {
chart.customPlotBand = ren.g('customPlotBand').add().toFront()
chart.customText = ren.g('customText').add().toFront();
ren.path(['M', point1[0], point1[2], 'L', point2[0], point2[2], point3[0], point3[2], point4[0], point4[2]])
.attr({
'stroke-width': 1,
stroke: 'red'
}).add(chart.customPlotBand);
ren.label(customOptions.text, point2[0] - 10, point2[2] - 17).attr({
padding: 5,
fill: 'white',
rotation: -90
}).add(chart.customText);
chart.customText.translate(0, -(point2[2] - point3[2]) / 2 + chart.customText.element.getBBox().height - 3)
}
}
Highcharts.chart('container', {
chart: {
marginLeft: 80,
events: {
render() {
renderCustomPlotBand(this)
}
}
},
yAxis: [{
//Declere your custom plotband
customPlotBand: {
enabled: true,
from: 2,
to: 4,
text: 'Target'
},
title: {
text: null
},
lineWidth: 1,
gridLineWidth: 1
}],
series: [{
data: [1, 3, 6, 2, 5]
}]
});```
Unfortunately, there is no option to create a custom plotBand like in the provided example, since the renderer module is not available in the Android wrapper.
The only way of achieving similar behaviour is using static plotBand.
HIYAxis hiyAxis = new HIYAxis();
HIPlotBands plotBands = new HIPlotBands();
plotBands.setColor(HIColor.initWithName("red"));
plotBands.setFrom(2);
plotBands.setTo(4);
hiyAxis.setPlotBands(new ArrayList<>(Collections.singletonList(plotBands)));
options.setYAxis(new ArrayList<>(Collections.singletonList(hiyAxis)));
Related
I am using Reanimated2 on my React Native app in an Android emulator. I am trying to rotate a component using useAnimatedStyle. Here's my code. It works on iOS, but on Android I get an error.
const animatedStyle = useAnimatedStyle(() => {
let rotate = interpolate(x.value, [-150, 0, 150], [-Math.PI / 36, 0, Math.PI / 36], Extrapolate.CLAMP);
return {
transform: [{ translateY: y.value }, { translateX: x.value }, { rotate }],
}
});
I'm getting the following error on Android only: Transform with key of "rotate" must be a string: {"rotate":0}]
Then I change the code to a string:
const animatedStyle = useAnimatedStyle(() => {
let rotate = interpolate(x.value, [-150, 0, 150], ["-10deg", "0deg", "10deg"], Extrapolate.CLAMP);
return {
transform: [{ translateY: y.value }, { translateX: x.value }, { rotate }],
}
});
Then I get this error:
Error while updating property 'transform' of a view managed by: RTCView
null
For input string: "-10degNaN"
Can anyone help me fix this?
https://docs.swmansion.com/react-native-reanimated/docs/1.x.x/nodes/interpolate/
The documentation states, that you should use your first approach. Interpolate the numbers and then add the deg afterwards.
This should do the trick:
const animatedStyle = useAnimatedStyle(() => {
let rotate = interpolate(x.value, [-150, 0, 150], [-Math.PI / 36, 0, Math.PI / 36], Extrapolate.CLAMP);
return {
transform: [{ translateY: y.value }, { translateX: x.value }, { rotate: `${rotate}deg` }],
}
});
Is there an equivalent of FastOutSlowInInterpolator for iOS? I've recently got my hands on AndroidX and really like this interpolator. I've found the source code for it too but have no idea how to convert it to iOS implementation.
If you are using UIViewPropertyAnimator the curve that you need is .easeInOut, and you can pass it as curve parameter when you create your animator:
let animator = UIViewPropertyAnimator(duration: 0.4, curve: .easeInOut) {
// Animations
}
If you are not happy with this system curve, you can follow this answer and use this handy website to replicate FastOutSlowInInterpolator's control points.
As FastOutSlowInInterpolator documentation states:
Interpolator corresponding to fast_out_slow_in. Uses a lookup table
for the Bezier curve from (0,0) to (1,1) with control points: P0 (0,
0) P1 (0.4, 0) P2 (0.2, 1.0) P3 (1.0, 1.0)
So, in your particular case you are looking for something like this:
let timingParameters = UICubicTimingParameters(
controlPoint1: CGPoint(x: 0.4, y: 0),
controlPoint2: CGPoint(x: 0.2, y: 1)
)
let animator = UIViewPropertyAnimator(duration: 0.4, timingParameters: timingParameters)
or this:
let animator = UIViewPropertyAnimator(
duration: 0.4,
controlPoint1: CGPoint(x: 0.4, y: 0),
controlPoint2: CGPoint(x: 0.2, y: 1)
) {
// Animations
}
SwiftUI
In SwiftUI you can animate almost any change with .animate modifier and it accepts the curve as the argument. I think .interpolatingSpring(stiffness: 30, damping: 20) is the curve that you are looking for (the bottom one).
Examples
struct ContentView: View {
#State var isLeading = false
var body: some View {
VStack {
SpacedCircle(isLeading: $isLeading)
.animation(.linear)
SpacedCircle(isLeading: $isLeading)
.animation(.easeIn)
SpacedCircle(isLeading: $isLeading)
.animation(.easeOut)
SpacedCircle(isLeading: $isLeading)
.animation(.easeInOut)
SpacedCircle(isLeading: $isLeading)
.animation(.interactiveSpring(response: 0.27, dampingFraction: 0.5, blendDuration: 0.2))
SpacedCircle(isLeading: $isLeading)
.animation(.interpolatingSpring(stiffness: 30, damping: 20))
Button("Toggle") { isLeading.toggle() }
}
}
}
UIKit
You can achieve that similarly in UIKit too:
Example
#IBAction func touched(_ sender: UIButton) {
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 3, options: []) {
self.circleView.transform = .identity
}
}
#IBAction func touchDown(_ sender: Any) {
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 3, options: []) {
self.circleView.transform = CGAffineTransform(translationX: 240, y: 0)
}
}
today during debugging of my app I found an issue in my <ArrayList<ArrayList<ArrayList<Float>>>.
My goal is to make a full copy of that ArrayList because now when I change something in the copy of the ArrayList, it makes a change in the original ArrayList too.
So I have something Like this
var first = ArrayList<ArrayList<ArrayList<Float>>>()
var second = ArrayList<ArrayList<Float>>()
var third = ArrayList<Float>()
for(j in allData) {
first.add(j.clone() as ArrayList<ArrayList<Float>>)
for(k in j)
{
second.add(k.clone() as ArrayList<Float>)
for(l in k)
{
third.add(l.toFloat())
}
}
}
normalizedAllData = first.clone() as ArrayList<ArrayList<ArrayList<Float>>>
Where normalizedAllData is <ArrayList<ArrayList<ArrayList<Float>>>
How should I create a full copy so the new ArrayList will not point to the original ArrayList?
Thanks for the help
You don't need to copy the Floats because they are immutable.
You can use nested map calls to create copies of the lists, and wrap the results in ArrayList constructors:
val normalizedAllData = ArrayList(allData.map { innerList ->
ArrayList(innerList.map { ArrayList(it) })
})
Well, I would resolved the issue in the following simple way:
I will create one helper method:
fun flattenList(nestedList: List<Any?>, flatList: MutableList<Any?>) {
nestedList.forEach { e ->
when (e) {
!is List<Any?> -> flatList.add(e)
else -> flattenList(e, flatList)
}
}
}
And this is how I would use this method:
// some sample list
val nestedList = arrayListOf(arrayListOf(arrayListOf(1f, 2f, 3f, 4f)))
// contain the flat list
val flatList = mutableListOf<Any?>()
flattenList(nestedList, flatList)
println("Nested : " + nestedList)
println("Flat : " + flatList)
Output:
Nested : [[[1.0, 2.0, 3.0, 4.0]]]
Flat : [1.0, 2.0, 3.0, 4.0]
You can use flattenList() method for any type:
Another sample:
val nestedList = listOf(
null,
1f,
listOf(2.0),
listOf(listOf(3.0, 4), 5.0),
listOf(listOf(listOf<String>("Hello Worlds"))),
listOf(listOf(listOf(6), "seven")),
"eight",
listOf<Long>()
)
val flatList = mutableListOf<Any?>()
flattenList(nestedList, flatList)
println("Nested : " + nestedList)
println("Flat : " + flatList)
Output:
Nested : [null, 1.0, [2.0], [[3.0, 4], 5.0], [[[Hello Worlds]]], [[[6], seven]], eight, []]
Flat : [null, 1.0, 2.0, 3.0, 4, 5.0, Hello Worlds, 6, seven, eight]
I am using this library https://reactnavigation.org/docs/intro/ to build android by react-native. I can make the navigation happens on android device but how I can make the screen slide in from the right and fade in from the left. It seems that this behaviour happens on iOS device but not in Android. Is there any animation configuration for android app?
Please see below animation. This is recorded in iOS.
Starting from : "#react-navigation/native": "^5.5.1",
import {createStackNavigator, TransitionPresets} from '#react-navigation/stack';
const TransitionScreenOptions = {
...TransitionPresets.SlideFromRightIOS, // This is where the transition happens
};
const CreditStack = createStackNavigator();
function CreditStackScreen() {
return (
<CreditStack.Navigator screenOptions={TransitionScreenOptions}> // Don't forget the screen options
<CreditStack.Screen
name="Credit"
component={HomeScreen}
options={headerWithLogo}
/>
<HomeStack.Screen
name="WorkerDetails"
component={WorkerDetails}
options={headerWithLogoAndBackBtn}
/>
</CreditStack.Navigator>
);
}
You can watch this video to understand more:
https://www.youtube.com/watch?v=PvjV96CNPqM&ab_channel=UnsureProgrammer
You should use transitionConfig to override default screen transitions as written on this page.
Unfortunately there is no example provided how that function works but you can find some examples in this file: \react-navigation\lib\views\CardStackStyleInterpolator.js
So your code should look like this:
const navigator = StackNavigator(scenes, {
transitionConfig: () => ({
screenInterpolator: sceneProps => {
const { layout, position, scene } = sceneProps;
const { index } = scene;
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [layout.initWidth, 0, 0]
});
const opacity = position.interpolate({
inputRange: [
index - 1,
index - 0.99,
index,
index + 0.99,
index + 1
],
outputRange: [0, 1, 1, 0.3, 0]
});
return { opacity, transform: [{ translateX }] };
}
})
});
For StackNavigatoin 6.x.x
Just import
import { TransitionPresets } from '#react-navigation/stack';
Then create a config:
const screenOptionStyle = {
// headerShown: false,
...TransitionPresets.SlideFromRightIOS,
};
And finally just assign them to the Stack Navigator Screen Options:
<Stack.Navigator
screenOptions={screenOptionStyle}
>
<Stack.Screen
...
...
All the above answers are correct, but the solutions work ONLY if you are using createStackNavigator, and not if you are using createNativeStackNavigator; unfortunatelly, if you are following the get started section from react-navigation's docs, you will end up using the latter.
Here you can find a SO question speaking about the differences between the two, but the most relevant one for this questions is that many of the options that your can pass to the former (such as transitionConfig), cannot be passed to the latter.
If you are using createNativeStackNavigator this is how you can do it:
import { createNativeStackNavigator } from '#react-navigation/native-stack'
const StackNavigator = createNativeStackNavigator()
const MyNativeStackNavigator = () =>{
return <StackNavigator.Navigation
screenOptions={{
animation: 'slide_from_right', //<-- this is what will do the trick
presentation: 'card',
}}
>
{routes}
</StackNavigator.Navigator>
}
you need to import StackViewTransitionConfigs from 'react-navigation-stack'
then, override the transitionConfing function.
const myStack = createStackNavigator({
Screen1,
Screen2,
Screen3
},{
transitionConfig: () => StackViewTransitionConfigs.SlideFromRightIOS
}
On #react-navigation/stack component version, the way to do a slide from the right animation is:
<Stack.Navigator
screenOptions={{
cardStyleInterpolator: ({index, current, next, layouts: {screen}}) => {
const translateX = current.progress.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [screen.width, 0, 0],
});
const opacity = next?.progress.interpolate({
inputRange: [0, 1, 2],
outputRange: [1, 0, 0],
});
return {cardStyle: {opacity, transform: [{translateX}]}};
},
}}>
<Stack.Screen name="MainScreen" component={MainScreen} />
...
</Stack.Navigator>
Better you can use the react native navigation for this. You can configure your screen using configureScene method. Inside that method use Navigator.SceneConfigs for animating screen. It's work for both android and iOS.
You can get useful information from index.d.ts file, find the export interface TransitionConfig , then press 'Ctrl' & left_click on NavigationTransitionSpec and NavigationSceneRendererProps, then you can get everything you want.
I'm triyng to add a chart to my Android app using Chart.js
At Intel-XDK emulator this works perfectly, but if I try run it using App Preview or if I build the apk I can't see the chart.
function Skills(){
document.getElementById("MinhasHabilidades").style.display = 'block';
document.getElementById("inicio").style.display = 'none';
var ChartData = {
labels: ["Ler", "Ouvir", "Escrever", "Falar"],
datasets: [{
fillColor: "rgba(0,128,255,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: [9, 13, 4, 12]
}]
};
var ctx = document.getElementById("myChart").getContext("2d");
window.myBar = new Chart(ctx).Radar(ChartData, {responsive: true});
}
When I call the "new Chart(ctx)..." the function stop.