917 lines
30 KiB
JavaScript
917 lines
30 KiB
JavaScript
/**
|
|
* jqPlot
|
|
* Pure JavaScript plotting plugin using jQuery
|
|
*
|
|
* Version: @VERSION
|
|
* Revision: @REVISION
|
|
*
|
|
* Copyright (c) 2009-2013 Chris Leonello
|
|
* jqPlot is currently available for use in all personal or commercial projects
|
|
* under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
|
|
* version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
|
|
* choose the license that best suits your project and use it accordingly.
|
|
*
|
|
* Although not required, the author would appreciate an email letting him
|
|
* know of any substantial use of jqPlot. You can reach the author at:
|
|
* chris at jqplot dot com or see http://www.jqplot.com/info.php .
|
|
*
|
|
* If you are feeling kind and generous, consider supporting the project by
|
|
* making a donation at: http://www.jqplot.com/donate.php .
|
|
*
|
|
* sprintf functions contained in jqplot.sprintf.js by Ash Searle:
|
|
*
|
|
* version 2007.04.27
|
|
* author Ash Searle
|
|
* http://hexmen.com/blog/2007/03/printf-sprintf/
|
|
* http://hexmen.com/js/sprintf.js
|
|
* The author (Ash Searle) has placed this code in the public domain:
|
|
* "This code is unrestricted: you are free to use it however you like."
|
|
*
|
|
*/
|
|
(function($) {
|
|
/**
|
|
* Class: $.jqplot.ThemeEngine
|
|
* Theme Engine provides a programatic way to change some of the more
|
|
* common jqplot styling options such as fonts, colors and grid options.
|
|
* A theme engine instance is created with each plot. The theme engine
|
|
* manages a collection of themes which can be modified, added to, or
|
|
* applied to the plot.
|
|
*
|
|
* The themeEngine class is not instantiated directly.
|
|
* When a plot is initialized, the current plot options are scanned
|
|
* an a default theme named "Default" is created. This theme is
|
|
* used as the basis for other themes added to the theme engine and
|
|
* is always available.
|
|
*
|
|
* A theme is a simple javascript object with styling parameters for
|
|
* various entities of the plot. A theme has the form:
|
|
*
|
|
*
|
|
* > {
|
|
* > _name:f "Default",
|
|
* > target: {
|
|
* > backgroundColor: "transparent"
|
|
* > },
|
|
* > legend: {
|
|
* > textColor: null,
|
|
* > fontFamily: null,
|
|
* > fontSize: null,
|
|
* > border: null,
|
|
* > background: null
|
|
* > },
|
|
* > title: {
|
|
* > textColor: "rgb(102, 102, 102)",
|
|
* > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif",
|
|
* > fontSize: "19.2px",
|
|
* > textAlign: "center"
|
|
* > },
|
|
* > seriesStyles: {},
|
|
* > series: [{
|
|
* > color: "#4bb2c5",
|
|
* > lineWidth: 2.5,
|
|
* > linePattern: "solid",
|
|
* > shadow: true,
|
|
* > fillColor: "#4bb2c5",
|
|
* > showMarker: true,
|
|
* > markerOptions: {
|
|
* > color: "#4bb2c5",
|
|
* > show: true,
|
|
* > style: 'filledCircle',
|
|
* > lineWidth: 1.5,
|
|
* > size: 4,
|
|
* > shadow: true
|
|
* > }
|
|
* > }],
|
|
* > grid: {
|
|
* > drawGridlines: true,
|
|
* > gridLineColor: "#cccccc",
|
|
* > gridLineWidth: 1,
|
|
* > backgroundColor: "#fffdf6",
|
|
* > borderColor: "#999999",
|
|
* > borderWidth: 2,
|
|
* > shadow: true
|
|
* > },
|
|
* > axesStyles: {
|
|
* > label: {},
|
|
* > ticks: {}
|
|
* > },
|
|
* > axes: {
|
|
* > xaxis: {
|
|
* > borderColor: "#999999",
|
|
* > borderWidth: 2,
|
|
* > ticks: {
|
|
* > show: true,
|
|
* > showGridline: true,
|
|
* > showLabel: true,
|
|
* > showMark: true,
|
|
* > size: 4,
|
|
* > textColor: "",
|
|
* > whiteSpace: "nowrap",
|
|
* > fontSize: "12px",
|
|
* > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif"
|
|
* > },
|
|
* > label: {
|
|
* > textColor: "rgb(102, 102, 102)",
|
|
* > whiteSpace: "normal",
|
|
* > fontSize: "14.6667px",
|
|
* > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif",
|
|
* > fontWeight: "400"
|
|
* > }
|
|
* > },
|
|
* > yaxis: {
|
|
* > borderColor: "#999999",
|
|
* > borderWidth: 2,
|
|
* > ticks: {
|
|
* > show: true,
|
|
* > showGridline: true,
|
|
* > showLabel: true,
|
|
* > showMark: true,
|
|
* > size: 4,
|
|
* > textColor: "",
|
|
* > whiteSpace: "nowrap",
|
|
* > fontSize: "12px",
|
|
* > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif"
|
|
* > },
|
|
* > label: {
|
|
* > textColor: null,
|
|
* > whiteSpace: null,
|
|
* > fontSize: null,
|
|
* > fontFamily: null,
|
|
* > fontWeight: null
|
|
* > }
|
|
* > },
|
|
* > x2axis: {...
|
|
* > },
|
|
* > ...
|
|
* > y9axis: {...
|
|
* > }
|
|
* > }
|
|
* > }
|
|
*
|
|
* "seriesStyles" is a style object that will be applied to all series in the plot.
|
|
* It will forcibly override any styles applied on the individual series. "axesStyles" is
|
|
* a style object that will be applied to all axes in the plot. It will also forcibly
|
|
* override any styles on the individual axes.
|
|
*
|
|
* The example shown above has series options for a line series. Options for other
|
|
* series types are shown below:
|
|
*
|
|
* Bar Series:
|
|
*
|
|
* > {
|
|
* > color: "#4bb2c5",
|
|
* > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"],
|
|
* > lineWidth: 2.5,
|
|
* > shadow: true,
|
|
* > barPadding: 2,
|
|
* > barMargin: 10,
|
|
* > barWidth: 15.09375,
|
|
* > highlightColors: ["rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)"]
|
|
* > }
|
|
*
|
|
* Pie Series:
|
|
*
|
|
* > {
|
|
* > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"],
|
|
* > padding: 20,
|
|
* > sliceMargin: 0,
|
|
* > fill: true,
|
|
* > shadow: true,
|
|
* > startAngle: 0,
|
|
* > lineWidth: 2.5,
|
|
* > highlightColors: ["rgb(129,201,214)", "rgb(240,189,104)", "rgb(214,202,165)", "rgb(137,180,158)", "rgb(168,180,137)", "rgb(180,174,89)", "rgb(180,113,161)", "rgb(129,141,236)", "rgb(227,205,120)", "rgb(255,138,76)", "rgb(76,169,219)", "rgb(215,126,190)", "rgb(220,232,135)", "rgb(200,167,96)", "rgb(103,202,235)", "rgb(208,154,215)"]
|
|
* > }
|
|
*
|
|
* Funnel Series:
|
|
*
|
|
* > {
|
|
* > color: "#4bb2c5",
|
|
* > lineWidth: 2,
|
|
* > shadow: true,
|
|
* > padding: {
|
|
* > top: 20,
|
|
* > right: 20,
|
|
* > bottom: 20,
|
|
* > left: 20
|
|
* > },
|
|
* > sectionMargin: 6,
|
|
* > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"],
|
|
* > highlightColors: ["rgb(147,208,220)", "rgb(242,199,126)", "rgb(220,210,178)", "rgb(154,191,172)", "rgb(180,191,154)", "rgb(191,186,112)", "rgb(191,133,174)", "rgb(147,157,238)", "rgb(231,212,139)", "rgb(255,154,102)", "rgb(102,181,224)", "rgb(221,144,199)", "rgb(225,235,152)", "rgb(200,167,96)", "rgb(124,210,238)", "rgb(215,169,221)"]
|
|
* > }
|
|
*
|
|
*/
|
|
$.jqplot.ThemeEngine = function(){
|
|
// Group: Properties
|
|
//
|
|
// prop: themes
|
|
// hash of themes managed by the theme engine.
|
|
// Indexed by theme name.
|
|
this.themes = {};
|
|
// prop: activeTheme
|
|
// Pointer to currently active theme
|
|
this.activeTheme=null;
|
|
|
|
};
|
|
|
|
// called with scope of plot
|
|
$.jqplot.ThemeEngine.prototype.init = function() {
|
|
// get the Default theme from the current plot settings.
|
|
var th = new $.jqplot.Theme({_name:'Default'});
|
|
var n, i, nn;
|
|
|
|
for (n in th.target) {
|
|
if (n == "textColor") {
|
|
th.target[n] = this.target.css('color');
|
|
}
|
|
else {
|
|
th.target[n] = this.target.css(n);
|
|
}
|
|
}
|
|
|
|
if (this.title.show && this.title._elem) {
|
|
for (n in th.title) {
|
|
if (n == "textColor") {
|
|
th.title[n] = this.title._elem.css('color');
|
|
}
|
|
else {
|
|
th.title[n] = this.title._elem.css(n);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (n in th.grid) {
|
|
th.grid[n] = this.grid[n];
|
|
}
|
|
if (th.grid.backgroundColor == null && this.grid.background != null) {
|
|
th.grid.backgroundColor = this.grid.background;
|
|
}
|
|
if (this.legend.show && this.legend._elem) {
|
|
for (n in th.legend) {
|
|
if (n == 'textColor') {
|
|
th.legend[n] = this.legend._elem.css('color');
|
|
}
|
|
else {
|
|
th.legend[n] = this.legend._elem.css(n);
|
|
}
|
|
}
|
|
}
|
|
var s;
|
|
|
|
for (i=0; i<this.series.length; i++) {
|
|
s = this.series[i];
|
|
if (s.renderer.constructor == $.jqplot.LineRenderer) {
|
|
th.series.push(new LineSeriesProperties());
|
|
}
|
|
else if (s.renderer.constructor == $.jqplot.BarRenderer) {
|
|
th.series.push(new BarSeriesProperties());
|
|
}
|
|
else if (s.renderer.constructor == $.jqplot.PieRenderer) {
|
|
th.series.push(new PieSeriesProperties());
|
|
}
|
|
else if (s.renderer.constructor == $.jqplot.DonutRenderer) {
|
|
th.series.push(new DonutSeriesProperties());
|
|
}
|
|
else if (s.renderer.constructor == $.jqplot.FunnelRenderer) {
|
|
th.series.push(new FunnelSeriesProperties());
|
|
}
|
|
else if (s.renderer.constructor == $.jqplot.MeterGaugeRenderer) {
|
|
th.series.push(new MeterSeriesProperties());
|
|
}
|
|
else {
|
|
th.series.push({});
|
|
}
|
|
for (n in th.series[i]) {
|
|
th.series[i][n] = s[n];
|
|
}
|
|
}
|
|
var a, ax;
|
|
for (n in this.axes) {
|
|
ax = this.axes[n];
|
|
a = th.axes[n] = new AxisProperties();
|
|
a.borderColor = ax.borderColor;
|
|
a.borderWidth = ax.borderWidth;
|
|
if (ax._ticks && ax._ticks[0]) {
|
|
for (nn in a.ticks) {
|
|
if (ax._ticks[0].hasOwnProperty(nn)) {
|
|
a.ticks[nn] = ax._ticks[0][nn];
|
|
}
|
|
else if (ax._ticks[0]._elem){
|
|
a.ticks[nn] = ax._ticks[0]._elem.css(nn);
|
|
}
|
|
}
|
|
}
|
|
if (ax._label && ax._label.show) {
|
|
for (nn in a.label) {
|
|
// a.label[nn] = ax._label._elem.css(nn);
|
|
if (ax._label[nn]) {
|
|
a.label[nn] = ax._label[nn];
|
|
}
|
|
else if (ax._label._elem){
|
|
if (nn == 'textColor') {
|
|
a.label[nn] = ax._label._elem.css('color');
|
|
}
|
|
else {
|
|
a.label[nn] = ax._label._elem.css(nn);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.themeEngine._add(th);
|
|
this.themeEngine.activeTheme = this.themeEngine.themes[th._name];
|
|
};
|
|
/**
|
|
* Group: methods
|
|
*
|
|
* method: get
|
|
*
|
|
* Get and return the named theme or the active theme if no name given.
|
|
*
|
|
* parameter:
|
|
*
|
|
* name - name of theme to get.
|
|
*
|
|
* returns:
|
|
*
|
|
* Theme instance of given name.
|
|
*/
|
|
$.jqplot.ThemeEngine.prototype.get = function(name) {
|
|
if (!name) {
|
|
// return the active theme
|
|
return this.activeTheme;
|
|
}
|
|
else {
|
|
return this.themes[name];
|
|
}
|
|
};
|
|
|
|
function numericalOrder(a,b) { return a-b; }
|
|
|
|
/**
|
|
* method: getThemeNames
|
|
*
|
|
* Return the list of theme names in this manager in alpha-numerical order.
|
|
*
|
|
* parameter:
|
|
*
|
|
* None
|
|
*
|
|
* returns:
|
|
*
|
|
* A the list of theme names in this manager in alpha-numerical order.
|
|
*/
|
|
$.jqplot.ThemeEngine.prototype.getThemeNames = function() {
|
|
var tn = [];
|
|
for (var n in this.themes) {
|
|
tn.push(n);
|
|
}
|
|
return tn.sort(numericalOrder);
|
|
};
|
|
|
|
/**
|
|
* method: getThemes
|
|
*
|
|
* Return a list of themes in alpha-numerical order by name.
|
|
*
|
|
* parameter:
|
|
*
|
|
* None
|
|
*
|
|
* returns:
|
|
*
|
|
* A list of themes in alpha-numerical order by name.
|
|
*/
|
|
$.jqplot.ThemeEngine.prototype.getThemes = function() {
|
|
var tn = [];
|
|
var themes = [];
|
|
for (var n in this.themes) {
|
|
tn.push(n);
|
|
}
|
|
tn.sort(numericalOrder);
|
|
for (var i=0; i<tn.length; i++) {
|
|
themes.push(this.themes[tn[i]]);
|
|
}
|
|
return themes;
|
|
};
|
|
|
|
$.jqplot.ThemeEngine.prototype.activate = function(plot, name) {
|
|
// sometimes need to redraw whole plot.
|
|
var redrawPlot = false;
|
|
if (!name && this.activeTheme && this.activeTheme._name) {
|
|
name = this.activeTheme._name;
|
|
}
|
|
if (!this.themes.hasOwnProperty(name)) {
|
|
throw new Error("No theme of that name");
|
|
}
|
|
else {
|
|
var th = this.themes[name];
|
|
this.activeTheme = th;
|
|
var val, checkBorderColor = false, checkBorderWidth = false;
|
|
var arr = ['xaxis', 'x2axis', 'yaxis', 'y2axis'];
|
|
|
|
for (i=0; i<arr.length; i++) {
|
|
var ax = arr[i];
|
|
if (th.axesStyles.borderColor != null) {
|
|
plot.axes[ax].borderColor = th.axesStyles.borderColor;
|
|
}
|
|
if (th.axesStyles.borderWidth != null) {
|
|
plot.axes[ax].borderWidth = th.axesStyles.borderWidth;
|
|
}
|
|
}
|
|
|
|
for (var axname in plot.axes) {
|
|
var axis = plot.axes[axname];
|
|
if (axis.show) {
|
|
var thaxis = th.axes[axname] || {};
|
|
var thaxstyle = th.axesStyles;
|
|
var thax = $.jqplot.extend(true, {}, thaxis, thaxstyle);
|
|
val = (th.axesStyles.borderColor != null) ? th.axesStyles.borderColor : thax.borderColor;
|
|
if (thax.borderColor != null) {
|
|
axis.borderColor = thax.borderColor;
|
|
redrawPlot = true;
|
|
}
|
|
val = (th.axesStyles.borderWidth != null) ? th.axesStyles.borderWidth : thax.borderWidth;
|
|
if (thax.borderWidth != null) {
|
|
axis.borderWidth = thax.borderWidth;
|
|
redrawPlot = true;
|
|
}
|
|
if (axis._ticks && axis._ticks[0]) {
|
|
for (var nn in thax.ticks) {
|
|
// val = null;
|
|
// if (th.axesStyles.ticks && th.axesStyles.ticks[nn] != null) {
|
|
// val = th.axesStyles.ticks[nn];
|
|
// }
|
|
// else if (thax.ticks[nn] != null){
|
|
// val = thax.ticks[nn]
|
|
// }
|
|
val = thax.ticks[nn];
|
|
if (val != null) {
|
|
axis.tickOptions[nn] = val;
|
|
axis._ticks = [];
|
|
redrawPlot = true;
|
|
}
|
|
}
|
|
}
|
|
if (axis._label && axis._label.show) {
|
|
for (var nn in thax.label) {
|
|
// val = null;
|
|
// if (th.axesStyles.label && th.axesStyles.label[nn] != null) {
|
|
// val = th.axesStyles.label[nn];
|
|
// }
|
|
// else if (thax.label && thax.label[nn] != null){
|
|
// val = thax.label[nn]
|
|
// }
|
|
val = thax.label[nn];
|
|
if (val != null) {
|
|
axis.labelOptions[nn] = val;
|
|
redrawPlot = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
for (var n in th.grid) {
|
|
if (th.grid[n] != null) {
|
|
plot.grid[n] = th.grid[n];
|
|
}
|
|
}
|
|
if (!redrawPlot) {
|
|
plot.grid.draw();
|
|
}
|
|
|
|
if (plot.legend.show) {
|
|
for (n in th.legend) {
|
|
if (th.legend[n] != null) {
|
|
plot.legend[n] = th.legend[n];
|
|
}
|
|
}
|
|
}
|
|
if (plot.title.show) {
|
|
for (n in th.title) {
|
|
if (th.title[n] != null) {
|
|
plot.title[n] = th.title[n];
|
|
}
|
|
}
|
|
}
|
|
|
|
var i;
|
|
for (i=0; i<th.series.length; i++) {
|
|
var opts = {};
|
|
var redrawSeries = false;
|
|
for (n in th.series[i]) {
|
|
val = (th.seriesStyles[n] != null) ? th.seriesStyles[n] : th.series[i][n];
|
|
if (val != null) {
|
|
opts[n] = val;
|
|
if (n == 'color') {
|
|
plot.series[i].renderer.shapeRenderer.fillStyle = val;
|
|
plot.series[i].renderer.shapeRenderer.strokeStyle = val;
|
|
plot.series[i][n] = val;
|
|
}
|
|
else if ((n == 'lineWidth') || (n == 'linePattern')) {
|
|
plot.series[i].renderer.shapeRenderer[n] = val;
|
|
plot.series[i][n] = val;
|
|
}
|
|
else if (n == 'markerOptions') {
|
|
merge (plot.series[i].markerOptions, val);
|
|
merge (plot.series[i].markerRenderer, val);
|
|
}
|
|
else {
|
|
plot.series[i][n] = val;
|
|
}
|
|
redrawPlot = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (redrawPlot) {
|
|
plot.target.empty();
|
|
plot.draw();
|
|
}
|
|
|
|
for (n in th.target) {
|
|
if (th.target[n] != null) {
|
|
plot.target.css(n, th.target[n]);
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
$.jqplot.ThemeEngine.prototype._add = function(theme, name) {
|
|
if (name) {
|
|
theme._name = name;
|
|
}
|
|
if (!theme._name) {
|
|
theme._name = Date.parse(new Date());
|
|
}
|
|
if (!this.themes.hasOwnProperty(theme._name)) {
|
|
this.themes[theme._name] = theme;
|
|
}
|
|
else {
|
|
throw new Error("jqplot.ThemeEngine Error: Theme already in use");
|
|
}
|
|
};
|
|
|
|
// method remove
|
|
// Delete the named theme, return true on success, false on failure.
|
|
|
|
|
|
/**
|
|
* method: remove
|
|
*
|
|
* Remove the given theme from the themeEngine.
|
|
*
|
|
* parameters:
|
|
*
|
|
* name - name of the theme to remove.
|
|
*
|
|
* returns:
|
|
*
|
|
* true on success, false on failure.
|
|
*/
|
|
$.jqplot.ThemeEngine.prototype.remove = function(name) {
|
|
if (name == 'Default') {
|
|
return false;
|
|
}
|
|
return delete this.themes[name];
|
|
};
|
|
|
|
/**
|
|
* method: newTheme
|
|
*
|
|
* Create a new theme based on the default theme, adding it the themeEngine.
|
|
*
|
|
* parameters:
|
|
*
|
|
* name - name of the new theme.
|
|
* obj - optional object of styles to be applied to this new theme.
|
|
*
|
|
* returns:
|
|
*
|
|
* new Theme object.
|
|
*/
|
|
$.jqplot.ThemeEngine.prototype.newTheme = function(name, obj) {
|
|
if (typeof(name) == 'object') {
|
|
obj = obj || name;
|
|
name = null;
|
|
}
|
|
if (obj && obj._name) {
|
|
name = obj._name;
|
|
}
|
|
else {
|
|
name = name || Date.parse(new Date());
|
|
}
|
|
// var th = new $.jqplot.Theme(name);
|
|
var th = this.copy(this.themes['Default']._name, name);
|
|
$.jqplot.extend(th, obj);
|
|
return th;
|
|
};
|
|
|
|
// function clone(obj) {
|
|
// return eval(obj.toSource());
|
|
// }
|
|
|
|
function clone(obj){
|
|
if(obj == null || typeof(obj) != 'object'){
|
|
return obj;
|
|
}
|
|
|
|
var temp = new obj.constructor();
|
|
for(var key in obj){
|
|
temp[key] = clone(obj[key]);
|
|
}
|
|
return temp;
|
|
}
|
|
|
|
$.jqplot.clone = clone;
|
|
|
|
function merge(obj1, obj2) {
|
|
if (obj2 == null || typeof(obj2) != 'object') {
|
|
return;
|
|
}
|
|
for (var key in obj2) {
|
|
if (key == 'highlightColors') {
|
|
obj1[key] = clone(obj2[key]);
|
|
}
|
|
if (obj2[key] != null && typeof(obj2[key]) == 'object') {
|
|
if (!obj1.hasOwnProperty(key)) {
|
|
obj1[key] = {};
|
|
}
|
|
merge(obj1[key], obj2[key]);
|
|
}
|
|
else {
|
|
obj1[key] = obj2[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
$.jqplot.merge = merge;
|
|
|
|
// Use the jQuery 1.3.2 extend function since behaviour in jQuery 1.4 seems problematic
|
|
$.jqplot.extend = function() {
|
|
// copy reference to target object
|
|
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
|
|
|
|
// Handle a deep copy situation
|
|
if ( typeof target === "boolean" ) {
|
|
deep = target;
|
|
target = arguments[1] || {};
|
|
// skip the boolean and the target
|
|
i = 2;
|
|
}
|
|
|
|
// Handle case when target is a string or something (possible in deep copy)
|
|
if ( typeof target !== "object" && !toString.call(target) === "[object Function]" ) {
|
|
target = {};
|
|
}
|
|
|
|
for ( ; i < length; i++ ){
|
|
// Only deal with non-null/undefined values
|
|
if ( (options = arguments[ i ]) != null ) {
|
|
// Extend the base object
|
|
for ( var name in options ) {
|
|
var src = target[ name ], copy = options[ name ];
|
|
|
|
// Prevent never-ending loop
|
|
if ( target === copy ) {
|
|
continue;
|
|
}
|
|
|
|
// Recurse if we're merging object values
|
|
if ( deep && copy && typeof copy === "object" && !copy.nodeType ) {
|
|
target[ name ] = $.jqplot.extend( deep,
|
|
// Never move original objects, clone them
|
|
src || ( copy.length != null ? [ ] : { } )
|
|
, copy );
|
|
}
|
|
// Don't bring in undefined values
|
|
else if ( copy !== undefined ) {
|
|
target[ name ] = copy;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Return the modified object
|
|
return target;
|
|
};
|
|
|
|
/**
|
|
* method: rename
|
|
*
|
|
* Rename a theme.
|
|
*
|
|
* parameters:
|
|
*
|
|
* oldName - current name of the theme.
|
|
* newName - desired name of the theme.
|
|
*
|
|
* returns:
|
|
*
|
|
* new Theme object.
|
|
*/
|
|
$.jqplot.ThemeEngine.prototype.rename = function (oldName, newName) {
|
|
if (oldName == 'Default' || newName == 'Default') {
|
|
throw new Error ("jqplot.ThemeEngine Error: Cannot rename from/to Default");
|
|
}
|
|
if (this.themes.hasOwnProperty(newName)) {
|
|
throw new Error ("jqplot.ThemeEngine Error: New name already in use.");
|
|
}
|
|
else if (this.themes.hasOwnProperty(oldName)) {
|
|
var th = this.copy (oldName, newName);
|
|
this.remove(oldName);
|
|
return th;
|
|
}
|
|
throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid");
|
|
};
|
|
|
|
/**
|
|
* method: copy
|
|
*
|
|
* Create a copy of an existing theme in the themeEngine, adding it the themeEngine.
|
|
*
|
|
* parameters:
|
|
*
|
|
* sourceName - name of the existing theme.
|
|
* targetName - name of the copy.
|
|
* obj - optional object of style parameter to apply to the new theme.
|
|
*
|
|
* returns:
|
|
*
|
|
* new Theme object.
|
|
*/
|
|
$.jqplot.ThemeEngine.prototype.copy = function (sourceName, targetName, obj) {
|
|
if (targetName == 'Default') {
|
|
throw new Error ("jqplot.ThemeEngine Error: Cannot copy over Default theme");
|
|
}
|
|
if (!this.themes.hasOwnProperty(sourceName)) {
|
|
var s = "jqplot.ThemeEngine Error: Source name invalid";
|
|
throw new Error(s);
|
|
}
|
|
if (this.themes.hasOwnProperty(targetName)) {
|
|
var s = "jqplot.ThemeEngine Error: Target name invalid";
|
|
throw new Error(s);
|
|
}
|
|
else {
|
|
var th = clone(this.themes[sourceName]);
|
|
th._name = targetName;
|
|
$.jqplot.extend(true, th, obj);
|
|
this._add(th);
|
|
return th;
|
|
}
|
|
};
|
|
|
|
|
|
$.jqplot.Theme = function(name, obj) {
|
|
if (typeof(name) == 'object') {
|
|
obj = obj || name;
|
|
name = null;
|
|
}
|
|
name = name || Date.parse(new Date());
|
|
this._name = name;
|
|
this.target = {
|
|
backgroundColor: null
|
|
};
|
|
this.legend = {
|
|
textColor: null,
|
|
fontFamily: null,
|
|
fontSize: null,
|
|
border: null,
|
|
background: null
|
|
};
|
|
this.title = {
|
|
textColor: null,
|
|
fontFamily: null,
|
|
fontSize: null,
|
|
textAlign: null
|
|
};
|
|
this.seriesStyles = {};
|
|
this.series = [];
|
|
this.grid = {
|
|
drawGridlines: null,
|
|
gridLineColor: null,
|
|
gridLineWidth: null,
|
|
backgroundColor: null,
|
|
borderColor: null,
|
|
borderWidth: null,
|
|
shadow: null
|
|
};
|
|
this.axesStyles = {label:{}, ticks:{}};
|
|
this.axes = {};
|
|
if (typeof(obj) == 'string') {
|
|
this._name = obj;
|
|
}
|
|
else if(typeof(obj) == 'object') {
|
|
$.jqplot.extend(true, this, obj);
|
|
}
|
|
};
|
|
|
|
var AxisProperties = function() {
|
|
this.borderColor = null;
|
|
this.borderWidth = null;
|
|
this.ticks = new AxisTicks();
|
|
this.label = new AxisLabel();
|
|
};
|
|
|
|
var AxisTicks = function() {
|
|
this.show = null;
|
|
this.showGridline = null;
|
|
this.showLabel = null;
|
|
this.showMark = null;
|
|
this.size = null;
|
|
this.textColor = null;
|
|
this.whiteSpace = null;
|
|
this.fontSize = null;
|
|
this.fontFamily = null;
|
|
};
|
|
|
|
var AxisLabel = function() {
|
|
this.textColor = null;
|
|
this.whiteSpace = null;
|
|
this.fontSize = null;
|
|
this.fontFamily = null;
|
|
this.fontWeight = null;
|
|
};
|
|
|
|
var LineSeriesProperties = function() {
|
|
this.color=null;
|
|
this.lineWidth=null;
|
|
this.linePattern=null;
|
|
this.shadow=null;
|
|
this.fillColor=null;
|
|
this.showMarker=null;
|
|
this.markerOptions = new MarkerOptions();
|
|
};
|
|
|
|
var MarkerOptions = function() {
|
|
this.show = null;
|
|
this.style = null;
|
|
this.lineWidth = null;
|
|
this.size = null;
|
|
this.color = null;
|
|
this.shadow = null;
|
|
};
|
|
|
|
var BarSeriesProperties = function() {
|
|
this.color=null;
|
|
this.seriesColors=null;
|
|
this.lineWidth=null;
|
|
this.shadow=null;
|
|
this.barPadding=null;
|
|
this.barMargin=null;
|
|
this.barWidth=null;
|
|
this.highlightColors=null;
|
|
};
|
|
|
|
var PieSeriesProperties = function() {
|
|
this.seriesColors=null;
|
|
this.padding=null;
|
|
this.sliceMargin=null;
|
|
this.fill=null;
|
|
this.shadow=null;
|
|
this.startAngle=null;
|
|
this.lineWidth=null;
|
|
this.highlightColors=null;
|
|
};
|
|
|
|
var DonutSeriesProperties = function() {
|
|
this.seriesColors=null;
|
|
this.padding=null;
|
|
this.sliceMargin=null;
|
|
this.fill=null;
|
|
this.shadow=null;
|
|
this.startAngle=null;
|
|
this.lineWidth=null;
|
|
this.innerDiameter=null;
|
|
this.thickness=null;
|
|
this.ringMargin=null;
|
|
this.highlightColors=null;
|
|
};
|
|
|
|
var FunnelSeriesProperties = function() {
|
|
this.color=null;
|
|
this.lineWidth=null;
|
|
this.shadow=null;
|
|
this.padding=null;
|
|
this.sectionMargin=null;
|
|
this.seriesColors=null;
|
|
this.highlightColors=null;
|
|
};
|
|
|
|
var MeterSeriesProperties = function() {
|
|
this.padding=null;
|
|
this.backgroundColor=null;
|
|
this.ringColor=null;
|
|
this.tickColor=null;
|
|
this.ringWidth=null;
|
|
this.intervalColors=null;
|
|
this.intervalInnerRadius=null;
|
|
this.intervalOuterRadius=null;
|
|
this.hubRadius=null;
|
|
this.needleThickness=null;
|
|
this.needlePad=null;
|
|
};
|
|
|
|
|
|
})(jQuery); |