added flot tickrotor

This commit is contained in:
hyung-hwan 2015-03-29 05:57:13 +00:00
parent 0f7b18c260
commit 8b19ad4754
3 changed files with 192 additions and 7 deletions

View File

@ -26,8 +26,9 @@
<script type="text/javascript" src="<?=base_url_make('/js/jquery.flot.time.min.js')?>"></script>
<script type="text/javascript" src="<?=base_url_make('/js/jquery.flot.categories.min.js')?>"></script>
<script type="text/javascript" src="<?=base_url_make('/js/jquery.flot.pie.min.js')?>"></script>
<script type="text/javascript" src="<?=base_url_make('/js/jquery.flot.pie.min.js')?>"></script>
<script type="text/javascript" src="<?=base_url_make('/js/jquery.flot.tickrotor.js')?>"></script>
<script type="text/javascript" src="<?=base_url_make('/js/Chart.js')?>"></script>
<script type="text/javascript">
function show_commits_per_month_graph(log)
@ -249,7 +250,6 @@ function show_commits_per_user_graph(log)
{
label: "Commits Per User",
data: commits_per_user_data
//color: "#FF0000"
}
];
@ -269,7 +269,8 @@ function show_commits_per_user_graph(log)
xaxes: [
{ mode: "categories",
autoscaleMargin: 0.05
autoscaleMargin: 0.05,
rotateTicks: ((commits_per_user_data.length >= 8)? 135: 0)
}
],
@ -313,10 +314,6 @@ function show_all_graphs (response)
show_commits_per_month_graph (log);
show_commits_per_user_graph (log);
}
function render_graphs()

View File

@ -21,6 +21,7 @@ www_DATA = \
jquery.flot.threshold.min.js \
jquery.flot.time.min.js \
excanvas.min.js \
jquery.flot.tickrotor.js \
Chart.js
EXTRA_DIST = $(www_DATA)

View File

@ -0,0 +1,187 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* flot-tickrotor: flot plugin to display angled X-axis tick labels.
*
* Requires flot 0.7 or higher and a browser supporting <canvas>.
*
* To activate, just set xaxis.rotateTicks to an angle in degrees. Labels
* are rotated clockwise, so if you want the labels to angle up and to the
* right (/) you need to provide an angle > 90. The text will be flipped so
* that it is still right-side-up.
* Angles greater than or equal to 180 are ignored.
*/
(function ($) {
var options = { };
function init(plot) {
// Taken from flot-axislabels.
// This is kind of a hack. There are no hooks in Flot between
// the creation and measuring of the ticks (setTicks, measureTickLabels
// in setupGrid() ) and the drawing of the ticks and plot box
// (insertAxisLabels in setupGrid() ).
//
// Therefore, we use a trick where we run the draw routine twice:
// the first time to get the tick measurements, so that we can change
// them, and then have it draw it again.
var ticks = []; // preserve between draw() calls.
var font;
var secondPass = false;
var rotateTicks, rotateTicksRads, radsAboveHoriz;
plot.hooks.draw.push(function (plot, ctx) {
var xaxis; // for convenience
if (!secondPass) {
var opts = plot.getAxes().xaxis.options;
if (opts.rotateTicks === undefined) {
return;
}
rotateTicks = parseInt(opts.rotateTicks, 10);
if (rotateTicks.toString() != opts.rotateTicks || rotateTicks == 0 || rotateTicks >= 180) {
return;
}
rotateTicksRads = rotateTicks * Math.PI/180;
if (rotateTicks > 90) {
radsAboveHoriz = Math.PI - rotateTicksRads;
} else {
radsAboveHoriz = Math.PI/2 - rotateTicksRads;
}
font = opts.rotateTicksFont;
if (!font) {
font = $('.tickLabel').css('font');
}
if (!font) {
font = 'smaller sans-serif';
}
var elem, maxLabelWidth = 0, maxLabelHeight = 0, minX = 0, maxX = 0;
// We have to clear the ticks option so that flot core
// doesn't draw ticks superimposed with ours, but we preserve
// the tick data as xaxis.rotatedTicks so that external code
// can still get to it.
// FIXME: It would obviously be better to just interrupt
// the drawing of the ticks and preserve the 'ticks'
// property. That probably requires another hook.
xaxis = plot.getAxes().xaxis;
ticks = plot.getAxes().xaxis.ticks;
xaxis.rotatedTicks = ticks;
opts.ticks = []; // we'll make our own
var x;
for (var i = 0; i < ticks.length; i++) {
elem = $('<span style="font:' + font + '">' + ticks[i].label + '</span>');
plot.getPlaceholder().append(elem);
ticks[i].height = elem.outerHeight(true);
ticks[i].width = elem.outerWidth(true);
elem.remove();
if (ticks[i].height > maxLabelHeight) {
maxLabelHeight = ticks[i].height;
}
if (ticks[i].width > maxLabelWidth) {
maxLabelWidth = ticks[i].width;
}
var tick = ticks[i];
// See second-draw code below for explanation of offsets.
if (rotateTicks > 90) {
// See if any labels are too long and require increased left
// padding.
x = Math.round(plot.getPlotOffset().left + xaxis.p2c(tick.v))
- Math.ceil(Math.cos(radsAboveHoriz) * tick.height)
- Math.ceil(Math.cos(radsAboveHoriz) * tick.width);
if (x < minX) {
minX = x;
}
} else {
// See if any labels are too long and require increased right
// padding.
x = Math.round(plot.getPlotOffset().left + xaxis.p2c(tick.v))
+ Math.ceil(Math.cos(radsAboveHoriz) * tick.height)
+ Math.ceil(Math.cos(radsAboveHoriz) * tick.width);
if (x > maxX) {
maxX = x;
}
}
}
// Calculate maximum label height after rotating.
if (rotateTicks > 90) {
var acuteRads = rotateTicksRads - Math.PI/2;
opts.labelHeight = Math.ceil(Math.sin(acuteRads) * maxLabelWidth)
+ Math.ceil(Math.sin(acuteRads) * maxLabelHeight);
} else {
var acuteRads = Math.PI/2 - rotateTicksRads;
// Center such that the top of the label is at the center of the tick.
opts.labelHeight = Math.ceil(Math.sin(rotateTicksRads) * maxLabelWidth)
+ Math.ceil(Math.sin(acuteRads) * maxLabelHeight);
}
if (minX < 0) {
plot.getAxes().yaxis.options.labelWidth = -1 * minX;
}
// Doesn't seem to work if there are no values using the
// second y axis.
//if (maxX > xaxis.box.left + xaxis.box.width) {
// plot.getAxes().y2axis.options.labelWidth = maxX - xaxis.box.left - xaxis.box.width;
//}
// re-draw with new label widths and heights
secondPass = true;
plot.setupGrid();
plot.draw();
} else {
if (ticks.length == 0) {
return;
}
xaxis = plot.getAxes().xaxis;
var box = xaxis.box;
var tick, label, xoffset, yoffset;
for (var i = 0; i < ticks.length; i++) {
tick = ticks[i];
if (!tick.label) {
continue;
}
ctx.save();
ctx.font = font;
if (rotateTicks <= 90) {
// Center such that the top of the label is at the center of the tick.
xoffset = -Math.ceil(Math.cos(radsAboveHoriz) * tick.height);
yoffset = Math.ceil(Math.sin(radsAboveHoriz) * tick.height);
ctx.translate(Math.round(plot.getPlotOffset().left + xaxis.p2c(tick.v)) + xoffset,
box.top + box.padding + plot.getOptions().grid.labelMargin + yoffset);
ctx.rotate(rotateTicksRads);
} else {
// We want the text to facing up, so we have to
// rotate counterclockwise, which means the label
// has to *end* at the center of the tick.
xoffset = Math.ceil(Math.cos(radsAboveHoriz) * tick.height)
- Math.ceil(Math.cos(radsAboveHoriz) * tick.width);
yoffset = Math.ceil(Math.sin(radsAboveHoriz) * tick.width)
+ Math.ceil(Math.sin(radsAboveHoriz) * tick.height);
ctx.translate(Math.round(plot.getPlotOffset().left + xaxis.p2c(tick.v) + xoffset),
box.top + box.padding + plot.getOptions().grid.labelMargin + yoffset);
ctx.rotate(-radsAboveHoriz);
}
ctx.fillText(tick.label, 0, 0);
ctx.restore();
}
}
});
}
$.plot.plugins.push({
init: init,
options: options,
name: 'tickRotor',
version: '1.0'
});
})(jQuery);