Skip to content

Commit

Permalink
First stab (issue #358)
Browse files Browse the repository at this point in the history
  • Loading branch information
almossawi committed Mar 23, 2015
1 parent 0811d10 commit 9c9cbe6
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 47 deletions.
75 changes: 54 additions & 21 deletions dist/metricsgraphics.js
Expand Up @@ -46,6 +46,7 @@
small_text: false, // coerces small text regardless of graphic size
xax_count: 6, // number of x axis ticks
xax_tick_length: 5, // x axis tick length
xax_start_at_min: false,
yax_count: 5, // number of y axis ticks
yax_tick_length: 5, // y axis tick length
x_extended_ticks: false, // extends x axis ticks across chart - useful for tall charts
Expand Down Expand Up @@ -1272,6 +1273,7 @@
args.scales.X = (args.time_series)
? d3.time.scale()
: d3.scale.linear();

args.scales.X
.domain([args.processed.min_x, args.processed.max_x])
.range([args.left + args.buffer, args.width - args.right - args.buffer - args.additional_buffer]);
Expand Down Expand Up @@ -1451,9 +1453,7 @@
g.append('text')
.attr('class', 'label')
.attr('x', function() {
return args.left + args.buffer
+ ((args.width - args.right - args.buffer)
- (args.left + args.buffer)) / 2;
return (args.left + args.width - args.right) / 2;
})
.attr('y', (args.height - args.bottom / 2).toFixed(2))
.attr('dy', '.50em')
Expand Down Expand Up @@ -1517,7 +1517,7 @@
// a custom function if desired
if(args.data[0][0][args.x_accessor] instanceof Date) {
return args.processed.main_x_time_format(d);
} if (typeof args.data[0][0][args.x_accessor] === 'number') {
} else if (typeof args.data[0][0][args.x_accessor] === 'number') {
if (d < 1.0) {
//don't scale tiny values
return args.xax_units + d3.round(d, args.decimals);
Expand All @@ -1533,17 +1533,32 @@

function mg_add_x_ticks(g, args) {
var last_i = args.scales.X.ticks(args.xax_count).length - 1;
var ticks = args.scales.X.ticks(args.xax_count);

//force min to be the first tick rather than the first element in ticks
if(args.xax_start_at_min) {
ticks[0] = args.processed.min_x;
}

if (args.chart_type !== 'bar' && !args.x_extended_ticks && !args.y_extended_ticks) {
//extend axis line across bottom, rather than from domain's min..max
g.append('line')
.attr('x1',
(args.concise === false || args.xax_count === 0)
? args.left + args.buffer
: (args.scales.X(args.scales.X.ticks(args.xax_count)[0])).toFixed(2)
)
.attr('x1', function() {
//start the axis line from the beginning, domain's min, or the auto-generated
//ticks' first element, depending on whether xax_count is set to 0 or
//xax_start_at_min is set to true
if (args.xax_count === 0) {
return args.left + args.buffer;
}
else if (args.xax_start_at_min) {
return args.scales.X(args.processed.min_x).toFixed(2)
}
else {
return (args.scales.X(args.scales.X.ticks(args.xax_count)[0])).toFixed(2);
}
})
.attr('x2',
(args.concise === false || args.xax_count === 0)
(args.xax_count === 0)
? args.width - args.right - args.buffer
: (args.scales.X(args.scales.X.ticks(args.xax_count)[last_i])).toFixed(2)
)
Expand All @@ -1552,7 +1567,7 @@
}

g.selectAll('.mg-xax-ticks')
.data(args.scales.X.ticks(args.xax_count)).enter()
.data(ticks).enter()
.append('line')
.attr('x1', function(d) { return args.scales.X(d).toFixed(2); })
.attr('x2', function(d) { return args.scales.X(d).toFixed(2); })
Expand All @@ -1570,8 +1585,15 @@
}

function mg_add_x_tick_labels(g, args) {
var ticks = args.scales.X.ticks(args.xax_count);

//force min to be the first tick rather than the first element in ticks
if(args.xax_start_at_min) {
ticks[0] = args.processed.min_x;
}

g.selectAll('.mg-xax-labels')
.data(args.scales.X.ticks(args.xax_count)).enter()
.data(ticks).enter()
.append('text')
.attr('x', function(d) { return args.scales.X(d).toFixed(2); })
.attr('y', (args.height - args.bottom + args.xax_tick_length * 7 / 3).toFixed(2))
Expand Down Expand Up @@ -1607,7 +1629,11 @@

var years = secondary_function(args.processed.min_x, args.processed.max_x);

if (years.length === 0) {
//if xax_start_at_min is set
if (args.xax_start_at_min && years.length === 0) {
var first_tick = ticks[0];
years = [first_tick];
} else if (years.length === 0) {
var first_tick = args.scales.X.ticks(args.xax_count)[0];
years = [first_tick];
}
Expand All @@ -1630,9 +1656,15 @@
g.selectAll('.mg-year-marker')
.data(years).enter()
.append('text')
.attr('x', function(d) { return args.scales.X(d).toFixed(2); })
.attr('x', function(d, i) {
if (args.xax_start_at_min && i == 0) {
d = ticks[0];
}

return args.scales.X(d).toFixed(2);
})
.attr('y', (args.height - args.bottom + args.xax_tick_length * 7 / 1.3).toFixed(2))
.attr('dy', args.use_small_class ? -3 : 0)//(args.y_extended_ticks) ? 0 : 0 )
.attr('dy', args.use_small_class ? -3 : 0)
.attr('text-anchor', 'middle')
.text(function(d) {
return yformat(d);
Expand Down Expand Up @@ -1947,12 +1979,14 @@
});
}

function preventOverlap (labels) {
if (labels.length == 1) {
function preventOverlap(labels) {
if (!labels || labels.length == 1) {
return;
}

//see if each of our labels overlaps any of the other labels
for (var i = 0; i < labels.length; i++) {
//if so, nudge it up a bit, if the label it intersects hasn't already been nudged
if (isOverlapping(labels[i], labels)) {
var node = d3.select(labels[i]);
var newY = +node.attr('y');
Expand All @@ -1974,7 +2008,6 @@

//check to see if this label overlaps with any of the other labels
var sibling_bbox = labels[i].getBoundingClientRect();

if (element_bbox.top === sibling_bbox.top &&
!(sibling_bbox.left > element_bbox.right || sibling_bbox.right < element_bbox.left)
) {
Expand All @@ -1984,15 +2017,15 @@
return false;
}

function xPosition (d) {
function xPosition(d) {
return args.scales.X(d[args.x_accessor]);
}

function xPositionFixed (d) {
function xPositionFixed(d) {
return xPosition(d).toFixed(2);
}

function inRange (d) {
function inRange(d) {
return (args.scales.X(d[args.x_accessor]) > args.buffer + args.left)
&& (args.scales.X(d[args.x_accessor]) < args.width - args.buffer - args.right);
}
Expand Down
4 changes: 2 additions & 2 deletions dist/metricsgraphics.min.js

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions examples/data/neg2.json
Expand Up @@ -5,26 +5,26 @@
},
{
"measure": 53.3423,
"subject": 20.27860065952477
"subject": 20.27
},
{
"measure": -10.343,
"subject": 12.426109787612926
"subject": 12.42
},
{
"measure": -1,
"subject": -1.699256257379318
"subject": -1.69
},
{
"measure": 10,
"subject": -10.019134369994354
"subject": -10.01
},
{
"measure": 25,
"subject": -21.59885296861614
"subject": -21.59
},
{
"measure": -20.343,
"subject": -31.867314787877127
"subject": -31.86
}
]
13 changes: 7 additions & 6 deletions examples/js/main.js
Expand Up @@ -729,7 +729,7 @@
right: trunk.right,
xax_format: function(f) {
var pf = d3.formatPrefix(f);
return pf.scale(f) + pf.symbol;
return Math.round(pf.scale(f)) + pf.symbol;
},
target: '#neg2',
x_accessor: 'subject',
Expand Down Expand Up @@ -932,10 +932,11 @@
target: '#scatter-simple',
xax_format: function(f) {
var pf = d3.formatPrefix(f);
return pf.scale(f) + pf.symbol;
return Math.round(pf.scale(f)) + pf.symbol;
},
x_accessor: 'x',
y_accessor: 'y',
mouseover: function(d, i) { console.log(d,i); },
y_rug: true
});

Expand All @@ -950,7 +951,7 @@
target: '#categorical1',
xax_format: function(f) {
var pf = d3.formatPrefix(f);
return pf.scale(f) + pf.symbol;
return Math.round(pf.scale(f)) + pf.symbol;
},
x_accessor: 'x',
y_accessor: 'y',
Expand All @@ -970,7 +971,7 @@
target: '#categorical2',
xax_format: function(f) {
var pf = d3.formatPrefix(f);
return pf.scale(f) + pf.symbol;
return Math.round(pf.scale(f)) + pf.symbol;
},
x_accessor: 'x',
y_accessor: 'y',
Expand All @@ -993,7 +994,7 @@
target: '#scatter-line-best-fit',
xax_format: function(f) {
var pf = d3.formatPrefix(f);
return pf.scale(f) + pf.symbol;
return Math.round(pf.scale(f)) + pf.symbol;
},
x_accessor: 'x',
y_accessor: 'y'
Expand Down Expand Up @@ -1076,7 +1077,7 @@
target: '#scatter-size-and-color',
xax_format: function(f) {
var pf = d3.formatPrefix(f);
return pf.scale(f) + pf.symbol;
return Math.round(pf.scale(f)) + pf.symbol;
},
x_accessor: 'x',
y_accessor: 'y',
Expand Down
1 change: 1 addition & 0 deletions src/js/common/data_graphic.js
Expand Up @@ -33,6 +33,7 @@ MG.data_graphic = function() {
small_text: false, // coerces small text regardless of graphic size
xax_count: 6, // number of x axis ticks
xax_tick_length: 5, // x axis tick length
xax_start_at_min: false,
yax_count: 5, // number of y axis ticks
yax_tick_length: 5, // y axis tick length
x_extended_ticks: false, // extends x axis ticks across chart - useful for tall charts
Expand Down
57 changes: 45 additions & 12 deletions src/js/common/x_axis.js
Expand Up @@ -64,6 +64,7 @@ function x_axis(args) {
args.scales.X = (args.time_series)
? d3.time.scale()
: d3.scale.linear();

args.scales.X
.domain([args.processed.min_x, args.processed.max_x])
.range([args.left + args.buffer, args.width - args.right - args.buffer - args.additional_buffer]);
Expand Down Expand Up @@ -307,7 +308,7 @@ function mg_default_xax_format(args) {
// a custom function if desired
if(args.data[0][0][args.x_accessor] instanceof Date) {
return args.processed.main_x_time_format(d);
} if (typeof args.data[0][0][args.x_accessor] === 'number') {
} else if (typeof args.data[0][0][args.x_accessor] === 'number') {
if (d < 1.0) {
//don't scale tiny values
return args.xax_units + d3.round(d, args.decimals);
Expand All @@ -323,17 +324,32 @@ function mg_default_xax_format(args) {

function mg_add_x_ticks(g, args) {
var last_i = args.scales.X.ticks(args.xax_count).length - 1;
var ticks = args.scales.X.ticks(args.xax_count);

//force min to be the first tick rather than the first element in ticks
if(args.xax_start_at_min) {
ticks[0] = args.processed.min_x;
}

if (args.chart_type !== 'bar' && !args.x_extended_ticks && !args.y_extended_ticks) {
//extend axis line across bottom, rather than from domain's min..max
g.append('line')
.attr('x1',
(args.concise === false || args.xax_count === 0)
? args.left + args.buffer
: (args.scales.X(args.scales.X.ticks(args.xax_count)[0])).toFixed(2)
)
.attr('x1', function() {
//start the axis line from the beginning, domain's min, or the auto-generated
//ticks' first element, depending on whether xax_count is set to 0 or
//xax_start_at_min is set to true
if (args.xax_count === 0) {
return args.left + args.buffer;
}
else if (args.xax_start_at_min) {
return args.scales.X(args.processed.min_x).toFixed(2)
}
else {
return (args.scales.X(args.scales.X.ticks(args.xax_count)[0])).toFixed(2);
}
})
.attr('x2',
(args.concise === false || args.xax_count === 0)
(args.xax_count === 0)
? args.width - args.right - args.buffer
: (args.scales.X(args.scales.X.ticks(args.xax_count)[last_i])).toFixed(2)
)
Expand All @@ -342,7 +358,7 @@ function mg_add_x_ticks(g, args) {
}

g.selectAll('.mg-xax-ticks')
.data(args.scales.X.ticks(args.xax_count)).enter()
.data(ticks).enter()
.append('line')
.attr('x1', function(d) { return args.scales.X(d).toFixed(2); })
.attr('x2', function(d) { return args.scales.X(d).toFixed(2); })
Expand All @@ -360,8 +376,15 @@ function mg_add_x_ticks(g, args) {
}

function mg_add_x_tick_labels(g, args) {
var ticks = args.scales.X.ticks(args.xax_count);

//force min to be the first tick rather than the first element in ticks
if(args.xax_start_at_min) {
ticks[0] = args.processed.min_x;
}

g.selectAll('.mg-xax-labels')
.data(args.scales.X.ticks(args.xax_count)).enter()
.data(ticks).enter()
.append('text')
.attr('x', function(d) { return args.scales.X(d).toFixed(2); })
.attr('y', (args.height - args.bottom + args.xax_tick_length * 7 / 3).toFixed(2))
Expand Down Expand Up @@ -397,7 +420,11 @@ function mg_add_x_tick_labels(g, args) {

var years = secondary_function(args.processed.min_x, args.processed.max_x);

if (years.length === 0) {
//if xax_start_at_min is set
if (args.xax_start_at_min && years.length === 0) {
var first_tick = ticks[0];
years = [first_tick];
} else if (years.length === 0) {
var first_tick = args.scales.X.ticks(args.xax_count)[0];
years = [first_tick];
}
Expand All @@ -420,9 +447,15 @@ function mg_add_x_tick_labels(g, args) {
g.selectAll('.mg-year-marker')
.data(years).enter()
.append('text')
.attr('x', function(d) { return args.scales.X(d).toFixed(2); })
.attr('x', function(d, i) {
if (args.xax_start_at_min && i == 0) {
d = ticks[0];
}

return args.scales.X(d).toFixed(2);
})
.attr('y', (args.height - args.bottom + args.xax_tick_length * 7 / 1.3).toFixed(2))
.attr('dy', args.use_small_class ? -3 : 0)//(args.y_extended_ticks) ? 0 : 0 )
.attr('dy', args.use_small_class ? -3 : 0)
.attr('text-anchor', 'middle')
.text(function(d) {
return yformat(d);
Expand Down

0 comments on commit 9c9cbe6

Please sign in to comment.