We arrive in the office the next morning just before nine o'clock. We begin thinking about Jeff's request to add a cursor tooltip to his donut chart. The cursor plugin does not create a tooltip for donut charts. So, if we want a tooltip, we will have to create one. We decide to look at modifying the donut renderer plugin to accomplish this.
We open the file, jqplot.donutRenderer.js
, found in our js
folder and save it as a new file called jqplot.donutRendererV2.js
. We begin working our way through it. The entire plugin is a method attached to the jqPlot object and by default attached to jQuery. We see that DonutRenderer
inherits its structure from the LineRenderer
plugin:
$.jqplot.DonutRenderer = function(){ $.jqplot.LineRenderer.call(this); }; $.jqplot.DonutRenderer.prototype = new $.jqplot.LineRenderer(); $.jqplot.DonutRenderer.prototype.constructor = $.jqplot.DonutRenderer;
We continue moving through the plugin and come to the init
method, which is where all our options are passed in and set.
// called with scope of a series $.jqplot.DonutRenderer.prototype.init = function(options, plot) { // Group: Properties // // prop: diameter // Outer diameter of the donut, auto computed by default this.diameter = null; // prop: innerDiameter // Inner diameter of the donut, auto calculated by default. // If specified will override thickness value. this.innerDiameter = null; // prop: showTooltip // true to add our custom tooltip. this.showTooltip = false;
preInit
method where the default renderers for the legend and axes are set, which is done before the chart is created. This gets us thinking. We can inject a div for our tooltip into the chart div. This is what is done for the legend and axes. So at the end of the method, we check to see if the tooltip is enabled and add the div as follows:function preInit(target, data, options) { options = options || {}; ... if(options.showTooltip) { $("#"+target).append("<div class='jqplot-donut-tooltip'></div>"); } }
handleMove
method. Inside the method, we see a reference to the jqplotDataHighlight
method and the pageX
and pageY
variables, which hold our mouse coordinates. Then there is the highlight
method, which highlights the selected wedge as shown in the following code snippet:function handleMove(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { ... if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.donutRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { var evt = jQuery.Event('jqplotDataHighlight'), evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, ins[0], ins[1]);
jqplot-donut-tooltip
class within our chart and set the top and left properties so it will appear next to our cursor. Once the tooltip is in place, we show it as follows:$(plot.targetId + " .jqplot-donut-tooltip").css({ top: evt.pageY-50, left: evt.pageX }); $(plot.targetId + " .jqplot-donut-tooltip").show(); } }
else
statement, the wedge is no longer highlighted so we hide the tooltip as follows: else if (neighbor == null) {
unhighlight (plot);
$(plot.targetId + " .jqplot-donut-tooltip").hide();
}
}
We have completed modifying our plugin. Since we are creating custom tooltip data for our inner ring, we will need to also modify the event handlers in our HTML file.
We open the file, 1168_05_05.html
, and save it as a new file, 1168_11_04.html
.
themes.js
so we can use the company colors. Since we are using the company colors, we also get rid of the arrSeriesColors
array as follows:<script src="../js/jqplot.donutRendererV2.js"></script> <script src="../js/functions.js"></script> <script src="../js/themes.js"></script> <script> var innerRingColors = [];
parseVersions
function, we switch to use the company_colors
array as follows:function parseVersions(v,browser) {
...
for (var ver in v[name]) {
innerRing.push([ver, v[name][ver], name]);
innerRingColors.push(company_colors[i]);
}
...
return versions;
}
title
, we enable showTooltip
. We also set backgroundcolor
and seriesColors
to the company_colors
as follows:title: 'Web Browser Usage', showTooltip: true, grid: { backgroundColor: $.jqplot.hex2rgb(company_colors[0], 0.1) }, seriesColors: company_colors, seriesDefaults: {
jqplotDataHighlight
and jqplotDataUnhighlight
event handlers as follows:if(seriesIndex == 0) { $(".jqplot-donut-tooltip").html(data[0]+' - '+percent.toFixed(2)+'%'), } else { $(".jqplot-donut-tooltip").html(data[2]+': '+data[0]+' - '+percent.toFixed(2)+'%'), } } ); $('#purple_browser_usage').on('jqplotDataUnhighlight', function (ev, seriesIndex, pointIndex, data) { $(".jqplot-donut-tooltip").html(''), } );
styles.css
and set the positioning and z-index
so the tooltip will appear next to our cursor and on top of any other layers as follows:#purple_browser_usage .jqplot-donut-tooltip { color: #000; position: absolute; white-space: nowrap; display: none; padding: 5px; background: rgba(255,255,255,.95); border: 1px solid #999; border-radius: 5px; z-index: 999; }
We load the updated chart and move our cursor around highlighting different wedges. We hover over the wedge for Firefox 26.0.
A nice tooltip appears near our cursor. This is a much better option than putting the highlighted data at the top of the chart like before.
It felt a little daunting at first when we began looking through the plugin, but then we began seeing patterns in the structure. We found the methods we needed and accomplished what Jeff asked for.
Later that afternoon, we meet with Roshan, Sara, Jeff, and Calvin. Roshan starts off, "This chart showing conversions is beautiful. I also really like the logo. You know you are going to need to update all the other charts now, right?" Roshan says with a smile.
Jeff speaks up next, "I'm glad you were able to figure out the tooltip issue. I've already got several other ideas for new charts."
With all we have accomplished over the past couple of weeks, we have a good understanding of jqPlot and how we can extend the functionality with plugins. We are confident we can fulfill whatever requests Roshan and the others may send our way during phase three.
18.226.4.191