Giter VIP home page Giter VIP logo

reactiveui / reactiveui Goto Github PK

View Code? Open in Web Editor NEW
7.9K 358.0 1.1K 86.66 MB

An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms that is inspired by functional reactive programming. ReactiveUI allows you to abstract mutable state away from your user interfaces, express the idea around a feature in one readable place and improve the testability of your application.

Home Page: https://www.reactiveui.net

License: MIT License

C# 99.58% Vim Snippet 0.42%
reactiveui xamarin ios android uwp wpf winforms reactive-programming reactive-extensions functional-reactive-programming

reactiveui's Issues

Tests don't clean up properly

We use sleeps everywhere which results in us having unreliable results on tests because an async action from the previous test could still be running and bork the current test.

ReactiveUI.Sample does not compile

There are number of compilation errors:

It is missing references to System.Windows.Controls.Navigation, ReactiveUI.Testing and ReactiveUI.Blend. It also makes references to Log().InfoFormat which should be Log().Info

Property setter RaiseAndSetIfChanged backing field cannot be altered

If you have a property setter like this.RaiseAndSetIfChanged(x => x.TextToTranslate, value) you will have to call your backing field for the property _TextToTranslate

Our projects Resharper settings does not allow me to have a backing field named something with _underscore. This is a minor issue but would be nice to have.

Windows Phone 7.1 app keeps crashing

Every time I try to use ReactiveObject in a viewmodel the application will just start crashing. If I use the INotifyPropertyChanged then the application stops crashing.

Here is the code:

using ReactiveUI;
using System.Collections.ObjectModel;
using MyForum.Models;
using System;
namespace MyForum
{
public class MainViewModel : ReactiveObject
{

    public ObservableCollection<PivotInfoItem> _PivotItems { get; set; }
    public MainViewModel()
    {
       this._PivotItems = new ObservableCollection<PivotInfoItem>();
        LoadData();
    }


    public ObservableCollection<PivotInfoItem> PageCollection
    {
        get { return _PivotItems; }
        set
        {
            this.RaiseAndSetIfChanged(x => x.PageCollection,value);
        }
    }



    public bool _loadvis;
    public Boolean OverlayVis
    {
        get
        {
        return _loadvis;
        }

       set
        {

            this.RaiseAndSetIfChanged(x => OverlayVis, value);
        }
    }


    public bool IsDataLoaded
    {
        get;
        private set;
    }

    /// <summary>
    /// Creates and adds a few ItemViewModel objects into the Items collection.
    /// </summary>
    public void LoadData()
    {
        // Sample data; replace with real data
     //   this._PivotItems.Add(new PivotInfoItem() { Title = "Discover" });
     //   this._PivotItems.Add(new PivotInfoItem() {Title="Search" });
        this.IsDataLoaded = true;
    }


}

}

ReactiveCollection should be CLS compilant (partial patch attached)

Adding "[assembly: CLSCompliant(true)]" to the Reactive UI results in an number of varnings about ReactiveCollection not beeing CLS compilat. The varnings are attached below and can easily be resolved.

1; Add [assembly: CLSCompliant(true)] to the AssemblyInfo.cs for all the projects
2; Update ReactiveCollection to become CLS compatible.
A patch is provided changing the offending member variables from protected to private,
it they really should be protected then they should instead be renamed (ex _ItemsAdded can be renamed to itemsAdded)

------------------------------------------------------ Varnings ------------------------------------------------------
ReactiveUI\ReactiveUI\ReactiveCollection.cs(157,34): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._ItemsAdded' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(169,31): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._BeforeItemsAdded' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(179,34): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._ItemsRemoved' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(190,31): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._BeforeItemsRemoved' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(204,36): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._CollectionCountChanging' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(215,36): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._CollectionCountChanged' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(226,56): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._ItemChanging' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(241,56): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._ItemChanged' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(255,64): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._Changing' is not CLS-compliant
ReactiveUI\ReactiveUI\ReactiveCollection.cs(266,64): warning CS3008: Identifier 'ReactiveUI.ReactiveCollection._Changed' is not CLS-compliant

------------------------------------------------------ Patch begin ------------------------------------------------------

Index: ReactiveCollection.cs

--- ReactiveCollection.cs (revision 378)
+++ ReactiveCollection.cs (working copy)
@@ -154,7 +154,7 @@
}

     [IgnoreDataMember]
  •    protected IObservable<T> _ItemsAdded;
    
  •    private IObservable<T> _ItemsAdded;
    
     /// <summary>
     /// Fires when items are added to the collection, once per item added.
    

    @@ -166,7 +166,7 @@
    }

     [IgnoreDataMember]
    
  •    protected ISubject<T> _BeforeItemsAdded;
    
  •    private ISubject<T> _BeforeItemsAdded;
    
     /// <summary>
     /// Fires before an item is going to be added to the collection.
    

    @@ -176,7 +176,7 @@
    }

     [IgnoreDataMember]
    
  •    protected IObservable<T> _ItemsRemoved;
    
  •    private IObservable<T> _ItemsRemoved;
    
     /// <summary>
     /// Fires once an item has been removed from a collection, providing the
    

    @@ -187,7 +187,7 @@
    }

     [IgnoreDataMember]
    
  •    protected ISubject<T> _BeforeItemsRemoved;
    
  •    private ISubject<T> _BeforeItemsRemoved;
    
     /// <summary>
     /// Fires before an item will be removed from a collection, providing
    

    @@ -198,10 +198,10 @@
    }

     [IgnoreDataMember]
    
  •    protected Subject<int> aboutToClear;
    
  •    private Subject<int> aboutToClear;
    
     [IgnoreDataMember]
    
  •    protected IObservable<int> _CollectionCountChanging;
    
  •    private IObservable<int> _CollectionCountChanging;
    
     /// <summary>
     /// Fires before a collection is about to change, providing the previous
    

    @@ -212,7 +212,7 @@
    }

     [IgnoreDataMember]
    
  •    protected IObservable<int> _CollectionCountChanged;
    
  •    private IObservable<int> _CollectionCountChanged;
    
     /// <summary>
     /// Fires whenever the number of items in a collection has changed,
    

    @@ -223,7 +223,7 @@
    }

     [IgnoreDataMember]
    
  •    protected ISubject<IObservedChange<T, object>> _ItemChanging;
    
  •    private ISubject<IObservedChange<T, object>> _ItemChanging;
    
     /// <summary>
     /// Provides Item Changed notifications for any item in collection that
    

    @@ -238,7 +238,7 @@
    }

     [IgnoreDataMember]
    
  •    protected ISubject<IObservedChange<T, object>> _ItemChanged;
    
  •    private ISubject<IObservedChange<T, object>> _ItemChanged;
    
     /// <summary>
     /// Provides Item Changing notifications for any item in collection that
    

    @@ -252,7 +252,7 @@
    }

     [IgnoreDataMember]
    
  •    protected IObservable<IObservedChange<object, object>> _Changing;
    
  •    private IObservable<IObservedChange<object, object>> _Changing;
    
     /// <summary>
     /// Fires when anything in the collection or any of its items (if Change
    

    @@ -263,7 +263,7 @@
    }

     [IgnoreDataMember]
    
  •    protected IObservable<IObservedChange<object, object>> _Changed;
    
  •    private IObservable<IObservedChange<object, object>> _Changed;
    
     /// <summary>
     /// Fires when anything in the collection or any of its items (if Change
    

    ------------------------------------------------------ Patch end ------------------------------------------------------

RegisterAsyncFunction in 2.1.0.1 fires callback on dispatcher

When running the Awesome People sample app for v2.1.0.1, the flickr picture fetching code uses ReactiveAsyncCommand.RegisterAsyncFunction(..). It should fire the callback on some other thread (the Taskpool by default, it looks like), but it seems to be firing on the dispatcher thread. I've made some cursory attempts to get it to fire on another thread by passing in an explicit scheduler to the ReactiveAsyncCommand constructor and the RegisterAsyncFunction method but one way or another it seems to either fire on the dispatcher thread (blocking the ui) or crash complaining about accessing an object that belongs to another thread.

INotifyPropertyChanging Collision when used with mscorlib.extenstions.dll

Windows PHone 7.1 silverlight profile, have the Mscorlib.extensions included, added ReactiveUI from NuGet, now get a type exists in both error

The type 'System.ComponentModel.PropertyChangingEventArgs' exists in both 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone71\mscorlib.Extensions.dll' and 'c:\Projects\Red Jungle\PixLCartSystem\packages\reactiveui-wp7.2.5.1.0\lib\sl3-wp\ReactiveUI_WP7.dll'

C:\Projects\Red Jungle\PixLCartSystem\PixLCart\Model\Dal.cs 363 18

System.ArgumentNullException in RxApp static constructor

Hi, when you try to create a ReactiveCommand before you have a RootVisual assigned in SL, RxApp will throw an exception because it is checking InUnitTestRunner() passing in Application.Current.RootVisual which it expects been set.

To reproduce simply create a new SL project, have a ViewLocator as a static resource to which you bind from the view. When instantiating the view, the model gets instantiated first and since the view wasn't set to the RootVisual before the model was instantiated it will be null.

Workaround: in Application_Startup set RootVisual to new Grid() and then set to the main view.

Nuget fails to install 'reactiveui' 2.3.1.0 on .NET Framework 4.0 (Client Profile)

I've just tried to install 'reactiveui' 2.3.1.0 nuget package on .NET Framework 4.0 (Client Profile) and it failed with the following error message:

'reactiveui-core (≥ 2.3.1.0)' not installed. Attempting to retrieve dependency from source...
Done.
'Rx-Main (≥ 1.1.10425)' not installed. Attempting to retrieve dependency from source...
Done.
'reactiveui-xaml (≥ 2.3.1.0)' not installed. Attempting to retrieve dependency from source...
Done.
'Rx-Xaml (≥ 1.1.10425)' not installed. Attempting to retrieve dependency from source...
Done.
'reactiveui-testing (≥ 2.3.1.0)' not installed. Attempting to retrieve dependency from source...
Done.
'Rx-Testing (≥ 1.1.10425)' not installed. Attempting to retrieve dependency from source...
Done.
'Rx-Main 1.1.10425' already installed.
Successfully installed 'reactiveui-core 2.3.1.0'.
Successfully installed 'Rx-Xaml 1.1.10425'.
Successfully installed 'reactiveui-xaml 2.3.1.0'.
Successfully installed 'Rx-Testing 1.1.10425'.
Successfully installed 'reactiveui-testing 2.3.1.0'.
Successfully installed 'reactiveui 2.3.1.0'.
Successfully added 'Rx-Main 1.1.10425' to UserRegistration.Rx.
Install failed. Rolling back...
Unable to find framework assemblies that are compatible with the target framework '.NETFramework,Version=v4.0,Profile=Client'.

IObservedChange <TSender,TValue> why not covariant now?

There is a comment in the code (see below) saying that in the future IObservedChanged will be covariant, why in the future and now now?

    /// <summary>
    /// IObservedChange is a generic interface that replaces the non-generic
    /// PropertyChangedEventArgs. Note that it is used for both Changing (i.e.
    /// 'before change') and Changed Observables. In the future, this interface
    /// will be Covariant which will allow simpler casting between specific and
    /// generic changes.
    /// </summary>
    public interface IObservedChange<TSender, TValue> {...}

Strong Name

Paul, is it unreasonable to expect that the ReactiveUI should be strong named so that I can easily use it within a solution where everything is strong named?

I have used ReactiveUI on other projects and it has worked very well. Great framework!

Thanks
Jeremy

Version change issues for System.Reactive

RxApp.cs chokes on line 342, probably because of this line referencing the wrong version of the System.Reactive.Windows.Threading assembly:

    // NB: Silverlight barfs unless we give this full name here
    internal const string dispatcherSchedulerQualifiedName =
        @"System.Reactive.Concurrency.DispatcherScheduler, System.Reactive.Windows.Threading, Version=2.0.20304.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

CreateDerivedCollection unnecessarily tries to cast IEnumerable<T> to IList<T>

CreateDerivedCollection is an extension method on IEumerable but for some reason creates a superfluous variable

var thisAsColl = (IList<T>)This;

that is only used once later to cast it back to an IEnumerable

var origEnum = (IEnumerable<T>)thisAsColl;

This limits limits you to collection types that implement IList (and causes unexpected exceptions when you don't). No features on IList are used within the method.

ObservableCollectionView does not remove items which do not match the filter

I've been using the ObservableCollectionView's ability to filter items in the collection but I saw issues where items which were modified in order to no longer meet the filter criteria not being removed. It seems this issue is due to how the ObserveCollectionItemChanged() call is made:

source.ObserveCollectionItemChanged<T>()
    .Where(updateFilter)
    .Select(x => x.Sender)
    .Where(filter)
    .ObserveOn(RxApp.DeferredScheduler)
    .Subscribe(updateItem);

The above will never call updateItem to remove items which don't meet the filter criteria.
This can be fixed by adding the following code as well:

source.ObserveCollectionItemChanged<T>()
    .Where(updateFilter)
    .Select(x => x.Sender)
    .Where(x=> !filter(x))
    .ObserveOn(RxApp.DeferredScheduler)
    .Subscribe(removeItem);

Add a deselector action to CreateDerivedCollection

This feature will add the flexibility of having custom cleanup code be executed on removing an item/s.

 public static ReactiveCollection<TNew> CreateDerivedCollection<T, TNew>( 
        this ObservableCollection<T> This, 
        Func<T, TNew> selector, Action<TNew> deselector = null) 
    { 
    // verbose code removed
   coll_changed.Subscribe(x => 
        { 
            switch (x.Action) 
            { 
                case NotifyCollectionChangedAction.Add: 
                case NotifyCollectionChangedAction.Remove: 
                case NotifyCollectionChangedAction.Replace: 
                    // NB: SL4 fills in OldStartingIndex with -1 on Replace :-/ 
                    int old_index = (x.Action == NotifyCollectionChangedAction.Replace ? x.NewStartingIndex : x.OldStartingIndex); 

                    if (x.OldItems != null) 
                    { 
                        foreach (object _ in x.OldItems) 
                        { 
                            if (deselector != null) 
                                deselector (ret[old_index]); 

                            ret.RemoveAt(old_index); 
                        } 
                    } 
                    if (x.NewItems != null) 
                    { 
                        foreach (T item in x.NewItems.Cast<T>()) 
                        { 
                            ret.Insert(x.NewStartingIndex, selector(item)); 
                        } 
                    } 
                    break; 
                case NotifyCollectionChangedAction.Reset: 
                    if (deselector != null) 
                        ret.Run(deselector ); 
                    ret.Clear(); 
                    break; 
                default: 
                    break; 
            } 
        }); 

Message Bus might send and listen to messages on different schedulers

The Listen method of MessageBus doesn't specify a scheduler. If you happen to call Listen for a type, and then send a message on a different scheduler than the default, it'll still get sent on the default scheduler because the Listen method creates a dictionary the first time and SendMessage calls the same dictionary.

ReactiveCommand can lead to memory leaks!

Hi Paul,
I noticed a place where you can have memory leaks and tried to fix it. I thought that implementing IDisposable will solve the problem. Unfortunately it didn't help. I assume it's something related to your caching (momoization).

You can find Leak project in my branch:
[email protected]:StanislawSwierc/ReactiveUI.git

ReactiveCommand doesn't seem to handle inital false state

I have a UI where an empty text box prevents an OK button being clicked, but unfortunately it seems to be enabled until after you have set and cleared the textbox. After stripping it down and down I can still recreate the issue with code as simple as

 static void Main(string[] args)
{
    ReactiveCommand cmd = new ReactiveCommand(Observable.Return(false));
    Debug.Assert(cmd.CanExecute(null) == false);
}

Following the ReactiveCommand constructor in the source, it seems to be that the InitialValue is being set to true. Can you remember the reason for this? Is there anyway we can detect an initial value from the observable that we are watching?

Assembly signing

Please sign the assemblies. They can't be referenced from signed assemblies otherwise.

Build against Rx Official 1.0 - not 1.1 experimental

We're already using Rx in other projects, but the 1.0 official and not 1.1 experimental, which we don't want to take a dependency on.

I grabbed your source and rebuilt -- doesn't look like you're using anything from 1.1. I would like to see official releases based off of 1.0, otherwise I've got a big assembly versioning problem on my hands.

Thanks for the consideration.

Sample code doesn't work

If you run the sample WPF application it will throw an "The calling thread must be STA, because many UI components require this" exception when clicking "Start"

ValidatedReactiveObject not available in .NET 3.5 build

As much as I can see, the ValidatedReactiveObject class is not available in the .NET 3.5. build? If this is the case, perhaps it's a well founded one; perhaps some validation types are new in .NET 4.0 and thus the class has been omitted for version 3.5?

ReactiveAsyncCommand.CanExecute() does not evaluate the maximumConcurrent constructor parameter

I have created a command as follows:

IObservable<bool> canLogin = this.WhenAny(x => x.Username,
                                          x => x.Password,
                                          (u, p) => !string.IsNullOrWhiteSpace(u.Value) &&
                                                    !string.IsNullOrWhiteSpace(p.Value));

I was expecting LoginCommand.CanExecute() to evaluate tofalse (and thereby disable the button to which the command is bound) if it is currently executing, as the constructor call above uses the default maximumConcurrent parameter value of 1. This doesn't appear to be the case.

Make WhenAny use INotifyPropertyChanged instead of IReactiveNotifyPropertyChanged

WhenAny requres IReactiveNotifyPropertyChanged instead of INotifyPropertyChanged like ObservableForProperty. This is annoying b/c I don't want my model classes to depend on ReactiveUI but I want the behavior of WhenAny to sync my ViewModel with the model. There doesn't appear to be a need to use IReactiveNotifyPropertyChanged instead of INotifyPropertyChanged.

SuppressChangeNotifications on derived collections / object properties

When creating a DerivedCollection (child) from a ReactiveCollection (source) and then adding to the source while suppressing change notifications the derived collection still raises events.

I guess the same thing will apply to a ReactiveObject owning ReactiveCollections i.e. calling SuppressChangeNotifications on the owning object and then adding to the collection will raise the collections change events (this is easier to handle but still a little counter intuitive).

Need help implementing a mechanism

I'm having a hard time setting up something. I have "OverlayVis" binded to a spinner.

public Boolean _OverlayVis;
public Boolean OverlayVis
{
get
{
return _OverlayVis;
}

        set
        {

            this.RaiseAndSetIfChanged(x => x.OverlayVis, value);

        }
    }
    public MainViewModel()
    {

      netcheck = new ReactiveAsyncCommand(null, 1);




      IObservable<Boolean> cmd2= netcheck.RegisterAsyncFunction(x =>{
           OverlayVis = true;

        LoadingMessage = "Checking for internet connection";

          return !NetworkInterface.GetIsNetworkAvailable();


       });


      this.ObservableToProperty(cmd2,x=>x.OverlayVis);

cmd2.Execute(null);

Currently,the above only checks once,,,,
What I am trying to achieve is:

  1. Continuously check NetworkInterface.GetIsNetworkAvailable(); until it becomes true.If it becomes true then OverlayVis=false,

What is the most effective and optimal way to do this using ReactiveUI?

ReactiveCommand constructor is ambiguous

SL4, don't know if it matters

private void ExecuteSave(object param)
{
//...
}

ReactiveCommand save = new ReactiveCommand(ExecuteSave);

gives compiler error

The call is ambiguous between the following methods or properties: 'ReactiveXaml.ReactiveCommand.ReactiveCommand(System.Action, System.Concurrency.IScheduler)' and 'ReactiveXaml.ReactiveCommand.ReactiveCommand(System.Func<object,bool>, System.Action, System.Concurrency.IScheduler)'

ReactiveCommand _Save = new ReactiveCommand(p => this.ExecuteSave(p));

works just fine but I would expect to be able to use supply the function I want it to call.

As a related side note, when you add additional parameters to a constructor they're usually added to the end of the standard parameter list to reduce confusion when using the class. I think that's a pretty standard convention.

ReactiveValidatedObject.ValidationObservable semantics of Value

Is it just me or is it counter intuitive for the IObservedChange<object,bool> items produced by ValidationObservable to have semantics which mean the item is invalid when Value is true? It seems like we should be returning true for items which are valid and false for invalid items.

Also am I the only one who feels that a method which fully validates the object would be useful. What if you want to show all invalid properties up front?

WPF Rx.NET DLL reference not added - using Event Loop

Hi Paul,
I'm getting all over this error message from your lib, when you are looking for "System.Reactive.Concurrency.DispatcherScheduler". I'm doing something wrong? I can not find any so called class on the Rx.Dlls.

bye,
Zool

ObservableAsPropertyHelper raising PropertyChanged on thread other than the UI thread in Silverlight

In the "Implementing search with ObservableAsPropertyHelper" blog post it's stated

One of the cool things about ObservableAsPropertyHelper, is that it guarantees that it will run notifications on the UI thread via the Dispatcher so that you don’t have to think about what thread the observable notification came in on.

When I use the following code

_CurrentCustomer = new ObservableAsPropertyHelper(currentNameObservable, _ => this.RaisePropertyChanged("CurrentCustomer"));

I get a System.UnauthorizedAccessException("Invalid cross-thread access.") in ReactiveObject.RaisePropertyChanged(string propertyName) every time currentNameObservable raises a new value.

The problem seems to be that the default IScheduler for ObservableAsPropertyHelper is not the Dispatcher. At the end of the RxApp static constructor you have

if (InUnitTestRunner())
{
//...
}
else
{
DeferredScheduler = Scheduler.Dispatcher;
}

if SILVERLIGHT

DeferredScheduler = Scheduler.ThreadPool;

else

TaskpoolScheduler = Scheduler.TaskPool;

endif

which resets the DeferredScheduler for Silverlight to Scheduler.ThreadPool. I'm guessing that assignment for #if SILVERLIGHT should have been

TaskpoolScheduler = Scheduler.ThreadPool;

ValidatesViaMethodAttribute with generated error message

It would be nice to have the ValidatesViaMethodAttribute allow error messages to be generated in code. Maybe the signature of IsValid could return a string instead of a bool, and it would return null or empty if there's no error.

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.