Architecture & Design

Information on the design behind Periscope and the features/capabilities it has/will have...

Widget Data Updates (Push/Pull)

Widgets support both push and pull of data...(TODO)

Templated Widgets

Using dotLiquid templates you can quickly add a new widget - just define the markup and script, configure the widget and bingo!

The demo clock widget uses the dotLiquid template engine to define and render the markup for the widget and script it requires - take a look at the Wolfpack.Periscope.Hosts program.cs...

...the widget is configured to use MarkupTemplate and ScriptTemplate "clock" - this is convention for the clock.html and clock.js files located in Wolfpack.Periscope.Core\widgets\templates\clock folder. More templates and widgets will be supported but it's pretty easy to create one yourself!

Configuration

Right now the only way of configuring a dashboard is through fluent configuration in code. In the future it could support drag and drop configuration from the UI or other persisted (config files/db) storage.

Fluent Configuration example

Here is an example of configuring the clock widget; it uses the "clock" markup and script templates and boots up a "DataPump" with a one second interval; the callback on this interval is to push a signalr message to the widget with the payload of the datetime value to display.
var dashboard = bootstrapper.Configure(infrastructure =>
{
    var panelBuilder = DashboardConfigurationBuilder.New()
        .Add("PanelA", (infra, builder) => builder.Add<TemplatedWidget<TemplatedWidgetConfiguration>, TemplatedWidgetConfiguration>(
            cfg =>
            {
                cfg.Title = "ClockWidget";
                cfg.Name = "Time";
                cfg.Height = 250;
                cfg.Width = 550;
                cfg.MarkupTemplate = "clock";
                cfg.ScriptTemplate = "clock";
                cfg.RegisterInclude("moment", "/scripts/moment-min.js")
                    .AddTemplateData(new {FontSize = "20px"});
            },
            cfg => new DataPumpBootstrapper<IntervalDataPump>(infra,
                new IntervalDataPump(infra, TimeSpan.FromSeconds(1)), cfg,
                () =>
                {
                    var payload = DateTime.Now.ToString("s");
                    infra.MessageBus.Publish(new WidgetUpdateEvent(infra, new WidgetUpdate
                    {
                        Payload = payload,
                        Target = cfg.Name
                    }));

                    infra.Logger.LogDebug("Callback fired {0} on widget '{1}'", payload, cfg.Name);
                }))
            .SetDwellTime(60));


    infrastructure.Container.RegisterInstance(panelBuilder);
    infrastructure.Container.RegisterType<IDashboardConfigurationRepository, PresetRepository>();
    infrastructure.RegisterPlugin<SignalRPlugin>();
    infrastructure.RegisterPlugin<NancyFxSelfHostPlugin>();
    infrastructure.RegisterPlugin<RotatingPanelSelectorPlugin>();
    infrastructure.RegisterPlugin<BootstrapWidgetsPlugin>();
});


Last edited Apr 5, 2014 at 10:31 PM by jimbobdog, version 5