summaryrefslogtreecommitdiff
path: root/priv/static/metrics-graphics-3.0-alpha3/examples/charts
diff options
context:
space:
mode:
Diffstat (limited to 'priv/static/metrics-graphics-3.0-alpha3/examples/charts')
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/annotations.htm338
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/auto-time-formatting.htm296
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/axes.htm486
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/brushing_zooming.htm166
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/data.htm386
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/experimental.htm1159
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/lines.htm335
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/multilines.htm368
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/other.htm48
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/rollovers.htm309
-rw-r--r--priv/static/metrics-graphics-3.0-alpha3/examples/charts/updating.htm169
11 files changed, 4060 insertions, 0 deletions
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/annotations.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/annotations.htm
new file mode 100644
index 0000000..5bd4d11
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/annotations.htm
@@ -0,0 +1,338 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='markers'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/some_percentage.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var markers = [{
+ 'date': new Date('2014-02-01T00:00:00.000Z'),
+ 'label': '1st Milestone'
+ }, {
+ 'date': new Date('2014-03-15T00:00:00.000Z'),
+ 'label': '2nd Milestone'
+ }];
+
+ MG.data_graphic({
+ title: "Markers",
+ description: "Markers are vertical lines that can be added at arbitrary points. Markers that are close to each other won't collide.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ format: 'percentage',
+ target: '#markers'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='markers-clickable'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/some_percentage.json'>data</a></div>
+
+ <pre><code class='javascript'>d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var clicker = function() {
+ window.open('https://www.youtube.com/watch?v=dQw4w9WgXcQ', '_blank');
+ };
+
+ var markers = [{
+ 'date': new Date('2014-02-01T00:00:00.000Z'),
+ 'label': "Click me",
+ 'click': clicker
+ }, {
+ 'date': new Date('2014-03-15T00:00:00.000Z'),
+ 'label': "Nothing to see here"
+ }];
+
+ MG.data_graphic({
+ title: "Clickable Markers",
+ description: "You can assign arbitrary functions to markers' click events.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ format: 'percentage',
+ target: '#markers-clickable'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='markers-mouseover'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/some_percentage.json'>data</a></div>
+
+ <pre><code class='javascript'>d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var mouseover = function() {
+ alert("You are over me!");
+ };
+
+ var markers = [{
+ 'date': new Date('2014-02-01T00:00:00.000Z'),
+ 'label': "Place your mouse here",
+ 'mouseover': mouseover
+ }, {
+ 'date': new Date('2014-03-15T00:00:00.000Z'),
+ 'label': "Nothing to see here"
+ }];
+
+ MG.data_graphic({
+ title: "Mouse Over Markers",
+ description: "You can assign arbitrary functions to markers' mouseover events.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ format: 'percentage',
+ target: '#markers-mouseover'
+ });</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='markers-mouseout'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/some_percentage.json'>data</a></div>
+
+ <pre><code class='javascript'>d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var mouseout = function() {
+ alert("You just left me!");
+ };
+
+ var markers = [{
+ 'date': new Date('2014-02-01T00:00:00.000Z'),
+ 'label': "Place your mouse here and out!",
+ 'mouseout': mouseout
+ }, {
+ 'date': new Date('2014-03-15T00:00:00.000Z'),
+ 'label': "Nothing to see here"
+ }];
+
+ MG.data_graphic({
+ title: "Mouse Out Markers",
+ description: "You can assign arbitrary functions to markers' mouseout events.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ format: 'percentage',
+ target: '#markers-mouseout'
+ });</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='baselines'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users1.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Baselines",
+ description: "Baselines are horizontal lines that can added at arbitrary points.",
+ data: data,
+ baselines: [{value: 160000000, label: 'a baseline'}],
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#baselines'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center mg-main-area-solid' id='spike'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users1.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+
+ var markers = [{
+ 'date': new Date('2014-03-17T00:00:00.000Z'),
+ 'label': 'Look, a spike!'
+ }];
+
+ MG.data_graphic({
+ title: "Annotating a Point",
+ description: "By setting the graphic's target a class name of mg-main-area-solid, markers don't extend down to the bottom of the graphic, which better draws attention to, say, spikes.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ target: '#spike'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+<script>
+MG._hooks = {};
+d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var markers = [{
+ 'date': new Date('2014-02-01T00:00:00.000Z'),
+ 'label': '1st Milestone'
+ }, {
+ 'date': new Date('2014-03-15T00:00:00.000Z'),
+ 'label': '2nd Milestone'
+ }];
+
+ MG.data_graphic({
+ title: "Markers",
+ description: "Markers are vertical lines that can be added at arbitrary points. Markers that are close to each other won't collide.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ format: 'percentage',
+ target: '#markers'
+ });
+
+ var clicker = function() {
+ window.open('https://www.youtube.com/watch?v=dQw4w9WgXcQ', '_blank');
+ };
+
+ markers = [{
+ 'date': new Date('2014-02-01T00:00:00.000Z'),
+ 'label': "Click me",
+ 'click': clicker
+ }, {
+ 'date': new Date('2014-03-15T00:00:00.000Z'),
+ 'label': "Nothing to see here"
+ }];
+
+ MG.data_graphic({
+ title: "Clickable Markers",
+ description: "You can assign arbitrary functions to markers' click events.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ format: 'percentage',
+ target: '#markers-clickable'
+ });
+
+ var mouseover = function() {
+ alert("You are over me!");
+ };
+
+ markers = [{
+ 'date': new Date('2014-02-01T00:00:00.000Z'),
+ 'label': "Place your mouse here",
+ 'mouseover': mouseover
+ }, {
+ 'date': new Date('2014-03-15T00:00:00.000Z'),
+ 'label': "Nothing to see here"
+ }];
+
+ MG.data_graphic({
+ title: "Mouse Over Markers",
+ description: "You can assign arbitrary functions to markers' mouseover events.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ format: 'percentage',
+ target: '#markers-mouseover'
+ });
+
+ var mouseout = function() {
+ alert("You just left me!");
+ };
+
+ markers = [{
+ 'date': new Date('2014-02-01T00:00:00.000Z'),
+ 'label': "Place your mouse here and out!",
+ 'mouseout': mouseout
+ }, {
+ 'date': new Date('2014-03-15T00:00:00.000Z'),
+ 'label': "Nothing to see here"
+ }];
+
+ MG.data_graphic({
+ title: "Mouse Out Markers",
+ description: "You can assign arbitrary functions to markers' mouseout events.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ format: 'percentage',
+ target: '#markers-mouseout'
+ });
+
+});
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Baselines",
+ description: "Baselines are horizontal lines that can added at arbitrary points.",
+ data: data,
+ baselines: [{value: 160000000, label: 'goal'}],
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#baselines'
+ });
+});
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+
+ var markers = [{
+ 'date': new Date('2014-03-17T00:00:00.000Z'),
+ 'label': 'Look, a spike!'
+ }];
+
+ MG.data_graphic({
+ title: "Annotating a Point",
+ description: "By setting the graphic's target a class name of main-area-solid, markers don't extend down to the bottom of the graphic, which better draws attention to, say, spikes.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ markers: markers,
+ target: '#spike'
+ });
+});
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/auto-time-formatting.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/auto-time-formatting.htm
new file mode 100644
index 0000000..af132dd
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/auto-time-formatting.htm
@@ -0,0 +1,296 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='time1'></div>
+ <div class='col-lg-12 text-center' id='time2'></div>
+ <div class='col-lg-12 text-center' id='time3'></div>
+ <div class='col-lg-12 text-center' id='time4'></div>
+ <div class='col-lg-12 text-center' id='many-months'></div>
+ <div class='col-lg-12 text-center' id='a-few-years'></div>
+ <div class='col-lg-12 text-center' id='years'></div>
+ <div class='col-lg-12 text-center' id='decades'></div>
+ <div class='col-lg-12 text-center' id='centuries'></div>
+
+ </div>
+ </div>
+ <div class='col-lg-5'>
+
+ <pre><code class='javascript'>function fake_data(length, seconds) {
+ var d = new Date();
+ var v = 100000;
+ var data=[];
+
+ for (var i = 0; i < length; i++) {
+ v += (Math.random() - 0.5) * 10000;
+ data.push({date: MG.clone(d), value: v});
+ d = new Date(d.getTime() + seconds * 1000);
+ }
+ return data;
+}
+
+function fake_days(length) {
+ var d = new Date();
+ var v = 100000;
+
+ var data = [];
+ for (var i = 0; i < length; i++) {
+ v += (Math.random() - 0.5) * 10000;
+ if (v < 0) v = 0;
+ data.push({date: MG.clone(d), value: v});
+ d.setDate(d.getDate() + 1);
+ }
+ return data;
+}
+
+function fake_years(length) {
+ var y = 2015;
+ var d = new Date(y,0,1);
+ out = [];
+ v = 100000;
+ for (var i = 0; i < length; i++) {
+ v += (Math.random()-.5) * 10000;
+ out.push({value:v, date: MG.clone(d)});
+ y -=1;
+ d = new Date(y,0,1);
+ }
+ out.reverse();
+ return out;
+}
+
+
+var less_than_a_minute = fake_data(25, 1);
+var less_than_a_day = fake_data(25,60 * 20);
+var a_few_days = fake_data(75,60 * 60);
+var many_days = fake_days(60);
+var many_many_many_days = fake_days(365*2);
+var a_few_years = fake_days(365*4);
+
+MG.data_graphic({
+ title: "European Clock",
+ description: 'By setting european_clock to true, you can default to European-style time. This is at the moment experimental, and the formatting may change.',
+ data: less_than_a_minute,
+ target: '#european',
+ european_clock: true,
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Less Than A Minute",
+ data: less_than_a_minute,
+ target: '#time1',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Less Than A Day",
+ data: less_than_a_day,
+ target: '#time2',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "A Few Days",
+ data: a_few_days,
+ target: '#time3',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Over A Large Span of Days",
+ data: many_days,
+ target: '#time4',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Over Many Months",
+ data: many_many_many_days,
+ target: '#many-months',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Over A Few Years",
+ data: a_few_years,
+ target: '#a-few-years',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Over Centuries",
+ data: fake_years(300),
+ target: '#centuries',
+ width: 600,
+ height: 200,
+ right: 40
+});</code></pre>
+
+ </div>
+ </div>
+
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='european'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+
+ <pre><code class='javascript'>MG.data_graphic({
+ title: "European Clock",
+ description: 'By setting european_clock to true, you can default to European-style time. This is at the moment experimental, and the formatting may change.',
+ data: less_than_a_minute,
+ target: '#european',
+ european_clock: true,
+ width: 600,
+ height: 200,
+ right: 40
+});
+ </code></pre>
+
+ </div>
+ </div>
+
+<script>
+MG._hooks = {};
+function fake_data(length, seconds) {
+ var d = new Date();
+ var v = 100000;
+ var data=[];
+
+ for (var i = 0; i < length; i++) {
+ v += (Math.random() - 0.5) * 10000;
+ data.push({date: MG.clone(d), value: v});
+ d = new Date(d.getTime() + seconds * 1000);
+ }
+ return data;
+}
+
+function fake_days(length) {
+ var d = new Date();
+ var v = 100000;
+
+ var data = [];
+ for (var i = 0; i < length; i++) {
+ v += (Math.random() - 0.5) * 10000;
+ if (v < 0) v = 0;
+ data.push({date: MG.clone(d), value: v});
+ d.setDate(d.getDate() + 1);
+ }
+ return data;
+}
+
+function fake_years(length) {
+ var y = 2015;
+ var d = new Date(y,0,1);
+ out = [];
+ v = 100000;
+ for (var i = 0; i < length; i++) {
+ v += (Math.random()-.5) * 10000;
+ out.push({value:v, date: MG.clone(d)});
+ y -=1;
+ d = new Date(y,0,1);
+ }
+ out.reverse();
+ return out;
+}
+
+
+var less_than_a_minute = fake_data(25, 1);
+var less_than_a_day = fake_data(25,60 * 20);
+var a_few_days = fake_data(75,60 * 60);
+var many_days = fake_days(80);
+var many_many_many_days = fake_days(365*2);
+var a_few_years = fake_days(365*3);
+
+MG.data_graphic({
+ title: "European Clock",
+ description: 'By setting european_clock to true, you can default to European-style time. This is at the moment experimental, and the formatting may change.',
+ data: less_than_a_minute,
+ target: '#european',
+ european_clock: true,
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Less Than A Minute",
+ data: less_than_a_minute,
+ target: '#time1',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Less Than A Day",
+ data: less_than_a_day,
+ target: '#time2',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "A Few Days",
+ data: a_few_days,
+ target: '#time3',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Over A Large Span of Days",
+ data: many_days,
+ width:600,
+ target: '#time4',
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Over Many Months",
+ data: many_many_many_days,
+ target: '#many-months',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Over A Few Years",
+ data: a_few_years,
+ target: '#a-few-years',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+MG.data_graphic({
+ title: "Over Centuries",
+ data: fake_years(300),
+ target: '#centuries',
+ width: 600,
+ height: 200,
+ right: 40
+});
+
+
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/axes.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/axes.htm
new file mode 100644
index 0000000..375120a
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/axes.htm
@@ -0,0 +1,486 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='xnotdate'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/xnotdate.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/xnotdate.json', function(data) {
+ MG.data_graphic({
+ title: "Axis Labels",
+ description: "A graphic where we're not plotting dates on the x-axis and where the axes include labels and the line animates on load. We've also enabled extended ticks along the y-axis.",
+ data: data,
+ animate_on_load: true,
+ area: false,
+ width: 600,
+ height: 240,
+ right: 40,
+ left: 90,
+ bottom: 50,
+ y_extended_ticks: true,
+ target: '#xnotdate',
+ x_accessor: 'males',
+ y_accessor: 'females',
+ x_label: 'males',
+ y_label: 'females',
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='percentage'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/some_percentage.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Some Percentages",
+ description: "Here is an example that shows percentages.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ format: 'percentage',
+ target: '#percentage'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='currency'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/some_currency.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/some_currency.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Some Currency",
+ description: "Here is an example that uses custom units for currency.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#currency',
+ yax_units: '$'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='log1'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/log.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/log.json', function(data) {
+ data = [data];
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Log Scale",
+ description: "You can change the y-axis' scale to logarithmic by setting <i>y_scale_type</i> to <i>log</i>.",
+ data: data,
+ y_scale_type: 'log',
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#log1'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='col-lg-12 text-center' id='hidden1'></div>
+ <div class='col-lg-12 text-center' id='hidden2'></div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/fake_users1.json'>data 1</a>,
+ <a href='data/brief-1.json'>data 2</a>
+ </div>
+
+<pre><code class='javascript'>d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "No X Axis",
+ description: "You can hide either axis by setting <i>x_axis</i> or <i>y_axis</i> to false.",
+ data: data,
+ decimals: 0,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#hidden1',
+ area: false,
+ x_axis: false,
+ });
+});
+
+d3.json('data/brief-1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "No Y Axis",
+ description: "You can hide either axis by setting <i>x_axis</i> or <i>y_axis</i> to false.",
+ data: data,
+ decimals: 0,
+ width: 600,
+ height: 200,
+ right: 20,
+ xax_count: 4,
+ target: '#hidden2',
+ area: false,
+ y_axis: false
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='y_rug'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users1.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Rug Plots",
+ description: "You can set rug plots either axis by setting <i>x_rug</i> or <i>y_rug</i> to true.",
+ data: data,
+ decimals: 0,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#y_rug',
+ area: false,
+ y_rug: true
+ });
+});</code></pre>
+
+ </div>
+</div>
+
+
+
+
+
+
+
+
+
+
+<div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-6 text-center' id='axis-pos-1'></div>
+ <div class='col-lg-6 text-center' id='axis-pos-2'></div>
+ </div>
+ <div class='row'>
+ <div class='col-lg-6 text-center' id='axis-pos-3'></div>
+ <div class='col-lg-6 text-center' id='axis-pos-4'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/fake_users1.json'>data 1</a>,
+ <a href='data/brief-1.json'>data 2</a>
+ </div>
+
+<pre><code class='javascript'>d3.json('data/brief-1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ var position = [['left', 'top'],['right', 'top'], ['left', 'bottom'], ['right', 'bottom']];
+ position.forEach(function(pos,i) {
+ console.log(pos,i)
+ var i = i+1;
+
+ MG.data_graphic({
+ title: "Axis Positions: " + pos[0] +', ' + pos[1],
+ description: "Set <i>x_axis_position: " + pos[1] + "</i> and <i>x_axis_position: " + pos[0] +"</i>.",
+ x_axis_position: pos[1],
+ y_axis_position: pos[0],
+ data: data,
+ decimals: 0,
+ left: pos[0] === 'right' ? 20 : 50,
+ right: pos[0] === 'left' ? 20 : 50,
+ top: pos[1] === 'bottom' ? 50 : 50,
+ bottom: pos[1] === 'top' ? 25 : 50,
+ target: '#axis-pos-'+i,
+ area: false
+ });
+ })
+});</code></pre>
+
+ </div>
+</div>
+
+
+<script>
+d3.json('data/brief-1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ var position = [['left', 'top'],['right', 'top'], ['left', 'bottom'], ['right', 'bottom']];
+ position.forEach(function(pos,i) {
+ var i = i+1;
+
+ MG.data_graphic({
+ title: "Axis Positions: " + pos[0] +', ' + pos[1],
+ description: "Set <i>x_axis_position: " + pos[1] + "</i> and <i>x_axis_position: " + pos[0] +"</i>.",
+ x_axis_position: pos[1],
+ y_axis_position: pos[0],
+ data: data,
+ decimals: 0,
+ left: pos[0] === 'right' ? 20 : 50,
+ right: pos[0] === 'left' ? 20 : 50,
+ top: pos[1] === 'bottom' ? 50 : 50,
+ bottom: pos[1] === 'top' ? 25 : 50,
+ target: '#axis-pos-'+i,
+ area: false
+ });
+ })
+});
+</script>
+
+
+
+
+
+
+
+
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='col-lg-6 text-center' id='neg1'></div>
+ <div class='col-lg-6 text-center' id='neg2'></div>
+ <div class='col-lg-6 text-center' id='y-axis-not-zero'></div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/neg1.json'>data 1</a>,
+ <a href='data/neg2.json'>data 2</a>
+ </div>
+
+<pre><code class='javascript'>d3.json('data/neg1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Negative Values 1",
+ description: "MG defaults to 0 on the y-axis as min if there are no negative numbers. If there are negatives, should provide some buffer below.",
+ data: data,
+ width: 295,
+ height: 220,
+ right: 10,
+ target: '#neg1'
+ });
+
+ var data2 = MG.clone(data).map(function(d) {
+ d.value = d.value + 550;
+ return d;
+ });
+
+ MG.data_graphic({
+ title: "Y-Axis Not Zero",
+ data: data2,
+ width: 295,
+ height: 220,
+ right: 10,
+ min_y_from_data: true,
+ yax_units: '$',
+ target: '#y-axis-not-zero',
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});
+
+d3.json('data/neg2.json', function(data) {
+ MG.data_graphic({
+ title: "Negative Values 2",
+ data: data,
+ width: 295,
+ height: 220,
+ right: 10,
+ target: '#neg2',
+ x_accessor: 'subject',
+ y_accessor: 'measure'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+<script>
+MG._hooks = {};
+d3.json('data/xnotdate.json', function(data) {
+ MG.data_graphic({
+ title: "Axis Labels",
+ description: "A graphic where we're not plotting dates on the x-axis and where the axes include labels and the line animates on load. We've also enabled extended ticks along the y-axis.",
+ data: data,
+ animate_on_load: true,
+ area: false,
+ width: 600,
+ height: 240,
+ right: 40,
+ left: 90,
+ bottom: 50,
+ y_extended_ticks: true,
+ target: '#xnotdate',
+ x_accessor: 'males',
+ y_accessor: 'females',
+ x_label: 'males',
+ y_label: 'females',
+ });
+});
+
+d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Some Percentages",
+ description: "Here is an example that shows percentages.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ format: 'percentage',
+ target: '#percentage'
+ });
+});
+
+d3.json('data/some_currency.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Some Currency",
+ description: "Here is an example that uses custom units for currency.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#currency',
+ yax_units: '$'
+ });
+});
+
+d3.json('data/log.json', function(data) {
+ data = [data];
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Log Scale",
+ description: "You can change the y-axis' scale to logarithmic by setting <i>y_scale_type</i> to <i>log</i>.",
+ data: data,
+ y_scale_type: 'log',
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#log1'
+ });
+});
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "No X Axis",
+ description: "You can hide either axis by setting <i>x_axis</i> or <i>y_axis</i> to false.",
+ data: data,
+ decimals: 0,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#hidden1',
+ area: false,
+ x_axis: false,
+ });
+});
+
+d3.json('data/brief-1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "No Y Axis",
+ description: "You can hide either axis by setting <i>x_axis</i> or <i>y_axis</i> to false.",
+ data: data,
+ decimals: 0,
+ width: 600,
+ height: 200,
+ right: 20,
+ xax_count: 4,
+ target: '#hidden2',
+ area: false,
+ y_axis: false
+ });
+});
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Rug Plots",
+ description: "You can set rug plots either axis by setting <i>x_rug</i> or <i>y_rug</i> to true.",
+ data: data,
+ decimals: 0,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#y_rug',
+ area: false,
+ y_rug: true
+ });
+});
+
+d3.json('data/neg1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Negative Values 1",
+ description: "MG defaults to 0 on the y-axis as min if there are no negative numbers. If there are negatives, should provide some buffer below.",
+ data: data,
+ width: 295,
+ height: 220,
+ right: 10,
+ target: '#neg1'
+ });
+
+ var data2 = MG.clone(data).map(function(d) {
+ d.value = d.value + 550;
+ return d;
+ });
+
+ MG.data_graphic({
+ title: "Y-Axis Not Zero",
+ data: data2,
+ width: 295,
+ height: 220,
+ right: 10,
+ min_y_from_data: true,
+ yax_units: '$',
+ target: '#y-axis-not-zero',
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});
+
+d3.json('data/neg2.json', function(data) {
+ MG.data_graphic({
+ title: "Negative Values 2",
+ data: data,
+ width: 295,
+ height: 220,
+ right: 10,
+ target: '#neg2',
+ x_accessor: 'subject',
+ y_accessor: 'measure'
+ });
+});
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/brushing_zooming.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/brushing_zooming.htm
new file mode 100644
index 0000000..e23e35d
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/brushing_zooming.htm
@@ -0,0 +1,166 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='basic_brushing'></div>
+ <div class='col-lg-12 text-center' id='point_chart_brushing'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users3.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+ MG.data_graphic({
+ title: "Basic Brushing &amp; Zooming",
+ description: "This is a simple example of brushing and zooming. You can set 'brush' as 'xy', 'x', 'y' to specify the axis(es) that may be brushed.",
+ data: data,
+ top: 70,
+ width: 600,
+ height: 240,
+ right: 40,
+ missing_is_hidden: true,
+ target: '#basic_brushing',
+ brush: 'xy',
+ });
+});
+
+d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Point Chart Brushing",
+ description: "Brushing and zooming also works for point charts.",
+ data: data,
+ chart_type: 'point',
+ width: 600,
+ height: 240,
+ right: 40,
+ target: '#point_chart_brushing',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ y_rug: true,
+ brush: 'xy',
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='main'></div>
+ <div class='col-lg-12 text-center' id='overview_plot'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users3.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+ const main = {
+ title: "Overview Plot",
+ description: "This is a simple example of an overview plot. You can create an overview plot by creating another chart with 'zoom_target' option and then setting it as the object of the main chart.",
+ data: data,
+ top: 70,
+ width: 600,
+ height: 200,
+ right: 40,
+ missing_is_hidden: true,
+ target: '#main',
+ brush: 'xy',
+ }
+ MG.data_graphic(main);
+ MG.data_graphic({
+ data: data,
+ width: 600,
+ height: 50,
+ top: 8,
+ bottom: 0,
+ right: 40,
+ missing_is_hidden: true,
+ target: '#overview_plot',
+ brush: 'x',
+ zoom_target: main,
+ x_axis: false,
+ y_axis: false,
+ showActivePoint: false,
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+<script>
+d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+ MG.data_graphic({
+ title: "Basic Brushing & Zooming",
+ description: "This is a simple example of brushing and zooming. You can set 'brush' as 'xy', 'x', 'y' to specify the axis(es) that may be brushed.",
+ data: data,
+ top: 70,
+ width: 600,
+ height: 240,
+ right: 40,
+ missing_is_hidden: true,
+ target: '#basic_brushing',
+ brush: 'xy',
+ });
+});
+
+d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Point Chart Brushing",
+ description: "Brushing and zooming also works for point charts.",
+ data: data,
+ chart_type: 'point',
+ width: 600,
+ height: 240,
+ right: 40,
+ target: '#point_chart_brushing',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ y_rug: true,
+ brush: 'xy',
+ });
+});
+
+d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+ const main = {
+ title: "Overview Plot",
+ description: "This is a simple example of an overview plot. You can create an overview plot by creating another chart with 'zoom_target' option and then setting it as the object of the main chart.",
+ data: data,
+ top: 70,
+ width: 600,
+ height: 200,
+ right: 40,
+ missing_is_hidden: true,
+ target: '#main',
+ brush: 'xy',
+ }
+ MG.data_graphic(main);
+ MG.data_graphic({
+ data: data,
+ width: 600,
+ height: 50,
+ top: 8,
+ bottom: 0,
+ right: 40,
+ missing_is_hidden: true,
+ target: '#overview_plot',
+ brush: 'x',
+ zoom_target: main,
+ x_axis: false,
+ y_axis: false,
+ showActivePoint: false,
+ });
+});
+
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/data.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/data.htm
new file mode 100644
index 0000000..aa0f076
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/data.htm
@@ -0,0 +1,386 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='missing-y'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/missing-y.json'>data</a>
+ </div>
+
+<pre><code class='javascript'>d3.json('data/missing-y.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Few Observations",
+ description: "We sometimes have only a few observations. By setting <i>missing_is_zero: true</i>, missing values for a time-series will be interpreted as zeros. In this example, we've overridden the rollover callback to show 'no data' for missing observations and have set the <i>min_x</i> and <i>max_x</i> options in order to expand the date range.",
+ data: data,
+ interpolate: d3.curveLinear,
+ missing_is_zero: true,
+ width: 600,
+ height: 200,
+ right: 40,
+ min_x: new Date('2014-01-01'),
+ max_x: new Date('2014-06-01'),
+ target: '#missing-y',
+ mouseover: function(d, i) {
+ var df = d3.timeFormat('%b %d, %Y');
+ var date = df(d.date);
+ var y_val = (d.value === 0) ? 'no data' : d.value;
+
+ d3.select('#missing-y svg .mg-active-datapoint')
+ .text(date + ' ' + y_val);
+ }
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='missing_is_hidden'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/missing-is-hidden.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/missing-is-hidden.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Broken Lines",
+ description: "Setting <i>missing_is_hidden</i> to true will hide missing ranges rather than considering them to be zeros or interpolating between the two points on either side.",
+ data: data,
+ missing_is_hidden: true,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#missing_is_hidden',
+ area: false,
+ show_secondary_x_label: false
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='missing_is_hidden_accessor'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/missing-is-hidden-accessor.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/missing-is-hidden-accessor.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Broken Lines (Missing Data Points)",
+ description: "You can hide individual data points on a particular attribute by setting <i>missing_is_hidden_accessor</i>. Data points whose y-accessor values are null are also hidden.",
+ data: data,
+ missing_is_hidden: true,
+ missing_is_hidden_accessor: 'dead',
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#missing_is_hidden_accessor'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='missing-data'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+
+<pre><code class='javascript'>MG.data_graphic({
+ title: "Missing Data",
+ description: "This is an example of a graphic whose data is currently missing. We've also set the <i>error</i> option, which appends an error icon to the title and logs an error to the browser's console.",
+ error: 'This data is blocked by Lorem Ipsum. Get your **** together, Ipsum.',
+ chart_type: 'missing-data',
+ missing_text: 'This is an example of a missing chart',
+ target: '#missing-data',
+ width: 600,
+ height: 200
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='missing1'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/fake_users2.json'>data</a>
+ </div>
+
+<pre><code class='javascript'>d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var all_the_data = MG.clone(data[0]);
+ for (i = 1; i < data.length; i++){
+ for (var j = 0; j < data[i].length; j++) {
+ if (i === 2 && all_the_data[j].date < new Date('2014-02-01')) {
+ } else {
+ all_the_data[j]['value' + (i + 1)] = data[i][j].value;
+ }
+ }
+ }
+
+ MG.data_graphic({
+ title: "Handling Different Sized Lines in a Single Array",
+ description: "How do you handle data with multiple implied time series lengths?",
+ data: all_the_data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#missing1',
+ linked: true,
+ x_accessor: 'date',
+ y_accessor: ['value', 'value2', 'value3']
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='display_active_point_01'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/fake_users2.json'>data</a>
+ </div>
+
+ <pre><code class='javascript'>d3.json('data/fake_users1.json', function(data) {
+
+ for (var i = 0; i < data.length; i++) {
+ data[i].active = (i % 5 === 0);
+ }
+
+ data = MG.convert.date(data, 'date');
+
+ MG.data_graphic({
+ title: "Show active points on line chart",
+ description: "This line chart displays pre-defined active points",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ point_size: 3,
+ active_point_on_lines: true,
+ active_point_accessor: 'active',
+ active_point_size: 2,
+ target: '#display_active_point_01',
+ aggregate_rollover: true
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='display_active_point_02'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/fake_users2.json'>data</a>
+ </div>
+
+ <pre><code class='javascript'>d3.json('data/fake_users2.json', function(data) {
+
+ for (var i = 0; i < data.length; i++) {
+ for (var j = 0; j < data[i].length; j++) {
+ if (i === 0) {
+ data[i][j].active = (j % 5 === 0);
+ }
+ if (i === 1) {
+ data[i][j].active = (j % 10 === 0);
+ }
+ }
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Show active points on multi-lines chart",
+ description: "This multi-lines chart displays pre-defined active points for each lines",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ point_size: 3,
+ active_point_on_lines: true,
+ active_point_accessor: 'active',
+ active_point_size: 2,
+ target: '#display_active_point_01',
+ aggregate_rollover: true
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+<script>
+MG._hooks = {};
+d3.json('data/missing-y.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Few Observations",
+ description: "We sometimes have only a few observations. By setting <i>missing_is_zero: true</i>, missing values for a time-series will be interpreted as zeros. In this example, we've overridden the rollover callback to show 'no data' for missing observations and have set the <i>min_x</i> and <i>max_x</i> options in order to expand the date range.",
+ data: data,
+ interpolate: d3.curveLinear,
+ missing_is_zero: true,
+ width: 600,
+ height: 200,
+ right: 40,
+ min_x: new Date('2014-01-01'),
+ max_x: new Date('2014-06-01'),
+ target: '#missing-y',
+ mouseover: function(d, i) {
+ var df = d3.timeFormat('%b %d, %Y');
+ var date = df(d.date);
+ var y_val = (d.value === 0) ? 'no data' : d.value;
+
+ d3.select('#missing-y svg .mg-active-datapoint')
+ .text(date + ' ' + y_val);
+ }
+ });
+});
+
+d3.json('data/missing-is-hidden.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Broken Lines (Missing Data Range)",
+ description: "Setting <i>missing_is_hidden</i> to true will hide missing ranges rather than considering them to be zeros or interpolating between the two points on either side.",
+ data: data,
+ missing_is_hidden: true,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#missing_is_hidden',
+ area: false,
+ show_secondary_x_label: false
+ });
+});
+
+d3.json('data/missing-is-hidden-accessor.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Broken Lines (Missing Data Points)",
+ description: "You can hide individual data points on a particular attribute by setting <i>missing_is_hidden_accessor</i>. Data points whose y-accessor values are null are also hidden.",
+ data: data,
+ missing_is_hidden: true,
+ missing_is_hidden_accessor: 'dead',
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#missing_is_hidden_accessor'
+ });
+});
+
+
+MG.data_graphic({
+ title: "Missing Data",
+ chart_type: 'missing-data',
+ description: "This is an example of a graphic whose data is currently missing. We've also set the <i>error</i> option, which appends an error icon to the title and logs an error to the browser's console.",
+ error: 'This data is blocked by Lorem Ipsum. Get your **** together, Ipsum.',
+ missing_text: 'This is an example of a missing chart',
+ target: '#missing-data',
+ width: 600,
+ height: 200
+});
+
+d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var all_the_data = MG.clone(data[0]);
+ for (i = 1; i < data.length; i++){
+ for (var j = 0; j < data[i].length; j++) {
+ if (i === 2 && all_the_data[j].date < new Date('2014-02-01')) {
+ } else {
+ all_the_data[j]['value' + (i + 1)] = data[i][j].value;
+ }
+ }
+ }
+
+ MG.data_graphic({
+ title: "Handling Different Sized Lines in a Single Array",
+ description: "How do you handle data with multiple implied time series lengths?",
+ data: all_the_data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#missing1',
+ linked: true,
+ x_accessor: 'date',
+ y_accessor: ['value', 'value2', 'value3']
+ });
+});
+
+d3.json('data/fake_users1.json', function(data) {
+
+ for (var i = 0; i < data.length; i++) {
+ data[i].active = (i % 5 === 0);
+ }
+
+ data = MG.convert.date(data, 'date');
+
+ MG.data_graphic({
+ title: "Show active points on line chart",
+ description: "This line chart displays pre-defined active points",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ point_size: 3,
+ active_point_on_lines: true,
+ active_point_accessor: 'active',
+ active_point_size: 2,
+ target: '#display_active_point_01',
+ aggregate_rollover: true
+ });
+});
+
+d3.json('data/fake_users2.json', function(data) {
+
+ for (var i = 0; i < data.length; i++) {
+ for (var j = 0; j < data[i].length; j++) {
+ if (i === 0) {
+ data[i][j].active = (j % 5 === 0);
+ }
+ if (i === 1) {
+ data[i][j].active = (j % 10 === 0);
+ }
+ }
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Show active points on multi-lines chart",
+ description: "This multi-lines chart displays pre-defined active points for each lines",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ point_size: 3,
+ active_point_on_lines: true,
+ active_point_accessor: 'active',
+ active_point_size: 2,
+ target: '#display_active_point_02',
+ aggregate_rollover: true
+ });
+});
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/experimental.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/experimental.htm
new file mode 100644
index 0000000..725a8d3
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/experimental.htm
@@ -0,0 +1,1159 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='col-lg-6 text-center' id='scatter-simple'></div>
+ <div class='col-lg-6 text-center' id='categorical1'></div>
+ <div class='col-lg-6 text-center' id='categorical2'></div>
+ <div class='col-lg-6 text-center' id='scatter-line-best-fit'></div>
+ <div class='col-lg-6 text-center' id='scatter-size-and-color'></div>
+ <div class='col-lg-6 text-center' id='sls-time-series'></div>
+ <div class='col-lg-6 text-center' id='highlight'></div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/points1.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Simple Scatterplot",
+ description: "This is an example of a simple scatterplot, in which we have enabled rug plots on the y-axis by setting the <i>y_rug</i> option to true.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#scatter-simple',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ mouseover: function(d, i) { console.log(d,i); },
+ y_rug: true
+ });
+
+ MG.data_graphic({
+ title: "Automatic Category Coloring",
+ description: "By setting <i>color_type</i> to 'category' you can color the points according to another discrete value.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#categorical1',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ color_accessor: 'v',
+ color_type:'category',
+ y_rug: true
+ });
+
+ MG.data_graphic({
+ title: "Custom Category Color Mapping",
+ description: "You can specify the color domain and the corresponding color range to get custom mapping of categories to colors.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#categorical2',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ color_accessor: 'v',
+ color_domain: ['cat_0', 'cat_1', 'other'],
+ color_range: ['blue', 'gray', 'black'],
+ color_type: 'category',
+ x_rug: true
+ });
+
+ MG.data_graphic({
+ title: "Simple Line of Best Fit",
+ description: "For any scatterplot, set <i>least_squares</i> to true to add.",
+ data: data,
+ least_squares: true,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#scatter-line-best-fit',
+ x_accessor: 'x',
+ y_accessor: 'y'
+ });
+
+ MG.data_graphic({
+ title: "Points Highlighting",
+ description: "You can set <i>highlight</i> to filter the points you want to highlight.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#highlight',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ y_rug: true,
+ highlight: (d, i) => d.z > 2
+ });
+});
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Another Least Squares Example",
+ description: "Least squares effortlessly works with dates or times on axes.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ left: 60,
+ right: 10,
+ least_squares: true,
+ target: '#sls-time-series',
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});
+
+var color_range = (theme === 'light') ? null : ['white','yellow'];
+
+d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Scatterplot with Size and Color",
+ description: "Scatterplots have <i>x_accessor</i>, <i>y_accessor</i>, <i>size_accessor</i>, and <i>color_accessor</i>. For the last two you can also provide domain and range functions, to make it easy to change the color ranges. Colors default to red and blue, but can be overridden by passing an array of colors to <i>color_range</i>, as we've done in this example for the dark theme.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#scatter-size-and-color',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ color_accessor:'z',
+ color_range: color_range,
+ size_accessor:'w',
+ x_rug: true,
+ y_rug: true
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+
+<div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='row'>
+ <div class='col-lg-6 text-center' id='point-categorical'></div>
+ <div class='col-lg-6 text-center' id='bar-categorical'></div>
+ </div>
+
+ <div class='row'>
+ <div class='col-lg-6 text-center' id='point-categorical2'></div>
+ <div class='col-lg-6 text-center' id='bar-categorical2'></div>
+
+ </div>
+ <div class='row'>
+ <div class='col-lg-6 text-center' id='point-categorical-group'></div>
+ <div class='col-lg-6 text-center' id='bar-categorical-group'>
+ </div>
+
+ </div>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='point-categorical-group-horizontal'></div>
+ </div>
+ <div class='row'>
+ <div class='col-lg-12 text-center' id='bar-categorical-group-horizontal'></div>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/nh-gop.tsv'>data</a></div>
+
+<pre><code class='javascript'>
+d3.tsv('data/nh-gop.tsv', function(data) {
+ var polls = [];
+ var who = ['Bush', 'Rubio', 'Trump', 'Cruz'];
+ data.forEach(function(p){
+ who.forEach(function(d){
+ var out = {};
+ out.candidate = d;
+ out.number = p[d] === '--' ? 0 : parseFloat(p[d]);
+ out.poll = p.Poll;
+ out.size = Math.random();
+ out.when = p.Date;
+ polls.push(out);
+ })
+ });
+
+ var trump = polls.filter(function(d){
+ return d.poll == 'PPP (D)';
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: X, points',
+ data: trump,
+ chart_type: 'point',
+ y_accessor: 'number',
+ x_accessor: 'candidate',
+ height:400,
+ width:300,
+ target: '#point-categorical',
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: X, bars',
+ data: trump,
+ chart_type: 'bar',
+ y_accessor: 'number',
+ x_accessor: 'candidate',
+ height:400,
+ width:300,
+ target: '#bar-categorical',
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: Y, points',
+ data: trump,
+ chart_type: 'point',
+ x_accessor: 'number',
+ y_accessor: 'candidate',
+ height:400,
+ width:300,
+ target: '#point-categorical2',
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: Y, bars',
+ data: trump,
+ chart_type: 'bar',
+ x_accessor: 'number',
+ y_accessor: 'candidate',
+ height:400,
+ width:300,
+ target: '#bar-categorical2',
+ })
+
+ MG.data_graphic({
+ title: 'Y points, groups',
+ data: polls,
+ chart_type: 'point',
+ y_axis_type: 'categorical',
+ x_accessor: 'number',
+ y_accessor: 'candidate',
+ ygroup_accessor: 'poll',
+ size_accessor: 'size',
+ size_domain: [0,1],
+ size_range: [3,6],
+ height:550,
+ width:300,
+ left:100,
+ target: '#point-categorical-group'
+ })
+
+ MG.data_graphic({
+ title: 'Y bars, groups',
+ data: polls,
+ chart_type: 'bar',
+ y_axis_type: 'categorical',
+ x_accessor: 'number',
+ y_accessor: 'candidate',
+ ygroup_accessor: 'poll',
+ height:550,
+ width:300,
+ left:100,
+ right:40,
+ target: '#bar-categorical-group'
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: Y, groups, horizontal',
+ data: polls,
+ chart_type: 'point',
+ y_accessor: 'number',
+ x_accessor: 'candidate',
+ xgroup_accessor: 'poll',
+ size_accessor: 'size',
+ size_domain: [0,1],
+ size_range: [3,6],
+ height:350,
+ width:700,
+ target: '#point-categorical-group-horizontal'
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: Y, groups, horizontal',
+ data: polls,
+ chart_type: 'bar',
+ y_accessor: 'number',
+ x_accessor: 'candidate',
+ xgroup_accessor: 'poll',
+ size_accessor: 'size',
+ size_domain: [0,1],
+ size_range: [3,6],
+ height:350,
+ width:700,
+ target: '#bar-categorical-group-horizontal'
+ })
+})
+</code></pre>
+
+ </div>
+</div>
+
+
+<script>
+d3.tsv('data/nh-gop.tsv', function(data) {
+ var polls = [];
+ var who = ['Bush', 'Rubio', 'Trump', 'Cruz'];
+ data.forEach(function(p,j){
+ who.forEach(function(d,i){
+ var out = {};
+ out.candidate = d;
+ out.number = p[d] === '--' ? 0 : parseFloat(p[d]);
+ out.poll = p.Poll;
+ out.size = Math.random();
+ out.when = p.Date;
+ out.reference = Math.floor(Math.random() * 20 + 1);
+ out.comparison = j+i + 1;
+ polls.push(out);
+ })
+ });
+
+ var trump = polls.filter(function(d){
+ return d.poll == 'PPP (D)';
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: X, points',
+ data: trump,
+ chart_type: 'point',
+ y_accessor: 'number',
+ x_accessor: 'candidate',
+ height:300,
+ width:300,
+ target: '#point-categorical',
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: X, bars',
+ data: trump,
+ chart_type: 'bar',
+ y_accessor: 'number',
+ x_accessor: 'candidate',
+ height:300,
+ width:300,
+ target: '#bar-categorical',
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: Y, points',
+ data: trump,
+ chart_type: 'point',
+ x_accessor: 'number',
+ y_accessor: 'candidate',
+ height:300,
+ width:300,
+ target: '#point-categorical2',
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: Y, bars',
+ data: trump,
+ chart_type: 'bar',
+ x_accessor: 'number',
+ y_accessor: 'candidate',
+ height:300,
+ width:300,
+ target: '#bar-categorical2',
+ })
+
+ MG.data_graphic({
+ title: 'Y points, groups',
+ data: polls,
+ chart_type: 'point',
+ y_axis_type: 'categorical',
+ x_accessor: 'number',
+ y_accessor: 'candidate',
+ ygroup_accessor: 'poll',
+ size_accessor: 'size',
+ size_domain: [0,1],
+ size_range: [3,6],
+ height:550,
+ width:300,
+ left:100,
+ target: '#point-categorical-group'
+ })
+
+ MG.data_graphic({
+ title: 'Y bars, groups',
+ data: polls,
+ chart_type: 'bar',
+ y_axis_type: 'categorical',
+ x_accessor: 'number',
+ y_accessor: 'candidate',
+ ygroup_accessor: 'poll',
+ height:550,
+ width:300,
+ left:100,
+ target: '#bar-categorical-group'
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: Y, groups, horizontal',
+ data: polls,
+ chart_type: 'point',
+ y_accessor: 'number',
+ x_accessor: 'candidate',
+ xgroup_accessor: 'poll',
+ size_accessor: 'size',
+ size_domain: [0,1],
+ size_range: [3,6],
+ height:300,
+ width:650,
+ target: '#point-categorical-group-horizontal'
+ })
+
+ MG.data_graphic({
+ title: 'Categorical Scale: Y, groups, horizontal',
+ data: polls,
+ chart_type: 'bar',
+ y_accessor: 'number',
+ x_accessor: 'candidate',
+ xgroup_accessor: 'poll',
+ size_accessor: 'size',
+ size_domain: [0,1],
+ size_range: [3,6],
+ height:300,
+ width:650,
+ target: '#bar-categorical-group-horizontal'
+ })
+})
+</script>
+
+
+
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='col-lg-6 text-center' id='histogram1'></div>
+ <div class='col-lg-6 text-center' id='histogram2'></div>
+ <div class='col-lg-6 text-center' id='histogram3'></div>
+ <div class='col-lg-6 text-center' id='histogram4'></div>
+ <div class='col-lg-12 text-center' id='time-hist'></div>
+ <div class='col-lg-12 text-center' id='ufos'></div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/ufo_dates.csv'>data</a></div>
+
+<pre><code class='javascript'>var values = d3.range(10000).map(d3.randomBates(10));
+
+MG.data_graphic({
+ title: "Histogram 1",
+ description: "Raw data values being fed in. Here, we specify the number of bins to be 50 and have bar margins set to 0. The histogram graphic type includes the ability to <a href='http://en.wikipedia.org/wiki/Freedman%E2%80%93Diaconis_rule'>bin data</a>.",
+ data: values,
+ chart_type: 'histogram',
+ width: 295,
+ height: 180,
+ right: 10,
+ bins: 50,
+ bar_margin: 0,
+ target: '#histogram1',
+ y_extended_ticks: true,
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#histogram1 svg .mg-active-datapoint')
+ .text('Value: ' + pf(d.x) + ' Count: ' + d.y);
+ }
+});
+
+d3.csv('data/ufo_dates.csv', function(ufos){
+ var data = ufos.map(function(d){
+ return parseInt(d.value) / 30;
+ });
+ data.sort();
+ MG.data_graphic({
+ title: "Difference in UFO Sighting and Reporting Dates (in months)",
+ description: "Semi-real data about the reported differences between the supposed sighting of a UFO and the date it was reported.",
+ data: data,
+ chart_type: 'histogram',
+ width: 600,
+ height: 300,
+ right: 40,
+ bar_margin: 0,
+ bins: 150,
+ target: '#ufos',
+ y_extended_ticks: true,
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#ufos svg .mg-active-datapoint')
+ .text(pf(d.x) + ' months Volume: ' + pf(d.y));
+ }
+ });
+});
+
+var second = d3.range(10000).map(function(d) { return Math.random() * 10; });
+second = d3.histogram()(second)
+ .map(function(d) {
+ return {'count': d.y, 'value': d.x};
+});
+
+MG.data_graphic({
+ title: "Histogram 2",
+ description: "Already binned data being fed in.",
+ data: second,
+ binned: true,
+ chart_type: 'histogram',
+ width: 295,
+ height: 180,
+ right: 10,
+ target: '#histogram2',
+ y_extended_ticks: true,
+ x_accessor: 'value',
+ y_accessor: 'count',
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#histogram2 svg .mg-active-datapoint')
+ .text('Value: ' + pf(d.x) + ' Count: ' + d.y);
+ }
+});
+
+var third = d3.range(10000).map(d3.randomBates(10));
+third = third.map(function(d,i){ return {val1: d, val2: i}; });
+
+MG.data_graphic({
+ title: "Histogram 3",
+ description: "Unbinned, but in same format as other line chart data.",
+ data: third,
+ chart_type: 'histogram',
+ width: 295,
+ height: 180,
+ right: 10,
+ target: '#histogram3',
+ linked: true,
+ y_extended_ticks: true,
+ x_accessor: 'val1',
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#histogram3 svg .mg-active-datapoint')
+ .text('Value: ' + pf(d.x) + ' Count: ' + d.y);
+ }
+});
+
+// check for negative values, for sanity.
+var fourth = d3.range(10000).map(d3.randomBates(10));
+fourth = fourth.map(function(d,i){ return d - 0.5; });
+
+MG.data_graphic({
+ title: "Histogram 4",
+ description: "Sanity-checking negative data.",
+ data: fourth,
+ chart_type: 'histogram',
+ width: 295,
+ height: 180,
+ right: 10,
+ target: '#histogram4',
+ y_extended_ticks: true,
+ x_accessor: 'val1',
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#histogram4 svg .mg-active-datapoint')
+ .text('Value: ' + pf(d.x) + ' Count: ' + d.y);
+ }
+});
+
+var hist1 = fake_data(25, 60).map(function(d){
+ d.value = Math.round(d.value);
+ return d;
+});
+
+MG.data_graphic({
+ title: "Histograms can be time series as well",
+ data: hist1,
+ target: '#time-hist',
+ chart_type: 'histogram',
+ width: 600,
+ height: 200,
+ binned: true,
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='table1'></div>
+ <div class='col-lg-5'>
+
+<pre><code class='javascript'>var table_data = [
+ { 'year': 1852, 'value1': 10.2, 'value2': 1030004.43423,'share': 0.12, 'total': 34003400, 'temp': 43, 'geo': 'United Kingdom', 'description': "Having a way of describing a row can be useful." },
+ { 'year': 1901, 'value1': 10.1, 'value2': 54003.223, 'share': 0.11, 'total': 4302100, 'temp': 55, 'geo': 'United States', 'description': "More made-up numbers." },
+ { 'year': 1732, 'value1': 4.3, 'value2': 1004.91422, 'share': 0.14, 'total': 4300240, 'temp': 42, 'geo': 'France', 'description': "We didn't specify a title for this column." },
+ { 'year': 1945, 'value1': 2.9, 'value2': 2430.121, 'share': 0.23, 'total': 24000000, 'temp': 54, 'geo': 'Brazil', 'description': "Brazil, Brazil." },
+ { 'year': 1910, 'value1': 1.0, 'value2': 5432.3, 'share': 0.19, 'total': 130000, 'temp': 52, 'geo': 'India', 'description': "Last description in the whole thing." }
+];
+
+var table1 = MG.data_table({
+ title: "A Data Table",
+ description: "A table is often the most appropriate way to present data. We aim to make the creation of data tables very simple. We are working on implementing sparklines, bullet charts, and other niceties.",
+ data: table_data,
+ show_tooltips: true
+ })
+ .target('#table1')
+ .title({
+ accessor: 'geo',
+ secondary_accessor:'year',
+ label: 'Country',
+ description: "These are arbitrary countries with arbitrary years underneath."
+ })
+ .number({ accessor: 'value1', label: 'Size', value_formatter: function(d){ return d + ' yrds'; }})
+ .number({ accessor: 'value2', label: 'Score', round: 2, font_weight: 'bold' })
+ .number({ accessor: 'temp', label: 'Temp.', format: 'temperature', width: 100, color: 'gray' })
+ .number({
+ accessor: 'total',
+ label: 'Volume',
+ format: 'count', currency: '$',
+ width: 100,
+ font_weight: function(d){ return d < 5000000 ? 'bold' : 'normal'; },
+ color: function(d){ return d < 5000000 ? '#f70101' : 'auto'; }
+ })
+ .number({ accessor: 'share', label: 'Share', format: 'percentage', width: 100 })
+ .text({ accessor: 'description', width: 240, font_style: 'italic' })
+ .display();</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='buttons'></div>
+ <div class='col-lg-5'>
+
+<pre><code class='javascript'>var bdata = [
+ {a:'apples', b:'quartz'},
+ {a:'bananas', b:'pyrite'},
+ {a:'durian', b:'obsidian'}
+];
+
+var resolution_features = ['weekly', 'monthly'];
+
+var buttons = MG.button_layout('#buttons')
+ .data(bdata)
+ .manual_button('Time Scale', resolution_features, function(){ console.log('switched time scales'); })
+ .button('a', 'Fruit')
+ .button('b', 'Rock')
+ .callback(function(){
+ console.log('made it');
+ return false;
+ })
+ .display();</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class="tooltip"></div>
+ <style>
+ .tooltip {
+ display: none;
+ min-height: 32px;
+ min-width: 100px;
+ padding: 12px;
+ margin-bottom: 8px;
+ background-color: #333;
+ color: white;
+ opacity: 0.7;
+ text-align: left;
+ }
+ </style>
+ <div class='col-lg-12 text-center' id='tooltip-line-chart'></div>
+ <div class='col-lg-12 text-center' id='tooltip-point-chart'></div>
+ </div>
+ <div class='col-lg-5'>
+
+<pre><code class='html'>&#x3C;div class=&#x22;tooltip&#x22;&#x3E;&#x3C;/div&#x3E;
+&#x3C;style&#x3E;
+.tooltip {
+ display: none;
+ min-height: 32px;
+ min-width: 100px;
+ padding: 12px;
+ margin-bottom: 8px;
+ background-color: #333;
+ color: white;
+ opacity: 0.7;
+ text-align: left;
+}
+&#x3C;/style&#x3E;
+</code></pre>
+
+<pre><code class='javascript'>const tooltipEl = d3.select('.tooltip').node();
+const tooltip = new Popper(document.documentElement, tooltipEl, { placement: 'top' });
+tooltipEl.addEventListener('mouseover', () => {
+ tooltipEl.style.display = 'block';
+})
+tooltipEl.addEventListener('mouseout', () => {
+ tooltipEl.style.display = 'none';
+})
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Tooltip on line chart",
+ description: "Using popper.js and the mouseover callback, you can easily create a tooltip when the user hovers over a particular datapoint.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#tooltip-line-chart',
+ x_accessor: 'date',
+ y_accessor: 'value',
+ show_rollover_text: false,
+ mouseover: (d, i) => {
+ tooltipEl.style.display = 'block';
+ tooltipEl.innerText = `date: ${d3.timeFormat('%b %e, %Y')(d.date)}\nvalue: ${d.value}`;
+ tooltip.reference = d3.select(`#tooltip-line-chart .mg-line-rollover-circle`).node();
+ tooltip.update();
+ },
+ mouseout: () => {
+ tooltipEl.style.display = 'none';
+ }
+ });
+});
+
+d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Tooltip on point chart",
+ description: "This technique also works for point charts.",
+ data: data,
+ chart_type: 'point',
+ width: 600,
+ height: 350,
+ right: 10,
+ target: '#tooltip-point-chart',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ show_rollover_text: false,
+ mouseover: (d, i) => {
+ tooltipEl.style.display = 'block';
+ tooltipEl.innerText = `X: ${d.data.x}\nY: ${d.data.y}`;
+ tooltip.reference = d3.select(`#tooltip-point-chart .mg-points .path-${i}`).node();
+ tooltip.update();
+ },
+ mouseout: (d, i) => {
+ tooltipEl.style.display = 'none';
+ }
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+
+<script>
+MG._hooks = {};
+d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Simple Scatterplot",
+ description: "This is an example of a simple scatterplot, in which we have enabled rug plots on the y-axis by setting the <i>y_rug</i> option to true.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#scatter-simple',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ y_rug: true
+ });
+
+ MG.data_graphic({
+ title: "Automatic Category Coloring",
+ description: "By setting <i>color_type</i> to 'category' you can color the points according to another discrete value.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#categorical1',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ color_accessor: 'v',
+ color_type: 'category',
+ y_rug: true
+ });
+
+ MG.data_graphic({
+ title: "Custom Category Color Mapping",
+ description: "You can specify the color domain and the corresponding color range to get custom mapping of categories to colors.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#categorical2',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ color_accessor: 'v',
+ color_domain: ['cat_0', 'cat_1', 'other'],
+ color_range: ['blue', 'gray', 'black'],
+ color_type: 'category',
+ x_rug: true
+ });
+
+ MG.data_graphic({
+ title: "Simple Line of Best Fit",
+ description: "For any scatterplot, set <i>least_squares</i> to true to add.",
+ data: data,
+ least_squares: true,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#scatter-line-best-fit',
+ x_accessor: 'x',
+ y_accessor: 'y'
+ });
+
+ MG.data_graphic({
+ title: "Points Highlighting",
+ description: "You can set <i>highlight</i> to filter the points you want to highlight.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#highlight',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ y_rug: true,
+ highlight: (d, i) => d.z > 2
+ });
+});
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Another Least Squares Example",
+ description: "Least squares effortlessly works with dates or times on axes.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ left: 60,
+ right: 10,
+ least_squares: true,
+ target: '#sls-time-series',
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});
+
+var color_range = (theme === 'light') ? null : ['white','yellow'];
+
+d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Scatterplot with Size and Color",
+ description: "Scatterplots have <i>x_accessor</i>, <i>y_accessor</i>, <i>size_accessor</i>, and <i>color_accessor</i>. For the last two you can also provide domain and range functions, to make it easy to change the color ranges. Colors default to red and blue, but can be overridden by passing an array of colors to <i>color_range</i>, as we've done in this example for the dark theme.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#scatter-size-and-color',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ color_accessor: 'z',
+ color_range: color_range,
+ size_accessor: 'w',
+ x_rug: true,
+ y_rug: true
+ });
+});
+
+var values = d3.range(10000).map(d3.randomBates(10));
+
+MG.data_graphic({
+ title: "Histogram 1",
+ description: "Raw data values being fed in. Here, we specify the number of bins to be 50 and have bar margins set to 0. The histogram graphic type includes the ability to <a href='http://en.wikipedia.org/wiki/Freedman%E2%80%93Diaconis_rule'>bin data</a>.",
+ data: values,
+ chart_type: 'histogram',
+ width: 295,
+ height: 180,
+ bins: 50,
+ bar_margin: 0,
+ target: '#histogram1',
+ y_extended_ticks: true,
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#histogram1 svg .mg-active-datapoint')
+ .text('Value: ' + pf(d.x) + ' Count: ' + d.y);
+ }
+});
+
+d3.csv('data/ufo_dates.csv', function(ufos){
+ var data = ufos.map(function(d){
+ return parseInt(d.value) / 30;
+ });
+ data.sort();
+ MG.data_graphic({
+ title: "Difference in UFO Sighting and Reporting Dates (in months)",
+ description: "Semi-real data about the reported differences between the supposed sighting of a UFO and the date it was reported.",
+ data: data,
+ chart_type: 'histogram',
+ width: 600,
+ height: 300,
+ right: 40,
+ bar_margin: 0,
+ bins: 150,
+ target: '#ufos',
+ y_extended_ticks: true,
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#ufos svg .mg-active-datapoint')
+ .text(pf(d.x) + ' months Volume: ' + d.y);
+ }
+ });
+});
+
+var second = d3.range(10000).map(function(d) { return Math.random() * 10; });
+second = d3.histogram()(second)
+ .map(function(d) {
+ return {'value': d.x0, 'count': d.length};
+});
+
+MG.data_graphic({
+ title: "Histogram 2",
+ description: "Already binned data being fed in.",
+ data: second,
+ binned: true,
+ chart_type: 'histogram',
+ width: 295,
+ height: 180,
+ target: '#histogram2',
+ y_extended_ticks: true,
+ x_accessor: 'value',
+ y_accessor: 'count',
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#histogram2 svg .mg-active-datapoint')
+ .text('Value: ' + pf(d.x) + ' Count: ' + d.y);
+ }
+});
+
+var third = d3.range(10000).map(d3.randomBates(10));
+third = third.map(function(d,i){ return {val1: d, val2: i}; });
+
+MG.data_graphic({
+ title: "Histogram 3",
+ description: "Unbinned, but in same format as other line chart data.",
+ data: third,
+ chart_type: 'histogram',
+ width: 295,
+ height: 180,
+ target: '#histogram3',
+ linked: true,
+ y_extended_ticks: true,
+ x_accessor: 'val1',
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#histogram3 svg .mg-active-datapoint')
+ .text('Value: ' + pf(d.x) + ' Count: ' + d.y);
+ }
+});
+
+// check for negative values, for sanity.
+var fourth = d3.range(10000).map(d3.randomBates(10));
+fourth = fourth.map(function(d,i){ return d - 0.5; });
+
+MG.data_graphic({
+ title: "Histogram 4",
+ description: "Sanity-checking negative data.",
+ data: fourth,
+ chart_type: 'histogram',
+ width: 295,
+ height: 180,
+ target: '#histogram4',
+ y_extended_ticks: true,
+ x_accessor: 'val1',
+ mouseover: function(d, i) {
+ var pf = d3.format(',.2f');
+ d3.select('#histogram4 svg .mg-active-datapoint')
+ .text('Value: ' + pf(d.x) + ' Count: ' + d.y);
+ }
+});
+
+var hist1 = fake_data(25, 60).map(function(d){
+ d.value = Math.round(d.value);
+ return d;
+});
+
+MG.data_graphic({
+ title: "Histograms can be time series as well",
+ data: hist1,
+ target: '#time-hist',
+ chart_type: 'histogram',
+ width: 600,
+ height: 200,
+ binned: true,
+});
+
+var table_data = [
+ { 'year': 1852, 'value1': 10.2, 'value2': 1030004.43423,'share': 0.12, 'total': 34003400, 'temp': 43, 'geo': 'United Kingdom', 'description': "Having a way of describing a row can be useful." },
+ { 'year': 1901, 'value1': 10.1, 'value2': 54003.223, 'share': 0.11, 'total': 4302100, 'temp': 55, 'geo': 'United States', 'description': "More made-up numbers." },
+ { 'year': 1732, 'value1': 4.3, 'value2': 1004.91422, 'share': 0.14, 'total': 4300240, 'temp': 42, 'geo': 'France', 'description': "We didn't specify a title for this column." },
+ { 'year': 1945, 'value1': 2.9, 'value2': 2430.121, 'share': 0.23, 'total': 24000000, 'temp': 54, 'geo': 'Brazil', 'description': "Brazil, Brazil." },
+ { 'year': 1910, 'value1': 1.0, 'value2': 5432.3, 'share': 0.19, 'total': 130000, 'temp': 52, 'geo': 'India', 'description': "Last description in the whole thing." }
+];
+
+var table1 = MG.data_table({
+ title: "A Data Table",
+ description: "A table is often the most appropriate way to present data. We aim to make the creation of data tables very simple. We are working on implementing sparklines, bullet charts, and other niceties.",
+ data: table_data,
+ show_tooltips: true
+ })
+ .target('#table1')
+ .title({
+ accessor: 'geo',
+ secondary_accessor:'year',
+ label: 'Country',
+ description: "These are arbitrary countries with arbitrary years underneath."
+ })
+ .number({ accessor: 'value1', label: 'Size', value_formatter: function(d){ return d + ' yrds'; }})
+ .number({ accessor: 'value2', label: 'Score', round: 2, font_weight: 'bold' })
+ .number({ accessor: 'temp', label: 'Temp.', format: 'temperature', width: 100, color: 'gray' })
+ .number({
+ accessor: 'total',
+ label: 'Volume',
+ format: 'count', currency: '$',
+ width: 100,
+ font_weight: function(d){ return d < 5000000 ? 'bold' : 'normal'; },
+ color: function(d){ return d < 5000000 ? '#f70101' : 'auto'; }
+ })
+ .number({ accessor: 'share', label: 'Share', format: 'percentage', width: 100 })
+ .text({ accessor: 'description', width: 240, font_style: 'italic' })
+ .display();
+
+var bdata = [
+ {a:'apples', b:'quartz'},
+ {a:'bananas', b:'pyrite'},
+ {a:'durian', b:'obsidian'}
+];
+
+var resolution_features = ['weekly', 'monthly'];
+
+var buttons = MG.button_layout('#buttons')
+ .data(bdata)
+ .manual_button('Time Scale', resolution_features, function(){ console.log('switched time scales'); })
+ .button('a', 'Fruit')
+ .button('b', 'Rock')
+ .callback(function(){
+ console.log('made it');
+ return false;
+ })
+ .display();
+
+addScatterplotSizeAndColor(theme);
+
+function addScatterplotSizeAndColor(theme) {
+ var color_range = (theme === 'light') ? null : ['white','yellow'];
+
+ // call data_graphic again since we need to use a different color_range for the dark theme
+ d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Scatterplot with Size and Color",
+ description: "Scatterplots have <i>x_accessor</i>, <i>y_accessor</i>, <i>size_accessor</i>, and <i>color_accessor</i>. For the last two you can also provide domain and range functions, to make it easy to change the color ranges. Colors default to red and blue, but can be overridden by passing an array of colors to <i>color_range</i>, as we've done in this example for the dark theme.",
+ data: data,
+ chart_type: 'point',
+ width: 295,
+ height: 225,
+ right: 10,
+ target: '#scatter-size-and-color',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ color_accessor: 'z',
+ color_range: color_range,
+ size_accessor: 'w',
+ x_rug: true,
+ y_rug: true
+ });
+ });
+}
+
+function fake_data(length, seconds) {
+ var d = new Date();
+ var v = 100000;
+ var data=[];
+
+ for (var i = 0; i < length; i++){
+ v += (Math.random() - 0.5) * 10000;
+ data.push({date: MG.clone(d), value: v});
+ d = new Date(d.getTime() + seconds * 1000);
+ }
+ return data;
+}
+
+function fake_days(length) {
+ var d = new Date();
+ var v = 100000;
+
+ var data = [];
+ for (var i = 0; i<length; i++) {
+ v += (Math.random() - 0.5) * 10000;
+ data.push({date: MG.clone(d), value: v});
+ d.setDate(d.getDate() + 1);
+ }
+ return data;
+}
+
+const tooltipEl = d3.select('.tooltip').node();
+const tooltip = new Popper(document.documentElement, tooltipEl, { placement: 'top' });
+tooltipEl.addEventListener('mouseover', () => {
+ tooltipEl.style.display = 'block';
+})
+tooltipEl.addEventListener('mouseout', () => {
+ tooltipEl.style.display = 'none';
+})
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Tooltip on line chart",
+ description: "Using popper.js and the mouseover callback, you can easily create a tooltip when the user hovers over a particular datapoint.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#tooltip-line-chart',
+ x_accessor: 'date',
+ y_accessor: 'value',
+ show_rollover_text: false,
+ mouseover: (d, i) => {
+ tooltipEl.style.display = 'block';
+ tooltipEl.innerText = `date: ${d3.timeFormat('%b %e, %Y')(d.date)}\nvalue: ${d.value}`;
+ tooltip.reference = d3.select(`#tooltip-line-chart .mg-line-rollover-circle`).node();
+ tooltip.update();
+ },
+ mouseout: () => {
+ tooltipEl.style.display = 'none';
+ }
+ });
+});
+
+d3.json('data/points1.json', function(data) {
+ MG.data_graphic({
+ title: "Tooltip on point chart",
+ description: "This technique also works for point charts.",
+ data: data,
+ chart_type: 'point',
+ width: 600,
+ height: 350,
+ right: 10,
+ target: '#tooltip-point-chart',
+ x_accessor: 'x',
+ y_accessor: 'y',
+ show_rollover_text: false,
+ mouseover: (d, i) => {
+ tooltipEl.style.display = 'block';
+ tooltipEl.innerText = `X: ${d.data.x}\nY: ${d.data.y}`;
+ tooltip.reference = d3.select(`#tooltip-point-chart .mg-points .path-${i}`).node();
+ tooltip.update();
+ },
+ mouseout: (d, i) => {
+ tooltipEl.style.display = 'none';
+ }
+ });
+});
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/lines.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/lines.htm
new file mode 100644
index 0000000..b758d34
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/lines.htm
@@ -0,0 +1,335 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='fake_users1'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users1.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Line Chart",
+ description: "This is a simple line chart. You can remove the area portion by adding <i>area: false</i> to the arguments list.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: document.getElementById('fake_users1'),
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='confidence_band'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/confidence_band.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/confidence_band.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Confidence Band",
+ description: "This is an example of a graphic with a confidence band and extended x-axis ticks enabled.",
+ data: data,
+ format: 'percentage',
+ width: 600,
+ height: 200,
+ right: 40,
+ area: false,
+ target: '#confidence_band',
+ show_secondary_x_label: false,
+ show_confidence_band: ['l', 'u'],
+ x_extended_ticks: true
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='small-range'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/small-range.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/small-range.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Small Range of Integers",
+ description: "When we have a data object of integers and a small range of values, the auto-generated set of y-axis ticks are filtered so that we don't include fractional values.",
+ data: data,
+ interpolate: d3.curveLinear,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#small-range'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div id='briefing-1'></div>
+ <div id='briefing-2'></div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/brief-1.json'>data 1</a>,
+ <a href='data/brief-2.json'>data 2</a>
+ </div>
+
+<pre><code class='javascript'>d3.json('data/brief-1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Linked Graphic",
+ description: "The two graphics in this section are linked together. A rollover in one causes a rollover in the other.",
+ data: data,
+ linked: true,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#briefing-1'
+ });
+});
+
+d3.json('data/brief-2.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Other Linked Graphic",
+ description: "Roll over and watch as the graphic to the left triggers.",
+ data: data,
+ area: false,
+ linked: true,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#briefing-2'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='singleton'></div>
+ <div class='col-lg-5'>
+
+<pre><code class='javascript'>MG.data_graphic({
+ title: "Singleton",
+ description: "Handling a solitary data point.",
+ data: [{'date': new Date('2015-03-05T21:00:00Z'), 'value': 12000}],
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#singleton'
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='custom-color'></div>
+ <div class='col-lg-5'>
+
+<pre><code class='javascript'>d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Changing Single Line Color",
+ description: "For single line charts, there are two simple ways to change a line color. The first is to change the css (described on the wiki). The other is to specify a color value using color: <em>string</em> or colors: <em>string</em>.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ color: '#8C001A',
+ target: 'div#custom-color',
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='area_flipped_users_gain_loss'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users1.json'>data</a></div>
+
+ <pre><code class='javascript'>d3.json('data/fake_users1.json', function(data) {
+
+ var max = d3.max(data, function (d) {
+ return d.value;
+ });
+ var min = d3.min(data, function(d) {
+ return d.value;
+ });
+
+ var offsetForNegativeValues = ((max - min) / 1.75);
+
+ for (var i = 0; i < data.length; i++) {
+ data[i].value = (data[i].value - offsetForNegativeValues) / 1000000;
+ }
+
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Flipped area under Y value baseline",
+ description: "This is a line chart having a flipped area under a Y value baseline",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ area: true,
+ flip_area_under_y_value: 0,
+ target: document.getElementById('area_flipped_users_gain_loss'),
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+<script>
+
+
+
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Changing Single Line Color",
+ description: "For single line charts, there are two simple ways to change a line color. The first is to change the css (described on the wiki). The other is to specify a color value using color: <em>string</em> or colors: <em>string</em>.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ color: '#8C001A',
+ target: 'div#custom-color',
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});
+
+MG._hooks = {};
+d3.json('data/fake_users1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Line Chart",
+ description: "This is a simple line chart. You can remove the area portion by adding <i>area: false</i> to the arguments list.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: document.getElementById('fake_users1'),
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});
+
+d3.json('data/confidence_band.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Confidence Band",
+ description: "This is an example of a graphic with a confidence band and extended x-axis ticks enabled.",
+ data: data,
+ format: 'percentage',
+ width: 600,
+ height: 200,
+ right: 40,
+ area: false,
+ target: '#confidence_band',
+ show_secondary_x_label: false,
+ show_confidence_band: ['l', 'u'],
+ x_extended_ticks: true
+ });
+});
+
+d3.json('data/small-range.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Small Range of Integers",
+ description: "When we have a data object of integers and a small range of values, the auto-generated set of y-axis ticks are filtered so that we don't include fractional values.",
+ data: data,
+ interpolate: d3.curveLinear,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#small-range'
+ });
+});
+
+d3.json('data/brief-1.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Linked Graphic",
+ description: "The two graphics in this section are linked together. A rollover in one causes a rollover in the other.",
+ data: data,
+ linked: true,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#briefing-1'
+ });
+});
+
+d3.json('data/brief-2.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Other Linked Graphic",
+ description: "Roll over and watch as the graphic to the left triggers.",
+ data: data,
+ area: false,
+ linked: true,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#briefing-2'
+ });
+});
+
+MG.data_graphic({
+ title: "Singleton",
+ description: "Handling a solitary data point.",
+ data: [{'date': new Date('2015-03-05T21:00:00Z'), 'value': 12000}],
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#singleton'
+});
+
+d3.json('data/fake_users1.json', function(data) {
+
+ var max = d3.max(data, function (d) {
+ return d.value;
+ });
+ var min = d3.min(data, function(d) {
+ return d.value;
+ });
+
+ var offsetForNegativeValues = ((max - min) / 1.75);
+
+ for (var i = 0; i < data.length; i++) {
+ data[i].value = (data[i].value - offsetForNegativeValues) / 1000000;
+ }
+
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Flipped area under Y value baseline",
+ description: "This is a line chart having a flipped area under a Y value baseline",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ area: true,
+ flip_area_under_y_value: 0,
+ target: document.getElementById('area_flipped_users_gain_loss'),
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/multilines.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/multilines.htm
new file mode 100644
index 0000000..d807466
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/multilines.htm
@@ -0,0 +1,368 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='fake_users2'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users2.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Multi-Line Chart",
+ description: "This line chart contains multiple lines.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#fake_users2',
+ legend: ['Line 1','Line 2','Line 3'],
+ legend_target: '.legend'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+ <div class='row'>
+ <div class='col-lg-7 text-center legend'></div>
+ <div class='col-lg-5'></div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='missing_is_hidden_multi'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/missing-is-hidden-multi.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/missing-is-hidden-multi.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Broken Multi-Lines",
+ description: 'Setting <i>missing_is_hidden</i> works with multiple lines too.',
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ missing_is_hidden: true,
+ target: '#missing_is_hidden_multi',
+ show_secondary_x_label: false
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div id='linked_multi1'></div>
+ <div id='linked_multi2'></div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/fake_users2.json'>data 1</a>,
+ <a href='data/fake_users3.json'>data 2</a>
+ </div>
+
+<pre><code class='javascript'>d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Multi-Line Linked",
+ description: "Demoing linked multi-line charts.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#linked_multi1',
+ linked: true
+ });
+})
+
+d3.json('data/fake_users3.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Multi-Line Linked 2",
+ description: "Demoing linked multi-line charts.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#linked_multi2',
+ linked: true
+ });
+});</code></pre>
+
+ </div>
+</div>
+
+<div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='missing-multi'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users3.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users3.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+ // set this to an empty array.
+ // data[0] and data[2] both still arrays of objects.
+ data[1] = [];
+
+ MG.data_graphic({
+ title: "Missing Time Series Don't Get Drawn",
+ description: "We set the second array to [] instead of the loaded data. The line color order is preserved.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#missing-multi'
+ });
+});
+});</code></pre>
+
+ </div>
+</div>
+
+<div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='multi-labelled'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users3.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users3.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ data[1][data[1].length-1].value = 50000000;
+ data[2][data[2].length-1] = MG.clone(data[1][data[1].length-1]);
+ data[2][data[2].length-1].value += 10000000;
+
+ MG.data_graphic({
+ title: "Labeling Lines",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ legend: ['US', 'CA', 'DE'],
+ target: '#multi-labelled'
+ });
+});</code></pre>
+
+ </div>
+</div>
+
+
+<div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='custom-colors'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users3.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users2.json', function(data){
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ };
+ MG.data_graphic({
+ title: "Custom Line Coloring",
+ description: "By passing in an array of hex / rgb / rgba / html strings, you can specify the colors of the lines. NOTE: this feature may have an API change before it is fully in Metrics Graphics. Use at your own risk.",
+ data: [data[0], data[1], data[2]],
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#custom-colors',
+ legend: ['Team A','Team B','Team C'],
+ legend_target: 'div#custom-color-key',
+ colors: ['blue', 'rgb(255,100,43)', '#CCCCFF'],
+ aggregate_rollover: true
+ });
+})
+</code></pre>
+
+ </div>
+</div>
+<div class='row'>
+ <div class='col-lg-7 text-center legend' id='custom-color-key'></div>
+ <div class='col-lg-5'></div>
+</div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='multiline_area_select'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users2.json'>data</a></div>
+
+ <pre><code class='javascript'>d3.json('data/fake_users3.json', function(data) {
+
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ };
+
+ MG.data_graphic({
+ title: "Select lines of your multi-line chart having areas",
+ description: "By passing in an array of booleans in 'area' property, you can choose which lines has an area or not.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#multiline_area_select',
+ area: [false, true, false],
+ y_extended_ticks: true,
+ x_accessor: 'date'
+ });
+});</code></pre>
+
+<script>
+MG._hooks = {};
+d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Multi-Line Chart",
+ description: "This line chart contains multiple lines.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#fake_users2',
+ legend: ['Line 1','Line 2','Line 3'],
+ legend_target: '.legend'
+ });
+});
+
+d3.json('data/missing-is-hidden-multi.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Broken Multi-Lines",
+ description: 'Setting <i>missing_is_hidden</i> works with multiple lines too.',
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ missing_is_hidden: true,
+ target: '#missing_is_hidden_multi',
+ show_secondary_x_label: false
+ });
+});
+
+d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Multi-Line Linked",
+ description: "Demoing linked multi-line charts.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#linked_multi1',
+ linked: true
+ });
+})
+
+d3.json('data/fake_users3.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Multi-Line Linked 2",
+ description: "Demoing linked multi-line charts.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#linked_multi2',
+ linked: true
+ });
+});
+
+d3.json('data/fake_users3.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ // set this to an empty array.
+ // data[0] and data[2] both still arrays of objects.
+ data[1] = [];
+ MG.data_graphic({
+ title: "Missing Time Series Don't Get Drawn",
+ description: "We set the second array to [] instead of the loaded data. The line color order is preserved.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#missing-multi'
+ });
+});
+
+d3.json('data/fake_users3.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+ data[1][data[1].length-1].value = 50000000;
+ data[2][data[2].length-1] = MG.clone(data[1][data[1].length-1]);
+ data[2][data[2].length-1].value += 10000000;
+
+
+ MG.data_graphic({
+ title: "Labeling Lines",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ legend: ['US', 'CA', 'DE'],
+ target: '#multi-labelled'
+ });
+});
+
+d3.json('data/fake_users2.json', function(data){
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ };
+ MG.data_graphic({
+ title: "Custom Line Coloring",
+ description: "By passing in an array of hex / rgb / rgba / html strings, you can specify the colors of the lines. NOTE: this feature may have an API change before it is fully in Metrics Graphics. Use at your own risk.",
+ data: [data[0], data[1], data[2]],
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#custom-colors',
+ legend: ['Team A','Team B','Team C'],
+ legend_target: 'div#custom-color-key',
+ colors: ['blue', 'rgb(255,100,43)', '#CCCCFF'],
+ aggregate_rollover: true
+ });
+});
+
+d3.json('data/fake_users3.json', function(data) {
+
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ };
+
+ MG.data_graphic({
+ title: "Select lines of your multi-line chart having areas",
+ description: "By passing in an array of booleans in 'area' property, you can choose which lines has an area or not.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#multiline_area_select',
+ area: [false, true, false],
+ y_extended_ticks: true,
+ x_accessor: 'date'
+ });
+});
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/other.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/other.htm
new file mode 100644
index 0000000..e65d641
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/other.htm
@@ -0,0 +1,48 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='aspect1'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users3.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users3.json', function(data) {
+ for(var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Preserving the aspect ratio",
+ description: "You can automatically set the width or height of a data graphic to fit its parent element. When done the graphic will rescale to fit the size of the parent element while preserving its aspect ratio.",
+ data: data,
+ full_width: true,
+ height: 300,
+ right: 40,
+ x_extended_ticks: true,
+ target: '#aspect1',
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+<script>
+MG._hooks = {};
+d3.json('data/fake_users3.json', function(data) {
+ for(var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Preserving the aspect ratio",
+ description: "You can automatically set the width or height of a data graphic to fit its parent element. When done the graphic will rescale to fit the size of the parent element while preserving its aspect ratio.",
+ data: data,
+ full_width: true,
+ height: 300,
+ right: 40,
+ x_extended_ticks: true,
+ target: '#aspect1',
+ x_accessor: 'date',
+ y_accessor: 'value'
+ });
+});
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/rollovers.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/rollovers.htm
new file mode 100644
index 0000000..53510bb
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/rollovers.htm
@@ -0,0 +1,309 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='col-lg-12 text-center' id='precision1'></div>
+ <div class='col-lg-12 text-center' id='precision2'></div>
+ <div class='col-lg-12 text-center' id='custom-rollover'></div>
+ <div class='col-lg-12 text-center' id='no-rollover-text'></div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'>
+ <a href='data/float.json'>data 1</a>,
+ <a href='data/some_percentage.json'>data 2</a>
+ </div>
+
+<pre><code class='javascript'>d3.json('data/float.json', function(data) {
+ data = MG.convert.date(data, 'date');
+
+ MG.data_graphic({
+ title: "Changing Precision 1",
+ description: "We can change the precision if the axis data type is a float. We can also change both the formatting, or hide the rollover text altogether. Here we set <i>decimals: 3</i> to get three decimals in the rollover for percentages.",
+ data: data,
+ decimals: 3,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#precision1'
+ });
+
+ MG.data_graphic({
+ title: "Custom Rollover Text",
+ description: "Here is an example of changing the rollover text. You could in theory actually update any DOM element with the data from that rollover - a title, for instance.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ mouseover: function(d, i) {
+ // custom format the rollover text, show days
+ var pf = d3.format('.0s');
+ d3.select('#custom-rollover svg .mg-active-datapoint')
+ .text('Day ' + (i + 1) + ' ' + pf(d.value));
+ },
+ target: '#custom-rollover'
+ });
+});
+
+d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Changing Precision 2",
+ description: "Here we set <i>decimals: 0</i> for percentages.",
+ data: data,
+ decimals: 0,
+ format: 'percentage',
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#precision2'
+ });
+
+ MG.data_graphic({
+ title: "... Or No Rollover Text",
+ description: "By setting <i>show_rollover_text: false</i>, you can hide the default rollover text from even appearing. This, coupled with the custom callback, gives a lot of interesting options for controlling rollovers.",
+ data: data,
+ decimals: 0,
+ show_rollover_text: false,
+ format: 'percentage',
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#no-rollover-text'
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='aggregate'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users2.json'>data</a></div>
+
+<pre><code class='javascript'>d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var all_the_data = MG.clone(data[0]);
+ for (i = 1; i < data.length; i++){
+ for (var j = 0; j < data[i].length; j++){
+ if (i === 2 && all_the_data[j].date < new Date('2014-02-01')) {
+ } else {
+ all_the_data[j]['value' + (i + 1)] = data[i][j].value;
+ }
+ }
+ }
+
+ MG.data_graphic({
+ title: "Aggregated Rollover Information",
+ description: "Aggregated information can be displayed with the <i>aggregate_rollover</i> option in order to clearly highlight the relationship between lines. Also handles non-contiguous data",
+ data: all_the_data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#aggregate',
+ y_extended_ticks: true,
+ x_accessor: 'date',
+ y_accessor: ['value', 'value2', 'value3'],
+ aggregate_rollover: true
+ });
+});</code></pre>
+
+ </div>
+ </div>
+
+
+<div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='formatting-with-strings'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users2.json'>data</a></div>
+
+<pre><code class='javascript'>
+d3.json('data/float.json', function(data) {
+
+ data = MG.convert.date(data, 'date');
+ // check out https://github.com/mbostock/d3/wiki/Formatting for number formatting
+ //and https://github.com/mbostock/d3/wiki/Time-Formatting for time formatting options.
+
+ MG.data_graphic({
+ title: "Rollover Formatting With Strings",
+ description: "Metrics Graphics comes with two arguments: y_rollover_format and x_rollover_format. These arguments take either strings or functions. Strings are formatted according to D3's number format, or D3's time formatting, if the accessor pulls out Date objects.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ y_mouseover: '%d',
+ x_mouseover: '%e of %b? Well, ',
+ target: '#y-formatting'
+ });
+})
+</code></pre>
+
+ </div>
+</div>
+
+
+<div class='row trunk-section'>
+ <div class='col-lg-7 text-center' id='formatting-with-functions'></div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/fake_users2.json'>data</a></div>
+
+<pre><code class='javascript'>
+d3.json('data/float.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ MG.data_graphic({
+ title: "Rollover Formatting With Functions",
+ description: "You can also pass in a function, whose arguments are the data point and the index.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ y_rollover_format: function(d){
+ return Math.round(d.value) + (Math.random() > .5 ? ' + 1' : ' - 1')
+ },
+ x_rollover_format: function(d){
+ var today = new Date()
+ return Math.round((today - d.date)/ (1000 * 60 * 60 * 24)) + ' days ago, ';
+ },
+ target: '#formatting-with-functions'
+ });
+})
+</code></pre>
+
+ </div>
+</div>
+
+
+<script>
+MG._hooks = {};
+d3.json('data/float.json', function(data) {
+ data = MG.convert.date(data, 'date');
+
+ MG.data_graphic({
+ title: "Updating Rollover Accessor Formatting With Strings",
+ description: "Metrics Graphics comes with two arguments: y_rollover_format and x_rollover_format. These arguments take either strings or functions. Strings are formatted according to D3's number format, or D3's time formatting, if the accessor pulls out Date objects.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ y_mouseover: '%d',
+ x_mouseover: '%e of %b? Well, ',
+ target: '#formatting-with-strings'
+ });
+
+ MG.data_graphic({
+ title: "Updating Rollover Accessor Formatting With Functions",
+ description: "You can also pass in a function, whose arguments are the data point and the index.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ y_mouseover: function(d){
+ return Math.round(d.value) + (Math.random() > .5 ? ' + 1' : ' - 1')
+ },
+ x_mouseover: function(d){
+ var today = new Date()
+ return Math.round((today - d.date)/ (1000 * 60 * 60 * 24)) + ' days ago, ';
+ },
+ target: '#formatting-with-functions'
+ });
+
+ MG.data_graphic({
+ title: "Changing Precision 1",
+ description: "We can change the precision if the axis data type is a float. We can also change both the formatting, or hide the rollover text altogether. Here we set <i>decimals: 3</i> to get three decimals in the rollover for percentages.",
+ data: data,
+ decimals: 3,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#precision1'
+ });
+
+ MG.data_graphic({
+ title: "Custom Rollover Text",
+ description: "Here is an example of changing the rollover text. You could in theory actually update any DOM element with the data from that rollover - a title, for instance.",
+ data: data,
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ mouseover: function(d, i) {
+ // custom format the rollover text, show days
+ var pf = d3.format('.0s');
+ d3.select('#custom-rollover svg .mg-active-datapoint')
+ .text('Day ' + (i + 1) + ' ' + pf(d.value));
+ },
+ target: '#custom-rollover'
+ });
+});
+
+d3.json('data/some_percentage.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ MG.data_graphic({
+ title: "Changing Precision 2",
+ description: "Here we set <i>decimals: 0</i> for percentages.",
+ data: data,
+ decimals: 0,
+ format: 'percentage',
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#precision2'
+ });
+
+ MG.data_graphic({
+ title: "... Or No Rollover Text",
+ description: "By setting <i>show_rollover_text: false</i>, you can hide the default rollover text from even appearing. This, coupled with the custom callback, gives a lot of interesting options for controlling rollovers.",
+ data: data,
+ decimals: 0,
+ show_rollover_text: false,
+ format: 'percentage',
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#no-rollover-text'
+ });
+});
+
+d3.json('data/fake_users2.json', function(data) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = MG.convert.date(data[i], 'date');
+ }
+
+ var all_the_data = MG.clone(data[0]);
+ for (i = 1; i < data.length; i++){
+ for (var j = 0; j < data[i].length; j++){
+ if (i === 2 && all_the_data[j].date < new Date('2014-02-01')) {
+ } else {
+ all_the_data[j]['value' + (i + 1)] = data[i][j].value;
+ }
+ }
+ }
+
+ MG.data_graphic({
+ title: "Aggregated Rollover Information",
+ description: "Aggregated information can be displayed with the <i>aggregate_rollover</i> option in order to clearly highlight the relationship between lines. Also handles non-contiguous data",
+ data: all_the_data,
+ width: 600,
+ height: 200,
+ right: 40,
+ target: '#aggregate',
+ y_extended_ticks: true,
+ x_accessor: 'date',
+ y_accessor: ['value', 'value2', 'value3'],
+ aggregate_rollover: true
+ });
+});
+</script>
diff --git a/priv/static/metrics-graphics-3.0-alpha3/examples/charts/updating.htm b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/updating.htm
new file mode 100644
index 0000000..af3919b
--- /dev/null
+++ b/priv/static/metrics-graphics-3.0-alpha3/examples/charts/updating.htm
@@ -0,0 +1,169 @@
+ <div class='row trunk-section'>
+ <div class='col-lg-7 text-center'>
+ <div class='col-lg-12' id='split_by'></div>
+ <div class='btn-group btn-group-sm text-center split-by-controls'>
+ <button type='button' class='btn btn-default active'
+ data-y_accessor='release'>Release</button>
+ <button type='button' class='btn btn-default'
+ data-y_accessor='beta'>Beta</button>
+ <button type='button' class='btn btn-default'
+ data-y_accessor='alpha'>Alpha</button>
+ </div>
+ <div class='col-lg-12' id='modify_time_period'></div>
+ <div class='btn-group btn-group-sm text-center
+ modify-time-period-controls'>
+ <button type='button' class='btn btn-default active'
+ data-time_period=''>All time</button>
+ <button type='button' class='btn btn-default'
+ data-time_period='61'>Past 2 months</button>
+ <button type='button' class='btn btn-default'
+ data-time_period='31'>Past month</button>
+ </div>
+ </div>
+ <div class='col-lg-5'>
+ <div class='data-column'><a href='data/split_by.json'>data</a></div>
+
+<pre><code class='javascript'>var globals = {};
+
+var split_by_params = {
+ title: "Downloads by Channel",
+ description: "We sometimes have the need to split the data and then gracefully update the graphic with the newly selected subset of data.",
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#split_by',
+ x_accessor: 'date',
+ y_accessor: 'release'
+};
+
+var modify_time_period_params = {
+ title: "Beta Downloads",
+ description: "We sometimes have the need to view data for just the past n days. Here, the <i>transition_on_update</i> option is set to false.",
+ width: 600,
+ height: 200,
+ right: 40,
+ show_secondary_x_label: false,
+ xax_count: 4,
+ target: '#modify_time_period',
+ x_accessor: 'date',
+ y_accessor: 'beta'
+}
+
+d3.json('data/split_by.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ globals.data = data;
+
+ split_by_params.data = data;
+ MG.data_graphic(split_by_params);
+
+ modify_time_period_params.data = data;
+ MG.data_graphic(modify_time_period_params);
+});
+
+$('.split-by-controls button').click(function() {
+ var new_y_accessor = $(this).data('y_accessor');
+ split_by_params.y_accessor = new_y_accessor;
+
+ // change button state
+ $(this).addClass('active').siblings().removeClass('active');
+
+ // update data
+ delete split_by_params.xax_format;
+ MG.data_graphic(split_by_params);
+});
+
+$('.modify-time-period-controls button').click(function() {
+ var past_n_days = $(this).data('time_period');
+ var data = modify_time_period(globals.data, past_n_days);
+
+ // change button state
+ $(this).addClass('active').siblings().removeClass('active');
+
+ delete modify_time_period_params.xax_format;
+ modify_time_period_params.data = data;
+ MG.data_graphic(modify_time_period_params);
+});
+
+function modify_time_period(data, past_n_days) {
+ if (past_n_days !== '') {
+ return MG.clone(data).slice(past_n_days * -1);
+ }
+
+ return data;
+}</code></pre>
+
+ </div>
+ </div>
+
+<script>
+MG._hooks = {};
+var globals = {};
+
+var split_by_params = {
+ title: "Downloads by Channel",
+ description: "We sometimes have the need to split the data and then gracefully update the graphic with the newly selected subset of data.",
+ width: 600,
+ height: 200,
+ right: 40,
+ xax_count: 4,
+ target: '#split_by',
+ x_accessor: 'date',
+ y_accessor: 'release'
+};
+
+var modify_time_period_params = {
+ title: "Beta Downloads",
+ description: "We sometimes have the need to view data for just the past n days. Here, the <i>transition_on_update</i> option is set to false.",
+ width: 600,
+ height: 200,
+ right: 40,
+ show_secondary_x_label: false,
+ xax_count: 4,
+ transition_on_update: false,
+ target: '#modify_time_period',
+ x_accessor: 'date',
+ y_accessor: 'beta'
+}
+
+d3.json('data/split_by.json', function(data) {
+ data = MG.convert.date(data, 'date');
+ globals.data = data;
+
+ split_by_params.data = data;
+ MG.data_graphic(split_by_params);
+
+ modify_time_period_params.data = data;
+ MG.data_graphic(modify_time_period_params);
+});
+
+$('.split-by-controls button').click(function() {
+ var new_y_accessor = $(this).data('y_accessor');
+ split_by_params.y_accessor = new_y_accessor;
+
+ // change button state
+ $(this).addClass('active').siblings().removeClass('active');
+
+ // update data
+ MG.data_graphic(split_by_params);
+});
+
+$('.modify-time-period-controls button').click(function() {
+ var past_n_days = $(this).data('time_period');
+ var data = modify_time_period(globals.data, past_n_days);
+
+ // change button state
+ $(this).addClass('active').siblings().removeClass('active');
+
+ modify_time_period_params.data = data;
+ MG.data_graphic(modify_time_period_params);
+});
+
+function modify_time_period(data, past_n_days) {
+ if (past_n_days !== '') {
+ return MG.clone(data).slice(past_n_days * -1);
+ }
+
+ return data;
+}
+</script> \ No newline at end of file