|
@@ -22,26 +22,34 @@ provides: [ HueChart.Box ]
|
|
|
|
|
|
|
|
...
|
|
...
|
|
|
*/
|
|
*/
|
|
|
|
|
+(function() {
|
|
|
|
|
+var getXValueFn = function(field) {
|
|
|
|
|
+ return function(data) {
|
|
|
|
|
+ if (field) return data[field];
|
|
|
|
|
+ else return data;
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
HueChart.Box = new Class({
|
|
HueChart.Box = new Class({
|
|
|
|
|
|
|
|
Extends: HueChart,
|
|
Extends: HueChart,
|
|
|
|
|
|
|
|
options: {
|
|
options: {
|
|
|
- //series: [], //the array of data series which are found in the chart data,
|
|
|
|
|
- //xField: '', //the field in the data table which should be used as the xAxis label, and for determining where points are on the xAxis
|
|
|
|
|
- xIsDate: false, //is the xField a date ?
|
|
|
|
|
|
|
+ series: [], //the array of data series which are found in the chart data,
|
|
|
|
|
+ xProperty: 'x', //the field in the data table which should be used for determining where points are on the xAxis
|
|
|
|
|
+ dates: {x: false, y: false}, //is the data in an axis a date ?
|
|
|
|
|
+ dateSpans:{x: 'day'}, //if an axis is a date, what time span should the tick marks for that axis be shown in
|
|
|
positionIndicator: false, //should the position indicator be shown ?
|
|
positionIndicator: false, //should the position indicator be shown ?
|
|
|
- ticks: false, //should tick marks be shown ?
|
|
|
|
|
- labels: false, //should axis labels be shown ?
|
|
|
|
|
|
|
+ showTicks: false, //should tick marks be shown ?
|
|
|
|
|
+ showLabels: false, //should axis labels be shown ?
|
|
|
tickColor: "#555", //the color of the tick marks
|
|
tickColor: "#555", //the color of the tick marks
|
|
|
dateFormat: "%b %d", //the format that should be used when displaying dates
|
|
dateFormat: "%b %d", //the format that should be used when displaying dates
|
|
|
verticalTickSpacing: 35, //the distance between vertical ticks
|
|
verticalTickSpacing: 35, //the distance between vertical ticks
|
|
|
- yFieldDisplayProcessor: function(field) {
|
|
|
|
|
- return field.replace("_", " ").capitalize();
|
|
|
|
|
- }, //fn to use to process the yField for display, field is this.options.yField
|
|
|
|
|
- xTickHeight: 10,
|
|
|
|
|
- xLabel: "Date"
|
|
|
|
|
|
|
+ xTickHeight: 10, //the height of the xTick marks.
|
|
|
|
|
+ labels:{x:"X", y: "Y"}, //the labels that should be used for each axis
|
|
|
|
|
+ selectColor: "rgba(255, 128, 128, .4)", //the color that should be used to fill selections in this chart
|
|
|
|
|
+ positionIndicatorColor: "black", //color that should be used to show the position of the selected index, when using the position indicator
|
|
|
|
|
+ yType: 'string' //the type of value that is being graphed on the y-axis
|
|
|
/*
|
|
/*
|
|
|
onPointMouseOut: function that should be run when the mouse is moved out of the chart
|
|
onPointMouseOut: function that should be run when the mouse is moved out of the chart
|
|
|
onPointMouseOver: function that should be run when the mouse is moved over a datapoint, takes the dataPoint and index as arguments
|
|
onPointMouseOver: function that should be run when the mouse is moved over a datapoint, takes the dataPoint and index as arguments
|
|
@@ -50,22 +58,19 @@ HueChart.Box = new Class({
|
|
|
*/
|
|
*/
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
-
|
|
|
|
|
initialize: function(element, options) {
|
|
initialize: function(element, options) {
|
|
|
this.parent(element, options);
|
|
this.parent(element, options);
|
|
|
- var requiredOptions = ["series", "xField"];
|
|
|
|
|
- requiredOptions.each(function(opt) {
|
|
|
|
|
- if (!$defined(this.options[opt])) console.error("The required option " + opt + " is missing from a HueChart.Box instantiation.");
|
|
|
|
|
- }.bind(this));
|
|
|
|
|
this.selected_index = -1;
|
|
this.selected_index = -1;
|
|
|
- if(this.options.xIsDate) {
|
|
|
|
|
- //If the xField is a date property, prepare the dates for sorting
|
|
|
|
|
- //Change the xField to the new property designed for sorting dates
|
|
|
|
|
- this.getData(true).prepareDates(this.options.xField);
|
|
|
|
|
- this.options.xField = 'seconds_from_first';
|
|
|
|
|
|
|
+ if(this.options.dates.x) {
|
|
|
|
|
+ //If the xProperty is a date property, prepare the dates for sorting
|
|
|
|
|
+ //Change the xProperty to the new property designed for sorting dates
|
|
|
|
|
+ this.getData(true).prepareDates(this.options.xProperty);
|
|
|
|
|
+ //Set dateProperty to the initial xProperty, this will hold a date object which will be used for rendering dates as strings
|
|
|
|
|
+ this.dateProperty = this.options.xProperty;
|
|
|
|
|
+ this.options.xProperty = 'seconds_from_first';
|
|
|
} else {
|
|
} else {
|
|
|
//Otherwise sort by the x property.
|
|
//Otherwise sort by the x property.
|
|
|
- this.getData(true).sortByProperty(this.options.xField);
|
|
|
|
|
|
|
+ this.getData(true).sortByProperty(this.options.xProperty);
|
|
|
}
|
|
}
|
|
|
//When the setupChart event is fired, the full ProtoVis visualization is being set up, in preparation for render.
|
|
//When the setupChart event is fired, the full ProtoVis visualization is being set up, in preparation for render.
|
|
|
//The addGraph function is responsible for adding the actual representation of the data, be that a group of lines, or a group of area graphs.
|
|
//The addGraph function is responsible for adding the actual representation of the data, be that a group of lines, or a group of area graphs.
|
|
@@ -75,9 +80,9 @@ HueChart.Box = new Class({
|
|
|
//Add representation of the data.
|
|
//Add representation of the data.
|
|
|
this.addGraph(vis);
|
|
this.addGraph(vis);
|
|
|
//Add tick marks (rules on side and bottom) if enabled
|
|
//Add tick marks (rules on side and bottom) if enabled
|
|
|
- if (this.options.ticks) this.setTicks(vis);
|
|
|
|
|
|
|
+ if (this.options.showTicks) this.setTicks(vis);
|
|
|
//Add axis labels if enabled
|
|
//Add axis labels if enabled
|
|
|
- if (this.options.labels) this.setLabels(vis);
|
|
|
|
|
|
|
+ if (this.options.showLabels) this.setLabels(vis);
|
|
|
//Add position indicator if enabled
|
|
//Add position indicator if enabled
|
|
|
if (this.options.positionIndicator) this.setPositionIndicator(vis);
|
|
if (this.options.positionIndicator) this.setPositionIndicator(vis);
|
|
|
//Create panel for capture of events
|
|
//Create panel for capture of events
|
|
@@ -91,8 +96,8 @@ HueChart.Box = new Class({
|
|
|
//Set the scales which will be used to convert data values into positions for graph objects
|
|
//Set the scales which will be used to convert data values into positions for graph objects
|
|
|
setScales: function(vis) {
|
|
setScales: function(vis) {
|
|
|
//Get the minimum and maximum x values.
|
|
//Get the minimum and maximum x values.
|
|
|
- var xMin = this.getData(true).getMinValue(this.options.xField);
|
|
|
|
|
- var xMax = this.getData(true).getMaxValue(this.options.xField);
|
|
|
|
|
|
|
+ var xMin = this.getData(true).getMinValue(this.options.xProperty);
|
|
|
|
|
+ var xMax = this.getData(true).getMaxValue(this.options.xProperty);
|
|
|
//Get the maximum of the values that are to be graphed
|
|
//Get the maximum of the values that are to be graphed
|
|
|
var maxValue = this.getData(true).getMaxValue(this.options.series);
|
|
var maxValue = this.getData(true).getMaxValue(this.options.series);
|
|
|
this.xScale = pv.Scale.linear(xMin, xMax).range(this.options.leftPadding, this.width - this.options.rightPadding);
|
|
this.xScale = pv.Scale.linear(xMin, xMax).range(this.options.leftPadding, this.width - this.options.rightPadding);
|
|
@@ -103,27 +108,29 @@ HueChart.Box = new Class({
|
|
|
setTicks:function(vis) {
|
|
setTicks:function(vis) {
|
|
|
//Add X-Ticks.
|
|
//Add X-Ticks.
|
|
|
//Create tick array.
|
|
//Create tick array.
|
|
|
- var xTicks = (this.options.xIsDate ? this.getData(true).createTickArray(7, 'day') : this.xScale.ticks(7));
|
|
|
|
|
|
|
+ var xTicks = (this.options.dates.x ? this.getData(true).createTickArray(7, this.options.dateSpans.x, this.dateProperty) : this.xScale.ticks(7));
|
|
|
|
|
+ //Function will return the correct xValue dependent on whether or not x is a date
|
|
|
|
|
+ var getXValue = getXValueFn(this.options.dates.x ? this.options.xProperty : null);
|
|
|
//Create rules (lines intended to denote scale)
|
|
//Create rules (lines intended to denote scale)
|
|
|
vis.add(pv.Rule)
|
|
vis.add(pv.Rule)
|
|
|
//Use the tick array as data.
|
|
//Use the tick array as data.
|
|
|
.data(xTicks)
|
|
.data(xTicks)
|
|
|
//The bottom of the rule should be at the bottomPadding - the height of the rule.
|
|
//The bottom of the rule should be at the bottomPadding - the height of the rule.
|
|
|
.bottom(this.options.bottomPadding - this.options.xTickHeight)
|
|
.bottom(this.options.bottomPadding - this.options.xTickHeight)
|
|
|
- //The left of the rule should be at the data object's xField value scaled to pixels.
|
|
|
|
|
- .left(function(d) { return this.xScale(d[this.options.xField]); }.bind(this))
|
|
|
|
|
|
|
+ //The left of the rule should be at the data object's xProperty value scaled to pixels.
|
|
|
|
|
+ .left(function(d) { return this.xScale(getXValue(d)); }.bind(this))
|
|
|
//Set the height of the rule to the xTickHeight
|
|
//Set the height of the rule to the xTickHeight
|
|
|
.height(this.options.xTickHeight)
|
|
.height(this.options.xTickHeight)
|
|
|
- .strokeStyle(this.options.ruleColor)
|
|
|
|
|
|
|
+ .strokeStyle(this.options.tickColor)
|
|
|
//Add label to bottom of each rule
|
|
//Add label to bottom of each rule
|
|
|
.anchor("bottom").add(pv.Label)
|
|
.anchor("bottom").add(pv.Label)
|
|
|
.text(function(d) {
|
|
.text(function(d) {
|
|
|
//If the option is a date, format the date property field.
|
|
//If the option is a date, format the date property field.
|
|
|
//Otherwise, simply show it.
|
|
//Otherwise, simply show it.
|
|
|
- if(this.options.xIsDate) {
|
|
|
|
|
- return d.sample_date.format(this.options.dateFormat);
|
|
|
|
|
|
|
+ if(this.options.dates.x) {
|
|
|
|
|
+ return d[this.dateProperty].format(this.options.dateFormat);
|
|
|
} else {
|
|
} else {
|
|
|
- return d[this.options.xField];
|
|
|
|
|
|
|
+ return getXValue(d);
|
|
|
}
|
|
}
|
|
|
}.bind(this));
|
|
}.bind(this));
|
|
|
|
|
|
|
@@ -145,11 +152,11 @@ HueChart.Box = new Class({
|
|
|
.bottom(function(d) {return tickScale(d);}.bind(this))
|
|
.bottom(function(d) {return tickScale(d);}.bind(this))
|
|
|
//The width of the rule should be the width minuis the hoizontal padding.
|
|
//The width of the rule should be the width minuis the hoizontal padding.
|
|
|
.width(this.width - this.options.leftPadding - this.options.rightPadding + 1)
|
|
.width(this.width - this.options.leftPadding - this.options.rightPadding + 1)
|
|
|
- .strokeStyle("#555")
|
|
|
|
|
|
|
+ .strokeStyle(this.options.tickColor)
|
|
|
//Add label to the left which shows the number of bytes.
|
|
//Add label to the left which shows the number of bytes.
|
|
|
.anchor("left").add(pv.Label)
|
|
.anchor("left").add(pv.Label)
|
|
|
.text(function(d) {
|
|
.text(function(d) {
|
|
|
- if(this.options.yField == 'bytes') return d.convertFileSize();
|
|
|
|
|
|
|
+ if(this.options.yType == 'bytes') return d.convertFileSize();
|
|
|
return d;
|
|
return d;
|
|
|
}.bind(this));
|
|
}.bind(this));
|
|
|
},
|
|
},
|
|
@@ -159,15 +166,13 @@ HueChart.Box = new Class({
|
|
|
//Add Y-Label to center of chart.
|
|
//Add Y-Label to center of chart.
|
|
|
vis.anchor("center").add(pv.Label)
|
|
vis.anchor("center").add(pv.Label)
|
|
|
.textAngle(-Math.PI/2)
|
|
.textAngle(-Math.PI/2)
|
|
|
- .text(function() {
|
|
|
|
|
- return this.options.yFieldDisplayProcessor(this.options.yField.replace("_", " ").capitalize());
|
|
|
|
|
- }.bind(this))
|
|
|
|
|
|
|
+ .text(this.options.labels.y)
|
|
|
.font(this.options.labelFont)
|
|
.font(this.options.labelFont)
|
|
|
.left(12);
|
|
.left(12);
|
|
|
|
|
|
|
|
//Add X-Label to center of chart.
|
|
//Add X-Label to center of chart.
|
|
|
vis.anchor("bottom").add(pv.Label)
|
|
vis.anchor("bottom").add(pv.Label)
|
|
|
- .text(this.options.xLabel)
|
|
|
|
|
|
|
+ .text(this.options.labels.x)
|
|
|
.font(this.options.labelFont)
|
|
.font(this.options.labelFont)
|
|
|
.bottom(0);
|
|
.bottom(0);
|
|
|
},
|
|
},
|
|
@@ -176,18 +181,20 @@ HueChart.Box = new Class({
|
|
|
setPositionIndicator: function(vis) {
|
|
setPositionIndicator: function(vis) {
|
|
|
//Put selected_index in scope.
|
|
//Put selected_index in scope.
|
|
|
get_selected_index = this.getSelectedIndex.bind(this);
|
|
get_selected_index = this.getSelectedIndex.bind(this);
|
|
|
|
|
+ var indicatorColor = this.options.positionIndicatorColor;
|
|
|
//Add a thin black bar which is approximately the height of the graphing area for each item on the graph.
|
|
//Add a thin black bar which is approximately the height of the graphing area for each item on the graph.
|
|
|
vis.add(pv.Bar)
|
|
vis.add(pv.Bar)
|
|
|
.data(this.getData(true).getObjects())
|
|
.data(this.getData(true).getObjects())
|
|
|
.left(function(d) {
|
|
.left(function(d) {
|
|
|
- return this.xScale(d[this.options.xField]);
|
|
|
|
|
|
|
+ return this.xScale(d[this.options.xProperty]);
|
|
|
}.bind(this))
|
|
}.bind(this))
|
|
|
.height(this.height - (this.options.bottomPadding + this.options.topPadding))
|
|
.height(this.height - (this.options.bottomPadding + this.options.topPadding))
|
|
|
.bottom(this.options.bottomPadding)
|
|
.bottom(this.options.bottomPadding)
|
|
|
.width(2)
|
|
.width(2)
|
|
|
//Show bar if its index is selected, otherwise hide it.
|
|
//Show bar if its index is selected, otherwise hide it.
|
|
|
|
|
+
|
|
|
.fillStyle(function() {
|
|
.fillStyle(function() {
|
|
|
- if(this.index == get_selected_index()) return "black";
|
|
|
|
|
|
|
+ if(this.index == get_selected_index()) return indicatorColor;
|
|
|
else return null;
|
|
else return null;
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
@@ -196,7 +203,7 @@ HueChart.Box = new Class({
|
|
|
//Convert the passedin in xValue into its corresponding data value on the xScale.
|
|
//Convert the passedin in xValue into its corresponding data value on the xScale.
|
|
|
var mx = this.xScale.invert(x);
|
|
var mx = this.xScale.invert(x);
|
|
|
//Search the data for the index of the element at this data value.
|
|
//Search the data for the index of the element at this data value.
|
|
|
- var i = pv.search(this.getData(true).getObjects().map(function(d){ return d[this.options.xField]; }.bind(this)), Math.round(mx));
|
|
|
|
|
|
|
+ var i = pv.search(this.getData(true).getObjects().map(function(d){ return d[this.options.xProperty]; }.bind(this)), Math.round(mx));
|
|
|
//Adjust for ProtoVis search
|
|
//Adjust for ProtoVis search
|
|
|
i = i < 0 ? (-i - 2) : i;
|
|
i = i < 0 ? (-i - 2) : i;
|
|
|
return (i >= 0 && i < this.getData(true).getLength() ? i : null);
|
|
return (i >= 0 && i < this.getData(true).getLength() ? i : null);
|
|
@@ -219,7 +226,7 @@ HueChart.Box = new Class({
|
|
|
}.bind(this);
|
|
}.bind(this);
|
|
|
var clickFn = function() {
|
|
var clickFn = function() {
|
|
|
//Only click if the movement is clearly not a drag.
|
|
//Only click if the movement is clearly not a drag.
|
|
|
- if (this.selectState && this.selectState.dx < 2) {
|
|
|
|
|
|
|
+ if (!this.selectState || this.selectState.dx < 2) {
|
|
|
var dataIndex = this.getDataIndexFromX(vis.mouse().x);
|
|
var dataIndex = this.getDataIndexFromX(vis.mouse().x);
|
|
|
//Fire pointClick if the item exists
|
|
//Fire pointClick if the item exists
|
|
|
if(dataIndex != null) {
|
|
if(dataIndex != null) {
|
|
@@ -264,7 +271,7 @@ HueChart.Box = new Class({
|
|
|
//Otherwise give it a width of 0.
|
|
//Otherwise give it a width of 0.
|
|
|
.width(function(d) { return this.selectState.dx > 0 ? this.adjustToGraph('x', this.selectState.x + this.selectState.dx) - this.selectState.x : 0;
|
|
.width(function(d) { return this.selectState.dx > 0 ? this.adjustToGraph('x', this.selectState.x + this.selectState.dx) - this.selectState.x : 0;
|
|
|
}.bind(this))
|
|
}.bind(this))
|
|
|
- .fillStyle("rgba(255, 128, 128, .4)");
|
|
|
|
|
|
|
+ .fillStyle(this.options.selectColor);
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
//Adjusts a point to the graph. Ie...if you give it a point that's greater than or less than
|
|
//Adjusts a point to the graph. Ie...if you give it a point that's greater than or less than
|
|
@@ -290,5 +297,5 @@ HueChart.Box = new Class({
|
|
|
return point;
|
|
return point;
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
|
|
+})();
|
|
|
|
|
|