GithubHelp home page GithubHelp logo

krausefx / tsmessages Goto Github PK

View Code? Open in Web Editor NEW
4.9K 156.0 724.0 942 KB

๐Ÿ’Œ Easy to use and customizable messages/notifications for iOS ร  la Tweetbot

Home Page: http://krausefx.com

License: MIT License

Ruby 2.76% Objective-C 97.24%
notifications tsmessages objective-c cocoapods ios library

tsmessages's Introduction

Notice: TSMessages is no longer being maintained/updated. We recommend everyone migrate to RMessage.

This repository will be kept as is for those who want to continue using TSMessages or are in the process of migrating. If an issue you submitted to TSMessages still applies to RMessage feel free to create a new issue in RMessage's repository.

If your project is Swift based, you might want to check out SwiftMessages, which offers the same features, but is written completely in Swift.

TSMessages

This library provides an easy to use class to show little notification views on the top of the screen. (ร  la Tweetbot).

Twitter: @KauseFx Version License Platform

The notification moves from the top of the screen underneath the navigation bar and stays there for a few seconds, depending on the length of the displayed text. To dismiss a notification before the time runs out, the user can swipe it to the top or just tap it.

There are 4 different types already set up for you: Success, Error, Warning, Message (take a look at the screenshots)

It is very easy to add new notification types with a different design. Add the new type to the notificationType enum, add the needed design properties to the configuration file and set the name of the theme (used in the config file and images) in TSMessagesView.m inside the switch case.

Take a look at the Example project to see how to use this library. You have to open the workspace, not the project file, since the Example project uses cocoapods.

Get in contact with the developer on Twitter: KrauseFx (Felix Krause)

Screenshots

Installation

From CocoaPods

TSMessages is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "TSMessages"

Manually

Copy the source files TSMessageView and TSMessage into your project. Also copy the TSMessagesDesignDefault.json.

Usage

To show notifications use the following code:

    [TSMessage showNotificationWithTitle:@"Your Title"
                                subtitle:@"A description"
                                    type:TSMessageNotificationTypeError];


    // Add a button inside the message
    [TSMessage showNotificationInViewController:self
                                          title:@"Update available"
                                       subtitle:@"Please update the app"
                                          image:nil
                                           type:TSMessageNotificationTypeMessage
                                       duration:TSMessageNotificationDurationAutomatic
                                       callback:nil
                                    buttonTitle:@"Update"
                                 buttonCallback:^{
                                     NSLog(@"User tapped the button");
                                 }
                                     atPosition:TSMessageNotificationPositionTop
                           canBeDismissedByUser:YES];


    // Use a custom design file
    [TSMessage addCustomDesignFromFileWithName:@"AlternativeDesign.json"];

You can define a default view controller in which the notifications should be displayed:

   [TSMessage setDefaultViewController:myNavController];

You can define a default view controller in which the notifications should be displayed:

   [TSMessage setDelegate:self];
   
   ...
   
   - (CGFloat)messageLocationOfMessageView:(TSMessageView *)messageView
   {
    return messageView.viewController...; // any calculation here
   }

You can customize a message view, right before it's displayed, like setting an alpha value, or adding a custom subview

   [TSMessage setDelegate:self];
   
   ...
   
   - (void)customizeMessageView:(TSMessageView *)messageView
   {
      messageView.alpha = 0.4;
      [messageView addSubview:...];
   }

You can customize message view elements using UIAppearance

#import <TSMessages/TSMessageView.h>
@implementation TSAppDelegate
....

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//If you want you can overidde some properties using UIAppearance
[[TSMessageView appearance] setTitleFont:[UIFont boldSystemFontOfSize:6]];
[[TSMessageView appearance] setTitleTextColor:[UIColor redColor]];
[[TSMessageView appearance] setContentFont:[UIFont boldSystemFontOfSize:10]];
[[TSMessageView appearance]setContentTextColor:[UIColor greenColor]];
[[TSMessageView appearance]setErrorIcon:[UIImage imageNamed:@"NotificationButtonBackground"]];
[[TSMessageView appearance]setSuccessIcon:[UIImage imageNamed:@"NotificationButtonBackground"]];
[[TSMessageView appearance]setMessageIcon:[UIImage imageNamed:@"NotificationButtonBackground"]];
[[TSMessageView appearance]setWarningIcon:[UIImage imageNamed:@"NotificationButtonBackground"]];
//End of override

return YES;
}

The following properties can be set when creating a new notification:

  • viewController: The view controller to show the notification in. This might be the navigation controller.
  • title: The title of the notification view
  • subtitle: The text that is displayed underneath the title (optional)
  • image: A custom icon image that is used instead of the default one (optional)
  • type: The notification type (Message, Warning, Error, Success)
  • duration: The duration the notification should be displayed
  • callback: The block that should be executed, when the user dismissed the message by tapping on it or swiping it to the top.

Except the title and the notification type, all of the listed values are optional

If you don't want a detailed description (the text underneath the title) you don't need to set one. The notification will automatically resize itself properly.

License

TSMessages is available under the MIT license. See the LICENSE file for more information.

Recent Changes

Can be found in the releases section of this repo.

tsmessages's People

Contributors

adlai-holler avatar al-little avatar dennisreimann avatar diogomaximo avatar dwarfland avatar fawkeswei avatar grichards-trulia avatar hamin avatar hannesoid avatar interstateone avatar jcarbaugh avatar jercik avatar khramtsoff avatar koraktor avatar krausefx avatar lasserafn avatar mbaranowski avatar mrs- avatar muesliq avatar myell0w avatar nicked avatar onato avatar paweljankowski avatar readmecritic avatar rileytestut avatar runmad avatar shayanzadeh avatar srekke avatar toco avatar wangyandongnx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tsmessages's Issues

Notification on scrollview controller

Hi,

If we show notification on a controller that has scrollbar, it will show on the top of the view instead on the top of the viewport.

Let's say if we have a long form that exceed the viewport (scrollbar shown) and the submit button on the bottom of the form, when user tap submit, the show notification won't be shown to the user since it's viewport origin y not zero anymore.

Hope you understand what i mean.

If you implement this, please make sure, when the user scroll (ex: scroll to the top) the notification will also follow the viewport (so it's stays on the top of the viewport even though the scroll happened and viewport frame changed).

Thank you

How to override notificationDesign ?

Hi,
There doesn't seem to be any simple way to customize either the design.json file, or the notificationDictionary in a maintainable way when importing TSMessages as a cocoapod, or am I missing something?

The podspec includes the design.json file in the Pods project, and there doesn't seem to be an easy way to override that by the project using the pod. TSDesignFileName is a local define, and notificationDictionary is a local static in TSMessageView.m, so also no easy way to override by a subclass or otherwise.

Please let me know if there is an easier way to customize the design dictionary. My next option is to fork TSMessages and submit a pull request that implements this for your consideration.

Thanks for all your work on TSMessages, I find it very useful.

  • Matt B.

Callback block not executed

Hi Felix,

on calling +showNotificationInViewController:withTitle:withMessage:withType:withDuration:withCallback: and setting a callback block, the message will dismiss after the specified duration, but the callback block is never executed.

Crash on `fadeOutNotification`

I have seen a crash occur a number of times on the removeObjectAtIndex NSMutableArray method called in fadeOutNotification.

It seems only to crash when there is more than one TSMessage queued to be shown on screen. It may happen when I tap a notification to dismiss it while it is already fading out.

Here is an example crash log showing this.

Different behaviours in iOS 6 & iOS7

I am showing TSMessage in view controller pushed in UINavigationController.
I am showing TSMessage using below code
-(void)showPopUpFromBottomWithTitle:(NSString_)title andMessage:(NSString_)message
{
[TSMessage showNotificationInViewController:self title:title subtitle:message image:nil type:TSMessageNotificationTypeSuccess duration:15 callback:nil buttonTitle:nil buttonCallback:nil atPosition:TSMessageNotificationPositionTop canBeDismisedByUser:YES];
}

But I am getting different behaviours in iOS 6 & iOS7 as shown below

  1. Why I am getting space between bottom of screen & alert if position is bottom ?
  2. Why can't I see background color (green) in case of iOS7 ?

iOS 6 top
ios6_top
iOS 6 bottom
ios6_bottom

iOS7 top
ios7_top

iOS7 bottom
ios7_bottom

Position at bottom?

I love this repo, compliments on your hard work. Is it possible to position TSMessages at the bottom of a controller? If not, please add this request as an enhancement. Thank you.

withButtonCallback not called on iOS 5

The buttonCallback doesn't get called on iOS 5 when I tap the button. Instead, callback gets called. I also tried it on iOS 6, doesn't have this issue. Any ideas?

+ (void)showNotificationInViewController:(UIViewController *)viewController
                               withTitle:(NSString *)title
                             withMessage:(NSString *)message
                                withType:(TSMessageNotificationType)type
                            withDuration:(NSTimeInterval)duration
                            withCallback:(void (^)())callback
                         withButtonTitle:(NSString *)buttonTitle
                      withButtonCallback:(void (^)())buttonCallback
                              atPosition:(TSMessageNotificationPosition)messagePosition
                     canBeDismisedByUser:(BOOL)dismissingEnabled;

Message has a vertical offset

Hi,
I'm not sure what I'm doing wrong but my TSMessage has a vertical offset and is not situated just under the navigation bar as I would expect.

// hide iOS 6 refresh control
[self.refreshControl endRefreshing];

dispatch_async(dispatch_get_main_queue(), ^{
        [TSMessage showNotificationInViewController:self.navigationController
                                            withTitle:message
                                          withMessage:nil
                                             withType:type
                                         withDuration:5.0];
});

What could be the reason?

Screen 1

Callback when user taps notification?

It would be great if there was a completion block available to know the a user taps the notification. That way, you could have the user tap it to say, refresh a network connection if there was an error.

TSMessage View Not Displaying when Used with EventKit

I currently have a navigation-based app with a modal view controller that allows users to add an event to their calendar. In the block where I check if the app has permission or not, I would love to display an error TSMessage if it has no permission. However, when I click the button the TSMessage is never triggered, yet my ns logs shows that the button is working.

This is how my storyboard is set up:
screen shot 2013-06-05 at 12 20 59 am

Here's my code:

EKEventStore *eventStore = [[EKEventStore alloc] init];
if([eventStore respondsToSelector: @selector(requestAccessToEntityType:completion:)]) {
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL permissionGranted, NSError *error) {

        if (permissionGranted){

          NSLog(@"PERMISSION GRANTED.");
            [self performSelectorOnMainThread:@selector(presentEventEditViewControllerWithEventStore:) withObject:eventStore waitUntilDone:NO];
        }

        else {

            NSLog(@"NO PERMISSION.");

            [TSMessage showNotificationInViewController:self
                                              withTitle:@"Error: Permission Required"
                                            withMessage:@"Oops! In order to use this feature, The app needs permission to access your calendars. Please update your privacy settings."
                                               withType:TSMessageNotificationTypeError];

        }
    }];
}

Any help would be greatly appreciated. PS When I just drop it into my viewDidLoad it loads perfectly fine, am I doing something wrong? Thank you. Do I only need to import "TSMessages.h"? I'm using cocoapods. Thanks.

Question: Getting the notification height

I am using TSMessages to show a notification when the network connection is lost.

The notification is being added to a Navigation Controller (that has a nav Bar) and holds a table view.

What I would like to do is change the contentInset of the tableview, when the Notification is shown. Is there a way I can access the height of the displayed Notification (or notifications if multiple are shown) ?

Secondly, is there a way to get a reference to what notification is being shown. For example, if I show one as a note to the user and one as a warning I need to determine when the warning one is being shown. I cannot check against title as I am using localisation so the title string would be different depending on the language.

shown behind UINavigationBar on iOS7

Hi,
for some reason, the TSMessageView is shown behind my UINavigationBar on iOS 7.

[TSMessage setDefaultViewController:self];
[TSMessage showNotificationWithTitle:@"Please select a player in the list." type:TSMessageNotificationTypeMessage];

I've also noticed that running the example project on iOS7 simulator does not show the iOS7 style message as in the readme file

ios simulator screen shot 21 nov 2013 09 44 32

What did I do wrong ?

cheers

call a block when the message is gone

Is it possible to have a block that is call when the message is gone ? Cause there is CallBack which is call only when the user dismissed the message by tapping on it or swiping it to the top. Do you think that we can also have a method like [TSMessage hide...]; in order to hide that actual message ? Anyway, great job ! thank you

Animatiion start with a positioning error after rotate with TSMessageNotificationPositionBottom

Hi all,

On Ipad (maybe also on Iphone) when I add consecutively two TSMessage in landscape orientation, if there is a portrait orientation change before the second TSMessage appears, the second TSMessage animation will start at the wrong position (the landscape position).

I think we should add a method for updating the TSMessageView frame before it appears when the positioning mode is TSMessageNotificationPositionBottom.

This issue appear with the last commit ef45252 when I add the TSMessage to a UINavigationController.

UITapGestureRecognizer triggered when UIButton is pressed (iOS 5)

Fix:

UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                 action:@selector(fadeMeOut)];
tapRec.delegate = self;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if ([touch.view isKindOfClass:[UIButton class]])
    {
        // we touched our control surface
        return NO; // ignore the touch
    }
    return YES; // handle the touch
}

See http://stackoverflow.com/questions/3344341/uibutton-inside-a-view-that-has-a-uitapgesturerecognizer

Compiler warnings

Hello, I noticed some compiler warnings:

/Pods/TSMessages/TSMessages/Views/TSBlurView.m:43:47: Undeclared selector 'barTintColor:'

/Pods/TSMessages/TSMessages/Views/TSMessageView.m:437:61: Undeclared selector 'fadeOutNotification:'

btw Xcode 5

HexColors Integration

Hi i am the creator of the MLUIColorAdditions which are used in this Project and i bumped the Version to 2.0 and renamed it to HexColors.

What about linking the Podspec directly to it. For drop in support you could link it with a sub-module.

If you are interested in this i will go for it and create a pull request.

HexColor.h - Missing

When building for iOS6 in XCode 4.3 you get a runtime crash as HexColor.h is not in the project.

This will be because I'm not using Cocopods...

(Was UIColor+ColorWithHex).

The crash
+[UIColor colorWithHexString:alpha:]: unrecognized selector sent to class 0x3bbbefc0
-[TSMessageView initWithTitle:subtitle:image:type:duration:inViewController:callback:buttonTitle:buttonCallback:atPosition:shouldBeDismissed:]
in TSMessageView.m on Line 168

Bottom messages iOS6.1 wrong position

In iOS6 using TSMessage with a UINavigationController, the bottom messages appear as the below image:

schermata 26 set 2013 21 44 12 simulatore ios

In iOS7 there are no problems.
To reproduce the bug, simply add a UINavigationController to the example project like the image:

schermata 2013-09-26 alle 21 49 51

Tags for alerts

Hello, sorry for my english. It would be nice if alert object had a tag to support something like dismissNotificationWithTag: (remove from queue if not displayed yet)

UX - Pull Tab - Question more than an Issue

Hey Dude,

BACKGROUND:
My friend just showed me this project. I haven't played around with it yet, but from the images in the README I have a question.

During a recent project I implemented a pull-tab right under the navigation bar, or header bar, similar kinda similar to yours.

QUESTION:
Did you have problems with folks pulling down iOS Notifications instead of your pull-tab?

-Tobias

iOS 7 Appearance

How do I enable the iOS 7 appearance as illustrated in the README? My iOS 7 project still has the old appearance.

call show notification from AppDelegate

i need to show a push notification at the currently opened view.

showNotificationInViewController/showNotificationWithTitle(it uses a default view) requires a view parameter. Is there way to find an active view or to develop the control not to be depends to a view?

thanks,

undeclared selector warning

I'm using TSMessages and have my project set to treat warnings as errors for Archive builds. There's an undeclared selector warning that comes up for fadeOutNotification: since that is added to the interface for TSMessage in TSMessage.m instead of TSMessage.h. Is there a reason it couldn't be added to TSMessage.h instead? I guess you want it to be a "private" method?

Here's what I get when building. For
/Users/mangtronix/Dropbox/Work/Changemakrs-mang/changemakrs-ios/Changemakrs/Externals/TSMessages/Views/TSMessageView.m:363:53: error: undeclared selector 'fadeOutNotification:' [-Werror,-Wundeclared-selector]
[[TSMessage sharedMessage] performSelector:@selector(fadeOutNotification:)

I could submit a patch for creating the fadeOutNotification: selector from a string, which would avoid the warning.

shouldBeDismissed and buttonCallback

When shouldBeDismissed is set NO, should we dismiss when button is tapped?
I think we should let buttonCallback decide to dismiss or not.

- (void)buttonTapped:(id) sender
{
    if (self.buttonCallback)
    {
        self.buttonCallback();
    }
    if (!shouldBeDismiss) {
        [self fadeMeOut];
    }
}

Not limited duration

Sometimes it's interesting that the message stays in the screen until a new message is thrown.
For example, I'm thinking in detectecting network reachability, when the network is down I would like to show an error message and that the error stays until I detect that the network is up again, then I will show a success message (this one with a limited duration), and this new message makes the previous one dissapear.

What do you think?

Few errors after update

Hi, I just updated the code to get some of the new features and this is what I got:

[self.toolbar setBarTintColor:blurTintColor];

the compiles show message: "No visible @interface for 'UIToolbar' declares the selector 'setBarTintColor' "

Also it cannot find the HexColor.h in the project

Compiler warning

Hi,

Just pulled down the latest source and got the following warning.
XCode: 4.6.3 -> Target: iOS 6.0
//TSMessages/Views/TSMessageView.m:278:33: Assigning to 'id' from incompatible type 'TSMessageView *__strong'

Thanks,

Al

textField becomeFirstResponder issue

As far as I know, I am not doing anything wrong here. What I want if to verify a textField, so if a user tries to add something that wont validade, I show the message by doing this:

        [TSMessage showNotificationInViewController:self
                                              title:@"Title"
                                           subtitle:@"Something went wrong!"
                                              image:nil
                                               type:TSMessageNotificationTypeWarning
                                           duration:TSMessageNotificationDurationAutomatic
                                           callback:^{
                                               [tabTextField becomeFirstResponder];
                                           }
                                        buttonTitle:nil
                                     buttonCallback:nil
                                         atPosition:TSMessageNotificationPositionTop
                                canBeDismisedByUser:YES];

The thing is that I added a callback so when the user hits the warning, he automatically goes to the textField that needs to be changed.

But when this happen, they keyboard goes up, then the warning goes off, then it ajusts the screen. So when I hit the 'done' button it shifts the whole view down again!

I dont know if I made myself clear but here is a short video showing whats happening:
http://screencast.com/t/IkzexWp0

bug when using custom "imageName" and only title

I used custom design.json file, where I defined my own image for alerts. When I show notification with title only, I have strange appearance of it - icon appears at bottom of view, doesn't at center. What did i do wrong?
P.S. If I don't specify imageName, all works fine.
1

iOS 7 Support

The TSMessages are really great in iOS 7 i think. But we should do something complete new in styling the messages. Something with red and a blur would be very nice to match the style of iOS 7.

Whats your point of view on this?

Got warning when compiling

On TSMessageView.m

@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *content;
@property (nonatomic, strong) UIViewController *viewController;

Got warning 'property attribute in continuation class does not match primary class'

Looks like because the variable implemented differently with the header file.

TSMessageView.h

@property (nonatomic, readonly) NSString *title;
....

The fix could be change the implementation file to

@property (nonatomic, readwrite) NSString *title;
@property (nonatomic, readwrite) NSString *content;
@property (nonatomic, readwrite) UIViewController *viewController;

But i don't know if this could be stable or not. (Haven't really test it)

Thank you

'data parameter is nil' Error

When I invoke the following code it throws the error saying "data parameter is nil".

[TSMessage showNotificationInViewController:self
withTitle:@"Success"
withMessage:@"Payment has been recorded!"
withType:TSMessageNotificationTypeSuccess];

Refactor setting up of a notification view

Currently the initializers are not implemented well: the word 'with' can be removed and the methods are too long.

The new way to init TSMessages should be

// Easy notifications
[TSMessage showNotificationWithTitle:@"" subTitle:@"" type:currentType];


// Advanced notifications
TSMessageView *messageView = [TSMessages messageViewWithTitle:@"" subTitle:@"" type:currentType];
messageView.position = ....; // optional
messageView.duration = 12; // optional
messageView.buttonTitle = @"Update"; //optional
...

// Show the notification
[TSMessages showNotification:messageView];
// or
[TSMessages showNotification:messageView inViewController:vc];

Podspec error

Am getting a error in the PodSpec file when i update TSmessage using the following syntax (fetch most recent version):
pod 'TSMessages', :git => 'https://github.com/toursprung/TSMessages.git'

[!] Invalid TSMessages.podspec file: compile error
/TSMessages.podspec:17: syntax error, unexpected ':', expecting '}'
...m/toursprung/TSMessages.git" :tag => "#{spec.version}"}
^
/TSMessages.podspec:17: syntax error, unexpected '}', expecting kEND. Updating CocoaPods might fix the issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.