1678847100
A set of useful components to help you build and maintain React Native (Web too) layouts with ease.
Stacks
is written in ReScript. It's compiled using BuckleScript to plain JavaScript and has typings for TypeScript and Flow.
This means that out of the box Stacks
is usable in any project that use the following:
Stacks
can be used in React Native and React Native Web projects.
yarn add @mobily/stacks
or with npm
npm install @mobily/stacks --save
The following example shows how simple it is building screens using Stacks
. For debugging purposes, you may want to turn the debug mode on (pass the debug
property to the provider) or use the customizable Grid
component.
import * as React from 'react'
import { ScrollView, Text } from 'react-native'
import { Stack, Box, Columns, Column, Tiles } from '@mobily/stacks'
// import components, styles, etc.
const Profile = () => {
return (
<ScrollView>
<Box padding={4}>
<Stack space={4}>
<Stack space={4} align="center">
<Avatar source="…" size={96} />
<Stack space={1} align="center">
<Title>Jenna Doe</Title>
<Description>Photographer & Artist</Description>
</Stack>
<Columns>
<Column>
<Stack space={1} align="center">
<Text>Followers</Text>
<Counter>258</Counter>
</Stack>
</Column>
<Column>
<Stack space={1} align="center">
<Text>Following</Text>
<Counter>346</Counter>
</Stack>
</Column>
</Columns>
<Divider />
</Stack>
<Text>Photos</Text>
<Tiles columns={4} space={2}>
<Photo source="…" />
<Photo source="…" />
<Photo source="…" />
</Tiles>
<Text>Followers</Text>
<Tiles columns={8} space={2}>
<Avatar source="…" />
<Avatar source="…" />
<Avatar source="…" />
</Tiles>
</Stack>
</Box>
</ScrollView>
)
}
Full documentation can be found here.
Max Stoiber wrote an interesting article some time ago about why margin is considered harmful. There are three main disadvantages of using margin:
It's obvious that handling margins across the entire project is simply difficult and may not be scalable. For web projects, a design system called Braid has developer-friendly API for building layouts. However, a similar library was missing for React Native based projects. Therefore, Stacks has been created and it adopts Braid Layouts API with subtle differences.
Author: Mobily
Source Code: https://github.com/mobily/stacks
License: MIT license
1678259040
A drop-in UITableView/UICollectionView superclass category for showing empty datasets whenever the view has no content to display. DZNEmptyDataSet with Swift.
pod 'EmptyDataSet-Swift', '~> 5.0.0'
github "Xiaoye220/EmptyDataSet-Swift" "4.2.0"
Same as DZNEmptyDataSet
import EmptyDataSet_Swift
class OriginalUsageViewController: UITableViewController, EmptyDataSetSource, EmptyDataSetDelegate {
override func viewDidLoad() {
super.viewDidLoad()
tableView.emptyDataSetSource = self
tableView.emptyDataSetDelegate = self
}
}
public protocol EmptyDataSetDelegate: class {
/// Asks the delegate to know if the empty dataset should fade in when displayed. Default is true.
func emptyDataSetShouldFadeIn(_ scrollView: UIScrollView) -> Bool
/// Asks the delegate to know if the empty dataset should still be displayed when the amount of items is more than 0. Default is false.
func emptyDataSetShouldBeForcedToDisplay(_ scrollView: UIScrollView) -> Bool
/// Asks the delegate to know if the empty dataset should be rendered and displayed. Default is true.
func emptyDataSetShouldDisplay(_ scrollView: UIScrollView) -> Bool
/// Asks the delegate for touch permission. Default is true.
func emptyDataSetShouldAllowTouch(_ scrollView: UIScrollView) -> Bool
/// Asks the delegate for scroll permission. Default is false.
func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView) -> Bool
/// Asks the delegate for image view animation permission. Default is false.
/// Make sure to return a valid CAAnimation object from imageAnimationForEmptyDataSet:
func emptyDataSetShouldAnimateImageView(_ scrollView: UIScrollView) -> Bool
/// Tells the delegate that the empty dataset view was tapped.
/// Use this method either to resignFirstResponder of a textfield or searchBar.
func emptyDataSet(_ scrollView: UIScrollView, didTapView view: UIView)
/// Tells the delegate that the action button was tapped.
func emptyDataSet(_ scrollView: UIScrollView, didTapButton button: UIButton)
/// Tells the delegate that the empty data set will appear.
func emptyDataSetWillAppear(_ scrollView: UIScrollView)
/// Tells the delegate that the empty data set did appear.
func emptyDataSetDidAppear(_ scrollView: UIScrollView)
/// Tells the delegate that the empty data set will disappear.
func emptyDataSetWillDisappear(_ scrollView: UIScrollView)
/// Tells the delegate that the empty data set did disappear.
func emptyDataSetDidDisappear(_ scrollView: UIScrollView)
}
public protocol EmptyDataSetSource: class {
/// Asks the data source for the title of the dataset.
/// The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
func title(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString?
/// Asks the data source for the description of the dataset.
/// The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
func description(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString?
/// Asks the data source for the image of the dataset.
func image(forEmptyDataSet scrollView: UIScrollView) -> UIImage?
/// Asks the data source for a tint color of the image dataset. Default is nil.
func imagetintColor(forEmptyDataSet scrollView: UIScrollView) -> UIColor?
/// Asks the data source for the image animation of the dataset.
func imageAnimation(forEmptyDataSet scrollView: UIScrollView) -> CAAnimation?
/// Asks the data source for the title to be used for the specified button state.
/// The dataset uses a fixed font style by default, if no attributes are set. If you want a different font style, return a attributed string.
func buttonTitle(forEmptyDataSet scrollView: UIScrollView, for state: UIControl.State) -> NSAttributedString?
/// Asks the data source for the image to be used for the specified button state.
/// This method will override buttonTitleForEmptyDataSet:forState: and present the image only without any text.
func buttonImage(forEmptyDataSet scrollView: UIScrollView, for state: UIControl.State) -> UIImage?
/// Asks the data source for a background image to be used for the specified button state.
/// There is no default style for this call.
func buttonBackgroundImage(forEmptyDataSet scrollView: UIScrollView, for state: UIControl.State) -> UIImage?
/// Asks the data source for the background color of the dataset. Default is clear color.
func backgroundColor(forEmptyDataSet scrollView: UIScrollView) -> UIColor?
/// Asks the data source for a custom view to be displayed instead of the default views such as labels, imageview and button. Default is nil.
/// Use this method to show an activity view indicator for loading feedback, or for complete custom empty data set.
/// Returning a custom view will ignore -offsetForEmptyDataSet and -spaceHeightForEmptyDataSet configurations.
func customView(forEmptyDataSet scrollView: UIScrollView) -> UIView?
/// Asks the data source for a offset for vertical alignment of the content. Default is 0.
func verticalOffset(forEmptyDataSet scrollView: UIScrollView) -> CGFloat
/// Asks the data source for a vertical space between elements. Default is 11 pts.
func spaceHeight(forEmptyDataSet scrollView: UIScrollView) -> CGFloat
}
Usage without conform to datasource and/or delegate.Tableview just calls the following method.
public func emptyDataSetView(_ closure: @escaping (EmptyDataSetView) -> Void)
Example:
tableView.emptyDataSetView { view in
view.titleLabelString(titleString)
.detailLabelString(detailString)
.image(image)
.imageAnimation(imageAnimation)
.buttonTitle(buttonTitle, for: .normal)
.buttonTitle(buttonTitle, for: .highlighted)
.buttonBackgroundImage(buttonBackgroundImage, for: .normal)
.buttonBackgroundImage(buttonBackgroundImage, for: .highlighted)
.dataSetBackgroundColor(backgroundColor)
.verticalOffset(verticalOffset)
.verticalSpace(spaceHeight)
.shouldDisplay(true, view: tableView)
.shouldFadeIn(true)
.isTouchAllowed(true)
.isScrollAllowed(true)
.isImageViewAnimateAllowed(isLoading)
.didTapDataButton {
// Do something
}
.didTapContentView {
// Do something
}
}
Set customView by using EmptyDataSetSource, other setting will be invalid.Set customView by using Extensions, other autolayout will be invalid.
Rule for displaying CustomView
func verticalOffset(forEmptyDataSet scrollView: UIScrollView) -> CGFloat
Example:
func customView(forEmptyDataSet scrollView: UIScrollView) -> UIView? {
let view = CustomView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
return view
}
tableView.emptyDataSetView { [weak self] view in
view.customView(CustomView(frame: CGRect(x: 0, y: 0, width: 150, height: 150)))
}
above code will show as follows
func customView(forEmptyDataSet scrollView: UIScrollView) -> UIView? {
let view = CustomView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
return view
}
func verticalOffset(forEmptyDataSet scrollView: UIScrollView) -> CGFloat {
return 200
}
tableView.emptyDataSetView { [weak self] view in
view.customView(CustomView(frame: CGRect(x: 0, y: 0, width: 150, height: 150)))
.verticalOffset(200)
}
above code will show as follows
func customView(forEmptyDataSet scrollView: UIScrollView) -> UIView? {
let label = UILabel()
label.text = "CustomView"
label.backgroundColor = UIColor.red
return label
}
above code will show as follows
Author: Xiaoye220
Source Code: https://github.com/Xiaoye220/EmptyDataSet-Swift
License: MIT license
1676677260
A Swift Package to easily perform flyovers on a MKMapView.
import SwiftUI
import FlyoverKit
struct ContentView: View {
var body: some View {
FlyoverMap(
latitude: 37.3348,
longitude: -122.0090
)
}
}
To integrate using Apple's Swift Package Manager, add the following as a dependency to your Package.swift
:
dependencies: [
.package(url: "https://github.com/SvenTiigi/FlyoverKit.git", from: "2.0.0")
]
Or navigate to your Xcode project then select Swift Packages
, click the “+” icon and search for FlyoverKit
.
Check out the example application to see FlyoverKit in action. Simply open the Example/Example.xcodeproj
and run the "Example" scheme.
When using SwiftUI a FlyoverMap
can be used to render and control a flyover.
var body: some View {
FlyoverMap(
// Bool value if flyover is started or stopped
isStarted: true,
// The coordinate to perform the flyover on
coordinate: CLLocationCoordinate2D(
latitude: 37.8023,
longitude: -122.4057
),
configuration: Flyover.Configuration(
// The animation curve
animationCurve: .linear,
// The altitude in meter
altitude: 900,
// The pitch in degree
pitch: 45.0,
// The heading
heading: .incremented(by: 1.5)
),
// The map type e.g. .standard, .satellite, .hybrid
mapType: .standard
)
}
let flyoverMapView = FlyoverMapView()
if flyoverMapView.isFlyoverStarted {
// ...
}
flyoverMapView.startFlyover(
at: CLLocationCoordinate2D(
latitude: 37.8023,
longitude: -122.4057
),
configuration: .default
)
flyoverMapView.stopFlyover()
flyoverMapView.resumeFlyover()
A Flyover
object represents the core object to start, stop and resume a flyover on an instance of MKMapView
.
let flyover = Flyover(
mapView: self.mapView
)
Note: The provided MKMapView is always weakly referenced
Author: SvenTiigi
Source Code: https://github.com/SvenTiigi/FlyoverKit
License: MIT license
1675552380
"PexWalls" app can allow to view and save best photos from Pexels, and set this photos as wallpaper. Base UI design implementing simple, clean and easy to understand approach to user experiense ispired by Pinterest.
Author: GreyLabsDev
Source Code: https://github.com/GreyLabsDev/PexWalls
License: MIT license
1673349420
A light-weight UITextView subclass that automatically grows and shrinks based on the size of user input and can be constrained by maximum and minimum number of lines.
To add the RSKGrowingTextView
package to your Xcode project, select File > Swift Packages > Add Package Dependency and enter the repository URL.
https://github.com/ruslanskorb/RSKGrowingTextView.git
Add the pod RSKGrowingTextView
to your Podfile.
pod 'RSKGrowingTextView'
Run pod install
from Terminal, then open your app's .xcworkspace
file to launch Xcode.
Add the ruslanskorb/RSKGrowingTextView
project to your Cartfile.
github "ruslanskorb/RSKGrowingTextView"
Run carthage update
, then follow the additional steps required to add the iOS and/or Mac frameworks into your project.
Build and run the RSKGrowingTextViewExample
project in Xcode to see RSKGrowingTextView
in action. Have fun. Figure out hooks for customization.
Ruslan Skorb
Author: ruslanskorb
Source Code: https://github.com/ruslanskorb/RSKGrowingTextView
License: Apache-2.0 license
1669367658
When we talk about data visualization tools, two names definitely pops up in our mind – Tableau and QlikView. But it has always been a dilemma which tool to choose out of the two. There has always been a silent battle between the two tools – Tableau vs QlikView. Both of these tools are in Leaders quadrant of Gartner’s magic quadrant among BI tools. Take a look at the diagram below:
In order to decide which tool to use for Data Visualization, it is very important for you to understand about both of these tools. It’s wrong to just listen to the word of mouth and just go with the majority. You can always be the better judge.
So, I will tell you all you need to know about Tableau and QlikView and you will tell me in the comment section below which tool do you think is the best and why. Fair enough? ;)
And since we are talking about data visualization tools, let’s move ahead in this Tableau vs QlikView blog and understand what is data visualization first. Then only we can observe whether these tools fit the requirements or not.
Big Data is booming!
In order for Big Data to have an enormous impact on the way information is disseminated and analyzed, data visualization plays a tremendous role. There are many organizations that find it real challenging to interpret data, and this is exactly where data visualization comes to the rescue. It is a generic term that describes an organization’s efforts to help them comprehend the significance of data by converting it into visual content. There are many important elements, including patterns and trends that often go unobserved in text-based data, but can be easily noticed with data visualization. It also helps digest information in the form of heat maps and rich graphical representations.
A picture conveys the meaning better than text. Similarly, data visualization provides access to rich visual elements that enhance the quality and ease of comprehension of the information being conveyed. Another vital benefit of data visualization is the stage at which it is employed. At this stage, the analyzed data passes on from the data scientists to business stakeholders. The latter group needs to be presented with the insights in a meaningful way so that they can understand the impact and influence of the insights. This is where data visualization comes in handy.
Therefore, it is very important to understand which is the best tool that will provide us with better solutions.
Let’s move ahead in this Tableau vs QlikView blog and compare these tools with the following parameters:
QlikView : It is easy to use and explore the hidden trends. To search, just type any word in any order into search box for instant and associative results and it will show connections and relationships across your data. It is difficult for user to design their own views due to menu driven properties.
Tableau: Its interface is simple, not filled with too many features at one page and has a drag and drop interface. It does not provide feature to search content across all your data. User can easily create their own views using various objects and it is easy because of well designed GUI interface.
QlikView: It has actively engaged community and resources to help you learn this software in the best possible manner.
Tableau: It also has actively engaged community and resources. It is a simple drag & drop application which makes it very easy to learn.
QlikView: Its personal edition is free with limitation of document sharing. Each named user license is $1,350 and $15,000 for a concurrent user. Server license is $35,000/server. Additional $21,000/server for PDF distribution service; $22,500 for SAP NetWeaver connector.
May require RAM upgrades if large numbers of concurrent users.
Tableau: Free Desktop version called “Public” that makes data is available for all to download. Private versions come with fixed fee $999 or $1,999 depending on data access. Tableau Server – anecdotal evidence says $1000/server user, with minimum of 10 users plus maintenance.
QlikView: It integrates with a very broad range of data sources like Amazon Vectorwise, EC2, and Redshift, Cloudera Hadoop and Impala, CSV, DatStax, Epicor Scala, EMC Green Plum, Hortonworks Hadoop, HP Vertica, IBM DB2, IBM Netezza, Infor Lawson, Informatica Powercenter, MicroStrategy, MS SQL Server, My SQL, ODBC, Par Accel, Sage 500, Salesforce, SAP, SAP Hana, Teradata, and many more. It can connect with R using API integration. It can connect with Big data.
Tableau: It can integrate with a broader range of data sources including spreadsheets, CSV, SQL databases, Salesforce, Cloudera Hadoop, Firebird, Google Analytics, Google BigQuery, Hortonworks Hadoop, HP Vertica, MS SQL Server, MySQL, OData, Oracle, Pivotal Greenplum, PostgreSQL, Salesforce, Teradata, and Windows Azure Marketplace. It can connect with R that powers the analytical capabilities of the tool. It can also connect with Big data sources.
QlikView: QlikView has its own data warehouse and addition of scripting feature adds more value to it. We can use multilevel layers in QlikView deployment. QlikView is easily deploy-able and configurable, and starts producing stunning reports within minutes of installation. This product does not use cubes; hence loads all the tables and charts in memory to enable interactive queries and creation of reports—a technology not found in other products. It can be developed on both 32 and 64 bit. Its associative technology makes data modeling easier.
Tableau: It does not have its own data warehouse. It can not create layers while connecting with data set. It is more easier to deploy because it requires more structured data.
QlikView: Associative technology makes it more powerful and it helps to read association between variables easily. This feature sometimes help businesses to understand hidden relation between data points.
Tableau: Story telling feature helps you to create presentation, using your available data points.
QlikView: It has good options available to visualize information. It is loaded with various objects. We can play with properties of these objects easily to customize it. We can also create custom charts like waterfall, boxplot, geo-spatial charts by customizing properties. While inserting object, it has layout and formatting options similar to theme of the document. Here, we need to work on formatting options to make it more visually appealing.
Tableau: It has good visualization objects with better formatting options. It has very good visualization for geo-spatial visualizations. It has numerous options of visualizing your data. The visualizations are always in the best quality.
QlikView: QlikView is not dependent on a device, we can easily access it from anywhere. Decision making becomes much faster compared to traditional methods.
Tableau: It is also available on all devices and can be accessed over internet. You can use Tableau on your laptop, tablet or phone.
9. Security
QlikView: It has various security options like security for Script, Document, Section Access and user authentication. Direct access to the QlikView Document using QlikView Desktop is always governed by Windows NTFS File Security. Access to the web-based QlikView Enterprise Management Console is restricted to Windows Users who are a member of a particular local Windows Group.
Tableau: Tableau has good security feature and it is highly handled by Tableau server. Tableau is a modern enterprise analytics platform that enables self-service analytics at scale through governance. Security is the first and most critical part of a data and content governance strategy. Tableau Server provides the comprehensive features and deep integration to address all aspects of enterprise security. Tableau helps organizations promote trusted data sources for all users, so the right data is used to make the right decisions quickly.
You may have heard Tableau offers better scalability than QlikView, or that QlikView can scale faster than Tableau. The truth is, both vendors can handle a huge amount of data. In fact, the majority of organizations are not producing that much of data which either solution can’t handle.
Now, let us take a look at the architecture of both the tools. This will help you identify the flexibility of both the tools.
Tableau vs QlikView: Tableau Architecture
Tableau Architecture is mostly focused on three stages : Integrating, Analyzing & Visualizing.
Tableau vs QlikView: QlikView Architecture
QlikView Architecture is based on three parts: Front End, Back End and Resources.
Let’s see how does each of these tool make visualizations:
Tableau:
QlikView:
This is how a QlikView Dashboard looks like:
The most important thing you should know that QlikView is used for data discovery rather than just visualizing the data. On the contrary, Tableau is a very powerful tool for visualization only. Now, I have mentioned the parameters and compared both the tools. To be very clear, you can use Tableau & QlikView for different purposes.
This brings us to the end of Tableau vs QlikView blog. I am sure with the above comparison you will be able to identify which tool suits you the best for your needs. I will be coming up with blogs on QlikView very soon and if you want to learn about Tableau, you can check out this blog.
If you wish to master Tableau or QlikView, Edureka has a curated course on Tableau Certification or QlikView Training & Certification which covers various concepts of data visualization in depth. It comes with 24*7 support to guide you throughout your learning period. New batches are starting soon.
Got a question for us? Please mention it in the comments section and we will get back to you at the earliest.
Original article source at: https://www.edureka.co/
1669174554
In this article, we will learn how to replace elements in Python NumPy Array. To replace elements in Python NumPy Array, We can follow the following examples.
The following code shows how to replace all elements in the NumPy array equal to 8 with a new value of 20:
#replace all elements equal to 8 with 20
my_array[my_array == 8] = 20
#view updated array
print(my_array)
[ 4 5 5 7 20 20 9 12]
The following code shows how to replace all elements in the NumPy array greater than 8 with a new value of 20:
#replace all elements greater than 8 with 20
my_array[my_array > 8] = 20
#view updated array
print(my_array)
[ 4 5 5 7 8 8 20 20]
The following code shows how to replace all elements in the NumPy array greater than 8 or less than 6 with a new value of 20:
#replace all elements greater than 8 or less than 6 with a new value of 20
my_array[(my_array > 8) | (my_array < 6)] = 20
#view updated array
print(my_array)
[20 20 20 7 8 8 20 20]
1667761980
A Sketch module for creating a complex UI with a webview. The API is mimicking the BrowserWindow API of Electron.
To use this module in your Sketch plugin you need a bundler utility like skpm and add it as a dependency:
npm install -S sketch-module-web-view
You can also use the with-webview skpm template to have a solid base to start your project with a webview:
skpm create my-plugin-name --template=skpm/with-webview
The version 2.x is only compatible with Sketch >= 51. If you need compatibility with previous versions of Sketch, use the version 1.x
import BrowserWindow from 'sketch-module-web-view'
export default function () {
const options = {
identifier: 'unique.id',
}
const browserWindow = new BrowserWindow(options)
browserWindow.loadURL(require('./my-screen.html'))
}
Author: skpm
Source Code: https://github.com/skpm/sketch-module-web-view
License: MIT license
1667103240
TL;DR UIPageViewController done properly.
Pageboy requires iOS 9 / tvOS 10; and is compatible with Swift 5.
Pageboy is compatible with Swift Package Manager and can be integrated via Xcode.
Pageboy is also available through CocoaPods:
pod 'Pageboy', '~> 3.7'
Pageboy is also available through Carthage:
github "uias/Pageboy" ~> 3.7
Create an instance of a PageboyViewController
and provide it with a PageboyViewControllerDataSource
.
class PageViewController: PageboyViewController, PageboyViewControllerDataSource {
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
}
}
Implement the PageboyViewControllerDataSource
functions.
func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
return viewControllers.count
}
func viewController(for pageboyViewController: PageboyViewController,
at index: PageboyViewController.PageIndex) -> UIViewController? {
return viewControllers[index]
}
func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
return nil
}
The delegate functions provided by a PageboyViewController
are much more reliable and useful than what a raw UIPageViewController
provides. You can use them to find out exactly where the current page is, and when it's moved, where it's headed.
About to embark on a transition to a new page.
func pageboyViewController(_ pageboyViewController: PageboyViewController,
willScrollToPageAt index: Int,
direction: PageboyViewController.NavigationDirection,
animated: Bool)
Scrolled to a relative position along the way transitioning to a new page.
func pageboyViewController(_ pageboyViewController: PageboyViewController,
didScrollTo position: CGPoint,
direction: PageboyViewController.NavigationDirection,
animated: Bool)
Successfully completed a scroll transition to a page.
func pageboyViewController(_ pageboyViewController: PageboyViewController,
didScrollToPageAt index: Int,
direction: PageboyViewController.NavigationDirection,
animated: Bool)
Child view controllers have been reloaded.
func pageboyViewController(_ pageboyViewController: PageboyViewController,
didReloadWith currentViewController: UIViewController,
currentPageIndex: PageIndex)
You can navigate programmatically through a PageboyViewController
using scrollToPage()
:
pageViewController.scrollToPage(.next, animated: true)
.isInfiniteScrollEnabled
..isScrollEnabled
.Pageboy provides the ability to insert and delete pages dynamically in the PageboyViewController
.
func insertPage(at index: PageIndex, then updateBehavior: PageUpdateBehavior)
func deletePage(at index: PageIndex, then updateBehavior: PageUpdateBehavior)
This behaves similarly to the insertion of rows in UITableView
, in the fact that you have to update the data source prior to calling any of the update functions.
Example:
let index = 2
viewControllers.insert(UIViewController(), at: index)
pageViewController.insertPage(at: index)
The default behavior after inserting or deleting a page is to scroll to the update location, this however can be configured by passing a PageUpdateBehavior
value other than .scrollToUpdate
.
reloadData()
- Reload the view controllers in the page view controller. (Reloads the data source)..navigationOrientation
- Whether to orientate the pages horizontally or vertically..currentViewController
- The currently visible view controller if it exists..currentPosition
- The exact current relative position of the page view controller..currentIndex
- The index of the currently visible page..parentPageboy
- Access the immediate parent PageboyViewController
from any child view controller.Pageboy also provides custom transition support for animated transitions. This can be customized via the .transition
property on PageboyViewController
.
pageboyViewController.transition = Transition(style: .push, duration: 1.0)
Note: By default this is set to nil
, which uses the standard animation provided by UIPageViewController
.
PageboyAutoScroller
is available to set up timer based automatic scrolling of the PageboyViewController
:
pageboyViewController.autoScroller.enable()
Support for custom intermission duration and other scroll behaviors is also available.
Bug reports and pull requests are welcome on GitHub at https://github.com/uias/Pageboy.
Author: uias
Source Code: https://github.com/uias/Pageboy
License: MIT license
1666739580
Transition is a library that helps you build iOS view controller transitions. Implementing a nice interactive custom view controller transition involves quite a number of components. You have to implement the correct delegates, handle the switching between passive animation and active interaction phases, ensure the timing is right, think of interruption and cancellation, keep responsibilities separated... It quickly gets messy! This is where Transition helps you out: you just define the animation and the interaction, Transition ties it all together.
In short:
There are several examples (which can be found in Examples/
):
UITabBarController
transition animations with custom interaction.To run an example project, clone the repo, navigate to one of these example directories, and run pod install
from that directory first.
The AnimationLayer
is the most essential part of setting up a transition; without it, there'll be no animation. An AnimationLayer
is a simple struct that takes two arguments:
1. Animation function
This is a simple closure with the signature () -> Void
. In this closure you define your animation, just as you would with a UIView
or UIViewPropertyAnimator
animation. For each AnimationLayer
, Transition will instantiate a UIViewPropertyAnimator
, passing it your animation block.
2. TimingParameters
This defines the timing of your animation. It must be a UITimingCurveProvider
, such as an instance of UICubicTimingParameters
or UISpringTimingParameters
.
(3. AnimationRange)
Additionally, you can set an AnimationRange
, which by default is set to AnimationRange.full
. This range defines the start and end point (as fractions of the total transition animation duration) between which your AnimationLayer
's animation will run.
You create your AnimationLayer
as follows:
let animationLayer = AnimationLayer(timingParameters: UICubicTimingParameters(animationCurve: .easeOut)
animation: { topView?.transform = targetTransform })
😦 ... Hey, wait! Where do that topView
and targetTransform
come from?
Your AnimationLayer
is defined as a part of your TransitionAnimation
. This represents all (non-interactive) animation during a transition. The TransitionAnimation
protocol exposes an array of AnimationLayers
. Additionally it contains two functions; one for setup and one for completion. Before starting animation, your setup function will be called, passing you the transitioningContext that among others contains the fromView
and toView
in the transition. The completion function is called when the entire transition completes, allowing you to clean up any temporary views added in the setup.
class SimpleAnimation : TransitionAnimation {
private weak var topView: UIView?
private var targetTransform: CGAffineTransform = .identity
func setup(in operationContext: TransitionOperationContext) {
let context = operationContext.context
let isPresenting = operationContext.operation.isPresenting
// We have to add the toView to the transitionContext, at the appropriate index:
if isPresenting {
context.containerView.addSubview(context.toView)
} else {
context.containerView.insertSubview(context.toView, at: 0)
}
context.toView.frame = context.finalFrame(for: context.toViewController)
// We only animate the view that will be on top:
topView = isPresenting ? context.toView : context.fromView
let hiddenTransform = CGAffineTransform(translationX: 0, y: -context.containerView.bounds.height)
topView?.transform = isPresenting ? hiddenTransform : .identity
targetTransform = isPresenting ? .identity : hiddenTransform
}
var layers: [AnimationLayer] {
return [AnimationLayer(timingParameters: AnimationTimingParameters(animationCurve: .easeOut), animation: animate)]
}
func animate() {
topView?.transform = targetTransform
}
func completion(position: UIViewAnimatingPosition) {}
}
🤔 ... But what about duration?
You just defined the animation of your transition. You now create a Transition
struct that has an animation
part (your TransitionAnimation
) and an optional sharedElement
part, which you can see implemented in the Modal and Navigation examples. And the Transition
has a duration!
let transition = Transition(duration: 2.0, animation: SimpleAnimation())
😬 ... And where do I put that transition?
Almost there. Say you want to use this transition for UINavigationController
transitions. Let's make a convenience object that isolates transition-related functionality for a navigationController:
class MyNavigationTransitions {
let transitionController: TransitionController
let transitionsSource = MyNavigationTransitionSource()
init(navigationController: UINavigationController) {
transitionController = TransitionController(forTransitionsIn: navigationController, transitionsSource: transitionsSource)
}
}
class MyNavigationTransitionSource : TransitionsSource {
func transitionFor(operationContext: TransitionOperationContext, interactionController: TransitionInteractionController?) -> Transition {
return Transition(duration: 0.5, animation: SimpleAnimation())
}
}
The TransitionController
takes responsibility for animating transitions in the given navigationController, using an external TransitionsSource
to provide operation-specific transitions (the operation – in this case push or pop – can be obtained from the TransitionOperationContext
). This means you can return different transition animations for push and pop. You can also provide a single animation that behaves differently depending on the operation (see the SimpleAnimation
).
Now, initialize your MyNavigationTransitions
, passing it your navigationController.
🤓 ... Is that it?
Yes!
😎
At least, for custom view controller transition animations. There's a lot more that'll help you set up a custom interaction gesture and a shared element that can move between the transitioning views.
The above steps are implemented in the SimpleExample
that can be found in the Examples/
directory.
Transition is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'Transition'
If you have any suggestions, please get in touch with us. Feel free to fork and submit pull requests. Also, we're Dutch, so if any naming is odd, might be improved or is just plain inappropriate, let us know!
UIPresentationController
support (it's there, but it doesn't animate properly...)Author: Touchwonders
Source Code: https://github.com/Touchwonders/Transition
License: MIT license
1666180920
TOCropViewController
is an open-source UIViewController
subclass to crop out sections of UIImage
objects, as well as perform basic rotations. It is excellent for things like editing profile pictures, or sharing parts of a photo online. It has been designed with the iOS Photos app editor in mind, and as such, behaves in a way that should already feel familiar to users of iOS.
For Swift developers, CropViewController
is a Swift wrapper that completely encapsulates TOCropViewController
and provides a much more native, Swiftier interface.
UIActivityViewController
.iOS 8.0 or above
CocoaPods
Add the following to your Podfile:
pod 'TOCropViewController'
Add the following to your Podfile:
pod 'CropViewController'
Swift Package Manager
Add the following to your Package.swift
:
dependencies: [
// ...
.package(url: "https://github.com/TimOliver/TOCropViewController.git"),
],
Carthage
Add the following to your Cartfile:
github "TimOliver/TOCropViewController"
Run carthage update
From the Carthage/Build
folder, import one of the two frameworks into your Xcode project. For Objective-C projects, import just TOCropViewController.framework
and for Swift, import CropViewController.framework
instead. Each framework is separate; you do not need to import both.
Follow the remaining steps on Getting Started with Carthage to finish integrating the framework.
Manual Installation
All of the necessary source and resource files for TOCropViewController
are in Objective-C/TOCropViewController
, and all of the necessary Swift files are in Swift/CropViewController
.
For Objective-C projects, copy just the TOCropViewController
directory to your Xcode project. For Swift projects, copy both TOCropViewController
and CropViewController
to your project.
Using TOCropViewController
is very straightforward. Simply create a new instance passing the UIImage
object you wish to crop, and then present it modally on the screen.
While TOCropViewController
prefers to be presented modally, it can also be pushed to a UINavigationController
stack.
For a complete working example, check out the sample apps included in this repo.
Basic Implementation
func presentCropViewController() {
let image: UIImage = ... //Load an image
let cropViewController = CropViewController(image: image)
cropViewController.delegate = self
present(cropViewController, animated: true, completion: nil)
}
func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
// 'image' is the newly cropped version of the original image
}
- (void)presentCropViewController
{
UIImage *image = ...; // Load an image
TOCropViewController *cropViewController = [[TOCropViewController alloc] initWithImage:image];
cropViewController.delegate = self;
[self presentViewController:cropViewController animated:YES completion:nil];
}
- (void)cropViewController:(TOCropViewController *)cropViewController didCropToImage:(UIImage *)image withRect:(CGRect)cropRect angle:(NSInteger)angle
{
// 'image' is the newly cropped version of the original image
}
Similar to many UIKit
UIViewController
subclasses, like MFMailComposeViewController
, the class responsible for presenting view controller should also take care of dismissing it upon cancellation. To dismiss TOCropViewController
, implement the cropViewController:didFinishCancelled:
delegate method, and call dismissViewController:animated:
from there.
Making a Circular Cropped Image
func presentCropViewController() {
var image: UIImage? // Load an image
let cropViewController = CropViewController(croppingStyle: .circular, image: image)
cropViewController.delegate = self
self.present(cropViewController, animated: true, completion: nil)
}
func cropViewController(_ cropViewController: TOCropViewController?, didCropToCircularImage image: UIImage?, with cropRect: CGRect, angle: Int) {
// 'image' is the newly cropped, circular version of the original image
}
- (void)presentCropViewController
{
UIImage *image = ...; // Load an image
TOCropViewController *cropViewController = [[TOCropViewController alloc] initWithCroppingStyle:TOCropViewCroppingStyleCircular image:image];
cropViewController.delegate = self;
[self presentViewController:cropViewController animated:YES completion:nil];
}
- (void)cropViewController:(TOCropViewController *)cropViewController didCropToCircularImage:(UIImage *)image withRect:(CGRect)cropRect angle:(NSInteger)angle
{
// 'image' is the newly cropped, circular version of the original image
}
Sharing Cropped Images Via a Share Sheet
func presentCropViewController() {
var image: UIImage? // Load an image
let cropViewController = CropViewController(image: image)
cropViewController.showActivitySheetOnDone = true
self.present(cropViewController, animated: true, completion: nil)
}
- (void)presentCropViewController
{
UIImage *image = ...; // Load an image
TOCropViewController *cropViewController = [[TOCropViewController alloc] initWithImage:image];
cropViewController.showActivitySheetOnDone = YES;
[self presentViewController:cropViewController animated:YES completion:nil];
}
Presenting With a Custom Animation
Optionally, TOCropViewController
also supports a custom presentation animation where an already-visible copy of the image will zoom in to fill the screen.
func presentCropViewController() {
var image: UIImage? // Load an image
var imageView = UIImageView(image: image)
var frame: CGRect = view.convert(imageView.frame, to: view)
let cropViewController = CropViewController(image: image)
cropViewController.delegate = self
self.present(cropViewController, animated: true, completion: nil)
cropViewController.presentAnimated(fromParentViewController: self, fromFrame: frame, completion: nil)
}
- (void)presentCropViewController
{
UIImage *image = ...;
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect frame = [self.view convertRect:imageView.frame toView:self.view];
TOCropViewController *cropViewController = [[TOCropViewController alloc] initWithImage:image];
cropViewController.delegate = self;
[self presentViewController:cropViewController animated:YES completion:nil];
[cropViewController presentAnimatedFromParentViewController:self fromFrame:frame completion:nil];
}
TOCropViewController
While traditional cropping UI implementations will usually just have a dimming view with a square hole cut out of the middle, TOCropViewController
goes about its implementation a little differently.
Since there are two views that are overlaid over the image (A dimming view and a translucency view), trying to cut a hole open in both of them would be rather complex. Instead, an image view is placed in a scroll view in the background, and a copy of the image view is placed on top, inside a container view that is clipped to the designated cropping size. The size and position of the foreground image is then made to match the background view, creating the illusion that there is a hole in the dimming views, and minimising the number of views onscreen.
TOCropViewController
was originally created by Tim Oliver as a component for iComics, a comic reader app for iOS.
Thanks also goes to TOCropViewController
's growing list of contributors!
iOS Device mockups used in the screenshot created by Pixeden.
Author: TimOliver
Source Code: https://github.com/TimOliver/TOCropViewController
License: MIT license
1666160100
Swift package for displaying charts effortlessly.
V2 focuses on providing a strong and easy to use base, on which you can build your beautiful custom charts. It provides basic building blocks, like a chart view (bar, pie, line and ring chart), grid view, card view, interactive label for displaying the curent chart value. So you decide, whether you build a fully fledged interactive view, or just display a bare bone chart
How to install SwiftUI ChartView
How to create your first chart
It supports:
Join our Slack channel for day to day conversation and more insights:
It requires iOS 13 and Xcode 11!
In Xcode go to File -> Swift Packages -> Add Package Dependency
and paste in the repo's url: https://github.com/AppPear/ChartView
import the package in the file you would like to use it: import SwiftUICharts
You can display a Chart by adding a chart view to your parent view:
Added an example project, with iOS, watchOS target: https://github.com/AppPear/ChartViewDemo
LineChartView with multiple lines! First release of this feature, interaction is disabled for now, I'll figure it out how could be the best to interact with multiple lines with a single touch.
Usage:
MultiLineChartView(data: [([8,32,11,23,40,28], GradientColors.green), ([90,99,78,111,70,60,77], GradientColors.purple), ([34,56,72,38,43,100,50], GradientColors.orngPink)], title: "Title")
Gradient colors are now under the GradientColor
struct you can create your own gradient by GradientColor(start: Color, end: Color)
Available preset gradients:
Full screen view called LineView!!!
LineView(data: [8,23,54,32,12,37,7,23,43], title: "Line chart", legend: "Full screen") // legend is optional, use optional .padding()
Adopts to dark mode automatically
You can add your custom darkmode style by specifying:
let myCustomStyle = ChartStyle(...)
let myCutsomDarkModeStyle = ChartStyle(...)
myCustomStyle.darkModeStyle = myCutsomDarkModeStyle
Line chart is interactive, so you can drag across to reveal the data points
You can add a line chart with the following code:
LineChartView(data: [8,23,54,32,12,37,7,23,43], title: "Title", legend: "Legendary") // legend is optional
Turn drop shadow off by adding to the Initialiser: dropShadow: false
[New feature] you can display labels also along values and points for each bar to descirbe your data better! Bar chart is interactive, so you can drag across to reveal the data points
You can add a bar chart with the following code:
Labels and points:
BarChartView(data: ChartData(values: [("2018 Q4",63150), ("2019 Q1",50900), ("2019 Q2",77550), ("2019 Q3",79600), ("2019 Q4",92550)]), title: "Sales", legend: "Quarterly") // legend is optional
Only points:
BarChartView(data: ChartData(points: [8,23,54,32,12,37,7,23,43]), title: "Title", legend: "Legendary") // legend is optional
ChartData structure Stores values in data pairs (actually tuple): (String,Double)
You can initialise ChartData multiple ways:
ChartData(points: [8,23,54,32,12,37,7,23,43])
ChartData(points: [2.34,3.14,4.56])
ChartData(values: [("2018 Q4",63150), ("2019 Q1",50900)])
You can add different formats:
ChartForm.small
ChartForm.medium
ChartForm.large
BarChartView(data: ChartData(points: [8,23,54,32,12,37,7,23,43]), title: "Title", form: ChartForm.small)
For floating point numbers, you can set a custom specifier:
BarChartView(data: ChartData(points:[1.23,2.43,3.37]) ,title: "A", valueSpecifier: "%.2f")
For integers you can disable by passing: valueSpecifier: "%.0f"
You can set your custom image in the upper right corner by passing in the initialiser: cornerImage:Image(systemName: "waveform.path.ecg")
Turn drop shadow off by adding to the Initialiser: dropShadow: false
Customizable:
let chartStyle = ChartStyle(backgroundColor: Color.black, accentColor: Colors.OrangeStart, secondGradientColor: Colors.OrangeEnd, chartFormSize: ChartForm.medium, textColor: Color.white, legendTextColor: Color.white )
...
BarChartView(data: [8,23,54,32,12,37,7,23,43], title: "Title", style: chartStyle)
You can access built-in styles:
BarChartView(data: [8,23,54,32,12,37,7,23,43], title: "Title", style: Styles.barChartMidnightGreen)
ChartForm
.small
.medium
.large
.detail
BarChartView(data: [8,23,54,32,12,37,7,23,43], title: "Title", form: ChartForm.small)
If you want to animate back movement after completing your gesture, you set animatedToBack
as true
.
You can add a pie chart with the following code:
PieChartView(data: [8,23,54,32], title: "Title", legend: "Legendary") // legend is optional
Turn drop shadow off by adding to the Initialiser: dropShadow: false
Author: AppPear
Source Code: https://github.com/AppPear/ChartView
License: MIT license
1665776760
A Julia package to explore a new system of array views.
By and large, this package is no longer necessary: base julia now has efficient SubArrays
(i.e., sub
and slice
). In choosing whether to use SubArray
s or the ArrayView
s package, here are some considerations:
Reasons to prefer SubArrays
:
ArrayViews
can only make a view of an Array
, whereas SubArray
s can create a view of any AbstractArray
.
The views created by ArrayViews
are most efficient for ContiguousView
s such as column slices. In contrast, the views created by SubArray
s are efficient for any type of view (e.g., also row slices), in some cases resulting in a 3- to 10-fold advantage. In either case, it's generally recommended to write functions using cartesian indexing rather than linear indexing (e.g., for I in eachindex(S)
rather than for i = 1:length(S)
), although in both cases there are some view types that are also efficient under linear indexing.
SubArray
s allow more general slicing behavior, e.g., you can make a view with S = sub(A, [1,3,17], :)
.
By default, SubArray
s check bounds upon construction whereas ArrayView
s do not: V = view(A, -5:10, :)
does not generate an error, and if V
is used in a function with an @inbounds
declaration you are likely to get a segfault. (You can bypass bounds checking with Base._sub
and Base._slice
, in cases where you want out-of-bounds construction for SubArray
s.)
Reasons to prefer ArrayViews
:
SubArray
s is frequently (but not always) 2-4 times slower than construction of view
s. If you are constructing many column views, ArrayView
s may still be the better choice.aview
function that implements array viewsaview
composition (i.e. construct views over views)The key function in this package is aview
. This function is similar to sub
in Julia Base, except that it returns an aview instance with more efficient representation:
a = rand(4, 5, 6)
aview(a, :)
aview(a, :, 2)
aview(a, 1:2, 1:2:5, 4)
aview(a, 2, :, 3:6)
The aview
function returns an array view of type ArrayView
. Here, ArrayView
is an abstract type with two derived types (ContiguousView
and StridedView
), defined as:
abstract type ArrayView{T,N,M} <: DenseArray{T,N} end
We can see that each view type has three static properties: element type T
, the number of dimensions N
, and the contiguous rank M
.
The contiguous rank plays an important role in determining (statically) the contiguousness of a subview. Below are illustrations of 2D views respective with contiguous rank 0
, 1
, and 2
.
2D View with contiguous rank 0
* * * * * *
. . . . . .
* * * * * *
. . . . . .
* * * * * *
. . . . . .
Here, *
indicates a position covered by the array view, and .
otherwise. We can see that the columns are not contiguous.
2D View with contiguous rank 1
* * * * * *
* * * * * *
* * * * * *
* * * * * *
. . . . . .
. . . . . .
We can see that each column is contiguous, while the entire array view is not.
2D View with contiguous rank 2
* * * * * *
* * * * * *
* * * * * *
* * * * * *
* * * * * *
* * * * * *
The entire 2D array view is contiguous.
Formally, when v
is an array view with contiguous rank M
, then aview(v, :, :, ..., :, 1)
must be contiguous when the number of colons is less than or equal to M
.
The package provide a hierarchy of array view types (defined as follows):
# T: the element type
# N: the number of dimensions
# M: the contiguous rank
abstract StridedArrayView{T,N,M} <: DenseArray{T,N}
abstract ArrayView{T,N,M} <: StridedArrayView{T,N,M}
abstract UnsafeArrayView{T,N,M} <: StridedArrayView{T,N,M}
immutable ContiguousView{T,N,Arr<:Array} <: ArrayView{T,N,N}
immutable StridedView{T,N,M,Arr<:Array} <: ArrayView{T,N,M}
immutable UnsafeContiguousView{T,N} <: UnsafeArrayView{T,N,N}
immutable UnsafeStridedView{T,N,M} <: UnsafeArrayView{T,N,M}
Here, an instance of ArrayView
maintains a reference to the underlying array, and is generally safe to use in most cases. An instance of UnsafeArrayView
maintains a raw pointer, and should only be used within a local scope (as it does not guarantee that the source array remains valid if it is passed out of a function).
The following example illustrates how contiguous rank is used to determine aview types in practice.
a = rand(m, n)
# safe views
v0 = aview(a, :) # of type ContiguousView{Float64, 1}
u1 = aview(a, a:b, :) # of type StridedView{Float64, 2, 1}
u2 = aview(u1, :, i) # of type ContiguousView{Float64, 1}
v1 = aview(a, a:2:b, :) # of type StridedView{Float64, 2, 0}
v2 = aview(v1, :, i) # of type StridedView{Float64, 1, 0}
# unsafe views
v0 = unsafe_aview(a, :) # of type UnsafeContiguousView{Float64, 1}
u1 = unsafe_aview(a, a:b, :) # of type UnsafeStridedView{Float64, 2, 1}
u2 = unsafe_aview(u1, :, i) # of type UnsafeContiguousView{Float64, 1}
v1 = unsafe_aview(a, a:2:b, :) # of type UnsafeStridedView{Float64, 2, 0}
v2 = unsafe_aview(v1, :, i) # of type UnsafeStridedView{Float64, 1, 0}
Four kinds of indexers are supported, integer, range (e.g. a:b
), stepped range (e.g. a:b:c
), and colon (i.e., :
).
The procedure of constructing a aview consists of several steps:
Compute the shape of an array view. This is done by an internal function vshape
.
Compute the offset of an array view. This is done by an internal function aoffset
. The computation is based on the following formula:
offset(v(I1, I2, ..., Im)) = (first(I1) - 1) * stride(v, 1)
+ (first(I2) - 1) * stride(v, 2)
+ ...
+ (first(Im) - 1) * stride(v, m)
Compute the contiguous rank, based on both view shape and the combination of indexer types. A type ContRank{M}
is introduced for static computation of contiguous rank (please refer to src/contrank.jl
for details).
Construct a aview, where the array view type is determined by both the number of dimensions and the value of contiguous rank (which is determined statically).
For runtime efficiency, specialized methods of these functions are implemented for views of 1D, 2D, and 3D. These methods are extensively tested.
The ArrayViews package provides several functions to make it more convenient to constructing certain views:
diagview(a) # make a strided view of the diagonal elements, the length is `min(size(a)...)`
# `a` needs to be a matrix here (contiguous or strided)
flatten_view(a) # make a contiguous view of `a` as a vector
# `a` needs to be contiguous here
reshape_view(a, shp) # make a contiguous view of `a` of shape `shp`
# `a` needs to be contiguous here.
rowvec_view(a, i) # make a view of `a[i,:]` as a strided vector.
# `a` needs to be a matrix here (contiguous or strided)
ellipview(a, i) # make a view of the i-th slice of a
# e.g. `a` is a matrix => this is equiv. to `aview(a, :, i)`
# `a` is a cube => this is equiv. to `aview(a, :, :, i)`, etc.
Author: JuliaArrays
Source Code: https://github.com/JuliaArrays/ArrayViews.jl
License: MIT license
1665551280
Animate Shiny and R Markdown content when it comes into view
The package aniview
allows to animate Shiny and R Markdown content when it comes into view using animate-css thanks to AniView.
Install the released version from CRAN.
install.packages("aniview")
To get a bug fix, or use a feature from the development version, you can install it from GitHub.
# install.packages("remotes")
remotes::install_github("lgnbhl/aniview")
In order to use aniview, you must first call use_aniview()
in the UI.
Then simply apply aniview()
to any shiny element with an animation listed on the animate-css website.
Here a basic example:
library(shiny)
library(tidyverse)
library(ggrepel)
library(aniview)
shinyApp(
ui = fluidPage(
align = "center",
aniview::use_aniview(), # add use_aniview() in the UI
aniview(h1("Shiny with AniView"), animation = "fadeInUp"),
HTML(rep("↓<br/><br/><br/><br/>scroll down<br/><br/>", 10)),
aniview(plotOutput("plot"), animation = "slideInLeft"),
br()
),
server = function(input, output){
output$plot <- renderPlot({
ggplot(starwars, aes(mass, height)) +
geom_point(aes(color = gender)) +
geom_label_repel(aes(label = name), size = 3) +
labs(title = "Star Wars Characters Height vs Mass")
})
}
)
The function aniview()
doesn’t work directly with htmlwidgets.
The solution is to put the htmlwidget inside a container and animate it.
Below an example animating the box()
from shinydashboard
in order to use plotly
.
library(shiny)
library(shinydashboard)
library(plotly)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
dashboardSidebar(),
dashboardBody(
use_aniview(), # use_aniview() should be inside the body element
fluidRow(
aniview(box(plotlyOutput("plotly")), animation = "slideInLeft"),
)
)
)
server <- function(input, output) {
output$plotly <- renderPlotly({
gg <- ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point()
ggplotly(gg)
})
}
shinyApp(ui, server)
To animate a element of a R Markdown document, you must first call use_aniview()
inside a R code chunk with {r, echo = FALSE}
so the code will not be shown in the final document.
```{r, echo = FALSE}
aniview::use_aniview()
```
Then you can animate any content of your R Markdown document using the :::
markers of the rmarkdown
package followed by {.aniview data-av-animation="ANIMATE-CSS EFFECT"}
. The animate-css effects are listed here.
Below an example with the “slideInUp” effect.
::: {.aniview data-av-animation="slideInUp"}
This element will be animated.
:::
You can learn more about the CSS class markers in the Custom block chapter of the R Markdown Cookbook from Yihui Xie.
xaringan is a package for creating slideshows with remark.js using R Markdown. You can take a look at its introductory presentation.
You can easily animate a slide using the “animated” class of animate-css with any animation effect.
Below is a minimal example.
---
title: "Presentation Ninja"
subtitle: "with xaringan"
output:
xaringan::moon_reader:
lib_dir: libs
---
```{r, echo = FALSE}
aniview::use_aniview()
```
# A normal slide
---
class: animated, bounceInDown
# An animated slide
Author: lgnbhl
Source Code: https://github.com/lgnbhl/aniview
License: View license
1665377181
mapview provides functions to very quickly and conveniently create interactive visualisations of spatial data. It’s main goal is to fill the gap of quick (not presentation grade) interactive plotting to examine and visually investigate both aspects of spatial data, the geometries and their attributes. It can also be considered a data-driven API for the leaflet package as it will automatically render correct map types, depending on the type of the data (points, lines, polygons, raster). In addition, it makes use of some advanced rendering functionality that will enable viewing of much larger data than is possible with leaflet. Furthermore, if you’re a fan of mapdeck (which you should!), you can choose to use it as the rendering platform instead of leaflet by setting mapviewOptions(platform = "mapdeck")
.
The main user relevant functions are:
mapview
- view (multiple) spatial objects on a set of background mapsviewExtent
- view extent / bounding box of spatial objectsviewRGB
- view RGB true- or false-color images of raster objectsmapshot
- easily save maps (including leaflet maps) as html
and/or png
(or other image formats)Functions that have been deprecated/deleted recently:
addHomeButton
- deprecated, use package leafem instead.addLogo
- deprecated, use package leafem instead.addFeatures
- deprecated, use package leafem instead.addMouseCoordinates
- deprecated, use package leafem instead.addExtent
- deprecated, use package leafem instead.addImageQuery
- deprecated, use package leafem instead.latticeView
& sync
- deprecated, use package leafsync instead.slideView
- deprecated, use package slideview instead.cubeView
- deprecated, use package cubeview instead.plainview
- deprecated, use package plainview instead.popupTable
, popupGraph
& popupImage
- deprecated, use package leafpop instead.addLargeFeatures
- use leafgl::addGL*
functions instead.Objects of the following spatial classes are supported:
For CRAN release version of mapview use
install.packages("mapview")
To install the development version you can install the remotes package.
NOTE: As of version 2.9.1 development will happen on the master
branch. Please consider the develop
branch obsolete.
remotes::install_github("r-spatial/mapview")
The most basic call
mapview(breweries)
will produce a web map visualisation of the breweries data with the following components:
Please file bug reports and feature requests at https://github.com/r-spatial/mapview/issues
Author: r-spatial
Source Code: https://github.com/r-spatial/mapview
License: GPL-3.0 license