Merge remote-tracking branch 'refs/remotes/Microsoft/master'

This commit is contained in:
Umachandar Jayachandran
2017-02-20 09:37:52 -08:00
307 changed files with 28883 additions and 1856 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

@@ -1,4 +1,4 @@
# Contoso Retail Data Warehose
# Contoso Retail Data Warehouse
Loads data from a public Azure Storage Blob into the Contoso Retail Data Warehouse schema in Azure SQL Data Warehouse.
@@ -1,5 +0,0 @@
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
@@ -59,4 +59,4 @@ GO
INNER JOIN Person.Person AS p ON h.CustomerID = p.BusinessEntityID
INNER JOIN Production.Product AS pr ON d.ProductID = pr.ProductID
) SELECT * FROM Prices;
GO
GO
@@ -58,4 +58,4 @@ GO
INNER JOIN Person.Person AS p ON h.CustomerID = p.BusinessEntityID
INNER JOIN Production.Product AS pr ON d.ProductID = pr.ProductID
) SELECT * FROM Prices;
GO
GO
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -30,7 +30,7 @@ GO
-- Get Actual Execution Plan
-- Execute the stored procedure first with parameter value WA which will select 1% of data.
-- Execute the stored procedure first with parameter value WA which will select 1% of data.
DBCC FREEPROCCACHE
GO
EXEC CustomersByState 'WA'
@@ -49,4 +49,4 @@ it is split into sub-partitions, which are also processed separately.
This splitting process continues until each partition fits into available memory
or until the maximum recursion level is reached.
In this case it stopped at level 1.
*/
*/
@@ -18,4 +18,4 @@ GO
In SELECT node properties:
MaxQueryMemory for maximum query memory grant under RG MAX_MEMORY_PERCENT hint
MaxCompileMemory for maximum query optimizer memory in KB during compile under RG
*/
*/
@@ -18,4 +18,4 @@ GO
/*
Observe the type of Spill = 1
Means one pass over the data was enough to complete the sort in the Worktable
*/
*/
@@ -8,4 +8,5 @@ obj/*
*.lock.json
Properties/PublishProfiles/*
appsettings.Development.json
appsettings.Production.json
appsettings.Production.json
*.ndjson
@@ -28,17 +28,21 @@ namespace ProductCatalog.Controllers
[HttpGet("login")]
public void Login(string id)
{
try
if(id=="0")
ControllerContext.HttpContext.Session.Remove("CompanyID");
else
ControllerContext.HttpContext.Session.SetString("CompanyID", id);
string referer;
switch (Request.Query["page"])
{
if(id=="0")
ControllerContext.HttpContext.Session.Remove("CompanyID");
else
ControllerContext.HttpContext.Session.SetString("CompanyID", id);
Response.Redirect("/index.html");
} catch (Exception ex)
{
Response.WriteAsync(ex.Message);
case "index": referer = "/index.html"; break;
case "report1": referer = "/report-pie.html"; break;
case "report2": referer = "/report-multibar.html"; break;
case "dashboard": referer = "/dashboard.html"; break;
case "temporal": referer = "/temporal.html"; break;
default: referer = "/index.html"; break;
}
Response.Redirect(referer);
}
}
}
@@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Mvc;
using ProductCatalog.Models;
using System;
using System.Linq;
namespace ProductCatalog.Controllers
{
public class ProductCatalogController : Controller
{
private ProductCatalogContext _context;
public ProductCatalogController (ProductCatalogContext context)
{
_context = context;
}
[HttpGet]
public IActionResult Index()
{
ViewData["page"] = "index";
return View(_context.Products.AsEnumerable());
}
// POST api/ProductCatalog/Add
public IActionResult Add(Product p)
{
try
{
_context.Products.Add(p);
_context.SaveChanges();
return Redirect("/ProductCatalog/Index");
} catch (Exception)
{
return Redirect("/ProductCatalog/Index");
}
}
public IActionResult Report1()
{
ViewData["page"] = "report1";
return View();
}
public IActionResult Report2()
{
ViewData["page"] = "report2";
return View();
}
}
}
@@ -1,9 +1,9 @@
using Belgrade.SqlClient;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Threading.Tasks;
// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
@@ -16,18 +16,28 @@ namespace ProductCatalog.Controllers
IQueryPipe sqlQuery = null;
ICommand sqlCmd = null;
private readonly string EMPTY_PRODUCTS_ARRAY = "{\"data\":[]}";
private readonly byte[] EMPTY_PRODUCTS_ARRAY_GZIPPED = new byte[] {0x1F,0x8B,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xAB,0x66,0x50,0x62,0x48,0x61,0x48,0x64,0x28,0x01,0x62,0x25,0x06,0x2B,0x86,0x68,0x86,0x58,0x86,0x5A,0x06,0x00,0xB3,0x4C,0x62,0xB2,0x16,0x00,0x00,0x00};
private readonly byte[] EMPTY_PRODUCTS_ARRAY_GZIPPED = new byte[] { 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xAB, 0x66, 0x50, 0x62, 0x48, 0x61, 0x48, 0x64, 0x28, 0x01, 0x62, 0x25, 0x06, 0x2B, 0x86, 0x68, 0x86, 0x58, 0x86, 0x5A, 0x06, 0x00, 0xB3, 0x4C, 0x62, 0xB2, 0x16, 0x00, 0x00, 0x00 };
private readonly ILogger logger;
public ProductController(IQueryPipe sqlQueryService, ICommand sqlCommandService)
public ProductController(IQueryPipe sqlQueryService, ICommand sqlCommandService, ILogger<ProductController> logger)
{
this.sqlQuery = sqlQueryService;
this.sqlCmd = sqlCommandService;
this.logger = logger;
}
// GET api/Product
public async Task Get()
{
await sqlQuery.Stream(@"
await sqlQuery
.OnError(
ex =>
{
logger.LogError("Error while trying to get products: {Error}\n{StackTrace}", ex.Message, ex.StackTrace);
this.Response.StatusCode = 500;
throw ex;
})
.Stream(@"
select ProductID, Name, Color, Price, Quantity,
JSON_VALUE(Data, '$.MadeIn') as MadeIn, JSON_QUERY(Tags) as Tags
from Product
@@ -64,7 +74,7 @@ FOR JSON PATH, WITHOUT_ARRAY_WRAPPER");
cmd.Parameters.AddWithValue("id", id);
await sqlQuery.Stream(cmd, Response.Body, "{}");
}
// POST api/Product
[HttpPost]
public async Task Post()
@@ -116,7 +126,47 @@ FOR JSON PATH, WITHOUT_ARRAY_WRAPPER");
var cmd = new SqlCommand("EXEC RestoreProduct @productid, @date");
cmd.Parameters.AddWithValue("@productid", ProductId);
cmd.Parameters.AddWithValue("@date", DateModified);
this.sqlCmd.ExecuteNonQuery(cmd);
this.sqlCmd
.OnError(
ex =>
{
logger.LogError("Error while trying to restore product with id {ProductID} from time {DateModified}.\n{Error}\n{StackTrace}", ProductId, DateModified, ex.Message, ex.StackTrace);
this.Response.StatusCode = 500;
throw ex;
})
.ExecuteNonQuery(cmd);
}
[HttpGet("Report1")]
[Produces("application/json")]
public async Task Report1()
{
await sqlQuery
.Stream(@"
select color as x, sum(quantity) as y
from product
where color is not null
group by color
for json path", Response.Body, EMPTY_PRODUCTS_ARRAY);
}
[HttpGet("Report2")]
[Produces("application/json")]
public async Task Report2()
{
await sqlQuery
.Stream(@"
select name as [key], [values].x, [values].y
from company
join (select companyid, color as x, sum(quantity) as y
from product
where color is not null
group by companyid, color
) as [values] on company.companyid = [values].companyid
order by company.companyid
for json auto", Response.Body, EMPTY_PRODUCTS_ARRAY);
}
}
}
@@ -0,0 +1,74 @@
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ProductCatalog.Models
{
[Table("Product")]
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Color { get; set; }
public string Size { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
public int CompanyID { get; set; }
[NotMapped]
public string[] Tags
{
get { return _Tags == null ? null : JsonConvert.DeserializeObject<string[]>(_Tags); }
set { _Tags = JsonConvert.SerializeObject(value); }
}
internal string _Tags { get; set; }
[NotMapped]
public Properties Data
{
get { return (this._Data == null) ? null : JsonConvert.DeserializeObject<Properties>(this._Data); }
set { _Data = JsonConvert.SerializeObject(value); }
}
internal string _Data { get; set; }
}
public class Properties
{
public string Type { get; set; }
public string MadeIn { get; set; }
}
public class ProductCatalogContext : DbContext
{
public ProductCatalogContext(DbContextOptions<ProductCatalogContext> options)
: base(options)
{ }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(x => x.ProductId)
.HasDefaultValueSql("NEXT VALUE FOR ProductId");
modelBuilder.Entity<Product>()
.Property(b => b._Tags).HasColumnName("Tags");
modelBuilder.Entity<Product>()
.Property(b => b._Data).HasColumnName("Data");
}
public DbSet<Product> Products { get; set; }
}
}
@@ -7,7 +7,7 @@
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>7e230e5a-b0b6-4f56-9561-942fd1817b80</ProjectGuid>
<RootNamespace>product_catalog</RootNamespace>
<RootNamespace>ProductCatalog</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
@@ -11,7 +11,7 @@
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "index.html",
"launchUrl": "ProductCatalog/Index",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
@@ -19,7 +19,7 @@
"ProductCatalog": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000/index.html",
"launchUrl": "http://localhost:5000/ProductCatalog/Index",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
@@ -1,12 +1,17 @@
using Belgrade.SqlClient;
using Belgrade.SqlClient.SqlDb;
using Belgrade.SqlClient.SqlDb;
using Belgrade.SqlClient.SqlDb.Rls;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ProductCatalog.Models;
using Serilog;
#if NET46
using Serilog.Sinks.MSSqlServer;
#endif
using System;
using System.Data.SqlClient;
using System.Linq;
@@ -23,6 +28,24 @@ namespace ProductCatalog
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
#if NETCOREAPP1_0
Log.Logger = new LoggerConfiguration()
.WriteTo.RollingFile(new Serilog.Formatting.Json.JsonFormatter(), System.IO.Path.Combine(env.ContentRootPath, "log-{Date}.ndjson"))
.CreateLogger();
#endif
#if NET46
var columnOptions = new ColumnOptions();
// Don't include the Properties XML column.
columnOptions.Store.Remove(StandardColumn.Properties);
columnOptions.Store.Remove(StandardColumn.MessageTemplate);
columnOptions.Store.Remove(StandardColumn.Exception);
// Do include the log event data as JSON.
columnOptions.Store.Add(StandardColumn.LogEvent);
Log.Logger = new LoggerConfiguration()
.WriteTo.MSSqlServer(Configuration["ConnectionStrings:BelgradeDemo"], "dbo.Logs", columnOptions: columnOptions)
.CreateLogger();
#endif
}
public IConfigurationRoot Configuration { get; }
@@ -30,30 +53,24 @@ namespace ProductCatalog
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//string ConnString = Configuration.GetConnectionString("BelgradeDemo");
string ConnString = Configuration["ConnectionStrings:BelgradeDemo"];
services.AddDbContext<ProductCatalogContext>(options => options.UseSqlServer(new SqlConnection(ConnString)));
// Adding data access services/components.
services.AddTransient<IQueryPipe>(
sp =>
{
return new QueryPipeSessionContextAdapter(
new QueryPipe(new SqlConnection(ConnString)),
"CompanyID",
() => GetCompanyIdFromSession(sp));
});
services.AddTransient(
sp => new QueryPipe(new SqlConnection(ConnString))
.AddRls("CompanyID",() => GetCompanyIdFromSession(sp))
);
services.AddTransient<ICommand>(
sp =>
{
return new CommandSessionContextAdapter(
new Command(new SqlConnection(ConnString)),
"CompanyID",
() => GetCompanyIdFromSession(sp));
});
services.AddTransient(
sp => new Command(new SqlConnection(ConnString))
.AddRls("CompanyID", () => GetCompanyIdFromSession(sp))
);
// Add framework services.
//// Add framework services.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddLogging();
services.AddSession();
services.AddMvc();
}
@@ -63,10 +80,17 @@ namespace ProductCatalog
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
loggerFactory.AddSerilog();
app.UseSession();
app.UseMvc();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=ProductCatalog}/{action=Index}");
});
}
/// <summary>
@@ -0,0 +1,124 @@
<div class="container">
<div class="clearfix">
<h1 class="pull-left">Products<span id="snapshot"></span></h1>
<button id="addProduct" type="button" class="btn btn-primary pull-right" data-toggle="modal" data-target="#modalAddProduct">
<span class="glyphicon glyphicon-plus"></span> Add
</button>
</div>
<!-- Bootstrap Modal (ADD) -->
<div class="modal fade" id="modalAddProduct" tabindex="-1" role="dialog" aria-labelledby="myModalAddProductLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalAddProductLabel">Add new product</h4>
</div>
<div class="modal-body">
<!-- Bootstrap form -->
<form id="AddProductForm" action="~/ProductCatalog/Add" method="post">
<div class="form-group">
<label for="Name">Title</label>
<input type="text" class="form-control" name="Name" placeholder="Title">
</div>
<div class="form-group">
<label for="Color">Color</label>
<select class="form-control" name="Color">
<option value="">N/A</option>
<option value="White">White</option>
<option value="Silver">Silver</option>
<option value="Magenta">Magenta</option>
<option value="Red">Red</option>
<option value="Multi">Multi</option>
<option value="Black">Black</option>
</select>
</div>
<div class="form-group">
<label for="Price" class="field-label">Price</label>
<input type="text" name="Price" class="form-control">
</div>
<div class="form-group">
<label for="Data.MadeIn" class="field-label">Made In</label>
<input type="text" name="Data.MadeIn" class="form-control">
</div>
<div class="form-group">
<label for="Tags[]">Tags</label>
<select class="form-control" name="Tags[]" multiple>
<option value="sales">Sales</option>
<option value="promo">Promo</option>
<option value="new">New</option>
</select>
</div>
<div class="form-group">
<label for="Company">Company</label>
<select class="form-control" name="CompanyID" id="CompanyList"></select>
</div>
<!-- Allow form submission with keyboard without duplicating the dialog button -->
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
</form>
<!-- End Bootstrap form -->
</div>
<div class="modal-footer">
<button id="cancelAddButton" type="reset" class="btn btn-link" data-dismiss="modal">Close</button>
<button id="submitAddButton2" type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-save"></span> Save</button>
</div>
</div>
</div>
</div>
<!-- End Bootstrap modal -->
<!-- JQuery DataTable -->
<table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Product</th>
<th>Color</th>
<th>Price</th>
<th>Quantity</th>
<th>Made in</th>
<th>Tags</th>
</tr>
</thead>
<tbody>
@foreach (var product in Model)
{
<tr>
<td>@product.Name</td>
<td>@product.Color</td>
<td>@product.Price</td>
<td>@product.Quantity</td>
<td>@(product.Data == null ? string.Empty : product.Data.MadeIn)</td>
<td>@(product.Tags==null ? string.Empty : string.Join(", ", product.Tags))</td>
</tr>
}
</tbody>
</table>
<!-- End JQuery DataTable -->
</div>
@section styles {
<link href="~/media/css/jquery-ui/jquery-ui.css" rel="stylesheet" />
<link href="~/media/css/dataTables.bootstrap.css" rel="stylesheet" />
<link href="~/media/css/toastr.min.css" rel="stylesheet" />
<link href="~/media/css/products.css" rel="stylesheet" />
}
@section scripts {
<script src="~/media/js/lib/jquery-ui.js"></script>
<script src="~/media/js/lib/jquery.dataTables.js"></script>
<script src="~/media/js/lib/jquery.dataTables.Bootstrap.js"></script>
<script src="~/media/js/lib/jquery.html-template.js"></script>
<script src="~/media/js/lib/jquery.serializejson.js"></script>
<script src="~/media/js/lib/toastr.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#example').DataTable();
});
</script>
<script src="~/media/js/products-crud.js"></script>
}
@@ -0,0 +1,80 @@
<div class="testBlock"><svg id="test1"></svg></div>
<div class="testBlock"><svg id="test2"></svg></div>
@section styles {
<link href="~/media/js/lib/nvd3/nv.d3.min.css" rel="stylesheet" />
<style>
text {
font: 12px sans-serif;
}
.testBlock {
display: block;
float: left;
height: 300px;
width: 300px;
}
html, body {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
</style>
}
@section scripts {
<script src="~/media/js/lib/nvd3/d3.min.js" charset="utf-8"></script>
<script src="~/media/js/lib/nvd3/nv.d3.min.js"></script>
<script>
$.ajax('/data/nvd3-pie.js', { "dataType": "json" })
//$.ajax('/api/Product/Report1', { "dataType": "json" })
.done(function (testdata) {
var width = 300;
var height = 300;
nv.addGraph(function () {
var chart = nv.models.pie()
.width(width)
.height(height)
.labelType(function (d, i, values) {
return values.key + ':' + values.value;
})
;
d3.select("#test1")
.datum([testdata])
.transition().duration(1200)
.attr('width', width)
.attr('height', height)
.call(chart);
return chart;
});
nv.addGraph(function () {
var chart = nv.models.pie()
.x(function (d) { return d.x; })
.y(function (d) { return d.y; })
.width(width)
.height(height)
.labelType('percent')
.valueFormat(d3.format('%'))
.donut(true);
d3.select("#test2")
.datum([testdata])
.transition().duration(1200)
.attr('width', width)
.attr('height', height)
.call(chart);
return chart;
});
});
</script>
}
@@ -0,0 +1,57 @@
<div id="chart1">
<svg></svg>
</div>
@section styles {
<link href="~/media/js/lib/nvd3/nv.d3.min.css" rel="stylesheet" />
<style>
text {
font: 12px sans-serif;
}
svg {
display: block;
}
html, body, #chart1, svg {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
</style>
}
@section scripts {
<script src="~/media/js/lib/nvd3/d3.min.js" charset="utf-8"></script>
<script src="~/media/js/lib/nvd3/nv.d3.min.js"></script>
<script>
$.ajax('/data/nvd3-multibar.js', { "dataType": "json" })
//$.ajax('/api/Product/Report2', { "dataType": "json" })
.done(function (exampleData) {
nv.addGraph(function () {
var chart = nv.models.multiBarChart()
.height(400)
.reduceXTicks(true) //If 'false', every single x-axis tick label will be rendered.
.rotateLabels(0) //Angle to rotate x-axis labels.
.showControls(false) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1) //Distance between each group of bars.
;
chart.yAxis
.tickFormat(d3.format(',.1f'));
d3.select('#chart1 svg')
.datum(exampleData)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
});
</script>
}
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" type="image/ico" href="/favicon.ico">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=2.0">
<title>Product Catalog</title>
<link href="~/media/css/Bootstrap.css" rel="stylesheet" />
@RenderSection("styles", required: false)
</head>
<body id='@ViewData["page"]'>
<!-- Static navbar -->
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/index.html">Product Catalog Demo</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="index"><a href="~/ProductCatalog/Index">Product list</a></li>
</ul>
<ul class="nav navbar-nav pull-right">
<li class="dropdown pull-right">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Current user: <span class="UserGreeting">Admin</span><span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href='/api/Company/login?id=0&page=@ViewData["page"]' class="user-role">Admin</a></li>
<li><a href='/api/Company/login?id=1&page=@ViewData["page"]' class="user-role">A Datum Corporation</a></li>
<li><a href='/api/Company/login?id=2&page=@ViewData["page"]' class="user-role">Contoso, Ltd.</a></li>
<li><a href='/api/Company/login?id=3&page=@ViewData["page"]' class="user-role">Consolidated Messenger</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container-fluid -->
</nav>
<!-- End Static navbar -->
@RenderBody()
<script src="~/media/js/lib/jquery.js"></script>
<script>$("li." + $("body")[0].id).addClass("active");</script>
<script src="~/media/js/lib/Bootstrap.js"></script>
<script src="~/media/js/rls.js"></script>
@RenderSection("scripts", required: false)
</body>
</html>
@@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}
@@ -1,6 +1,6 @@
{
{
"Logging": {
"IncludeScopes": false,
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
@@ -8,6 +8,6 @@
}
},
"ConnectionStrings": {
"BelgradeDemo": "Server=.;Database=ProductCatalog;Integrated Security=true"
"BelgradeDemo": "Server=.\\SQLEXPRESS;Database=ProductCatalog;Integrated Security=true"
}
}
}
@@ -1,17 +1,22 @@
{
"dependencies": {
"Belgrade.Sql.Client": "0.6.0",
"Belgrade.Sql.Client": "0.6.2",
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.AspNetCore.Session": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Serilog": "2.3.0",
"Serilog.Extensions.Logging": "1.3.1",
"Serilog.Sinks.PeriodicBatching": "2.1.0",
"Serilog.Sinks.RollingFile": "3.3.0",
"System.Data.SqlClient": "4.1.0"
},
@@ -33,6 +38,7 @@
},
"net46": {
"dependencies": {
"Serilog.Sinks.MSSqlServer": "4.2.0"
}
}
},
@@ -35,7 +35,7 @@ CREATE TABLE Product (
GO
DECLARE @products NVARCHAR(MAX) =
N'[{"ProductID":15,"Name":"Adjustable Race","Color":"Magenta","Size":"62","Price":100.0000,"Quantity":75,"CompanyID":1,"Data":{"Type":"Part","MadeIn":"China"},"DateModified":"2016-02-11T21:27:32"},{"ProductID":16,"Name":"Bearing Ball","Color":"Magenta","Size":"62","Price":15.9900,"Quantity":90,"CompanyID":2,"Data":{"ManufacturingCost":11.672700,"Type":"Part","MadeIn":"China"},"Tags":["promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":17,"Name":"BB Ball Bearing","Color":"Magenta","Size":"62","Price":28.9900,"Quantity":80,"CompanyID":3,"Data":{"ManufacturingCost":21.162700,"Type":"Part","MadeIn":"China"},"DateModified":"2016-02-11T21:27:32"},{"ProductID":18,"Name":"Blade","Color":"Magenta","Size":"62","Price":18.0000,"Quantity":45,"CompanyID":4,"Data":{},"Tags":["new"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":19,"Name":"Sport-100 Helmet, Red","Color":"Red","Size":"72","Price":41.9900,"Quantity":38,"CompanyID":3,"Data":{"ManufacturingCost":30.652700,"Type":"Еquipment","MadeIn":"China"},"Tags":["promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":20,"Name":"Sport-100 Helmet, Black","Color":"Black","Size":"72","Price":31.4900,"Quantity":60,"CompanyID":1,"Data":{"ManufacturingCost":22.987700,"Type":"Еquipment","MadeIn":"China"},"Tags":["new","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":21,"Name":"Mountain Bike Socks, M","Color":"White","Size":"M","Price":560.9900,"Quantity":30,"CompanyID":2,"Data":{"Type":"Clothes"},"Tags":["sales","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":22,"Name":"Mountain Bike Socks, L","Color":"White","Size":"L","Price":120.9900,"Quantity":20,"CompanyID":3,"Data":{"ManufacturingCost":88.322700,"Type":"Clothes"},"Tags":["sales","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":23,"Name":"Long-Sleeve Logo Jersey, XL","Color":"Multi","Size":"XL","Price":44.9900,"Quantity":60,"CompanyID":4,"Data":{"ManufacturingCost":32.842700,"Type":"Clothes"},"Tags":["sales","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":24,"Name":"Road-650 Black, 52","Color":"Black","Size":"52","Price":704.6900,"Quantity":70,"CompanyID":5,"Data":{"Type":"Bike","MadeIn":"UK"},"DateModified":"2016-02-11T21:27:32"},{"ProductID":25,"Name":"Mountain-100 Silver, 38","Color":"Silver","Size":"38","Price":359.9900,"Quantity":45,"CompanyID":1,"Data":{"ManufacturingCost":262.792700,"Type":"Bike","MadeIn":"UK"},"Tags":["promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":26,"Name":"Road-250 Black, 48","Color":"Black","Size":"48","Price":299.0200,"Quantity":25,"CompanyID":2,"Data":{"ManufacturingCost":218.284600,"Type":"Bike","MadeIn":"UK"},"Tags":["new","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":27,"Name":"ML Bottom Bracket","Price":101.2400,"Quantity":50,"CompanyID":3,"Data":{"Type":"Part","MadeIn":"China"},"DateModified":"2016-02-11T21:27:32"},{"ProductID":28,"Name":"HL Bottom Bracket","Price":121.4900,"Quantity":65,"CompanyID":4,"Data":{"ManufacturingCost":88.687700,"Type":"Part","MadeIn":"China"},"DateModified":"2016-02-11T21:27:32"}]'
N'[{"ProductID":15,"Name":"Adjustable Race","Color":"Magenta","Size":"62","Price":100.0000,"Quantity":75,"CompanyID":1,"Data":{"Type":"Part","MadeIn":"China"},"DateModified":"2016-02-11T21:27:32"},{"ProductID":16,"Name":"Bearing Ball","Color":"Magenta","Size":"62","Price":15.9900,"Quantity":90,"CompanyID":2,"Data":{"ManufacturingCost":11.672700,"Type":"Part","MadeIn":"China"},"Tags":["promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":17,"Name":"BB Ball Bearing","Color":"Magenta","Size":"62","Price":28.9900,"Quantity":80,"CompanyID":3,"Data":{"ManufacturingCost":21.162700,"Type":"Part","MadeIn":"China"},"DateModified":"2016-02-11T21:27:32"},{"ProductID":18,"Name":"Blade","Color":"Silver","Size":"62","Price":18.0000,"Quantity":45,"CompanyID":1,"Data":{},"Tags":["new"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":19,"Name":"Sport-100 Helmet, Red","Color":"Black","Size":"72","Price":41.9900,"Quantity":38,"CompanyID":3,"Data":{"ManufacturingCost":30.652700,"Type":"Еquipment","MadeIn":"China"},"Tags":["promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":20,"Name":"Sport-100 Helmet, Black","Color":"Black","Size":"72","Price":31.4900,"Quantity":60,"CompanyID":1,"Data":{"ManufacturingCost":22.987700,"Type":"Еquipment","MadeIn":"China"},"Tags":["new","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":21,"Name":"Mountain Bike Socks, M","Color":"White","Size":"M","Price":560.9900,"Quantity":30,"CompanyID":2,"Data":{"Type":"Clothes"},"Tags":["sales","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":22,"Name":"Mountain Bike Socks, L","Color":"White","Size":"L","Price":120.9900,"Quantity":20,"CompanyID":3,"Data":{"ManufacturingCost":88.322700,"Type":"Clothes"},"Tags":["sales","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":23,"Name":"Long-Sleeve Logo Jersey, XL","Color":"White","Size":"XL","Price":44.9900,"Quantity":60,"CompanyID":1,"Data":{"ManufacturingCost":32.842700,"Type":"Clothes"},"Tags":["sales","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":24,"Name":"Road-650 Black, 52","Color":"Black","Size":"52","Price":704.6900,"Quantity":70,"CompanyID":1,"Data":{"Type":"Bike","MadeIn":"UK"},"DateModified":"2016-02-11T21:27:32"},{"ProductID":25,"Name":"Mountain-100 Silver, 38","Color":"White","Size":"38","Price":359.9900,"Quantity":45,"CompanyID":1,"Data":{"ManufacturingCost":262.792700,"Type":"Bike","MadeIn":"UK"},"Tags":["promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":26,"Name":"Road-250 Black, 48","Color":"Black","Size":"48","Price":299.0200,"Quantity":25,"CompanyID":2,"Data":{"ManufacturingCost":218.284600,"Type":"Bike","MadeIn":"UK"},"Tags":["new","promo"],"DateModified":"2016-02-11T21:27:32"},{"ProductID":27,"Name":"ML Bottom Bracket","Color":"Silver","Size":"36","Price":101.2400,"Quantity":50,"CompanyID":3,"Data":{"Type":"Part","MadeIn":"China"},"DateModified":"2016-02-11T21:27:32"},{"ProductID":28,"Name":"HL Bottom Bracket","Color":"Silver","Size":"36","Price":121.4900,"Quantity":65,"CompanyID":2,"Data":{"ManufacturingCost":88.687700,"Type":"Part","MadeIn":"China"},"DateModified":"2016-02-11T21:27:32"}]'
INSERT INTO Product (ProductID, Name, Color, Size, Price, Quantity, CompanyID, Data, Tags, DateModified)
SELECT ProductID, Name, Color, Size, Price, Quantity, CompanyID, Data, Tags, DateModified
FROM OPENJSON (@products) WITH(
@@ -53,6 +53,7 @@ CREATE TABLE Company (
CompanyID int PRIMARY KEY DEFAULT (NEXT VALUE FOR CompanyId),
Name nvarchar(50) NOT NULL,
Address nvarchar(100) NULL,
Contact nvarchar(100) NULL,
Email nvarchar(50) NULL,
Phone nvarchar(50) NULL,
Postcode nvarchar(20) NULL,
@@ -60,11 +61,11 @@ CREATE TABLE Company (
GO
declare @companies nvarchar(max) =
N'[{"CompanyID":1,"Name":"A Datum Corporation","Email":"msavic@datum.com","Address":"Suite 10, 183838 Southwest Boulevard, Surrey","Phone":"(381) 555-7639","Postcode":"46077"},{"CompanyID":2,"Name":"Contoso, Ltd.","Email":"zmisic@contoso.com","Address":"Unit 2, 2934 Night Road, Jolimont","Phone":"(360) 555-4901","Postcode":"98253"},{"CompanyID":3,"Name":"Consolidated Messenger","Email":"rputnik@consolidated-messanger.com","Address":"894 Market Day Street, West Mont","Phone":"(415) 555-1105","Postcode":"94101"}]'
INSERT INTO Company (CompanyID, Name, Address, Email, Phone, Postcode)
SELECT CompanyID, Name, Address, Email, Phone, Postcode
N'[{"CompanyID":1,"Name":"A Datum Corporation","Email":"msavic@datum.com","Address":"Suite 10, 183838 Southwest Boulevard, Surrey","Contact":"Milunka Savic","Phone":"(381) 555-7639","Postcode":"46077"},{"CompanyID":2,"Name":"Contoso, Ltd.","Email":"zmisic@contoso.com","Address":"Unit 2, 2934 Night Road, Jolimont","Contact":"Zivojin Misic","Phone":"(360) 555-4901","Postcode":"98253"},{"CompanyID":3,"Name":"Consolidated Messenger","Contact":"Radomir Putnik","Email":"rputnik@consolidated-messanger.com","Address":"894 Market Day Street, West Mont","Phone":"(415) 555-1105","Postcode":"94101"}]'
INSERT INTO Company (CompanyID, Name, Address, Email, Phone, Postcode, Contact)
SELECT CompanyID, Name, Address, Email, Phone, Postcode, Contact
FROM OPENJSON (@companies)
WITH(CompanyID int, Name nvarchar(50), Address nvarchar(100), Email nvarchar(50), Phone nvarchar(50), Postcode nvarchar(20))
WITH(CompanyID int, Name nvarchar(50), Address nvarchar(100), Email nvarchar(50), Phone nvarchar(50), Postcode nvarchar(20),Contact nvarchar(100))
GO
DROP PROCEDURE IF EXISTS [dbo].[InsertProductFromJson]
@@ -112,3 +113,15 @@ AS BEGIN
END
GO
DROP TABLE IF EXISTS Logs;
GO
CREATE TABLE Logs (
Id int IDENTITY PRIMARY KEY,
Message nvarchar(max) NULL,
MessageTemplate nvarchar(max) NULL,
Level nvarchar(128) NULL,
TimeStamp datetimeoffset(7) NOT NULL,
Exception nvarchar(max) NULL,
Properties xml NULL,
LogEvent nvarchar(max) NULL
);
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="media/css/Bootstrap.css" rel="stylesheet" />
<link href="media/js/lib/nvd3/nv.d3.min.css" rel="stylesheet" />
<script src="media/js/lib/jquery.js"></script>
<script src="media/js/lib/jquery.html-template.js"></script>
<script src="media/js/lib/nvd3/d3.min.js"></script>
<script src="media/js/lib/nvd3/nv.d3.min.js"></script>
<script src="media/js/lib/Bootstrap.js"></script>
<script src="media/js/rls.js"></script>
<script src="media/js/dashboard.js"></script>
</head>
<body>
<!-- Static navbar -->
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/ProductCatalog/Index">Product Catalog Demo</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="index.html">Product List</a></li>
<li class="active"><a href="#">Dashboard</a></li>
<li><a href="temporal.html">Product History</a></li>
</ul>
<ul class="nav navbar-nav pull-right">
<li class="dropdown pull-right">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Current user: <span class="UserGreeting">Admin</span><span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="/api/Company/login?id=0&page=dashboard" class="user-role">Admin</a></li>
<li><a href="/api/Company/login?id=1&page=dashboard" class="user-role">A Datum Corporation</a></li>
<li><a href="/api/Company/login?id=2&page=dashboard" class="user-role">Contoso, Ltd.</a></li>
<li><a href="/api/Company/login?id=3&page=dashboard" class="user-role">Consolidated Messenger</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container-fluid -->
</nav>
<!-- End Static navbar -->
<div class="container-fluid">
<div class="row">
<div class="col-xs-3">
<svg id="pie1"></svg>
</div>
<div class="col-xs-3">
<svg id="pie2"></svg>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<svg id="chart1"></svg>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,104 @@
{
"data": [{
"ProductID": 15,
"Name": "Adjustable Race",
"Color": "Magenta",
"Price": 100.0000,
"Quantity": 75,
"MadeIn": "China"
}, {
"ProductID": 16,
"Name": "Bearing Ball",
"Color": "Magenta",
"Price": 15.9900,
"Quantity": 90,
"MadeIn": "China",
"Tags": ["promo"]
}, {
"ProductID": 17,
"Name": "BB Ball Bearing",
"Color": "Magenta",
"Price": 28.9900,
"Quantity": 80,
"MadeIn": "China"
}, {
"ProductID": 18,
"Name": "Blade",
"Color": "Magenta",
"Price": 18.0000,
"Quantity": 45,
"Tags": ["new"]
}, {
"ProductID": 19,
"Name": "Sport-100 Helmet, Red",
"Color": "Red",
"Price": 41.9900,
"Quantity": 38,
"MadeIn": "China",
"Tags": ["promo"]
}, {
"ProductID": 20,
"Name": "Sport-100 Helmet, Black",
"Color": "Black",
"Price": 31.4900,
"Quantity": 60,
"MadeIn": "China",
"Tags": ["new", "promo"]
}, {
"ProductID": 21,
"Name": "Mountain Bike Socks, M",
"Color": "White",
"Price": 560.9900,
"Quantity": 30,
"Tags": ["sales", "promo"]
}, {
"ProductID": 22,
"Name": "Mountain Bike Socks, L",
"Color": "White",
"Price": 120.9900,
"Quantity": 20,
"Tags": ["sales", "promo"]
}, {
"ProductID": 23,
"Name": "Long-Sleeve Logo Jersey, XL",
"Color": "Multi",
"Price": 44.9900,
"Quantity": 60,
"Tags": ["sales", "promo"]
}, {
"ProductID": 24,
"Name": "Road-650 Black, 52",
"Color": "Black",
"Price": 704.6900,
"Quantity": 70,
"MadeIn": "UK"
}, {
"ProductID": 25,
"Name": "Mountain-100 Silver, 38",
"Color": "Silver",
"Price": 359.9900,
"Quantity": 45,
"MadeIn": "UK",
"Tags": ["promo"]
}, {
"ProductID": 26,
"Name": "Road-250 Black, 48",
"Color": "Black",
"Price": 299.0200,
"Quantity": 25,
"MadeIn": "UK",
"Tags": ["new", "promo"]
}, {
"ProductID": 27,
"Name": "ML Bottom Bracket",
"Price": 101.2400,
"Quantity": 50,
"MadeIn": "China"
}, {
"ProductID": 28,
"Name": "HL Bottom Bracket",
"Price": 121.4900,
"Quantity": 65,
"MadeIn": "China"
}]
}
@@ -0,0 +1,25 @@
[
{
"key": "A Datum Corporation",
"values": [
{ "x": "Black", "y": 31.4900 },
{ "x": "Magenta", "y": 100.0000 },
{ "x": "Silver", "y": 359.9900 }
]
},
{
"key": "Consolidated Messenger",
"values": [
{ "x": "Magenta", "y": 28.9900 },
{ "x": "Red", "y": 41.9900 },
{ "x": "White", "y": 120.9900 }
]
}, {
"key": "Contoso, Ltd.",
"values": [
{ "x": "White", "y": 560.9900 },
{ "x": "Magenta", "y": 15.9900 },
{ "x": "Black", "y": 299.0200 }
]
}
]
@@ -0,0 +1,9 @@
[
{ "x": "Red", "y": 5 },
{ "x": "Silver", "y": 2 },
{ "x": "Black", "y": 9 },
{ "x": "Red", "y": 7 },
{ "x": "Magenta", "y": 4 },
{ "x": "White", "y": 3 },
{ "x": "Blue", "y": 0.5 }
]

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -23,9 +23,9 @@
<script src="media/js/lib/jquery.serializejson.js"></script>
<script src="media/js/lib/toastr.min.js"></script>
<script src="media/js/products.js"></script>
<script src="media/js/products-temporal.js"></script>
<script type="text/javascript" src="media/js/products.js"></script>
<script src="media/js/products-crud.js"></script>
<script src="media/js/rls.js"></script>
</head>
<body>
<!-- Static navbar -->
@@ -38,20 +38,22 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Product Catalog Demo</a>
<a class="navbar-brand" href="/ProductCatalog/Index">Product Catalog Demo</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Products</a></li>
<li class="active"><a href="#">Product List</a></li>
<li><a href="dashboard.html">Dashboard</a></li>
<li><a href="temporal.html">Product History</a></li>
</ul>
<ul class="nav navbar-nav pull-right">
<li class="dropdown pull-right">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Current user: <span class="UserGreeting">Admin</span><span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="/api/Company/login?id=0" class="user-role">Admin</a></li>
<li><a href="/api/Company/login?id=1" class="user-role">A Datum Corporation</a></li>
<li><a href="/api/Company/login?id=2" class="user-role">Contoso, Ltd.</a></li>
<li><a href="/api/Company/login?id=3" class="user-role">Consolidated Messenger</a></li>
<li><a href="/api/Company/login?id=0&page=index" class="user-role">Admin</a></li>
<li><a href="/api/Company/login?id=1&page=index" class="user-role">A Datum Corporation</a></li>
<li><a href="/api/Company/login?id=2&page=index" class="user-role">Contoso, Ltd.</a></li>
<li><a href="/api/Company/login?id=3&page=index" class="user-role">Consolidated Messenger</a></li>
</ul>
</li>
</ul>
@@ -193,7 +195,6 @@
<table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th></th>
<th>Product</th>
<th>Color</th>
<th>Price</th>
@@ -202,7 +203,6 @@
<th>Tags</th>
<th>Edit</th>
<th>Delete</th>
<th>Restore</th>
</tr>
</thead>
<tbody></tbody>
@@ -0,0 +1,76 @@
$(function () {
//$.ajax('data/nvd3-pie.js', { "dataType": "json" })
$.ajax('api/Product/report1', { "dataType": "json" })
.done(function (testdata) {
var width = 300;
var height = 300;
nv.addGraph(function () {
var chart =
nv.models
.pie()
.width(width)
.height(height)
.labelType(function (d, i, values) {
return values.key + ':' + values.value;
});
d3.select("#pie1")
.datum([testdata])
.transition().duration(1200)
.attr('width', width)
.attr('height', height)
.call(chart);
return chart;
});
nv.addGraph(function () {
var chart = nv.models.pie()
.x(function (d) { return d.key; })
.y(function (d) { return d.y; })
.width(width)
.height(height)
.labelType('percent')
.valueFormat(d3.format('%'))
.donut(true);
d3.select("#pie2")
.datum([testdata])
.transition().duration(1200)
.attr('width', width)
.attr('height', height)
.call(chart);
return chart;
});
});
//$.ajax('data/nvd3-multibar.js', { "dataType": "json" })
$.ajax('api/Product/report2', { "dataType": "json" })
.done(function (exampleData) {
nv.addGraph(function () {
var chart = nv.models.multiBarChart()
.reduceXTicks(true) //If 'false', every single x-axis tick label will be rendered.
.rotateLabels(0) //Angle to rotate x-axis labels.
.showControls(false) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1) //Distance between each group of bars.
;
chart.yAxis
.tickFormat(d3.format(',.1f'));
d3.select('svg#chart1')
.datum(exampleData)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
});
});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More