GithubHelp home page GithubHelp logo

alskipp / asvaluetrackingslider Goto Github PK

View Code? Open in Web Editor NEW
1.8K 1.8K 236.0 1.67 MB

A UISlider subclass that displays the slider value in a popup view

License: MIT License

Objective-C 96.91% Ruby 3.09%

asvaluetrackingslider's People

Contributors

alskipp avatar aybar avatar biosli 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

asvaluetrackingslider's Issues

String instead of Number like in ASProgressPopUpView

Hello,

you have an option in your other project "ASProgressPopUpView" to write a string instead of a formatted number value. Is it possible to add this option to the "ASValueTrackingSlider" too?

Example from "ASProgressPopUpView":

  • (NSString *)progressView:(ASProgressPopUpView *)progressView stringForProgress:(float)progress
    {
    NSString *s;
    if (progress < 0.2) {
    s = @"Just starting";
    } else if (progress > 0.4 && progress < 0.6) {
    s = @"About halfway";
    } else if (progress > 0.75 && progress < 1.0) {
    s = @"Nearly there";
    } else if (progress >= 1.0) {
    s = @"Complete";
    }
    return s;
    }

Thanks!
Kenan.

speechless problem

duplicate symbol _FillColorAnimation in:
/Users/kjx/Library/Developer/Xcode/DerivedData/XHEnglishBrushStudent-cxzudhmcyvisjbazxhbeptwqyszn/Build/Products/Debug-iphonesimulator/libASProgressPopUpView.a(ASPopUpView.o)
/Users/kjx/Library/Developer/Xcode/DerivedData/XHEnglishBrushStudent-cxzudhmcyvisjbazxhbeptwqyszn/Build/Products/Debug-iphonesimulator/libASValueTrackingSlider.a(ASValuePopUpView.o)
duplicate symbol _ARROW_LENGTH in:
/Users/kjx/Library/Developer/Xcode/DerivedData/XHEnglishBrushStudent-cxzudhmcyvisjbazxhbeptwqyszn/Build/Products/Debug-iphonesimulator/libASProgressPopUpView.a(ASPopUpView.o)
/Users/kjx/Library/Developer/Xcode/DerivedData/XHEnglishBrushStudent-cxzudhmcyvisjbazxhbeptwqyszn/Build/Products/Debug-iphonesimulator/libASValueTrackingSlider.a(ASValuePopUpView.o)
duplicate symbol _POPUPVIEW_HEIGHT_PAD in:
/Users/kjx/Library/Developer/Xcode/DerivedData/XHEnglishBrushStudent-cxzudhmcyvisjbazxhbeptwqyszn/Build/Products/Debug-iphonesimulator/libASProgressPopUpView.a(ASPopUpView.o)
/Users/kjx/Library/Developer/Xcode/DerivedData/XHEnglishBrushStudent-cxzudhmcyvisjbazxhbeptwqyszn/Build/Products/Debug-iphonesimulator/libASValueTrackingSlider.a(ASValuePopUpView.o)
duplicate symbol _POPUPVIEW_WIDTH_PAD in:
/Users/kjx/Library/Developer/Xcode/DerivedData/XHEnglishBrushStudent-cxzudhmcyvisjbazxhbeptwqyszn/Build/Products/Debug-iphonesimulator/libASProgressPopUpView.a(ASPopUpView.o)
/Users/kjx/Library/Developer/Xcode/DerivedData/XHEnglishBrushStudent-cxzudhmcyvisjbazxhbeptwqyszn/Build/Products/Debug-iphonesimulator/libASValueTrackingSlider.a(ASValuePopUpView.o)
ld: 4 duplicate symbols for architecture x86_64

Swift, PopUp is hidden by tableview cell.

I read a similar post in the issues about someone having the same problem, except they had a jail broken phone and this was a while back.

The example project in Objective C is working but when I tried to implement it in my Swift project the pop over was being slightly hidden.

The delegate functions are being called.

screen shot 2016-06-17 at 12 15 39 pm

Any guesses?

    func sliderWillDisplayPopUpView(slider:ASValueTrackingSlider?) {
    self.superview?.bringSubviewToFront(self)
    } 

Compiler warning on Xcode 8 GM + fix

I got the following compiler warning on Xcode 8:

/ASValueTrackingSlider/ASValueTrackingSlider/ASValuePopUpView.m:157:24: Assigning to 'id<CAAnimationDelegate> _Nullable' from incompatible type 'ASValuePopUpView *const __strong'

I fixed it as follows:

@interface ASValuePopUpView : UIView <CAAnimationDelegate>

Tried to push it using git, but kept getting permission errors, so I am posting it here.

Cheers

Popup animated color not working when slider's ValueChanged is assigned in IB

Hi,
I've been trying to integrate this wonderful control in my project and I needed to track the change the slider's value and it appears that doing so in Interface Builder (i.e. connecting the value changed property to an IBOutlet) will stop the slider from changing the popup and slider's tint color to their animated values.
My workaround for now is to addTarget in the viewDidLoad for now and it solves the issue.
Any thoughts?
Thanks a lot.

slider when only have one digits

the pop view looks a little weird when the max value less than 10 (_defaultPopUpViewSize comes from 1digit), the length-width ratio looks funny.

Is it convenient to set a minViewSize or make childSlider can provide popview size?
thanks

Demo crashes on iOS 6

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSConcreteMutableAttributedString addAttribute:value:range:: nil value' as - [ASValuePopUpView setTextColor:] and - [ASValuePopUpView setFont:] do not handle nil value.

- (void)setFont:(UIFont *)font
{
    [_attributedString addAttribute:NSFontAttributeName
                                  value:font
                                  range:NSMakeRange(0, [_attributedString length])];
}

==>

- (void)setFont:(UIFont *)font
{
    if (nil != font)
    {
        [_attributedString addAttribute:NSFontAttributeName
                                  value:font
                                  range:NSMakeRange(0, [_attributedString length])];
    }
    else
    {
        // Or use a default font settings ???
        [_attributedString removeAttribute:NSFontAttributeName range:NSMakeRange(0, [_attributedString length])];
    }
}

Improved control of popupview dimensions

First of all, thank you very much for sharing this class! I've been looking for something like this for a while, but all solutions I came across were pretty outdated.

Anyway, I'm using a pretty small font (size 12) for the text in the popUpView, and the relative size IMO of the popUpView is too big for that. I was able to tweak it by decreasing the values of ARROW_LENGTH and MIN_POPUPVIEW_HEIGHT, and it looks much better proportionally. Is this maybe something that could be built in the class, eg by making those constants a property, or size them based on the font size?

Doesn't work in iOS 8

App crashes when using this in iOS 8. Could be an edge case but would love if you could confirm.

CALayerInvalidGeometry

Hi @alskipp,

Following the 0.9.1 update, I start to experience crash. Here is the output:


2014-05-08 16:56:34.278 TSA[12501:60b] *** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan 0]'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001031de495 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000102db599e objc_exception_throw + 43
    2   CoreFoundation                      0x00000001031de2ad +[NSException raise:format:] + 205
    3   QuartzCore                          0x0000000101647cf6 _ZN2CA5Layer12set_positionERKNS_4Vec2IdEEb + 158
    4   QuartzCore                          0x0000000101647e77 -[CALayer setPosition:] + 44
    5   QuartzCore                          0x0000000101648544 -[CALayer setFrame:] + 856
    6   TSA                                 0x000000010010c36c -[ASValuePopUpView setArrowCenterOffset:] + 700
    7   TSA                                 0x000000010010fe00 -[ASValueTrackingSlider adjustPopUpViewFrame] + 688
    8   TSA                                 0x000000010010fa0b -[ASValueTrackingSlider positionAndUpdatePopUpView] + 43
    9   TSA                                 0x000000010010f8de -[ASValueTrackingSlider setup] + 1070
    10  TSA                                 0x000000010010e5e0 -[ASValueTrackingSlider initWithCoder:] + 160
    11  UIKit                               0x0000000101b4359c -[UIClassSwapper initWithCoder:] + 202
    12  UIKit                               0x0000000101c7f794 UINibDecoderDecodeObjectForValue + 678
    13  UIKit                               0x0000000101c7f95c UINibDecoderDecodeObjectForValue + 1134
    14  UIKit                               0x0000000101c7f4df -[UINibDecoder decodeObjectForKey:] + 94
    15  UIKit                               0x000000010192f956 -[UIView initWithCoder:] + 815
    16  UIKit                               0x0000000101c7f794 UINibDecoderDecodeObjectForValue + 678
    17  UIKit                               0x0000000101c7f95c UINibDecoderDecodeObjectForValue + 1134
    18  UIKit                               0x0000000101c7f4df -[UINibDecoder decodeObjectForKey:] + 94
    19  UIKit                               0x000000010192f956 -[UIView initWithCoder:] + 815
    20  UIKit                               0x0000000101b078a2 -[UITableViewCell initWithCoder:] + 68
    21  UIKit                               0x0000000101b4359c -[UIClassSwapper initWithCoder:] + 202
    22  UIKit                               0x0000000101c7f794 UINibDecoderDecodeObjectForValue + 678
    23  UIKit                               0x0000000101c7f4df -[UINibDecoder decodeObjectForKey:] + 94
    24  UIKit                               0x0000000101b4316c -[UIRuntimeConnection initWithCoder:] + 109
    25  UIKit                               0x0000000101c7f794 UINibDecoderDecodeObjectForValue + 678
    26  UIKit                               0x0000000101c7f95c UINibDecoderDecodeObjectForValue + 1134
    27  UIKit                               0x0000000101c7f4df -[UINibDecoder decodeObjectForKey:] + 94
    28  UIKit                               0x0000000101b427b6 -[UINib instantiateWithOwner:options:] + 891
    29  UIKit                               0x00000001019b144b -[UITableView _dequeueReusableViewOfType:withIdentifier:] + 302
    30  UIKit                               0x00000001019b16b6 -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 44
    31  TSA                                 0x0000000100033984 -[DetailTableViewController tableView:cellForRowAtIndexPath:] + 7876
    32  UIKit                               0x00000001019bbf8a -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 348
    33  UIKit                               0x00000001019a1d5b -[UITableView _updateVisibleCellsNow:] + 2337
    34  UIKit                               0x00000001019b3721 -[UITableView layoutSubviews] + 207
    35  UIKit                               0x0000000101947993 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 354
    36  QuartzCore                          0x0000000101650802 -[CALayer layoutSublayers] + 151
    37  QuartzCore                          0x0000000101645369 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 363
    38  QuartzCore                          0x00000001016451ea _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
    39  QuartzCore                          0x00000001015b8fb8 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 252
    40  QuartzCore                          0x00000001015ba030 _ZN2CA11Transaction6commitEv + 394
    41  QuartzCore                          0x00000001015ba69d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
    42  CoreFoundation                      0x00000001031a9dc7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    43  CoreFoundation                      0x00000001031a9d37 __CFRunLoopDoObservers + 391
    44  CoreFoundation                      0x0000000103189522 __CFRunLoopRun + 946
    45  CoreFoundation                      0x0000000103188d83 CFRunLoopRunSpecific + 467
    46  GraphicsServices                    0x0000000104becf04 GSEventRunModal + 161
    47  UIKit                               0x00000001018e7e33 UIApplicationMain + 1010
    48  TSA                                 0x000000010002ac33 main + 115
    49  libdyld.dylib                       0x00000001037635fd start + 1
    50  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Do you have any idea of what's going on?

It is currently working fine with 0.9.0

Dates and times?

This would be terrific to select date/times. I tried a quick hack to see if I could pass NSDateFormatter, but the formatter expects a number :(

Any chance of adding a NSDateFormatter option? It's probably beyond my current abilities to do this.

Thx.

Keep the PopUpView always visible

Hi,

First of all, thanks for such useful lib :)

I wonder if there's a way to always keep the slider's popUpView visible (by default, it gets hidden once you stop interacting with the slider).

Thanks,
Matheus

left side of bar color looses color when cell is reused

I am using the slider in a table cell. I am using the default setting for autoAdjustTrackColor (yes). I set the popUpViewColor and the left side of the slider reflects my color until the cell scrolls off screen and back (resued). Now, the entire bar is black. Can the left side color be made to stick?

Slider over borders will show incomplete

Slider on the UICollectionView or UITableView will show more than the border is not complete, can not let the bubbles show up in the UIWindow so that it will not be blocked #

Setting corner radius manually

Hi @alskipp,

I want to have rectangular background layer for the popUpView. So I think best practice for this could be having an option to control radius. What do you think?

Cannot adjust popup size

The slider popup looks weird with custom fonts (e.g. small Roboto fonts). There should be a way (without modifying the source) to specify the size of the popup view, maybe by allowing clients to customize width/height padding factors.

Crash in iOS8. [__NSCFType CGColor]: unrecognized selector

I seem to have an app which is crashing with ASValueTrackingSlider. Setting the class of the slider to UISlider, it runs fine.

This is the error given during runtime:

"-[__NSCFType CGColor]: unrecognized selector sent to instance 0x12345678"

The instance is just a sample, that hex value changes every time.

Help?

slider

这个slider值为什么不能保存啊 ,每次再点进来 这个值都是中间 不是上次slider位置的值 。。。

How to have the popoverview below the thumb.

I implemented this cool slider. But the problem is that am not able to have the popover below the thumb. Can you please help me how to do this without breaking your codes. Is there anyway I can do this?

Crash when setting CALayer's frame

Overall setup:
View controller inside of a popover
Add slider as only view in VC's viewDidLoad, no XIBs or Storyboards involved

Crash here:

[ASValuePopUpView setArrowCenterOffset:]
[ASValueTrackingSlider adjustPopUpViewFrame]
[ASValueTrackingSlider positionAndUpdatePopUpView]
[ASValueTrackingSlider setup]
[ASValueTrackingSlider initWithFrame:]  // crash with either CGRectZero or CGRectMake(0, 0, 320, 30)
[MyViewController viewDidLoad]
[UIViewController loadViewIfRequired] ()
[UIViewController view] ()
[UINavigationController preferredContentSize] ()
[UIViewController(UIPopoverController_Internal) _resolvedPreferredContentSize] ()
[UIPopoverController _transitionFromViewController:toViewController:animated:] ()
[UIPopoverController _initWithContentViewController:popoverControllerStyle:] ()

on line

self.layer.frame = f; // changing anchor repositions layer, so must reset frame afterwards
CGRect f = self.layer.frame;  // This looks like CGRectZero before crash

Message:
*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan 0]'

iOS SDK 7.1, iOS 7.1.1

Issue when sliding from a long string to a shorter one

When using custom strings with different lengths in popUpView label, if you slide from a long string to a shorter string, the long string remains appearing a bit while target popupview size is already drawn.
It can be seen in your demo project.

Keep popup open

It would be cool to keep the popup open so that the value is visible all the time. It should still animate, but it should shrink and not disappear...

Show pop up from left, right or bottom of slider knob?

Might be useful, I'm running into the issue where it's cut off in a tableview cell and I am trying to avoid subclassing cells. I saw a few methods that might enable this if I start hacking around but no easy interface to it. I may end up having to implement this, if i do I'll send a pull request. Great class though very well thought out and clean code. Thanks for your work.

Updated Cocoapod soon?

Looking at ASValuePopUpView.h on master you have the a property that I need to update the arrow length:

@interface ASValuePopUpView : UIView

@property (nonatomic) CGFloat arrowLength;

However, using the latest Cocoapod, 0.10.1 (which points to tag 0.10.1), this property doesn't exist. Is there a plan to roll out this change in an updated Cocoapod soon?

Thanks!

ASValueTrackingSliderDataSource is triggered by mistake

After calling "hidePopUpViewAnimated"
Following method will be called:

  • (NSString *)slider:(ASValueTrackingSlider *)slider stringForValue:(float)value

I don't think it makes sense. Reasonably, it should be only triggered when value is changed.

Rotating the uislider makes the popupview rotate too

Hi and Thanks for a great addon!

When i use CGAffineTransformMakeRotation(-M_PI * 90 / 180.0f)

on my uislider to make it rotate 90* standing up, the popupvalueview also rotates with the slider, is there anyway to prevent this ?

Missing the file “ValueTrackingSliderTests-Info.plist”

If i try pod try ASValueTrackingSlider and try to build the xcode project i run in this failure.
`error: could not read data from '/tmp/CocoaPods/Try/ASValueTrackingSlider/Example/ValueTrackingSliderTests/ValueTrackingSliderTests-Info.plist': The file “ValueTrackingSliderTests-Info.plist” couldn’t be opened because there is no such file.``
The same when i download the Project as zip and try to build the example project.

Cheers

Slider not changing between colors when changing value

self.recordPercentageSlider = [ASValueTrackingSlider new];
self.recordPercentageSlider.delegate = self;
self.recordPercentageSlider.frame = CGRectMake(20.0, 45.0, CGRectGetWidth(self.frame) - 2.0 * 20.0, 31.0);
//self.recordPercentageSlider.value = 1.0;
self.recordPercentageSlider.font = [UIFont fontWithName:@"AvenirNext-Medium" size:15.0];
self.recordPercentageSlider.tintColor = [UIColor autumnColorWithAlpha:ZTAlphaLevelFull];
[self.recordPercentageSlider addTarget:self action:@selector(recordPercentageValueChanged) forControlEvents:UIControlEventValueChanged];
[self.contentView addSubview:self.recordPercentageSlider];

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterPercentStyle];
[self.recordPercentageSlider setNumberFormatter:numberFormatter];
self.recordPercentageSlider.popUpViewAnimatedColors = @[[UIColor carbonColorWithAlpha:ZTAlphaLevelFull], [UIColor autumnColorWithAlpha:ZTAlphaLevelFull]];

This is the code I used for inserting the slider but will only display the first color in the array. I used these same lines for two different part of a project, both in table's cells, in which the animation did trigger while the other didn't.

Tap to Slide

I thank you for a wonderful piece of work, and it will be great if you add Tap to slide with PopView animating.

The popUpView size is calculated incorrectly in specific circumstances

When the minimum value of the slider is negative, but its absolute value is less than the maximum value (e.g. min:-20, max:60), the popUpView size is calculated incorrectly. Need to give extra space for the sign "-".
-20
60

If the abs of the minimum value is the same or greater than the maximum then the size is calculated correctly.
-60

Added snapping capability

Hello again,

Sorry, I don't know how to commit my own enhancements, but I added a snapping capability to your project, this way:

In "ASValueTrackingSlider.h":

// ADD THESE TWO LINES
@property (nonatomic) float stepValue;
- (void)valueChanged;

In "ASValueTrackingSlider.m":

@interface ASValueTrackingSlider() <ASValuePopUpViewDelegate>

@property (strong, nonatomic) NSNumberFormatter *numberFormatter;
@property (strong, nonatomic) ASValuePopUpView *popUpView;
@property (nonatomic) BOOL popUpViewAlwaysOn; // (default is NO)
// THIS IS NEW:
@property (nonatomic) float lastQuestionStep;

@end

@implementation ASValueTrackingSlider
{
    CGSize _popUpViewSize;
    UIColor *_popUpViewColor;
    NSArray *_keyTimes;
    CGFloat _valueRange;
        // THIS IS NEW:
    float _lastQuestionStep;
}

 -(void)setup {
    // ...
    // THIS IS NEW
    if (0.0 == self.stepValue) self.stepValue = 1.0;
    _lastQuestionStep = (self.value) / self.stepValue;
    // ...
}

// ADD ALSO THIS METHOD
- (void)valueChanged {
  if (0.0 == self.stepValue) self.stepValue = 1.0;
  float newStep = roundf((self.value) / self.stepValue);
  self.value = newStep * self.stepValue;
}

valueChanged must be called from UITableViewController when the slider changes its value ( connect an action from slider in storyboard for Value Changed and name it sliderValueChanged)

In your UITableViewController class:

- (IBAction)sliderValueChanged:(id)sender {
  [self.slider valueChanged];
}

In viewDidLoad of your UITableViewController

- (void)viewDidLoad {
  [super viewDidLoad]
  // ...
  self.slider.minimumValue = 0.0;
  self.slider.maximumValue = 4.0;
  //THIS IS NEW:
  self.slider.stepValue = 1.0;
}

Greetings from Berlin
Kenan.

Add "tap to slide' feature

Hi,

Sometimes it is quite annoying for the user to drag the handle all the way from one side to another side.
Allowing the user to just tap the slider at some point and have the handle go to this point on its own would be nice.

Thanks for this great slider anyway!

Option to make the rect underneath the slider?

I have a UISlider at the very top of the screen. It would be really great if there was an option to have it underneath the slider. I kinda sorta managed it by modifying line 219 in ASValuePopUpView.m:
CGPoint p0 = CGPointMake(arrowX, -(CGRectGetMaxY(self.bounds)));

and line 221 in ASValueTrackingSlider.m to:
popUpRect.origin.y = (thumbRect.origin.y - _popUpViewSize.height) * -1

but this feels a bit hackish to me. I'm also now getting the wide end of the arrow cutting through the rect and I'm not sure how to correct that.

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.