From 41955de85cfac3895e1d830a622817c2e4066fcb Mon Sep 17 00:00:00 2001 From: johnkiernander Date: Sat, 19 Apr 2014 00:33:08 +0100 Subject: [PATCH] Dual Measure Area Chart Handling Added --- dist/dimple.v1.2.0.js | 606 +++----------------- dist/dimple.v1.2.0.min.js | 6 +- src/methods/_showBarTooltip.js | 4 +- src/objects/chart/methods/_getSeriesData.js | 4 +- src/objects/plot/area.js | 104 +++- src/objects/plot/bar.js | 4 +- src/objects/series/methods/_axisBounds.js | 2 +- src/objects/series/methods/_isStacked.js | 6 + tmp/dimple.js | 606 +++----------------- 9 files changed, 282 insertions(+), 1060 deletions(-) create mode 100644 src/objects/series/methods/_isStacked.js diff --git a/dist/dimple.v1.2.0.js b/dist/dimple.v1.2.0.js index 1d0148f..4d656de 100644 --- a/dist/dimple.v1.2.0.js +++ b/dist/dimple.v1.2.0.js @@ -964,7 +964,7 @@ var dimple = { value = (axis.showPercent ? ret[pos + "Value"] / totals[opp][ret[opp + "Field"].join("/")] : ret[pos + "Value"]); totalField = ret[opp + "Field"].join("/") + (ret[pos + "Value"] >= 0); cumValue = running[pos][totalField] = ((running[pos][totalField] === null || running[pos][totalField] === undefined || pos === "z") ? 0 : running[pos][totalField]) + value; - selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series.stacked) ? cumValue : value); + selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series._isStacked()) ? cumValue : value); ret[size] = value; ret[pos] = selectValue - (((pos === "x" && value >= 0) || (pos === "y" && value <= 0)) ? value : 0); } else { @@ -975,7 +975,7 @@ var dimple = { catTotals[totalField] = value + (addedCats.length > 0 ? catTotals[addedCats[addedCats.length - 1]] : 0); addedCats.push(totalField); } - selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series.stacked) ? catTotals[totalField] : value); + selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series._isStacked()) ? catTotals[totalField] : value); ret[size] = value; ret[pos] = selectValue - (((pos === "x" && value >= 0) || (pos === "y" && value <= 0)) ? value : 0); } else { @@ -2164,7 +2164,7 @@ var dimple = { } else if (secondaryAxis === null || secondaryAxis.categoryFields === null || secondaryAxis.categoryFields.length === 0) { aggData.forEach(function (d) { // If the primary axis is stacked - if (this.stacked && (primaryAxis.position === "x" || primaryAxis.position === "y")) { + if (this._isStacked() && (primaryAxis.position === "x" || primaryAxis.position === "y")) { // We just need to push the bounds. A stacked axis will always include 0 so I just need to push the min and max out from there if (d[primaryAxis.position + "Value"] < 0) { bounds.min = bounds.min + d[primaryAxis.position + "Value"]; @@ -2318,6 +2318,12 @@ var dimple = { }; // Copyright: 2014 PMSI-AlignAlytics // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" + // Source: /src/objects/series/methods/_isStacked.js + this._isStacked = function() { + return this.stacked && (this.x._hasCategories() || this.y._hasCategories()); + }; + // Copyright: 2014 PMSI-AlignAlytics + // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" // Source: /src/objects/series/methods/addEventHandler.js // Help: http://github.com/PMSI-AlignAlytics/dimple/wiki/dimple.series#wiki-addEventHandler this.addEventHandler = function (event, handler) { @@ -2637,6 +2643,7 @@ var dimple = { basePoints, basePoint, cat, + lastAngle, catCoord, valCoord, onEnter = function () { @@ -2672,6 +2679,29 @@ var dimple = { .x(function (d) { return (series.x._hasCategories() || !originProperty ? d.x : series.x[originProperty]); }) .y(function (d) { return (series.y._hasCategories() || !originProperty ? d.y : series.y[originProperty]); }) .interpolate(inter); + }, + sortByX = function (a, b) { + return parseFloat(a.x) - parseFloat(b.x); + }, + addNextPoint = function (source, target, startAngle) { + // Given a point we need to find the next point clockwise from the start angle + var i, + point = target[target.length - 1], + thisAngle, + bestAngleSoFar = 9999, + returnPoint = point; + for (i = 0; i < source.length; i += 1) { + if (source[i].x !== point.x || source[i].y !== point.y) { + // get the angle in degrees since start angle + thisAngle = 180 - (Math.atan2(source[i].x - point.x, source[i].y - point.y) * (180 / Math.PI)); + if (thisAngle > startAngle && thisAngle < bestAngleSoFar) { + returnPoint = source[i]; + bestAngleSoFar = thisAngle; + } + } + } + target.push(returnPoint); + return bestAngleSoFar; }; // Handle the special interpolation handling for step @@ -2773,32 +2803,64 @@ var dimple = { dimple._addGradient(areaData[i].key, "fill-area-gradient-" + areaData[i].keyString, (series.x._hasCategories() ? series.x : series.y), data, chart, duration, "fill"); } - // Iterate the point array because we need to fill in zero points for missing ones, otherwise the areas - // will cross where an upper area has no value and a lower value has a spike Issue #7 - for (j = 0, k = 0; j < allPoints.length; j += 1) { - // We are only interested in points between the first and last point of this areas data (i.e. don't fill ends - important - // for grouped area charts) - if (allPoints[j] >= points[0][catCoord] && allPoints[j] <= points[points.length - 1][catCoord]) { - // Get a base point, this needs to go on the base points array as well as filling in gaps in the point array. - // Create a point using the coordinate on the category axis and the last recorded value - // position from the dictionary - basePoint = {}; - basePoint[catCoord] = allPoints[j]; - basePoint[valCoord] = catPoints[allPoints[j]]; - // add the base point - basePoints.push(basePoint); - // handle missing points - if (points[k][catCoord] > allPoints[j]) { - // If there is a missing point we need to in fill - finalPointArray.push(basePoint); - } else { - // They must be the same - finalPointArray.push(points[k]); - // Use this to update the dictionary to the new value coordinate - catPoints[allPoints[j]] = points[k][valCoord]; - k += 1; + // All points will only be populated if there is a category axis + if (allPoints && allPoints.length > 0) { + // Iterate the point array because we need to fill in zero points for missing ones, otherwise the areas + // will cross where an upper area has no value and a lower value has a spike Issue #7 + for (j = 0, k = 0; j < allPoints.length; j += 1) { + // We are only interested in points between the first and last point of this areas data (i.e. don't fill ends - important + // for grouped area charts) + if (allPoints[j] >= points[0][catCoord] && allPoints[j] <= points[points.length - 1][catCoord]) { + // Get a base point, this needs to go on the base points array as well as filling in gaps in the point array. + // Create a point using the coordinate on the category axis and the last recorded value + // position from the dictionary + basePoint = {}; + basePoint[catCoord] = allPoints[j]; + basePoint[valCoord] = catPoints[allPoints[j]]; + // add the base point + basePoints.push(basePoint); + // handle missing points + if (points[k][catCoord] > allPoints[j]) { + // If there is a missing point we need to in fill + finalPointArray.push(basePoint); + } else { + // They must be the same + finalPointArray.push(points[k]); + // Use this to update the dictionary to the new value coordinate + catPoints[allPoints[j]] = points[k][valCoord]; + k += 1; + } } } + } else { + // If there is no category axis we need to apply some custom logic. In order to avoid + // really jagged areas the default behaviour will be to draw from the left most point then rotate a line + // clockwise until it hits another point and continue from each point until back to where we started. This + // means it will not connect every point, but it will contain every point: + // E.g. + // D + // C + // A B E + // F G + // H + // + // Would draw A -> C -> D -> E -> G -> H -> A + // + // This may not be what everyone wants so if there is a series order specified we will just join + // the points in that order instead. This will not allow users to skip points and therefore not achieve + // the default behaviour explicitly. + if (series._orderRules && series._orderRules.length > 0) { + finalPointArray = points.concat(points[0]); + } else { + // Find the leftmost point + points = points.sort(sortByX); + finalPointArray.push(points[0]); + lastAngle = 0; + // Iterate until the first and last points match + do { + lastAngle = addNextPoint(points, finalPointArray, lastAngle); + } while (finalPointArray.length <= points.length && (finalPointArray[0].x !== finalPointArray[finalPointArray.length - 1].x || finalPointArray[0].y !== finalPointArray[finalPointArray.length - 1].y)); + } } // The final array of points for the entire outskirts of the area @@ -2935,488 +2997,6 @@ var dimple = { }; - // Copyright: 2014 PMSI-AlignAlytics - // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" - // Source: /src/objects/plot/area.js - dimple.plot.area_old = { - stacked: true, - - supportedAxes: ["x", "y", "c"], - - draw: function (chart, series, duration) { - // Get self pointer for inner functions - var self = this, - data = series._positionData, - uniqueValues = [], - firstAgg = 1, - graded = false, - seriesClass = "series" + chart.series.indexOf(series), - line, - catPoints = {}, - markers, - markerBacks; - - if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { - chart._tooltipGroup.remove(); - } - - // If there is a category axis we should draw a line for each aggField. Otherwise - // the first aggField defines the points and the others define the line - if (series.x._hasCategories() || series.y._hasCategories()) { - firstAgg = 0; - } - data.forEach(function (d) { - var filter = [], - match = false, - k; - for (k = firstAgg; k < d.aggField.length; k += 1) { - filter.push(d.aggField[k]); - } - uniqueValues.forEach(function (e) { - match = match || (e === filter.join("/")); - }, this); - if (!match) { - uniqueValues.push(filter.join("/")); - } - }, this); - - if (series.c !== null && series.c !== undefined && ((series.x._hasCategories() && series.y._hasMeasure()) || (series.y._hasCategories() && series.x._hasMeasure()))) { - graded = true; - uniqueValues.forEach(function (seriesValue) { - dimple._addGradient(seriesValue, "fill-area-gradient-" + seriesValue.join("_").replace(" ", ""), (series.x._hasCategories() ? series.x : series.y), data, chart, duration, "fill"); - dimple._addGradient(seriesValue, "stroke-area-gradient-" + seriesValue.join("_").replace(" ", ""), (series.x._hasCategories() ? series.x : series.y), data, chart, duration, "stroke"); - }, this); - } - - line = d3.svg.line() - .x(function (d) { return dimple._helpers.cx(d, chart, series); }) - .y(function (d) { return dimple._helpers.cy(d, chart, series); }); - - if (series.shapes === null || series.shapes === undefined) { - series.shapes = chart._group.selectAll(".area." + seriesClass) - .data(uniqueValues) - .enter() - .append("svg:path") - .attr("opacity", function(d) { return chart.getColor(d).opacity; }); - } - - series.shapes - .data(uniqueValues) - .transition() - .duration(duration) - .attr("class", function (d) { return seriesClass + " series area " + d.split(" ").join("_"); }) - .attr("d", function (d) { - var seriesData, - baseline = [], - max = 0, - row, - newObj, - j, - k, - m, - q, - r; - seriesData = dimple.filterData(data, "aggField", d); - seriesData.sort(function (a, b) { - var sortValue = 0; - if (series.x._hasCategories()) { - sortValue = (dimple._helpers.cx(a, chart, series) < dimple._helpers.cx(b, chart, series) ? -1 : 1); - } else if (series.y._hasCategories()) { - sortValue = (dimple._helpers.cy(a, chart, series) < dimple._helpers.cy(b, chart, series) ? -1 : 1); - } - return sortValue; - }); - for (j = seriesData.length - 1; j >= 0; j -= 1) { - row = seriesData[j]; - newObj = { cx: 0, cy: 0, height: 0, width: 0, xOffset: 0, yOffset: 0 }; - if (series.x._hasCategories()) { - // Fix the x properties - newObj.cx = row.cx; - newObj.width = row.width; - newObj.xOffset = row.xOffset; - // Find the largest value for the xField less than this value - if (catPoints[row.xField] === undefined) { - catPoints[row.xField] = []; - } else { - max = 0; - for (k = 0; k <= catPoints[row.xField].length; k += 1) { - q = catPoints[row.xField][k]; - if ((row.cy >= 0 && q >= 0) || (row.cy <= 0 && q <= 0)) { - if (Math.abs(q) <= Math.abs(row.cy) && Math.abs(q) > Math.abs(max)) { - max = q; - } - } - } - newObj.cy = max; - } - baseline.push(newObj); - catPoints[row.xField].push(row.cy); - } else if (series.y._hasCategories()) { - // Fix the y properties - newObj.cy = row.cy; - newObj.height = row.height; - newObj.yOffset = row.yOffset; - // Find the largest value for the xField less than this value - if (catPoints[row.yField] === undefined) { - catPoints[row.yField] = []; - } else { - max = 0; - for (m = 0; m <= catPoints[row.yField].length; m += 1) { - r = catPoints[row.yField][m]; - if ((row.cx >= 0 && r >= 0) || (row.cx <= 0 && r <= 0)) { - if (Math.abs(r) <= Math.abs(row.cx) && Math.abs(r) > Math.abs(max)) { - max = r; - } - } - } - newObj.cx = max; - } - baseline.push(newObj); - catPoints[row.yField].push(row.cx); - } - } - //return line(startPoint.concat(seriesData).concat(endPoint)); - return line(seriesData.concat(baseline).concat(seriesData[0])); - }) - .call(function () { - if (!chart.noFormats) { - this.attr("fill", function (d) { return (graded ? "url(#fill-area-gradient-" + d.join("_").replace(" ", "") + ")" : chart.getColor(d).fill); }) - .attr("stroke", function (d) { return (graded ? "url(#stroke-area-gradient-" + d.join("_").replace(" ", "") + ")" : chart.getColor(d).stroke); }) - .attr("stroke-width", series.lineWeight); - } - }); - - if (series.lineMarkers) { - if (series._markerBacks === null || series._markerBacks === undefined) { - markerBacks = chart._group.selectAll(".markerBacks." + seriesClass).data(data); - } else { - markerBacks = series._markerBacks.data(data, function (d) { return d.key; }); - } - // Add - markerBacks - .enter() - .append("circle") - .attr("id", function (d) { return d.key; }) - .attr("class", "markerBacks " + seriesClass) - .attr("cx", function (d) { return dimple._helpers.cx(d, chart, series); }) - .attr("cy", function (d) { return dimple._helpers.cy(d, chart, series); }) - .attr("r", 0) - .attr("fill", "white") - .attr("stroke", "none"); - - // Update - markerBacks - .transition().duration(duration) - .attr("cx", function (d) { return dimple._helpers.cx(d, chart, series); }) - .attr("cy", function (d) { return dimple._helpers.cy(d, chart, series); }) - .attr("r", 2 + series.lineWeight); - // Remove - markerBacks - .exit() - .transition().duration(duration) - .attr("r", 0) - .each("end", function () { - d3.select(this).remove(); - }); - series._markerBacks = markerBacks; - } - - // Deal with markers in the same way as main series to fix #28 - if (series._markers === null || series._markers === undefined) { - markers = chart._group.selectAll(".markers." + seriesClass).data(data); - } else { - markers = series._markers.data(data, function (d) { return d.key; }); - } - - - // Add the actual marker. We need to do this even if we aren't displaying them because they - // catch hover events - markers - .enter() - .append("circle") - .attr("id", function (d) { return d.key; }) - .attr("class", "markers " + seriesClass) - .on("mouseover", function (e) { - self.enterEventHandler(e, this, chart, series); - }) - .on("mouseleave", function (e) { - self.leaveEventHandler(e, this, chart, series); - }) - .attr("cx", function (d) { return dimple._helpers.cx(d, chart, series); }) - .attr("cy", function (d) { return dimple._helpers.cy(d, chart, series); }) - .attr("r", 0) - .attr("opacity", function (d) { return (series.lineMarkers ? chart.getColor(d).opacity : 0); }) - .call(function () { - if (!chart.noFormats) { - this.attr("fill", "white") - .style("stroke-width", series.lineWeight) - .attr("stroke", function (d) { - return (graded ? dimple._helpers.fill(d, chart, series) : chart.getColor(d.aggField[d.aggField.length - 1]).stroke); - }); - } - }); - - markers - .transition().duration(duration) - .attr("cx", function (d) { return dimple._helpers.cx(d, chart, series); }) - .attr("cy", function (d) { return dimple._helpers.cy(d, chart, series); }) - .attr("r", 2 + series.lineWeight) - .call(function () { - if (!chart.noFormats) { - this.attr("fill", "white") - .style("stroke-width", series.lineWeight) - .attr("stroke", function (d) { - return (graded ? dimple._helpers.fill(d, chart, series) : chart.getColor(d.aggField[d.aggField.length - 1]).stroke); - }); - } - }); - - markers - .exit() - .transition().duration(duration) - .attr("r", 0) - .each("end", function () { - d3.select(this).remove(); - }); - - // Save the shapes to the series array - series._markers = markers; - }, - - // Handle the mouse enter event - enterEventHandler: function (e, shape, chart, series) { - - // The margin between the text and the box - var textMargin = 5, - // The margin between the ring and the popup - popupMargin = 10, - // The popup animation duration in ms - animDuration = 750, - // Collect some facts about the highlighted bubble - selectedShape = d3.select(shape), - cx = parseFloat(selectedShape.attr("cx")), - cy = parseFloat(selectedShape.attr("cy")), - r = parseFloat(selectedShape.attr("r")), - opacity = dimple._helpers.opacity(e, chart, series), - fill = dimple._helpers.fill(e, chart, series), - dropDest = series._dropLineOrigin(), - // Fade the popup stroke mixing the shape fill with 60% white - popupStrokeColor = d3.rgb( - d3.rgb(fill).r + 0.6 * (255 - d3.rgb(fill).r), - d3.rgb(fill).g + 0.6 * (255 - d3.rgb(fill).g), - d3.rgb(fill).b + 0.6 * (255 - d3.rgb(fill).b) - ), - // Fade the popup fill mixing the shape fill with 80% white - popupFillColor = d3.rgb( - d3.rgb(fill).r + 0.8 * (255 - d3.rgb(fill).r), - d3.rgb(fill).g + 0.8 * (255 - d3.rgb(fill).g), - d3.rgb(fill).b + 0.8 * (255 - d3.rgb(fill).b) - ), - t, - y = 0, - w = 0, - h = 0, - box, - overlap, - rows = []; - - if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { - chart._tooltipGroup.remove(); - } - chart._tooltipGroup = chart.svg.append("g"); - - // On hover make the line marker visible immediately - selectedShape.style("opacity", 1); - // Add a ring around the data point - chart._tooltipGroup.append("circle") - .attr("cx", cx) - .attr("cy", cy) - .attr("r", r) - .attr("opacity", 0) - .style("fill", "none") - .style("stroke", fill) - .style("stroke-width", 1) - .transition() - .duration(animDuration / 2) - .ease("linear") - .attr("opacity", 1) - .attr("r", r + 4) - .style("stroke-width", 2); - - // Add a drop line to the x axis - if (dropDest.y !== null) { - chart._tooltipGroup.append("line") - .attr("x1", cx) - .attr("y1", (cy < dropDest.y ? cy + r + 4 : cy - r - 4)) - .attr("x2", cx) - .attr("y2", (cy < dropDest.y ? cy + r + 4 : cy - r - 4)) - .style("fill", "none") - .style("stroke", fill) - .style("stroke-width", 2) - .style("stroke-dasharray", ("3, 3")) - .style("opacity", opacity) - .transition() - .delay(animDuration / 2) - .duration(animDuration / 2) - .ease("linear") - // Added 1px offset to cater for svg issue where a transparent - // group overlapping a line can sometimes hide it in some browsers - // Issue #10 - .attr("y2", (cy < dropDest.y ? dropDest.y - 1 : dropDest.y + 1)); - } - - // Add a drop line to the y axis - if (dropDest.x !== null) { - chart._tooltipGroup.append("line") - .attr("x1", (cx < dropDest.x ? cx + r + 4 : cx - r - 4)) - .attr("y1", cy) - .attr("x2", (cx < dropDest.x ? cx + r + 4 : cx - r - 4)) - .attr("y2", cy) - .style("fill", "none") - .style("stroke", fill) - .style("stroke-width", 2) - .style("stroke-dasharray", ("3, 3")) - .style("opacity", opacity) - .transition() - .delay(animDuration / 2) - .duration(animDuration / 2) - .ease("linear") - // Added 1px offset to cater for svg issue where a transparent - // group overlapping a line can sometimes hide it in some browsers - // Issue #10 - .attr("x2", (cx < dropDest.x ? dropDest.x - 1 : dropDest.x + 1)); - } - - // Add a group for text - t = chart._tooltipGroup.append("g"); - // Create a box for the popup in the text group - box = t.append("rect") - .attr("class", "chartTooltip"); - - // Add the series categories - if (series.categoryFields !== null && series.categoryFields !== undefined && series.categoryFields.length > 0) { - series.categoryFields.forEach(function (c, i) { - if (c !== null && c !== undefined && e.aggField[i] !== null && e.aggField[i] !== undefined) { - // If the category name and value match don't display the category name - rows.push(c + (e.aggField[i] !== c ? ": " + e.aggField[i] : "")); - } - }, this); - } - - if (series.x._hasTimeField()) { - if (e.xField[0] !== null && e.xField[0] !== undefined) { - rows.push(series.x.timeField + ": " + series.x._getFormat()(e.xField[0])); - } - } else if (series.x._hasCategories()) { - // Add the x axis categories - series.x.categoryFields.forEach(function (c, i) { - if (c !== null && c !== undefined && e.xField[i] !== null && e.xField[i] !== undefined) { - // If the category name and value match don't display the category name - rows.push(c + (e.xField[i] !== c ? ": " + e.xField[i] : "")); - } - }, this); - } else { - // Add the axis measure value - if (series.x.measure !== null && series.x.measure !== undefined && e.width !== null && e.width !== undefined) { - rows.push(series.x.measure + ": " + series.x._getFormat()(e.width)); - } - } - - if (series.y._hasTimeField()) { - if (e.yField[0] !== null && e.yField[0] !== undefined) { - rows.push(series.y.timeField + ": " + series.y._getFormat()(e.yField[0])); - } - } else if (series.y._hasCategories()) { - // Add the y axis categories - series.y.categoryFields.forEach(function (c, i) { - if (c !== null && c !== undefined && e.yField[i] !== null && e.yField[i] !== undefined) { - rows.push(c + (e.yField[i] !== c ? ": " + e.yField[i] : "")); - } - }, this); - } else { - // Add the axis measure value - if (series.y.measure !== null && series.y.measure !== undefined && e.height !== null && e.height !== undefined) { - rows.push(series.y.measure + ": " + series.y._getFormat()(e.height)); - } - } - - if (series.z !== null && series.z !== undefined) { - // Add the axis measure value - if (series.z.measure !== null && series.z.measure !== undefined && e.zValue !== null && e.zValue !== undefined) { - rows.push(series.z.measure + ": " + series.z._getFormat()(e.zValue)); - } - } - - if (series.c !== null && series.c !== undefined) { - // Add the axis measure value - if (series.c.measure !== null && series.c.measure !== undefined && e.cValue !== null && e.cValue !== undefined) { - rows.push(series.c.measure + ": " + series.c._getFormat()(e.cValue)); - } - } - - // Get distinct text rows to deal with cases where 2 axes have the same dimensionality - rows = rows.filter(function(elem, pos) { - return rows.indexOf(elem) === pos; - }); - - // Create a text object for every row in the popup - t.selectAll(".textHoverShapes").data(rows).enter() - .append("text") - .attr("class", "chartTooltip") - .text(function (d) { return d; }) - .style("font-family", "sans-serif") - .style("font-size", "10px"); - - // Get the max height and width of the text items - t.each(function () { - w = (this.getBBox().width > w ? this.getBBox().width : w); - h = (this.getBBox().width > h ? this.getBBox().height : h); - }); - - // Position the text relative to the bubble, the absolute positioning - // will be done by translating the group - t.selectAll("text") - .attr("x", 0) - .attr("y", function () { - // Increment the y position - y += this.getBBox().height; - // Position the text at the centre point - return y - (this.getBBox().height / 2); - }); - - // Draw the box with a margin around the text - box.attr("x", -textMargin) - .attr("y", -textMargin) - .attr("height", Math.floor(y + textMargin) - 0.5) - .attr("width", w + 2 * textMargin) - .attr("rx", 5) - .attr("ry", 5) - .style("fill", popupFillColor) - .style("stroke", popupStrokeColor) - .style("stroke-width", 2) - .style("opacity", 0.95); - - // Shift the ring margin left or right depending on whether it will overlap the edge - overlap = cx + r + textMargin + popupMargin + w > parseFloat(chart.svg.node().getBBox().width); - - // Translate the shapes to the x position of the bubble (the x position of the shapes is handled) - t.attr("transform", "translate(" + - (overlap ? cx - (r + textMargin + popupMargin + w) : cx + r + textMargin + popupMargin) + " , " + - (cy - ((y - (h - textMargin)) / 2)) + - ")"); - }, - - // Handle the mouse leave event - leaveEventHandler: function (e, shape, chart, series) { - // Return the opacity of the marker - d3.select(shape).style("opacity", (series.lineMarkers ? dimple._helpers.opacity(e, chart, series) : 0)); - if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { - chart._tooltipGroup.remove(); - } - } - }; - - // Copyright: 2014 PMSI-AlignAlytics // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" // Source: /src/objects/plot/bar.js @@ -3436,8 +3016,8 @@ var dimple = { classes = ["dimple-series-" + chart.series.indexOf(series), "dimple-bar"], updated, removed, - xFloat = !series.stacked && series.x._hasMeasure(), - yFloat = !series.stacked && series.y._hasMeasure(); + xFloat = !series._isStacked() && series.x._hasMeasure(), + yFloat = !series._isStacked() && series.y._hasMeasure(); if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { chart._tooltipGroup.remove(); @@ -4714,7 +4294,7 @@ var dimple = { } chart._tooltipGroup = chart.svg.append("g"); - offset = (series.stacked ? 1 : width / 2); + offset = (series._isStacked() ? 1 : width / 2); // Add a drop line to the x axis if (!series.x._hasCategories() && dropDest.y !== null) { @@ -4738,7 +4318,7 @@ var dimple = { .attr("y2", (y < dropDest.y ? dropDest.y - 1 : dropDest.y + 1)); } - offset = (series.stacked ? 1 : height / 2); + offset = (series._isStacked() ? 1 : height / 2); // Add a drop line to the y axis if (!series.y._hasCategories() && dropDest.x !== null) { diff --git a/dist/dimple.v1.2.0.min.js b/dist/dimple.v1.2.0.min.js index 0c64e15..91673b8 100644 --- a/dist/dimple.v1.2.0.min.js +++ b/dist/dimple.v1.2.0.min.js @@ -1,3 +1,3 @@ -var dimple={version:"1.2.0",plot:{},aggregateMethod:{}};!function(){"use strict";dimple.axis=function(a,b,c,d,e){this.chart=a,this.position=b,this.categoryFields=null===e||void 0===e?c:[].concat(e),this.measure=d,this.timeField=e,this.floatingBarWidth=5,this.hidden=!1,this.showPercent=!1,this.colors=null,this.overrideMin=null,this.overrideMax=null,this.shapes=null,this.showGridlines=null,this.gridlineShapes=null,this.titleShape=null,this.dateParseFormat=null,this.tickFormat=null,this.timePeriod=null,this.timeInterval=1,this.useLog=!1,this.logBase=10,this.title=void 0,this.clamp=!0,this.ticks=null,this._slaves=[],this._scale=null,this._min=0,this._max=0,this._previousOrigin=null,this._origin=null,this._orderRules=[],this._groupOrderRules=[],this._draw=null,this._getAxisData=function(){var a,b,c=[],d=!1;if(this.chart&&this.chart.series){for(a=0;a0?c=c.concat(b.data):d=!0);d&&this.chart.data&&(c=c.concat(this.chart.data))}return c},this._getFormat=function(){var a,b,c,d,e,f,g;return null!==this.tickFormat&&void 0!==this.tickFormat?a=this._hasTimeField()?d3.time.format(this.tickFormat):d3.format(this.tickFormat):this.showPercent?a=d3.format("%"):this.useLog&&null!==this.measure?a=function(a){var b=Math.floor(Math.abs(a),0).toString().length,c=Math.min(Math.floor((b-1)/3),4),d="kmBT".substring(c-1,c),e="0"===Math.round(10*(a/Math.pow(1e3,c))).toString().slice(-1)?0:1;return 0===a?0:d3.format(",."+e+"f")(a/Math.pow(1e3,c))+d}:null!==this.measure?(b=Math.floor(Math.abs(this._max),0).toString(),c=Math.floor(Math.abs(this._min),0).toString(),d=Math.max(c.length,b.length),d>3?(e=Math.min(Math.floor((d-1)/3),4),f="kmBT".substring(e-1,e),g=1>=d-3*e?1:0,a=function(a){return 0===a?0:d3.format(",."+g+"f")(a/Math.pow(1e3,e))+f}):(g=1>=d?1:0,a=d3.format(",."+g+"f"))):a=function(a){return a},a},this._getTimePeriod=function(){var a=this.timePeriod,b=30,c=this._max-this._min;return this._hasTimeField()&&!this.timePeriod&&(a=b>=c/1e3?d3.time.seconds:b>=c/6e4?d3.time.minutes:b>=c/36e5?d3.time.hours:b>=c/864e5?d3.time.days:b>=c/6048e5?d3.time.weeks:b>=c/26298e5?d3.time.months:d3.time.years),a},this._getTooltipText=function(a,b){if(this._hasTimeField())b[this.position+"Field"][0]&&a.push(this.timeField+": "+this._getFormat()(b[this.position+"Field"][0]));else if(this._hasCategories())this.categoryFields.forEach(function(c,d){null!==c&&void 0!==c&&b[this.position+"Field"][d]&&a.push(c+(b[this.position+"Field"][d]!==c?": "+b[this.position+"Field"][d]:""))},this);else if(this._hasMeasure())switch(this.position){case"x":a.push(this.measure+": "+this._getFormat()(b.width));break;case"y":a.push(this.measure+": "+this._getFormat()(b.height));break;case"z":a.push(this.measure+": "+this._getFormat()(b.zValue));break;case"c":a.push(this.measure+": "+this._getFormat()(b.cValue))}},this._getTopMaster=function(){var a=this;return null!==this.master&&void 0!==this.master&&(a=this.master._getTopMaster()),a},this._hasCategories=function(){return null!==this.categoryFields&&void 0!==this.categoryFields&&this.categoryFields.length>0},this._hasMeasure=function(){return null!==this.measure&&void 0!==this.measure},this._hasTimeField=function(){return null!==this.timeField&&void 0!==this.timeField},this._parseDate=function(a){var b;return b=null===this.dateParseFormat||void 0===this.dateParseFormat?isNaN(a)?Date.parse(a):new Date(a):d3.time.format(this.dateParseFormat).parse(a)},this._update=function(a){var b,c,d,e,f=[],g=this.ticks||10,h=function(a,b,c){var d,e,f=a.categoryFields[0],g=a._getAxisData(),h=f,i=!1,j=!0,k=null;for(d=0;d1?1:this._max,this._min=null!==this.overrideMin?this.overrideMin:this._min,this._max=null!==this.overrideMax?this.overrideMax:this._max,"x"===this.position&&null===this._scale){if(this._hasTimeField()?this._scale=d3.time.scale().rangeRound([this.chart._xPixels(),this.chart._xPixels()+this.chart._widthPixels()]).domain([this._min,this._max]).clamp(this.clamp):this.useLog?this._scale=d3.scale.log().range([this.chart._xPixels(),this.chart._xPixels()+this.chart._widthPixels()]).domain([0===this._min?Math.pow(this.logBase,-1):this._min,0===this._max?-1*Math.pow(this.logBase,-1):this._max]).clamp(this.clamp).base(this.logBase).nice():null===this.measure||void 0===this.measure?(f=h(this,"x","y"),null!==this._slaves&&void 0!==this._slaves&&this._slaves.forEach(function(a){f=f.concat(h(a,"x","y"))},this),this._scale=d3.scale.ordinal().rangePoints([this.chart._xPixels(),this.chart._xPixels()+this.chart._widthPixels()]).domain(f.concat([""]))):this._scale=d3.scale.linear().range([this.chart._xPixels(),this.chart._xPixels()+this.chart._widthPixels()]).domain([this._min,this._max]).clamp(this.clamp).nice(),!this.hidden)switch(this.chart._axisIndex(this,"x")){case 0:this._draw=d3.svg.axis().orient("bottom").scale(this._scale),this.ticks&&this._draw.ticks(g);break;case 1:this._draw=d3.svg.axis().orient("top").scale(this._scale),this.ticks&&this._draw.ticks(g)}}else if("y"===this.position&&null===this._scale){if(this._hasTimeField()?this._scale=d3.time.scale().rangeRound([this.chart._yPixels()+this.chart._heightPixels(),this.chart._yPixels()]).domain([this._min,this._max]).clamp(this.clamp):this.useLog?this._scale=d3.scale.log().range([this.chart._yPixels()+this.chart._heightPixels(),this.chart._yPixels()]).domain([0===this._min?Math.pow(this.logBase,-1):this._min,0===this._max?-1*Math.pow(this.logBase,-1):this._max]).clamp(this.clamp).base(this.logBase).nice():null===this.measure||void 0===this.measure?(f=h(this,"y","x"),null!==this._slaves&&void 0!==this._slaves&&this._slaves.forEach(function(a){f=f.concat(h(a,"y","x"))},this),this._scale=d3.scale.ordinal().rangePoints([this.chart._yPixels()+this.chart._heightPixels(),this.chart._yPixels()]).domain(f.concat([""]))):this._scale=d3.scale.linear().range([this.chart._yPixels()+this.chart._heightPixels(),this.chart._yPixels()]).domain([this._min,this._max]).clamp(this.clamp).nice(),!this.hidden)switch(this.chart._axisIndex(this,"y")){case 0:this._draw=d3.svg.axis().orient("left").scale(this._scale),this.ticks&&this._draw.ticks(g);break;case 1:this._draw=d3.svg.axis().orient("right").scale(this._scale),this.ticks&&this._draw.ticks(g)}}else this.position.length>0&&"z"===this.position[0]&&null===this._scale?this._scale=this.useLog?d3.scale.log().range([this.chart._heightPixels()/300,this.chart._heightPixels()/10]).domain([0===this._min?Math.pow(this.logBase,-1):this._min,0===this._max?-1*Math.pow(this.logBase,-1):this._max]).clamp(this.clamp).base(this.logBase):d3.scale.linear().range([this.chart._heightPixels()/300,this.chart._heightPixels()/10]).domain([this._min,this._max]).clamp(this.clamp):this.position.length>0&&"c"===this.position[0]&&null===this._scale&&(this._scale=d3.scale.linear().range([0,null===this.colors||1===this.colors.length?1:this.colors.length-1]).domain([this._min,this._max]).clamp(this.clamp));return null!==this._slaves&&void 0!==this._slaves&&this._slaves.length>0&&this._slaves.forEach(function(a){a._scale=this._scale},this),null!==a&&void 0!==a&&a!==!1||this._hasTimeField()||null===this._scale||null===this._scale.ticks||void 0===this._scale.ticks||!(this._scale.ticks(g).length>0)||"x"!==this.position&&"y"!==this.position||(b=this._scale.ticks(g),c=b[1]-b[0],d=((this._max-this._min)%c).toFixed(0),0!==d&&(this._max=Math.ceil(this._max/c)*c,this._min=Math.floor(this._min/c)*c,this._update(!0))),e=null!==f&&void 0!==f&&f.length>0?this._scale.copy()(f[0]):this._min>0?this._scale.copy()(this._min):this._max<0?this._scale.copy()(this._max):this._scale.copy()(0),this._origin!==e&&(this._previousOrigin=null===this._origin?e:this._origin,this._origin=e),this},this.addGroupOrderRule=function(a,b){this._groupOrderRules.push({ordering:a,desc:b})},this.addOrderRule=function(a,b){this._orderRules.push({ordering:a,desc:b})}},dimple.chart=function(a,b){this.svg=a,this.x="10%",this.y="10%",this.width="80%",this.height="80%",this.data=b,this.noFormats=!1,this.axes=[],this.series=[],this.legends=[],this.storyboard=null,this.titleShape=null,this.shapes=null,this._group=a.append("g"),this._tooltipGroup=null,this._assignedColors={},this._nextColor=0,this._axisIndex=function(a,b){var c=0,d=0,e=-1;for(c=0;c0&&(a=a.concat(this.data)),null!==this.series&&void 0!==this.series&&this.series.length>0&&this.series.forEach(function(b){null!==b.data&&void 0!==b.data&&b.data.length>0&&(a=a.concat(b.data))}),a},this._getSeriesData=function(){null!==this.series&&void 0!==this.series&&this.series.forEach(function(a){var b,c,d=[],e=function(a,b){var c=[];return null!==a&&(a._hasTimeField()?c.push(a._parseDate(b[a.timeField])):a._hasCategories()&&a.categoryFields.forEach(function(a){c.push(b[a])},this)),c},f={x:!1,y:!1,z:!1,c:!1},g={x:[],y:[]},h={x:[],y:[],z:[]},i={min:null,max:null},j={x:[],y:[],z:[]},k=[],l={},m={x:0,y:0,z:0},n="",o=[],p=[],q=[],r="",s=[],t="",u=[],v=[],w=a.data||this.data,x=[];null!==this.storyboard&&void 0!==this.storyboard&&this.storyboard.categoryFields.length>0&&(n=this.storyboard.categoryFields[0],o=dimple._getOrderedList(w,n,this.storyboard._orderRules)),a.x._hasCategories()&&a.x._hasMeasure()&&(r=a.x.categoryFields[0],s=dimple._getOrderedList(w,r,a.x._orderRules.concat([{ordering:a.x.measure,desc:!0}]))),a.y._hasCategories()&&a.y._hasMeasure()&&(t=a.y.categoryFields[0],u=dimple._getOrderedList(w,t,a.y._orderRules.concat([{ordering:a.y.measure,desc:!0}]))),null!==a.categoryFields&&void 0!==a.categoryFields&&a.categoryFields.length>0&&(v=[].concat(a._orderRules),p=[],a.categoryFields.forEach(function(a){void 0!==w[0][a]&&p.push(a)},this),null!==a.c&&void 0!==a.c&&a.c._hasMeasure()?v.push({ordering:a.c.measure,desc:!0}):null!==a.z&&void 0!==a.z&&a.z._hasMeasure()?v.push({ordering:a.z.measure,desc:!0}):a.x._hasMeasure()?v.push({ordering:a.x.measure,desc:!0}):a.y._hasMeasure()&&v.push({ordering:a.y.measure,desc:!0}),q=dimple._getOrderedList(w,p,v)),w.sort(function(a,b){var c,d,e,f,g,h,i=0;if(""!==n&&(i=o.indexOf(a[n])-o.indexOf(b[n])),""!==r&&0===i&&(i=s.indexOf(a[r])-s.indexOf(b[r])),""!==t&&0===i&&(i=u.indexOf(a[t])-u.indexOf(b[t])),p&&p.length>0&&0===i)for(c=[].concat(p),i=0,e=0;e0&&(m+="/"),m+=b[a],i=m===g},this)),null!==c&&void 0!==c&&i&&(h=d[k],c._hasMeasure()&&null!==b[c.measure]&&void 0!==b[c.measure]&&(-1===h[c.position+"ValueList"].indexOf(b[c.measure])&&h[c.position+"ValueList"].push(b[c.measure]),isNaN(parseFloat(b[c.measure]))&&(f[c.position]=!0),j.value=h[c.position+"Value"],j.count=h[c.position+"Count"],l.value=b[c.measure],h[c.position+"Value"]=a.aggregate(j,l),h[c.position+"Count"]+=1))},j(a.x,this.storyboard),j(a.y,this.storyboard),j(a.z,this.storyboard),j(a.c,this.storyboard)},this),null!==a.x&&void 0!==a.x&&a.x._hasCategories()&&a.x.categoryFields.length>1&&void 0!==g.x&&(x=[],a.y._hasMeasure()&&x.push({ordering:a.y.measure,desc:!0}),g.x=dimple._getOrderedList(w,a.x.categoryFields[1],a.x._groupOrderRules.concat(x))),null!==a.y&&void 0!==a.y&&a.y._hasCategories()&&a.y.categoryFields.length>1&&void 0!==g.y&&(x=[],a.x._hasMeasure()&&x.push({ordering:a.x.measure,desc:!0}),g.y=dimple._getOrderedList(w,a.y.categoryFields[1],a.y._groupOrderRules.concat(x)),g.y.reverse()),d.forEach(function(c){null!==a.x&&(f.x===!0&&(c.xValue=c.xValueList.length),b=(null===h.x[c.xField.join("/")]||void 0===h.x[c.xField.join("/")]?0:h.x[c.xField.join("/")])+(a.y._hasMeasure()?Math.abs(c.yValue):0),h.x[c.xField.join("/")]=b),null!==a.y&&(f.y===!0&&(c.yValue=c.yValueList.length),b=(null===h.y[c.yField.join("/")]||void 0===h.y[c.yField.join("/")]?0:h.y[c.yField.join("/")])+(a.x._hasMeasure()?Math.abs(c.xValue):0),h.y[c.yField.join("/")]=b),null!==a.z&&(f.z===!0&&(c.zValue=c.zValueList.length),b=(null===h.z[c.zField.join("/")]||void 0===h.z[c.zField.join("/")]?0:h.z[c.zField.join("/")])+(a.z._hasMeasure()?Math.abs(c.zValue):0),h.z[c.zField.join("/")]=b),null!==a.c&&((null===i.min||c.cValuei.max)&&(i.max=c.cValue))},this);for(c in h.x)h.x.hasOwnProperty(c)&&(m.x+=h.x[c]);for(c in h.y)h.y.hasOwnProperty(c)&&(m.y+=h.y[c]);for(c in h.z)h.z.hasOwnProperty(c)&&(m.z+=h.z[c]);d.forEach(function(b){var c,d,e,f,n,o=function(c,d,e){var f,i,n,o,p;null!==c&&void 0!==c&&(o=c.position,c._hasCategories()?c._hasMeasure()?(f=b[c.position+"Field"].join("/"),i=c.showPercent?h[c.position][f]/m[c.position]:h[c.position][f],-1===k.indexOf(f)&&(l[f]=i+(k.length>0?l[k[k.length-1]]:0),k.push(f)),n=b[o+"Bound"]=b["c"+o]="x"!==o&&"y"!==o||!a.stacked?i:l[f],b[e]=i,b[o]=n-("x"===o&&i>=0||"y"===o&&0>=i?i:0)):(b[o]=b["c"+o]=b[o+"Field"][0],b[e]=1,void 0!==g[o]&&null!==g[o]&&g[o].length>=2&&(b[o+"Offset"]=g[o].indexOf(b[o+"Field"][1]),b[e]=1/g[o].length)):(i=c.showPercent?b[o+"Value"]/h[d][b[d+"Field"].join("/")]:b[o+"Value"],f=b[d+"Field"].join("/")+(b[o+"Value"]>=0),p=j[o][f]=(null===j[o][f]||void 0===j[o][f]||"z"===o?0:j[o][f])+i,n=b[o+"Bound"]=b["c"+o]="x"!==o&&"y"!==o||!a.stacked?i:p,b[e]=i,b[o]=n-("x"===o&&i>=0||"y"===o&&0>=i?i:0)))};o(a.x,"y","width"),o(a.y,"x","height"),o(a.z,"z","r"),null!==a.c&&null!==i.min&&null!==i.max&&(i.min===i.max&&(i.min-=.5,i.max+=.5),i.min=null!==a.c.overrideMin&&void 0!==a.c.overrideMin?a.c.overrideMin:i.min,i.max=null!==a.c.overrideMax&&void 0!==a.c.overrideMax?a.c.overrideMax:i.max,b.cValue=b.cValue>i.max?i.max:b.cValue1?(c=d3.rgb(a.c.colors[Math.floor(f)]),d=d3.rgb(a.c.colors[Math.ceil(f)])):(c=d3.rgb("white"),d=d3.rgb(this.getColor(b.aggField.slice(-1)[0]).fill)),c.r=Math.floor(c.r+(d.r-c.r)*n),c.g=Math.floor(c.g+(d.g-c.g)*n),c.b=Math.floor(c.b+(d.b-c.b)*n),b.fill=c.toString(),b.stroke=c.darker(.5).toString())},this),a._positionData=d},this)},this._heightPixels=function(){return dimple._parseYPosition(this.height,this.svg.node())},this._registerEventHandlers=function(a){null!==a._eventHandlers&&a._eventHandlers.length>0&&a._eventHandlers.forEach(function(b){var c=null;null!==b.handler&&"function"==typeof b.handler&&(c=null!==a._markers&&void 0!==a._markers?a._markers:a.shapes,c.on(b.event,function(c){var d=new dimple.eventArgs;null!==a.chart.storyboard&&(d.frameValue=a.chart.storyboard.getFrameValue()),d.seriesValue=c.aggField,d.xValue=c.x,d.yValue=c.y,d.zValue=c.z,d.colorValue=c.cValue,d.seriesShapes=a.shapes,d.selectedShape=d3.select(this),b.handler(d)}))},this)},this._widthPixels=function(){return dimple._parseXPosition(this.width,this.svg.node())},this._xPixels=function(){return dimple._parseXPosition(this.x,this.svg.node())},this._yPixels=function(){return dimple._parseYPosition(this.y,this.svg.node())},this.addAxis=function(a,b,c,d){var e=null,f=null;if(null!==b&&void 0!==b&&(b=[].concat(b)),"string"==typeof a||a instanceof String)e=new dimple.axis(this,a,b,c,d),this.axes.push(e);else{if(f=a,e=new dimple.axis(this,f.position,b,c,d),e._hasMeasure()!==f._hasMeasure())throw"You have specified a composite axis where some but not all axes have a measure - this is not supported, all axes must be of the same type.";if(e._hasTimeField()!==f._hasTimeField())throw"You have specified a composite axis where some but not all axes have a time field - this is not supported, all axes must be of the same type.";if((null===e.categoryFields||void 0===e.categoryFields?0:e.categoryFields.length)!==(null===f.categoryFields||void 0===f.categoryFields?0:f.categoryFields.length))throw"You have specified a composite axis where axes have differing numbers of category fields - this is not supported, all axes must be of the same type.";f._slaves.push(e)}return e},this.addCategoryAxis=function(a,b){return this.addAxis(a,b,null)},this.addColorAxis=function(a,b){var c=this.addAxis("c",null,a);return c.colors=null===b||void 0===b?null:[].concat(b),c},this.addLegend=function(a,b,c,d,e,f){f=null===f||void 0===f?this.series:[].concat(f),e=null===e||void 0===e?"left":e;var g=new dimple.legend(this,a,b,c,d,e,f);return this.legends.push(g),g},this.addLogAxis=function(a,b,c){var d=this.addAxis(a,null,b,null);return null!==c&&void 0!==c&&(d.logBase=c),d.useLog=!0,d},this.addMeasureAxis=function(a,b){return this.addAxis(a,null,b)},this.addPctAxis=function(a,b,c){var d=null;return d=null!==c&&void 0!==c?this.addAxis(a,c,b):this.addMeasureAxis(a,b),d.showPercent=!0,d},this.addSeries=function(a,b,c){(null===c||void 0===c)&&(c=this.axes),(null===b||void 0===b)&&(b=dimple.plot.bubble);var d,e=null,f=null,g=null,h=null;return c.forEach(function(a){null!==a&&b.supportedAxes.indexOf(a.position)>-1&&(null===e&&"x"===a.position[0]?e=a:null===f&&"y"===a.position[0]?f=a:null===g&&"z"===a.position[0]?g=a:null===h&&"c"===a.position[0]&&(h=a))},this),null!==a&&void 0!==a&&(a=[].concat(a)),d=new dimple.series(this,a,e,f,g,h,b,dimple.aggregateMethod.sum,b.stacked),this.series.push(d),d},this.addTimeAxis=function(a,b,c,d){var e=this.addAxis(a,null,null,b);return e.tickFormat=d,e.dateParseFormat=c,e},this.assignColor=function(a,b,c,d){return this._assignedColors[a]=new dimple.color(b,c,d),this._assignedColors[a]},this.defaultColors=[new dimple.color("#80B1D3"),new dimple.color("#FB8072"),new dimple.color("#FDB462"),new dimple.color("#B3DE69"),new dimple.color("#FFED6F"),new dimple.color("#BC80BD"),new dimple.color("#8DD3C7"),new dimple.color("#CCEBC5"),new dimple.color("#FFFFB3"),new dimple.color("#BEBADA"),new dimple.color("#FCCDE5"),new dimple.color("#D9D9D9")],this.draw=function(a,b){a=null===a||void 0===a?0:a;var c,d=null,e=null,f=!1,g=!1,h=this._xPixels(),i=this._yPixels(),j=this._widthPixels(),k=this._heightPixels(),l=[];return(void 0===b||null===b||b===!1)&&this._getSeriesData(),this.axes.forEach(function(a){a._scale=null},this),this.axes.forEach(function(a){if(a._min=0,a._max=0,a._hasMeasure()){var b=!1;this.series.forEach(function(c){if(c._deepMatch(a)){var d=c._axisBounds(a.position);a._min>d.min&&(a._min=d.min),a._maxb[a.measure]&&(a._min=b[a.measure]),a._maxa._max)&&(a._max=d)},this)},this)):a._hasCategories()&&(a._min=0,c=[],this.series.forEach(function(b){b._deepMatch(a)&&null!==b[a.position].categoryFields[0]&&void 0!==b[a.position].categoryFields[0]&&-1===l.indexOf(b[a.position].categoryFields[0])&&l.push(b[a.position].categoryFields[0])},this),a._getAxisData().forEach(function(a){l.forEach(function(b){-1===c.indexOf(a[b])&&c.push(a[b])},this)},this),a._max=c.length);null!==a._slaves&&void 0!==a._slaves&&a._slaves.length>0&&a._slaves.forEach(function(b){b._min=a._min,b._max=a._max},this),a._update(),null===d&&"x"===a.position?d=a:null===e&&"y"===a.position&&(e=a)},this),this.axes.forEach(function(b){var c,l=!1,m=null,n=0,o=null,p=!1,q=0,r={l:null,t:null,r:null,b:null},s=0,t=0,u="",v=this;null===b.gridlineShapes?(b.showGridlines||null===b.showGridlines&&!b._hasCategories()&&(!f&&"x"===b.position||!g&&"y"===b.position))&&(b.gridlineShapes=this._group.append("g").attr("class","dimple-gridline"),"x"===b.position?f=!0:g=!0):"x"===b.position?f=!0:g=!0,null===b.shapes&&(b.shapes=this._group.append("g").attr("class","dimple-axis"),l=!0),b===d&&null!==e?(m="translate(0, "+(null===e.categoryFields||0===e.categoryFields.length?e._scale(0):i+k)+")",o="translate(0, "+(b===d?i+k:i)+")",n=-k):b===e&&null!==d?(m="translate("+(null===d.categoryFields||0===d.categoryFields.length?d._scale(0):h)+", 0)",o="translate("+(b===e?h:h+j)+", 0)",n=-j):"x"===b.position?(o=m="translate(0, "+(b===d?i+k:i)+")",n=-k):"y"===b.position&&(o=m="translate("+(b===e?h:h+j)+", 0)",n=-j),c=function(b){var c;return c=null===m||0===a||l?b:b.transition().duration(a)},null!==m&&null!==b._draw&&(b._hasTimeField()?c(b.shapes).call(b._draw.ticks(b._getTimePeriod(),b.timeInterval).tickFormat(b._getFormat())).attr("transform",m):b.useLog?c(b.shapes).call(b._draw.ticks(4,b._getFormat())).attr("transform",m):c(b.shapes).call(b._draw.tickFormat(b._getFormat())).attr("transform",m),null!==b.gridlineShapes&&c(b.gridlineShapes).call(b._draw.tickSize(n,0,0).tickFormat("")).attr("transform",o),(null===b.measure||void 0===b.measure)&&("x"===b.position?c(b.shapes.selectAll("text")).attr("x",j/b._max/2):"y"===b.position&&c(b.shapes.selectAll("text")).attr("y",-1*(k/b._max)/2)),null!==b.categoryFields&&void 0!==b.categoryFields&&b.categoryFields.length>0&&(b!==d||null!==e.categoryFields&&0!==e.categoryFields.length||c(b.shapes.selectAll("text")).attr("y",i+k-e._scale(0)+9),b!==e||null!==d.categoryFields&&0!==d.categoryFields.length||c(b.shapes.selectAll("text")).attr("x",-1*(d._scale(0)-h)-9))),this.noFormats||(c(b.shapes.selectAll("text")).style("font-family","sans-serif").style("font-size",(k/35>10?k/35:10)+"px"),c(b.shapes.selectAll("path, line")).style("fill","none").style("stroke","black").style("shape-rendering","crispEdges"),null!==b.gridlineShapes&&c(b.gridlineShapes.selectAll("line")).style("fill","none").style("stroke","lightgray").style("opacity",.8)),(null===b.measure||void 0===b.measure)&&(b===d?(q=0,b.shapes.selectAll("text").each(function(){var a=this.getComputedTextLength();q=a>q?a:q}),q>j/b.shapes.selectAll("text")[0].length?(p=!0,b.shapes.selectAll("text").style("text-anchor","start").each(function(){var a=this.getBBox();d3.select(this).attr("transform","rotate(90,"+a.x+","+(a.y+a.height/2)+") translate(-5, 0)")})):(p=!1,b.shapes.selectAll("text").style("text-anchor","middle").attr("transform",""))):"x"===b.position&&(q=0,b.shapes.selectAll("text").each(function(){var a=this.getComputedTextLength();q=a>q?a:q}),q>j/b.shapes.selectAll("text")[0].length?(p=!0,b.shapes.selectAll("text").style("text-anchor","end").each(function(){var a=this.getBBox();d3.select(this).attr("transform","rotate(90,"+(a.x+a.width)+","+(a.y+a.height/2)+") translate(5, 0)")})):(p=!1,b.shapes.selectAll("text").style("text-anchor","middle").attr("transform","")))),null!==b.titleShape&&void 0!==b.titleShape&&b.titleShape.remove(),b.shapes.selectAll("text").each(function(){var a=this.getBBox();(null===r.l||-9-a.widthr.r)&&(r.r=a.x+a.width),p?((null===r.t||a.y+a.height-a.widthr.b)&&(r.b=a.height+a.width)):((null===r.t||a.yr.b)&&(r.b=9+a.height))}),"x"===b.position?(t=b===d?i+k+r.b+5:i+r.t-10,s=h+j/2):"y"===b.position&&(s=b===e?h+r.l-10:h+j+r.r+20,t=i+k/2,u="rotate(270, "+s+", "+t+")"),b.hidden||"x"!==b.position&&"y"!==b.position||null===b.title||(b.titleShape=this._group.append("text").attr("class","dimple-axis dimple-title"),b.titleShape.attr("x",s).attr("y",t).attr("text-anchor","middle").attr("transform",u).text(void 0!==b.title?b.title:null===b.categoryFields||void 0===b.categoryFields||0===b.categoryFields.length?b.measure:b.categoryFields.join("/")).each(function(){v.noFormats||d3.select(this).style("font-family","sans-serif").style("font-size",(k/35>10?k/35:10)+"px")}),b===d?b.titleShape.each(function(){d3.select(this).attr("y",t+this.getBBox().height/1.65)}):b===e&&b.titleShape.each(function(){d3.select(this).attr("x",s+this.getBBox().height/1.65)}))},this),this.series.forEach(function(b){b.plot.draw(this,b,a),this._registerEventHandlers(b)},this),this.legends.forEach(function(b){b._draw(a)},this),null!==this.storyboard&&void 0!==this.storyboard&&(this.storyboard._drawText(),this.storyboard.autoplay&&this.storyboard.startAnimation()),this},this.getColor=function(a){return(null===this._assignedColors[a]||void 0===this._assignedColors[a])&&(this._assignedColors[a]=this.defaultColors[this._nextColor],this._nextColor=(this._nextColor+1)%this.defaultColors.length),this._assignedColors[a]},this.setBounds=function(a,b,c,d){return this.x=a,this.y=b,this.width=c,this.height=d,this._xPixels=function(){return dimple._parseXPosition(this.x,this.svg.node())},this._yPixels=function(){return dimple._parseYPosition(this.y,this.svg.node())},this._widthPixels=function(){return dimple._parseXPosition(this.width,this.svg.node())},this._heightPixels=function(){return dimple._parseYPosition(this.height,this.svg.node())},this.draw(0,!0),this},this.setMargins=function(a,b,c,d){return this.x=a,this.y=b,this.width=0,this.height=0,this._xPixels=function(){return dimple._parseXPosition(this.x,this.svg.node())},this._yPixels=function(){return dimple._parseYPosition(this.y,this.svg.node())},this._widthPixels=function(){return dimple._parentWidth(this.svg.node())-this._xPixels()-dimple._parseXPosition(c,this.svg.node())},this._heightPixels=function(){return dimple._parentHeight(this.svg.node())-this._yPixels()-dimple._parseYPosition(d,this.svg.node())},this.draw(0,!0),this},this.setStoryboard=function(a,b){return this.storyboard=new dimple.storyboard(this,a),null!==b&&void 0!==b&&(this.storyboard.onTick=b),this.storyboard}},dimple.color=function(a,b,c){this.fill=a,this.stroke=null===b||void 0===b?d3.rgb(a).darker(.5).toString():b,this.opacity=null===c||void 0===c?.8:c},dimple.eventArgs=function(){this.seriesValue=null,this.xValue=null,this.yValue=null,this.zValue=null,this.colorValue=null,this.frameValue=null,this.seriesShapes=null,this.selectedShape=null},dimple.legend=function(a,b,c,d,e,f,g){this.chart=a,this.series=g,this.x=b,this.y=c,this.width=d,this.height=e,this.horizontalAlign=f,this.shapes=null,this._draw=function(a){var b,c=this._getEntries(),d=0,e=0,f=0,g=0,h=15,i=9,j=this;null!==this.shapes&&void 0!==this.shapes&&this.shapes.transition().duration(.2*a).attr("opacity",0).remove(),b=this.chart._group.selectAll(".dimple-dont-select-any").data(c).enter().append("g").attr("class",function(a){return"dimple-legend "+dimple._createClass(a.aggField)}).attr("opacity",0),b.append("text").attr("class",function(a){return"dimple-legend dimple-legend-text "+dimple._createClass(a.aggField)}).text(function(a){return a.key}).call(function(){j.chart.noFormats||this.style("font-family","sans-serif").style("font-size",(j.chart._heightPixels()/35>10?j.chart._heightPixels()/35:10)+"px").style("shape-rendering","crispEdges")}).each(function(){var a=this.getBBox();a.width>d&&(d=a.width),a.height>e&&(e=a.height)}),b.append("rect").attr("class",function(a){return"dimple-legend dimple-legend-key "+dimple._createClass(a.aggField)}).attr("height",i).attr("width",h),e=(i>e?i:e)+2,d+=h+20,b.each(function(a){f+d>j._widthPixels()&&(f=0,g+=e),g>j._heightPixels()?d3.select(this).remove():(d3.select(this).select("text").attr("x","left"===j.horizontalAlign?j._xPixels()+h+5+f:j._xPixels()+(j._widthPixels()-f-d)+h+5).attr("y",function(){return j._yPixels()+g+this.getBBox().height/1.65}).attr("width",j._widthPixels()).attr("height",j._heightPixels()),d3.select(this).select("rect").attr("class",function(a){return"dimple-legend dimple-legend-key "+dimple._createClass(a.aggField)}).attr("x","left"===j.horizontalAlign?j._xPixels()+f:j._xPixels()+(j._widthPixels()-f-d)).attr("y",j._yPixels()+g).attr("height",i).attr("width",h).style("fill",function(){return dimple._helpers.fill(a,j.chart,a.series)}).style("stroke",function(){return dimple._helpers.stroke(a,j.chart,a.series)}).style("opacity",function(){return dimple._helpers.opacity(a,j.chart,a.series)}).style("shape-rendering","crispEdges"),f+=d)}),b.transition().delay(.2*a).duration(.8*a).attr("opacity",1),this.shapes=b},this._getEntries=function(){var a=[];return null!==this.series&&void 0!==this.series&&this.series.forEach(function(b){var c=b._positionData;c.forEach(function(c){var d,e=-1;for(d=0;de.max&&(e.max=a[f.position+"Bound"])},this):null===g||null===g.categoryFields||0===g.categoryFields.length?j.forEach(function(a){!this.stacked||"x"!==f.position&&"y"!==f.position?(a[f.position+"Value"]e.max&&(e.max=a[f.position+"Value"])):a[f.position+"Value"]<0?e.min=e.min+a[f.position+"Value"]:e.max=e.max+a[f.position+"Value"]},this):(b=f.position+"Value",c=g.position+"Field",d=[],j.forEach(function(a){var e=a[c].join("/"),f=d.indexOf(e);-1===f&&(d.push(e),f=d.length-1),void 0===h[f]&&(h[f]={min:0,max:0},f>=i&&(i=f+1)),this.stacked?a[b]<0?h[f].min=h[f].min+a[b]:h[f].max=h[f].max+a[b]:(a[b]h[f].max&&(h[f].max=a[b]))},this),h.forEach(function(a){void 0!==a&&(a.mine.max&&(e.max=a.max))},this)),e},this._deepMatch=function(a){var b=!1;return this[a.position]===a?b=!0:void 0!==a._slaves&&null!==a._slaves&&a._slaves.length>0&&a._slaves.forEach(function(a){b=b||this._deepMatch(a)},this),b},this._dropLineOrigin=function(){var a=0,b=0,c={x:null,y:null},d={x:null,y:null}; -return this.chart.axes.forEach(function(a){"x"===a.position&&null===d.x?d.x=a._hasTimeField()?this.chart._xPixels():a._origin:"y"===a.position&&null===d.y&&(d.y=a._hasTimeField()?this.chart._yPixels()+this.chart._heightPixels():a._origin)},this),this.chart.axes.forEach(function(e){"x"!==e.position||this.x.hidden?"y"!==e.position||this.y.hidden||(this._deepMatch(e)&&(0===b?c.x=d.x:1===b&&(c.x=this.chart._xPixels()+this.chart._widthPixels())),b+=1):(this._deepMatch(e)&&(0===a?c.y=d.y:1===a&&(c.y=this.chart._yPixels())),a+=1)},this),c},this.addEventHandler=function(a,b){this._eventHandlers.push({event:a,handler:b})},this.addOrderRule=function(a,b){this._orderRules.push({ordering:a,desc:b})},this.getTooltipText=function(a){var b=[];return null!==this.categoryFields&&void 0!==this.categoryFields&&this.categoryFields.length>0&&this.categoryFields.forEach(function(c,d){null!==c&&void 0!==c&&null!==a.aggField[d]&&void 0!==a.aggField[d]&&b.push(c+(a.aggField[d]!==c?": "+a.aggField[d]:""))},this),this.x&&this.x._getTooltipText(b,a),this.y&&this.y._getTooltipText(b,a),this.z&&this.z._getTooltipText(b,a),this.c&&this.c._getTooltipText(b,a),b.filter(function(a,c){return b.indexOf(a)===c})}},dimple.storyboard=function(a,b){null!==b&&void 0!==b&&(b=[].concat(b)),this.chart=a,this.categoryFields=b,this.autoplay=!0,this.frameDuration=3e3,this.storyLabel=null,this.onTick=null,this._frame=0,this._animationTimer=null,this._categories=[],this._cachedCategoryFields=[],this._orderRules=[],this._drawText=function(a){if(null===this.storyLabel||void 0===this.storyLabel){var b=this.chart,c=0;this.chart.axes.forEach(function(a){"x"===a.position&&(c+=1)},this),this.storyLabel=this.chart._group.append("text").attr("x",this.chart._xPixels()+.01*this.chart._widthPixels()).attr("y",this.chart._yPixels()+(this.chart._heightPixels()/35>10?this.chart._heightPixels()/35:10)*(c>1?1.25:-1)).call(function(){b.noFormats||this.style("font-family","sans-serif").style("font-size",(b._heightPixels()/35>10?b._heightPixels()/35:10)+"px")})}this.storyLabel.transition().duration(.2*a).attr("opacity",0),this.storyLabel.transition().delay(.2*a).attr("class","dimple-storyboard-label").text(this.categoryFields.join("\\")+": "+this.getFrameValue()).transition().duration(.8*a).attr("opacity",1)},this._getCategories=function(){return this._categoryFields!==this._cachedCategoryFields&&(this._categories=[],this.chart._getAllData().forEach(function(a){var b=-1,c="";null!==this.categoryFields&&(this.categoryFields.forEach(function(b,d){d>0&&(c+="/"),c+=a[b]},this),b=this._categories.indexOf(c),-1===b&&(this._categories.push(c),b=this._categories.length-1))},this),this._cachedCategoryFields=this._categoryFields),this._categories},this._goToFrameIndex=function(a){this._frame=a%this._getCategories().length,this.chart.draw(this.frameDuration/2)},this.addOrderRule=function(a,b){this._orderRules.push({ordering:a,desc:b})},this.getFrameValue=function(){var a=null;return this._frame>=0&&this._getCategories().length>this._frame&&(a=this._getCategories()[this._frame]),a},this.goToFrame=function(a){if(this._getCategories().length>0){var b=this._getCategories().indexOf(a);this._goToFrameIndex(b)}},this.pauseAnimation=function(){null!==this._animationTimer&&(window.clearInterval(this._animationTimer),this._animationTimer=null)},this.startAnimation=function(){null===this._animationTimer&&(null!==this.onTick&&this.onTick(this.getFrameValue()),this._animationTimer=window.setInterval(function(a){return function(){a._goToFrameIndex(a._frame+1),null!==a.onTick&&a.onTick(a.getFrameValue()),a._drawText(a.frameDuration/2)}}(this),this.frameDuration))},this.stopAnimation=function(){null!==this._animationTimer&&(window.clearInterval(this._animationTimer),this._animationTimer=null,this._frame=0)}},dimple.aggregateMethod.avg=function(a,b){return a.value=null===a.value||void 0===a.value?0:parseFloat(a.value),a.count=null===a.count||void 0===a.count?1:parseFloat(a.count),b.value=null===b.value||void 0===b.value?0:parseFloat(b.value),b.count=null===b.count||void 0===b.count?1:parseFloat(b.count),(a.value*a.count+b.value*b.count)/(a.count+b.count)},dimple.aggregateMethod.count=function(a,b){return a.count=null===a.count||void 0===a.count?0:parseFloat(a.count),b.count=null===b.count||void 0===b.count?0:parseFloat(b.count),a.count+b.count},dimple.aggregateMethod.max=function(a,b){return a.value=null===a.value||void 0===a.value?0:parseFloat(a.value),b.value=null===b.value||void 0===b.value?0:parseFloat(b.value),a.value>b.value?a.value:b.value},dimple.aggregateMethod.min=function(a,b){return null===a.value?parseFloat(b.value):parseFloat(a.value)=n[0][r]&&A[f]<=n[n.length-1][r]&&(p={},p[r]=A[f],p[s]=z[A[f]],o.push(p),n[g][r]>A[f]?B.push(p):(B.push(n[g]),z[A[f]]=n[g][s],g+=1));B=B.concat(o.reverse()).concat(B[0]),u[e].entry=G(d,"_previousOrigin")(B),u[e].update=G(d)(B),u[e].exit=G(d,"_origin")(B),u[e].color=a.getColor(u[e].key.length>0?u[e].key[u[e].key.length-1]:"All")}null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),v=null===b.shapes||void 0===b.shapes?a._group.selectAll("."+w).data(u):b.shapes.data(u,function(a){return a.key}),v.enter().append("path").attr("id",function(a){return a.key}).attr("class",function(a){return w+" dimple-line "+a.keyString}).attr("d",function(a){return a.entry}).call(function(){a.noFormats||this.attr("opacity",function(a){return y?1:a.color.opacity}).attr("fill",function(a){return y?"url(#fill-line-gradient-"+a.keyString+")":a.color.fill}).attr("stroke",function(a){return y?"url(#stroke-line-gradient-"+a.keyString+")":a.color.stroke}).attr("stroke-width",b.lineWeight)}).each(E),k=dimple._handleTransition(v,c).attr("d",function(a){return a.update}).each(E),l=dimple._handleTransition(v.exit(),c).attr("d",function(a){return a.exit}).each(E),dimple._postDrawHandling(b,k,l,c),b.shapes=v}},dimple.plot.area_old={stacked:!0,supportedAxes:["x","y","c"],draw:function(a,b,c){var d,e,f,g=this,h=b._positionData,i=[],j=1,k=!1,l="series"+a.series.indexOf(b),m={};null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),(b.x._hasCategories()||b.y._hasCategories())&&(j=0),h.forEach(function(a){var b,c=[],d=!1;for(b=j;b=0;i-=1)if(f=e[i],g={cx:0,cy:0,height:0,width:0,xOffset:0,yOffset:0},b.x._hasCategories()){if(g.cx=f.cx,g.width=f.width,g.xOffset=f.xOffset,void 0===m[f.xField])m[f.xField]=[];else{for(p=0,j=0;j<=m[f.xField].length;j+=1)l=m[f.xField][j],(f.cy>=0&&l>=0||f.cy<=0&&0>=l)&&Math.abs(l)<=Math.abs(f.cy)&&Math.abs(l)>Math.abs(p)&&(p=l);g.cy=p}o.push(g),m[f.xField].push(f.cy)}else if(b.y._hasCategories()){if(g.cy=f.cy,g.height=f.height,g.yOffset=f.yOffset,void 0===m[f.yField])m[f.yField]=[];else{for(p=0,k=0;k<=m[f.yField].length;k+=1)n=m[f.yField][k],(f.cx>=0&&n>=0||f.cx<=0&&0>=n)&&Math.abs(n)<=Math.abs(f.cx)&&Math.abs(n)>Math.abs(p)&&(p=n);g.cx=p}o.push(g),m[f.yField].push(f.cx)}return d(e.concat(o).concat(e[0]))}).call(function(){a.noFormats||this.attr("fill",function(b){return k?"url(#fill-area-gradient-"+b.join("_").replace(" ","")+")":a.getColor(b).fill}).attr("stroke",function(b){return k?"url(#stroke-area-gradient-"+b.join("_").replace(" ","")+")":a.getColor(b).stroke}).attr("stroke-width",b.lineWeight)}),b.lineMarkers&&(f=null===b._markerBacks||void 0===b._markerBacks?a._group.selectAll(".markerBacks."+l).data(h):b._markerBacks.data(h,function(a){return a.key}),f.enter().append("circle").attr("id",function(a){return a.key}).attr("class","markerBacks "+l).attr("cx",function(c){return dimple._helpers.cx(c,a,b)}).attr("cy",function(c){return dimple._helpers.cy(c,a,b)}).attr("r",0).attr("fill","white").attr("stroke","none"),f.transition().duration(c).attr("cx",function(c){return dimple._helpers.cx(c,a,b)}).attr("cy",function(c){return dimple._helpers.cy(c,a,b)}).attr("r",2+b.lineWeight),f.exit().transition().duration(c).attr("r",0).each("end",function(){d3.select(this).remove()}),b._markerBacks=f),e=null===b._markers||void 0===b._markers?a._group.selectAll(".markers."+l).data(h):b._markers.data(h,function(a){return a.key}),e.enter().append("circle").attr("id",function(a){return a.key}).attr("class","markers "+l).on("mouseover",function(c){g.enterEventHandler(c,this,a,b)}).on("mouseleave",function(c){g.leaveEventHandler(c,this,a,b)}).attr("cx",function(c){return dimple._helpers.cx(c,a,b)}).attr("cy",function(c){return dimple._helpers.cy(c,a,b)}).attr("r",0).attr("opacity",function(c){return b.lineMarkers?a.getColor(c).opacity:0}).call(function(){a.noFormats||this.attr("fill","white").style("stroke-width",b.lineWeight).attr("stroke",function(c){return k?dimple._helpers.fill(c,a,b):a.getColor(c.aggField[c.aggField.length-1]).stroke})}),e.transition().duration(c).attr("cx",function(c){return dimple._helpers.cx(c,a,b)}).attr("cy",function(c){return dimple._helpers.cy(c,a,b)}).attr("r",2+b.lineWeight).call(function(){a.noFormats||this.attr("fill","white").style("stroke-width",b.lineWeight).attr("stroke",function(c){return k?dimple._helpers.fill(c,a,b):a.getColor(c.aggField[c.aggField.length-1]).stroke})}),e.exit().transition().duration(c).attr("r",0).each("end",function(){d3.select(this).remove()}),b._markers=e},enterEventHandler:function(a,b,c,d){var e,f,g,h=5,i=10,j=750,k=d3.select(b),l=parseFloat(k.attr("cx")),m=parseFloat(k.attr("cy")),n=parseFloat(k.attr("r")),o=dimple._helpers.opacity(a,c,d),p=dimple._helpers.fill(a,c,d),q=d._dropLineOrigin(),r=d3.rgb(d3.rgb(p).r+.6*(255-d3.rgb(p).r),d3.rgb(p).g+.6*(255-d3.rgb(p).g),d3.rgb(p).b+.6*(255-d3.rgb(p).b)),s=d3.rgb(d3.rgb(p).r+.8*(255-d3.rgb(p).r),d3.rgb(p).g+.8*(255-d3.rgb(p).g),d3.rgb(p).b+.8*(255-d3.rgb(p).b)),t=0,u=0,v=0,w=[];null!==c._tooltipGroup&&void 0!==c._tooltipGroup&&c._tooltipGroup.remove(),c._tooltipGroup=c.svg.append("g"),k.style("opacity",1),c._tooltipGroup.append("circle").attr("cx",l).attr("cy",m).attr("r",n).attr("opacity",0).style("fill","none").style("stroke",p).style("stroke-width",1).transition().duration(j/2).ease("linear").attr("opacity",1).attr("r",n+4).style("stroke-width",2),null!==q.y&&c._tooltipGroup.append("line").attr("x1",l).attr("y1",m0&&d.categoryFields.forEach(function(b,c){null!==b&&void 0!==b&&null!==a.aggField[c]&&void 0!==a.aggField[c]&&w.push(b+(a.aggField[c]!==b?": "+a.aggField[c]:""))},this),d.x._hasTimeField()?null!==a.xField[0]&&void 0!==a.xField[0]&&w.push(d.x.timeField+": "+d.x._getFormat()(a.xField[0])):d.x._hasCategories()?d.x.categoryFields.forEach(function(b,c){null!==b&&void 0!==b&&null!==a.xField[c]&&void 0!==a.xField[c]&&w.push(b+(a.xField[c]!==b?": "+a.xField[c]:""))},this):null!==d.x.measure&&void 0!==d.x.measure&&null!==a.width&&void 0!==a.width&&w.push(d.x.measure+": "+d.x._getFormat()(a.width)),d.y._hasTimeField()?null!==a.yField[0]&&void 0!==a.yField[0]&&w.push(d.y.timeField+": "+d.y._getFormat()(a.yField[0])):d.y._hasCategories()?d.y.categoryFields.forEach(function(b,c){null!==b&&void 0!==b&&null!==a.yField[c]&&void 0!==a.yField[c]&&w.push(b+(a.yField[c]!==b?": "+a.yField[c]:""))},this):null!==d.y.measure&&void 0!==d.y.measure&&null!==a.height&&void 0!==a.height&&w.push(d.y.measure+": "+d.y._getFormat()(a.height)),null!==d.z&&void 0!==d.z&&null!==d.z.measure&&void 0!==d.z.measure&&null!==a.zValue&&void 0!==a.zValue&&w.push(d.z.measure+": "+d.z._getFormat()(a.zValue)),null!==d.c&&void 0!==d.c&&null!==d.c.measure&&void 0!==d.c.measure&&null!==a.cValue&&void 0!==a.cValue&&w.push(d.c.measure+": "+d.c._getFormat()(a.cValue)),w=w.filter(function(a,b){return w.indexOf(a)===b}),e.selectAll(".textHoverShapes").data(w).enter().append("text").attr("class","chartTooltip").text(function(a){return a}).style("font-family","sans-serif").style("font-size","10px"),e.each(function(){u=this.getBBox().width>u?this.getBBox().width:u,v=this.getBBox().width>v?this.getBBox().height:v}),e.selectAll("text").attr("x",0).attr("y",function(){return t+=this.getBBox().height,t-this.getBBox().height/2}),f.attr("x",-h).attr("y",-h).attr("height",Math.floor(t+h)-.5).attr("width",u+2*h).attr("rx",5).attr("ry",5).style("fill",s).style("stroke",r).style("stroke-width",2).style("opacity",.95),g=l+n+h+i+u>parseFloat(c.svg.node().getBBox().width),e.attr("transform","translate("+(g?l-(n+h+i+u):l+n+h+i)+" , "+(m-(t-(v-h))/2)+")")},leaveEventHandler:function(a,b,c,d){d3.select(b).style("opacity",d.lineMarkers?dimple._helpers.opacity(a,c,d):0),null!==c._tooltipGroup&&void 0!==c._tooltipGroup&&c._tooltipGroup.remove()}},dimple.plot.bar={stacked:!0,supportedAxes:["x","y","c"],draw:function(a,b,c){var d,e,f=b._positionData,g=null,h=["dimple-series-"+a.series.indexOf(b),"dimple-bar"],i=!b.stacked&&b.x._hasMeasure(),j=!b.stacked&&b.y._hasMeasure();null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),g=null===b.shapes||void 0===b.shapes?a._group.selectAll("."+h.join(".")).data(f):b.shapes.data(f,function(a){return a.key}),g.enter().append("rect").attr("id",function(a){return a.key}).attr("class",function(a){var b=[];return b=b.concat(a.aggField),b=b.concat(a.xField),b=b.concat(a.yField),h.join(" ")+" "+dimple._createClass(b)}).attr("x",function(c){return dimple._helpers.x(c,a,b)}).attr("y",function(c){return dimple._helpers.y(c,a,b)+dimple._helpers.height(c,a,b)}).attr("width",function(c){return null!==c.xField&&c.xField.length>0?dimple._helpers.width(c,a,b):0}).attr("height",function(c){return null!==c.yField&&c.yField.length>0?dimple._helpers.height(c,a,b):0}).attr("opacity",function(c){return dimple._helpers.opacity(c,a,b)}).on("mouseover",function(c){dimple._showBarTooltip(c,this,a,b)}).on("mouseleave",function(c){dimple._removeTooltip(c,this,a,b)}).call(function(){a.noFormats||this.attr("fill",function(c){return dimple._helpers.fill(c,a,b)}).attr("stroke",function(c){return dimple._helpers.stroke(c,a,b)})}),d=dimple._handleTransition(g,c).attr("x",function(c){return i?dimple._helpers.cx(c,a,b)-b.x.floatingBarWidth/2:dimple._helpers.x(c,a,b)}).attr("y",function(c){return j?dimple._helpers.cy(c,a,b)-b.y.floatingBarWidth/2:dimple._helpers.y(c,a,b)}).attr("width",function(c){return i?b.x.floatingBarWidth:dimple._helpers.width(c,a,b)}).attr("height",function(c){return j?b.y.floatingBarWidth:dimple._helpers.height(c,a,b)}).call(function(){a.noFormats||this.attr("fill",function(c){return dimple._helpers.fill(c,a,b)}).attr("stroke",function(c){return dimple._helpers.stroke(c,a,b)})}),e=dimple._handleTransition(g.exit(),c).attr("x",function(c){return dimple._helpers.x(c,a,b)}).attr("y",function(c){return dimple._helpers.y(c,a,b)+dimple._helpers.height(c,a,b)}).attr("width",function(c){return null!==c.xField&&c.xField.length>0?dimple._helpers.width(c,a,b):0}).attr("height",function(c){return null!==c.yField&&c.yField.length>0?dimple._helpers.height(c,a,b):0}),dimple._postDrawHandling(b,d,e,c),b.shapes=g}},dimple.plot.bubble={stacked:!1,supportedAxes:["x","y","z","c"],draw:function(a,b,c){var d,e,f=b._positionData,g=null,h=["dimple-series-"+a.series.indexOf(b),"dimple-bubble"];null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),g=null===b.shapes||void 0===b.shapes?a._group.selectAll("."+h.join(".")).data(f):b.shapes.data(f,function(a){return a.key}),g.enter().append("circle").attr("id",function(a){return a.key}).attr("class",function(a){var b=[];return b=b.concat(a.aggField),b=b.concat(a.xField),b=b.concat(a.yField),b=b.concat(a.zField),h.join(" ")+" "+dimple._createClass(b)}).attr("cx",function(c){return b.x._hasCategories()?dimple._helpers.cx(c,a,b):b.x._previousOrigin}).attr("cy",function(c){return b.y._hasCategories()?dimple._helpers.cy(c,a,b):b.y._previousOrigin}).attr("r",0).attr("opacity",function(c){return dimple._helpers.opacity(c,a,b)}).on("mouseover",function(c){dimple._showPointTooltip(c,this,a,b)}).on("mouseleave",function(c){dimple._removeTooltip(c,this,a,b)}).call(function(){a.noFormats||this.attr("fill",function(c){return dimple._helpers.fill(c,a,b)}).attr("stroke",function(c){return dimple._helpers.stroke(c,a,b)})}),d=dimple._handleTransition(g,c).attr("cx",function(c){return dimple._helpers.cx(c,a,b)}).attr("cy",function(c){return dimple._helpers.cy(c,a,b)}).attr("r",function(c){return dimple._helpers.r(c,a,b)}).call(function(){a.noFormats||this.attr("fill",function(c){return dimple._helpers.fill(c,a,b)}).attr("stroke",function(c){return dimple._helpers.stroke(c,a,b)})}),e=dimple._handleTransition(g.exit(),c).attr("r",0).attr("cx",function(c){return b.x._hasCategories()?dimple._helpers.cx(c,a,b):b.x._origin}).attr("cy",function(c){return b.y._hasCategories()?dimple._helpers.cy(c,a,b):b.y._origin}),dimple._postDrawHandling(b,d,e,c),b.shapes=g}},dimple.plot.line={stacked:!1,supportedAxes:["x","y","c"],draw:function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n=b._positionData,o=[],p=null,q="dimple-series-"+a.series.indexOf(b),r=b.x._hasCategories()||b.y._hasCategories()?0:1,s=!1,t=function(){return function(a,b,c,d){d3.select(b).style("opacity",1),dimple._showPointTooltip(a,b,c,d)}},u=function(a){return function(b,c,d,e){d3.select(c).style("opacity",e.lineMarkers||a.data.length<2?dimple._helpers.opacity(b,d,e):0),dimple._removeTooltip(b,c,d,e)}},v=function(d){dimple._drawMarkers(d,a,b,c,q,s,t(d),u(d))},w=function(c,d){var e;return"step"===b.interpolation&&b[c]._hasCategories()?(b.barGap=0,b.clusterBarGap=0,e=dimple._helpers[c](d,a,b)+("y"===c?dimple._helpers.height(d,a,b):0)):e=dimple._helpers["c"+c](d,a,b),e},x=function(a,c){return d3.svg.line().x(function(a){return b.x._hasCategories()||!c?w("x",a):b.x[c]}).y(function(a){return b.y._hasCategories()||!c?w("y",a):b.y[c]}).interpolate(a)};for(d="step"===b.interpolation?"step-after":b.interpolation,l=dimple._getSeriesOrder(b.data||a.data,b),b.c&&(b.x._hasCategories()&&b.y._hasMeasure()||b.y._hasCategories()&&b.x._hasMeasure())&&(s=!0),e=0;e0?o[e].key[o[e].key.length-1]:"All");null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),p=null===b.shapes||void 0===b.shapes?a._group.selectAll("."+q).data(o):b.shapes.data(o,function(a){return a.key}),p.enter().append("path").attr("id",function(a){return a.key}).attr("class",function(a){return q+" dimple-line "+a.keyString}).attr("d",function(a){return a.entry}).call(function(){a.noFormats||this.attr("opacity",function(a){return s?1:a.color.opacity}).attr("fill","none").attr("stroke",function(a){return s?"url(#fill-line-gradient-"+a.keyString+")":a.color.stroke}).attr("stroke-width",b.lineWeight)}).each(v),j=dimple._handleTransition(p,c).attr("d",function(a){return a.update}).each(v),k=dimple._handleTransition(p.exit(),c).attr("d",function(a){return a.exit}).each(v),dimple._postDrawHandling(b,j,k,c),b.shapes=p}},dimple._addGradient=function(a,b,c,d,e,f,g){var h=[].concat(a),i=e._group.select("#"+b),j=[],k=c.position+"Field",l=!0,m=[];d.forEach(function(a){-1===j.indexOf(a[k])&&a.aggField.join("_")===h.join("_")&&j.push(a[k])},this),j=j.sort(function(a,b){return c._scale(a)-c._scale(b)}),null===i.node()&&(l=!1,i=e._group.append("linearGradient").attr("id",b).attr("gradientUnits","userSpaceOnUse").attr("x1","x"===c.position?c._scale(j[0])+e._widthPixels()/j.length/2:0).attr("y1","y"===c.position?c._scale(j[0])-e._heightPixels()/j.length/2:0).attr("x2","x"===c.position?c._scale(j[j.length-1])+e._widthPixels()/j.length/2:0).attr("y2","y"===c.position?c._scale(j[j.length-1])-e._heightPixels()/j.length/2:0)),j.forEach(function(a,b){var c={},e=0;for(e=0;e=65&&90>=b&&(c=a.toLowerCase()),c};for(b=0;b=1&&(i.forEach(function(a){var b=null===a.desc||void 0===a.desc?!1:a.desc,c=a.ordering,d=[],f="string"==typeof c?c:null,h=function(a){var b,c=0;for(b=0;bb[0]&&(c=1):c=Date.parse(a[0])-Date.parse(b[0]):c=parseFloat(d)-parseFloat(e),c};"function"==typeof c?e.push(function(a,d){return(b?-1:1)*c(a,d)}):c instanceof Array?(c.forEach(function(a){d.push([].concat(a).join("|"))},this),e.push(function(a,c){var e,f,h,i="",j="";for(h=0;h0&&(i+="|",j+="|"),i+=a[g[h]],j+=c[g[h]];return e=d.indexOf(i),f=d.indexOf(j),e=0>e?b?-1:d.length:e,f=0>f?b?-1:d.length:f,(b?-1:1)*(e-f)})):e.push(function(a,c){var d=0;return void 0!==a[f]&&void 0!==c[f]&&(d=i([].concat(a[f]),[].concat(c[f]))),(b?-1:1)*d})}),d.sort(function(a,b){for(var c=0,d=0;c0&&(null!==b.c&&void 0!==b.c&&b.c._hasMeasure()&&c.push({ordering:b.c.measure,desc:!0}),b.x._hasMeasure()&&c.push({ordering:b.x.measure,desc:!0}),b.y._hasMeasure()&&c.push({ordering:b.y.measure,desc:!0}),e=dimple._getOrderedList(a,d,c)),e},dimple._getSeriesSortPredicate=function(a,b,c){return function(d,e){var f=0;return b.x._hasCategories()?f=dimple._helpers.cx(d,a,b)=2?c.x._scale(a.cx)+dimple._helpers.xGap(b,c)+(a.xOffset+.5)*(b._widthPixels()/c.x._max-2*dimple._helpers.xGap(b,c))*a.width:c.x._scale(a.cx)+b._widthPixels()/c.x._max/2},cy:function(a,b,c){var d=0;return d=null!==c.y.measure&&void 0!==c.y.measure?c.y._scale(a.cy):null!==c.y.categoryFields&&void 0!==c.y.categoryFields&&c.y.categoryFields.length>=2?c.y._scale(a.cy)-b._heightPixels()/c.y._max+dimple._helpers.yGap(b,c)+(a.yOffset+.5)*(b._heightPixels()/c.y._max-2*dimple._helpers.yGap(b,c))*a.height:c.y._scale(a.cy)-b._heightPixels()/c.y._max/2},r:function(a,b,c){var d=0;return d=null===c.z||void 0===c.z?5:c.z._hasMeasure()?c.z._scale(a.r):c.z._scale(b._heightPixels()/100)},xGap:function(a,b){var c=0;return(null===b.x.measure||void 0===b.x.measure)&&b.barGap>0&&(c=a._widthPixels()/b.x._max*(b.barGap>.99?.99:b.barGap)/2),c -},xClusterGap:function(a,b,c){var d=0;return null!==c.x.categoryFields&&void 0!==c.x.categoryFields&&c.x.categoryFields.length>=2&&c.clusterBarGap>0&&!c.x._hasMeasure()&&(d=a.width*(b._widthPixels()/c.x._max-2*dimple._helpers.xGap(b,c))*(c.clusterBarGap>.99?.99:c.clusterBarGap)/2),d},yGap:function(a,b){var c=0;return(null===b.y.measure||void 0===b.y.measure)&&b.barGap>0&&(c=a._heightPixels()/b.y._max*(b.barGap>.99?.99:b.barGap)/2),c},yClusterGap:function(a,b,c){var d=0;return null!==c.y.categoryFields&&void 0!==c.y.categoryFields&&c.y.categoryFields.length>=2&&c.clusterBarGap>0&&!c.y._hasMeasure()&&(d=a.height*(b._heightPixels()/c.y._max-2*dimple._helpers.yGap(b,c))*(c.clusterBarGap>.99?.99:c.clusterBarGap)/2),d},x:function(a,b,c){var d=0;return d=c.x._hasTimeField()?c.x._scale(a.x)-dimple._helpers.width(a,b,c)/2:null!==c.x.measure&&void 0!==c.x.measure?c.x._scale(a.x):c.x._scale(a.x)+dimple._helpers.xGap(b,c)+a.xOffset*(dimple._helpers.width(a,b,c)+2*dimple._helpers.xClusterGap(a,b,c))+dimple._helpers.xClusterGap(a,b,c)},y:function(a,b,c){var d=0;return d=c.y._hasTimeField()?c.y._scale(a.y)-dimple._helpers.height(a,b,c)/2:null!==c.y.measure&&void 0!==c.y.measure?c.y._scale(a.y):c.y._scale(a.y)-b._heightPixels()/c.y._max+dimple._helpers.yGap(b,c)+a.yOffset*(dimple._helpers.height(a,b,c)+2*dimple._helpers.yClusterGap(a,b,c))+dimple._helpers.yClusterGap(a,b,c)},width:function(a,b,c){var d=0;return d=null!==c.x.measure&&void 0!==c.x.measure?Math.abs(c.x._scale(a.x<0?a.x-a.width:a.x+a.width)-c.x._scale(a.x)):c.x._hasTimeField()?c.x.floatingBarWidth:a.width*(b._widthPixels()/c.x._max-2*dimple._helpers.xGap(b,c))-2*dimple._helpers.xClusterGap(a,b,c)},height:function(a,b,c){var d=0;return d=c.y._hasTimeField()?c.y.floatingBarWidth:null!==c.y.measure&&void 0!==c.y.measure?Math.abs(c.y._scale(a.y)-c.y._scale(a.y<=0?a.y+a.height:a.y-a.height)):a.height*(b._heightPixels()/c.y._max-2*dimple._helpers.yGap(b,c))-2*dimple._helpers.yClusterGap(a,b,c)},opacity:function(a,b,c){var d=0;return d=null!==c.c&&void 0!==c.c?a.opacity:b.getColor(a.aggField.slice(-1)[0]).opacity},fill:function(a,b,c){var d=0;return d=null!==c.c&&void 0!==c.c?a.fill:b.getColor(a.aggField.slice(-1)[0]).fill},stroke:function(a,b,c){var d=0;return d=null!==c.c&&void 0!==c.c?a.stroke:b.getColor(a.aggField.slice(-1)[0]).stroke}},dimple._parentHeight=function(a){var b=a.offsetHeight;return(0>=b||null===b||void 0===b)&&(b=a.clientHeight),(0>=b||null===b||void 0===b)&&(b=null===a.parentNode||void 0===a.parentNode?0:dimple._parentHeight(a.parentNode)),b},dimple._parentWidth=function(a){var b=a.offsetWidth;return(0>=b||null===b||void 0===b)&&(b=a.clientWidth),(0>=b||null===b||void 0===b)&&(b=null===a.parentNode||void 0===a.parentNode?0:dimple._parentWidth(a.parentNode)),b},dimple._parseXPosition=function(a,b){var c,d=0;return null!==a&&void 0!==a&&(c=a.toString().split(","),c.forEach(function(c){void 0!==c&&null!==c&&(isNaN(c)?"%"===c.slice(-1)?d+=dimple._parentWidth(b)*(parseFloat(c.slice(0,c.length-1))/100):"px"===c.slice(-2)?d+=parseFloat(c.slice(0,c.length-2)):d=a:d+=parseFloat(c))},this)),d},dimple._parseYPosition=function(a,b){var c,d=0;return null!==a&&void 0!==a&&(c=a.toString().split(","),c.forEach(function(c){void 0!==c&&null!==c&&(isNaN(c)?"%"===c.slice(-1)?d+=dimple._parentHeight(b)*(parseFloat(c.slice(0,c.length-1))/100):"px"===c.slice(-2)?d+=parseFloat(c.slice(0,c.length-2)):d=a:d+=parseFloat(c))},this)),d},dimple._postDrawHandling=function(a,b,c,d){0===d?(b.each(function(b,c){null!==a.afterDraw&&void 0!==a.afterDraw&&a.afterDraw(this,b,c)}),c.remove()):(b.each("end",function(b,c){null!==a.afterDraw&&void 0!==a.afterDraw&&a.afterDraw(this,b,c)}),c.each("end",function(){d3.select(this).remove()}))},dimple._removeTooltip=function(a,b,c){c._tooltipGroup&&c._tooltipGroup.remove()},dimple._rollUp=function(a,b,c){var d=[];return b=null!==b&&void 0!==b?[].concat(b):[],a.forEach(function(a){var e=-1,f={},g=!0;d.forEach(function(c,d){-1===e&&(g=!0,b.forEach(function(b){g=g&&a[b]===c[b]},this),g&&(e=d))},this),-1!==e?f=d[e]:(b.forEach(function(b){f[b]=a[b]},this),d.push(f),e=d.length-1),c.forEach(function(c){-1===b.indexOf(c)&&(void 0===f[c]&&(f[c]=[]),f[c]=f[c].concat(a[c]))},this),d[e]=f},this),d},dimple._showBarTooltip=function(a,b,c,d){var e,f,g,h,i,j=5,k=10,l=750,m=d3.select(b),n=parseFloat(m.attr("x")),o=parseFloat(m.attr("y")),p=parseFloat(m.attr("width")),q=parseFloat(m.attr("height")),r=m.attr("opacity"),s=m.attr("fill"),t=d._dropLineOrigin(),u=d3.rgb(d3.rgb(s).r+.6*(255-d3.rgb(s).r),d3.rgb(s).g+.6*(255-d3.rgb(s).g),d3.rgb(s).b+.6*(255-d3.rgb(s).b)),v=d3.rgb(d3.rgb(s).r+.8*(255-d3.rgb(s).r),d3.rgb(s).g+.8*(255-d3.rgb(s).g),d3.rgb(s).b+.8*(255-d3.rgb(s).b)),w=d.getTooltipText(a),x=0,y=0,z=0;null!==c._tooltipGroup&&void 0!==c._tooltipGroup&&c._tooltipGroup.remove(),c._tooltipGroup=c.svg.append("g"),i=d.stacked?1:p/2,d.x._hasCategories()||null===t.y||c._tooltipGroup.append("line").attr("x1",ny?this.getBBox().width:y,z=this.getBBox().width>z?this.getBBox().height:z}),e.selectAll("text").attr("x",0).attr("y",function(){return x+=this.getBBox().height,x-this.getBBox().height/2}),f.attr("x",-j).attr("y",-j).attr("height",Math.floor(x+j)-.5).attr("width",y+2*j).attr("rx",5).attr("ry",5).style("fill",v).style("stroke",u).style("stroke-width",2).style("opacity",.95),n+p+j+k+y0?(g=n-(j+k+y),h=o+q/2-(x-(z-j))/2):o+q+x+k+j0?g:k,g=g+y0?g:k,g=g+yv?this.getBBox().width:v,w=this.getBBox().width>w?this.getBBox().height:w}),e.selectAll("text").attr("x",0).attr("y",function(){return u+=this.getBBox().height,u-this.getBBox().height/2}),f.attr("x",-i).attr("y",-i).attr("height",Math.floor(u+i)-.5).attr("width",v+2*i).attr("rx",5).attr("ry",5).style("fill",t).style("stroke",s).style("stroke-width",2).style("opacity",.95),m+o+i+j+v0?(g=m-o-(i+j+v),h=n-(u-(w-i))/2):n+o+u+j+i0?g:j,g=g+v0?g:j,g=g+v-1&&d.push(a)},this)),d},dimple.getUniqueValues=function(a,b){var c=[];return null!==b&&void 0!==b&&(b=[].concat(b),a.forEach(function(a){var d="";b.forEach(function(b,c){c>0&&(d+="/"),d+=a[b]},this),-1===c.indexOf(d)&&c.push(d)},this)),c},dimple.newSvg=function(a,b,c){var d=null;if((null===a||void 0===a)&&(a="body"),d=d3.select(a),d.empty())throw"The '"+a+"' selector did not match any elements. Please prefix with '#' to select by id or '.' to select by class";return d.append("svg").attr("width",b).attr("height",c)}}(); \ No newline at end of file +var dimple={version:"1.2.0",plot:{},aggregateMethod:{}};!function(){"use strict";dimple.axis=function(a,b,c,d,e){this.chart=a,this.position=b,this.categoryFields=null===e||void 0===e?c:[].concat(e),this.measure=d,this.timeField=e,this.floatingBarWidth=5,this.hidden=!1,this.showPercent=!1,this.colors=null,this.overrideMin=null,this.overrideMax=null,this.shapes=null,this.showGridlines=null,this.gridlineShapes=null,this.titleShape=null,this.dateParseFormat=null,this.tickFormat=null,this.timePeriod=null,this.timeInterval=1,this.useLog=!1,this.logBase=10,this.title=void 0,this.clamp=!0,this.ticks=null,this._slaves=[],this._scale=null,this._min=0,this._max=0,this._previousOrigin=null,this._origin=null,this._orderRules=[],this._groupOrderRules=[],this._draw=null,this._getAxisData=function(){var a,b,c=[],d=!1;if(this.chart&&this.chart.series){for(a=0;a0?c=c.concat(b.data):d=!0);d&&this.chart.data&&(c=c.concat(this.chart.data))}return c},this._getFormat=function(){var a,b,c,d,e,f,g;return null!==this.tickFormat&&void 0!==this.tickFormat?a=this._hasTimeField()?d3.time.format(this.tickFormat):d3.format(this.tickFormat):this.showPercent?a=d3.format("%"):this.useLog&&null!==this.measure?a=function(a){var b=Math.floor(Math.abs(a),0).toString().length,c=Math.min(Math.floor((b-1)/3),4),d="kmBT".substring(c-1,c),e="0"===Math.round(10*(a/Math.pow(1e3,c))).toString().slice(-1)?0:1;return 0===a?0:d3.format(",."+e+"f")(a/Math.pow(1e3,c))+d}:null!==this.measure?(b=Math.floor(Math.abs(this._max),0).toString(),c=Math.floor(Math.abs(this._min),0).toString(),d=Math.max(c.length,b.length),d>3?(e=Math.min(Math.floor((d-1)/3),4),f="kmBT".substring(e-1,e),g=1>=d-3*e?1:0,a=function(a){return 0===a?0:d3.format(",."+g+"f")(a/Math.pow(1e3,e))+f}):(g=1>=d?1:0,a=d3.format(",."+g+"f"))):a=function(a){return a},a},this._getTimePeriod=function(){var a=this.timePeriod,b=30,c=this._max-this._min;return this._hasTimeField()&&!this.timePeriod&&(a=b>=c/1e3?d3.time.seconds:b>=c/6e4?d3.time.minutes:b>=c/36e5?d3.time.hours:b>=c/864e5?d3.time.days:b>=c/6048e5?d3.time.weeks:b>=c/26298e5?d3.time.months:d3.time.years),a},this._getTooltipText=function(a,b){if(this._hasTimeField())b[this.position+"Field"][0]&&a.push(this.timeField+": "+this._getFormat()(b[this.position+"Field"][0]));else if(this._hasCategories())this.categoryFields.forEach(function(c,d){null!==c&&void 0!==c&&b[this.position+"Field"][d]&&a.push(c+(b[this.position+"Field"][d]!==c?": "+b[this.position+"Field"][d]:""))},this);else if(this._hasMeasure())switch(this.position){case"x":a.push(this.measure+": "+this._getFormat()(b.width));break;case"y":a.push(this.measure+": "+this._getFormat()(b.height));break;case"z":a.push(this.measure+": "+this._getFormat()(b.zValue));break;case"c":a.push(this.measure+": "+this._getFormat()(b.cValue))}},this._getTopMaster=function(){var a=this;return null!==this.master&&void 0!==this.master&&(a=this.master._getTopMaster()),a},this._hasCategories=function(){return null!==this.categoryFields&&void 0!==this.categoryFields&&this.categoryFields.length>0},this._hasMeasure=function(){return null!==this.measure&&void 0!==this.measure},this._hasTimeField=function(){return null!==this.timeField&&void 0!==this.timeField},this._parseDate=function(a){var b;return b=null===this.dateParseFormat||void 0===this.dateParseFormat?isNaN(a)?Date.parse(a):new Date(a):d3.time.format(this.dateParseFormat).parse(a)},this._update=function(a){var b,c,d,e,f=[],g=this.ticks||10,h=function(a,b,c){var d,e,f=a.categoryFields[0],g=a._getAxisData(),h=f,i=!1,j=!0,k=null;for(d=0;d1?1:this._max,this._min=null!==this.overrideMin?this.overrideMin:this._min,this._max=null!==this.overrideMax?this.overrideMax:this._max,"x"===this.position&&null===this._scale){if(this._hasTimeField()?this._scale=d3.time.scale().rangeRound([this.chart._xPixels(),this.chart._xPixels()+this.chart._widthPixels()]).domain([this._min,this._max]).clamp(this.clamp):this.useLog?this._scale=d3.scale.log().range([this.chart._xPixels(),this.chart._xPixels()+this.chart._widthPixels()]).domain([0===this._min?Math.pow(this.logBase,-1):this._min,0===this._max?-1*Math.pow(this.logBase,-1):this._max]).clamp(this.clamp).base(this.logBase).nice():null===this.measure||void 0===this.measure?(f=h(this,"x","y"),null!==this._slaves&&void 0!==this._slaves&&this._slaves.forEach(function(a){f=f.concat(h(a,"x","y"))},this),this._scale=d3.scale.ordinal().rangePoints([this.chart._xPixels(),this.chart._xPixels()+this.chart._widthPixels()]).domain(f.concat([""]))):this._scale=d3.scale.linear().range([this.chart._xPixels(),this.chart._xPixels()+this.chart._widthPixels()]).domain([this._min,this._max]).clamp(this.clamp).nice(),!this.hidden)switch(this.chart._axisIndex(this,"x")){case 0:this._draw=d3.svg.axis().orient("bottom").scale(this._scale),this.ticks&&this._draw.ticks(g);break;case 1:this._draw=d3.svg.axis().orient("top").scale(this._scale),this.ticks&&this._draw.ticks(g)}}else if("y"===this.position&&null===this._scale){if(this._hasTimeField()?this._scale=d3.time.scale().rangeRound([this.chart._yPixels()+this.chart._heightPixels(),this.chart._yPixels()]).domain([this._min,this._max]).clamp(this.clamp):this.useLog?this._scale=d3.scale.log().range([this.chart._yPixels()+this.chart._heightPixels(),this.chart._yPixels()]).domain([0===this._min?Math.pow(this.logBase,-1):this._min,0===this._max?-1*Math.pow(this.logBase,-1):this._max]).clamp(this.clamp).base(this.logBase).nice():null===this.measure||void 0===this.measure?(f=h(this,"y","x"),null!==this._slaves&&void 0!==this._slaves&&this._slaves.forEach(function(a){f=f.concat(h(a,"y","x"))},this),this._scale=d3.scale.ordinal().rangePoints([this.chart._yPixels()+this.chart._heightPixels(),this.chart._yPixels()]).domain(f.concat([""]))):this._scale=d3.scale.linear().range([this.chart._yPixels()+this.chart._heightPixels(),this.chart._yPixels()]).domain([this._min,this._max]).clamp(this.clamp).nice(),!this.hidden)switch(this.chart._axisIndex(this,"y")){case 0:this._draw=d3.svg.axis().orient("left").scale(this._scale),this.ticks&&this._draw.ticks(g);break;case 1:this._draw=d3.svg.axis().orient("right").scale(this._scale),this.ticks&&this._draw.ticks(g)}}else this.position.length>0&&"z"===this.position[0]&&null===this._scale?this._scale=this.useLog?d3.scale.log().range([this.chart._heightPixels()/300,this.chart._heightPixels()/10]).domain([0===this._min?Math.pow(this.logBase,-1):this._min,0===this._max?-1*Math.pow(this.logBase,-1):this._max]).clamp(this.clamp).base(this.logBase):d3.scale.linear().range([this.chart._heightPixels()/300,this.chart._heightPixels()/10]).domain([this._min,this._max]).clamp(this.clamp):this.position.length>0&&"c"===this.position[0]&&null===this._scale&&(this._scale=d3.scale.linear().range([0,null===this.colors||1===this.colors.length?1:this.colors.length-1]).domain([this._min,this._max]).clamp(this.clamp));return null!==this._slaves&&void 0!==this._slaves&&this._slaves.length>0&&this._slaves.forEach(function(a){a._scale=this._scale},this),null!==a&&void 0!==a&&a!==!1||this._hasTimeField()||null===this._scale||null===this._scale.ticks||void 0===this._scale.ticks||!(this._scale.ticks(g).length>0)||"x"!==this.position&&"y"!==this.position||(b=this._scale.ticks(g),c=b[1]-b[0],d=((this._max-this._min)%c).toFixed(0),0!==d&&(this._max=Math.ceil(this._max/c)*c,this._min=Math.floor(this._min/c)*c,this._update(!0))),e=null!==f&&void 0!==f&&f.length>0?this._scale.copy()(f[0]):this._min>0?this._scale.copy()(this._min):this._max<0?this._scale.copy()(this._max):this._scale.copy()(0),this._origin!==e&&(this._previousOrigin=null===this._origin?e:this._origin,this._origin=e),this},this.addGroupOrderRule=function(a,b){this._groupOrderRules.push({ordering:a,desc:b})},this.addOrderRule=function(a,b){this._orderRules.push({ordering:a,desc:b})}},dimple.chart=function(a,b){this.svg=a,this.x="10%",this.y="10%",this.width="80%",this.height="80%",this.data=b,this.noFormats=!1,this.axes=[],this.series=[],this.legends=[],this.storyboard=null,this.titleShape=null,this.shapes=null,this._group=a.append("g"),this._tooltipGroup=null,this._assignedColors={},this._nextColor=0,this._axisIndex=function(a,b){var c=0,d=0,e=-1;for(c=0;c0&&(a=a.concat(this.data)),null!==this.series&&void 0!==this.series&&this.series.length>0&&this.series.forEach(function(b){null!==b.data&&void 0!==b.data&&b.data.length>0&&(a=a.concat(b.data))}),a},this._getSeriesData=function(){null!==this.series&&void 0!==this.series&&this.series.forEach(function(a){var b,c,d=[],e=function(a,b){var c=[];return null!==a&&(a._hasTimeField()?c.push(a._parseDate(b[a.timeField])):a._hasCategories()&&a.categoryFields.forEach(function(a){c.push(b[a])},this)),c},f={x:!1,y:!1,z:!1,c:!1},g={x:[],y:[]},h={x:[],y:[],z:[]},i={min:null,max:null},j={x:[],y:[],z:[]},k=[],l={},m={x:0,y:0,z:0},n="",o=[],p=[],q=[],r="",s=[],t="",u=[],v=[],w=a.data||this.data,x=[];null!==this.storyboard&&void 0!==this.storyboard&&this.storyboard.categoryFields.length>0&&(n=this.storyboard.categoryFields[0],o=dimple._getOrderedList(w,n,this.storyboard._orderRules)),a.x._hasCategories()&&a.x._hasMeasure()&&(r=a.x.categoryFields[0],s=dimple._getOrderedList(w,r,a.x._orderRules.concat([{ordering:a.x.measure,desc:!0}]))),a.y._hasCategories()&&a.y._hasMeasure()&&(t=a.y.categoryFields[0],u=dimple._getOrderedList(w,t,a.y._orderRules.concat([{ordering:a.y.measure,desc:!0}]))),null!==a.categoryFields&&void 0!==a.categoryFields&&a.categoryFields.length>0&&(v=[].concat(a._orderRules),p=[],a.categoryFields.forEach(function(a){void 0!==w[0][a]&&p.push(a)},this),null!==a.c&&void 0!==a.c&&a.c._hasMeasure()?v.push({ordering:a.c.measure,desc:!0}):null!==a.z&&void 0!==a.z&&a.z._hasMeasure()?v.push({ordering:a.z.measure,desc:!0}):a.x._hasMeasure()?v.push({ordering:a.x.measure,desc:!0}):a.y._hasMeasure()&&v.push({ordering:a.y.measure,desc:!0}),q=dimple._getOrderedList(w,p,v)),w.sort(function(a,b){var c,d,e,f,g,h,i=0;if(""!==n&&(i=o.indexOf(a[n])-o.indexOf(b[n])),""!==r&&0===i&&(i=s.indexOf(a[r])-s.indexOf(b[r])),""!==t&&0===i&&(i=u.indexOf(a[t])-u.indexOf(b[t])),p&&p.length>0&&0===i)for(c=[].concat(p),i=0,e=0;e0&&(m+="/"),m+=b[a],i=m===g},this)),null!==c&&void 0!==c&&i&&(h=d[k],c._hasMeasure()&&null!==b[c.measure]&&void 0!==b[c.measure]&&(-1===h[c.position+"ValueList"].indexOf(b[c.measure])&&h[c.position+"ValueList"].push(b[c.measure]),isNaN(parseFloat(b[c.measure]))&&(f[c.position]=!0),j.value=h[c.position+"Value"],j.count=h[c.position+"Count"],l.value=b[c.measure],h[c.position+"Value"]=a.aggregate(j,l),h[c.position+"Count"]+=1))},j(a.x,this.storyboard),j(a.y,this.storyboard),j(a.z,this.storyboard),j(a.c,this.storyboard)},this),null!==a.x&&void 0!==a.x&&a.x._hasCategories()&&a.x.categoryFields.length>1&&void 0!==g.x&&(x=[],a.y._hasMeasure()&&x.push({ordering:a.y.measure,desc:!0}),g.x=dimple._getOrderedList(w,a.x.categoryFields[1],a.x._groupOrderRules.concat(x))),null!==a.y&&void 0!==a.y&&a.y._hasCategories()&&a.y.categoryFields.length>1&&void 0!==g.y&&(x=[],a.x._hasMeasure()&&x.push({ordering:a.x.measure,desc:!0}),g.y=dimple._getOrderedList(w,a.y.categoryFields[1],a.y._groupOrderRules.concat(x)),g.y.reverse()),d.forEach(function(c){null!==a.x&&(f.x===!0&&(c.xValue=c.xValueList.length),b=(null===h.x[c.xField.join("/")]||void 0===h.x[c.xField.join("/")]?0:h.x[c.xField.join("/")])+(a.y._hasMeasure()?Math.abs(c.yValue):0),h.x[c.xField.join("/")]=b),null!==a.y&&(f.y===!0&&(c.yValue=c.yValueList.length),b=(null===h.y[c.yField.join("/")]||void 0===h.y[c.yField.join("/")]?0:h.y[c.yField.join("/")])+(a.x._hasMeasure()?Math.abs(c.xValue):0),h.y[c.yField.join("/")]=b),null!==a.z&&(f.z===!0&&(c.zValue=c.zValueList.length),b=(null===h.z[c.zField.join("/")]||void 0===h.z[c.zField.join("/")]?0:h.z[c.zField.join("/")])+(a.z._hasMeasure()?Math.abs(c.zValue):0),h.z[c.zField.join("/")]=b),null!==a.c&&((null===i.min||c.cValuei.max)&&(i.max=c.cValue))},this);for(c in h.x)h.x.hasOwnProperty(c)&&(m.x+=h.x[c]);for(c in h.y)h.y.hasOwnProperty(c)&&(m.y+=h.y[c]);for(c in h.z)h.z.hasOwnProperty(c)&&(m.z+=h.z[c]);d.forEach(function(b){var c,d,e,f,n,o=function(c,d,e){var f,i,n,o,p;null!==c&&void 0!==c&&(o=c.position,c._hasCategories()?c._hasMeasure()?(f=b[c.position+"Field"].join("/"),i=c.showPercent?h[c.position][f]/m[c.position]:h[c.position][f],-1===k.indexOf(f)&&(l[f]=i+(k.length>0?l[k[k.length-1]]:0),k.push(f)),n=b[o+"Bound"]=b["c"+o]="x"!==o&&"y"!==o||!a._isStacked()?i:l[f],b[e]=i,b[o]=n-("x"===o&&i>=0||"y"===o&&0>=i?i:0)):(b[o]=b["c"+o]=b[o+"Field"][0],b[e]=1,void 0!==g[o]&&null!==g[o]&&g[o].length>=2&&(b[o+"Offset"]=g[o].indexOf(b[o+"Field"][1]),b[e]=1/g[o].length)):(i=c.showPercent?b[o+"Value"]/h[d][b[d+"Field"].join("/")]:b[o+"Value"],f=b[d+"Field"].join("/")+(b[o+"Value"]>=0),p=j[o][f]=(null===j[o][f]||void 0===j[o][f]||"z"===o?0:j[o][f])+i,n=b[o+"Bound"]=b["c"+o]="x"!==o&&"y"!==o||!a._isStacked()?i:p,b[e]=i,b[o]=n-("x"===o&&i>=0||"y"===o&&0>=i?i:0)))};o(a.x,"y","width"),o(a.y,"x","height"),o(a.z,"z","r"),null!==a.c&&null!==i.min&&null!==i.max&&(i.min===i.max&&(i.min-=.5,i.max+=.5),i.min=null!==a.c.overrideMin&&void 0!==a.c.overrideMin?a.c.overrideMin:i.min,i.max=null!==a.c.overrideMax&&void 0!==a.c.overrideMax?a.c.overrideMax:i.max,b.cValue=b.cValue>i.max?i.max:b.cValue1?(c=d3.rgb(a.c.colors[Math.floor(f)]),d=d3.rgb(a.c.colors[Math.ceil(f)])):(c=d3.rgb("white"),d=d3.rgb(this.getColor(b.aggField.slice(-1)[0]).fill)),c.r=Math.floor(c.r+(d.r-c.r)*n),c.g=Math.floor(c.g+(d.g-c.g)*n),c.b=Math.floor(c.b+(d.b-c.b)*n),b.fill=c.toString(),b.stroke=c.darker(.5).toString())},this),a._positionData=d},this)},this._heightPixels=function(){return dimple._parseYPosition(this.height,this.svg.node())},this._registerEventHandlers=function(a){null!==a._eventHandlers&&a._eventHandlers.length>0&&a._eventHandlers.forEach(function(b){var c=null;null!==b.handler&&"function"==typeof b.handler&&(c=null!==a._markers&&void 0!==a._markers?a._markers:a.shapes,c.on(b.event,function(c){var d=new dimple.eventArgs;null!==a.chart.storyboard&&(d.frameValue=a.chart.storyboard.getFrameValue()),d.seriesValue=c.aggField,d.xValue=c.x,d.yValue=c.y,d.zValue=c.z,d.colorValue=c.cValue,d.seriesShapes=a.shapes,d.selectedShape=d3.select(this),b.handler(d)}))},this)},this._widthPixels=function(){return dimple._parseXPosition(this.width,this.svg.node())},this._xPixels=function(){return dimple._parseXPosition(this.x,this.svg.node())},this._yPixels=function(){return dimple._parseYPosition(this.y,this.svg.node())},this.addAxis=function(a,b,c,d){var e=null,f=null;if(null!==b&&void 0!==b&&(b=[].concat(b)),"string"==typeof a||a instanceof String)e=new dimple.axis(this,a,b,c,d),this.axes.push(e);else{if(f=a,e=new dimple.axis(this,f.position,b,c,d),e._hasMeasure()!==f._hasMeasure())throw"You have specified a composite axis where some but not all axes have a measure - this is not supported, all axes must be of the same type.";if(e._hasTimeField()!==f._hasTimeField())throw"You have specified a composite axis where some but not all axes have a time field - this is not supported, all axes must be of the same type.";if((null===e.categoryFields||void 0===e.categoryFields?0:e.categoryFields.length)!==(null===f.categoryFields||void 0===f.categoryFields?0:f.categoryFields.length))throw"You have specified a composite axis where axes have differing numbers of category fields - this is not supported, all axes must be of the same type.";f._slaves.push(e)}return e},this.addCategoryAxis=function(a,b){return this.addAxis(a,b,null)},this.addColorAxis=function(a,b){var c=this.addAxis("c",null,a);return c.colors=null===b||void 0===b?null:[].concat(b),c},this.addLegend=function(a,b,c,d,e,f){f=null===f||void 0===f?this.series:[].concat(f),e=null===e||void 0===e?"left":e;var g=new dimple.legend(this,a,b,c,d,e,f);return this.legends.push(g),g},this.addLogAxis=function(a,b,c){var d=this.addAxis(a,null,b,null);return null!==c&&void 0!==c&&(d.logBase=c),d.useLog=!0,d},this.addMeasureAxis=function(a,b){return this.addAxis(a,null,b)},this.addPctAxis=function(a,b,c){var d=null;return d=null!==c&&void 0!==c?this.addAxis(a,c,b):this.addMeasureAxis(a,b),d.showPercent=!0,d},this.addSeries=function(a,b,c){(null===c||void 0===c)&&(c=this.axes),(null===b||void 0===b)&&(b=dimple.plot.bubble);var d,e=null,f=null,g=null,h=null;return c.forEach(function(a){null!==a&&b.supportedAxes.indexOf(a.position)>-1&&(null===e&&"x"===a.position[0]?e=a:null===f&&"y"===a.position[0]?f=a:null===g&&"z"===a.position[0]?g=a:null===h&&"c"===a.position[0]&&(h=a))},this),null!==a&&void 0!==a&&(a=[].concat(a)),d=new dimple.series(this,a,e,f,g,h,b,dimple.aggregateMethod.sum,b.stacked),this.series.push(d),d},this.addTimeAxis=function(a,b,c,d){var e=this.addAxis(a,null,null,b);return e.tickFormat=d,e.dateParseFormat=c,e},this.assignColor=function(a,b,c,d){return this._assignedColors[a]=new dimple.color(b,c,d),this._assignedColors[a]},this.defaultColors=[new dimple.color("#80B1D3"),new dimple.color("#FB8072"),new dimple.color("#FDB462"),new dimple.color("#B3DE69"),new dimple.color("#FFED6F"),new dimple.color("#BC80BD"),new dimple.color("#8DD3C7"),new dimple.color("#CCEBC5"),new dimple.color("#FFFFB3"),new dimple.color("#BEBADA"),new dimple.color("#FCCDE5"),new dimple.color("#D9D9D9")],this.draw=function(a,b){a=null===a||void 0===a?0:a;var c,d=null,e=null,f=!1,g=!1,h=this._xPixels(),i=this._yPixels(),j=this._widthPixels(),k=this._heightPixels(),l=[];return(void 0===b||null===b||b===!1)&&this._getSeriesData(),this.axes.forEach(function(a){a._scale=null},this),this.axes.forEach(function(a){if(a._min=0,a._max=0,a._hasMeasure()){var b=!1;this.series.forEach(function(c){if(c._deepMatch(a)){var d=c._axisBounds(a.position);a._min>d.min&&(a._min=d.min),a._maxb[a.measure]&&(a._min=b[a.measure]),a._maxa._max)&&(a._max=d)},this)},this)):a._hasCategories()&&(a._min=0,c=[],this.series.forEach(function(b){b._deepMatch(a)&&null!==b[a.position].categoryFields[0]&&void 0!==b[a.position].categoryFields[0]&&-1===l.indexOf(b[a.position].categoryFields[0])&&l.push(b[a.position].categoryFields[0])},this),a._getAxisData().forEach(function(a){l.forEach(function(b){-1===c.indexOf(a[b])&&c.push(a[b])},this)},this),a._max=c.length);null!==a._slaves&&void 0!==a._slaves&&a._slaves.length>0&&a._slaves.forEach(function(b){b._min=a._min,b._max=a._max},this),a._update(),null===d&&"x"===a.position?d=a:null===e&&"y"===a.position&&(e=a)},this),this.axes.forEach(function(b){var c,l=!1,m=null,n=0,o=null,p=!1,q=0,r={l:null,t:null,r:null,b:null},s=0,t=0,u="",v=this;null===b.gridlineShapes?(b.showGridlines||null===b.showGridlines&&!b._hasCategories()&&(!f&&"x"===b.position||!g&&"y"===b.position))&&(b.gridlineShapes=this._group.append("g").attr("class","dimple-gridline"),"x"===b.position?f=!0:g=!0):"x"===b.position?f=!0:g=!0,null===b.shapes&&(b.shapes=this._group.append("g").attr("class","dimple-axis"),l=!0),b===d&&null!==e?(m="translate(0, "+(null===e.categoryFields||0===e.categoryFields.length?e._scale(0):i+k)+")",o="translate(0, "+(b===d?i+k:i)+")",n=-k):b===e&&null!==d?(m="translate("+(null===d.categoryFields||0===d.categoryFields.length?d._scale(0):h)+", 0)",o="translate("+(b===e?h:h+j)+", 0)",n=-j):"x"===b.position?(o=m="translate(0, "+(b===d?i+k:i)+")",n=-k):"y"===b.position&&(o=m="translate("+(b===e?h:h+j)+", 0)",n=-j),c=function(b){var c;return c=null===m||0===a||l?b:b.transition().duration(a)},null!==m&&null!==b._draw&&(b._hasTimeField()?c(b.shapes).call(b._draw.ticks(b._getTimePeriod(),b.timeInterval).tickFormat(b._getFormat())).attr("transform",m):b.useLog?c(b.shapes).call(b._draw.ticks(4,b._getFormat())).attr("transform",m):c(b.shapes).call(b._draw.tickFormat(b._getFormat())).attr("transform",m),null!==b.gridlineShapes&&c(b.gridlineShapes).call(b._draw.tickSize(n,0,0).tickFormat("")).attr("transform",o),(null===b.measure||void 0===b.measure)&&("x"===b.position?c(b.shapes.selectAll("text")).attr("x",j/b._max/2):"y"===b.position&&c(b.shapes.selectAll("text")).attr("y",-1*(k/b._max)/2)),null!==b.categoryFields&&void 0!==b.categoryFields&&b.categoryFields.length>0&&(b!==d||null!==e.categoryFields&&0!==e.categoryFields.length||c(b.shapes.selectAll("text")).attr("y",i+k-e._scale(0)+9),b!==e||null!==d.categoryFields&&0!==d.categoryFields.length||c(b.shapes.selectAll("text")).attr("x",-1*(d._scale(0)-h)-9))),this.noFormats||(c(b.shapes.selectAll("text")).style("font-family","sans-serif").style("font-size",(k/35>10?k/35:10)+"px"),c(b.shapes.selectAll("path, line")).style("fill","none").style("stroke","black").style("shape-rendering","crispEdges"),null!==b.gridlineShapes&&c(b.gridlineShapes.selectAll("line")).style("fill","none").style("stroke","lightgray").style("opacity",.8)),(null===b.measure||void 0===b.measure)&&(b===d?(q=0,b.shapes.selectAll("text").each(function(){var a=this.getComputedTextLength();q=a>q?a:q}),q>j/b.shapes.selectAll("text")[0].length?(p=!0,b.shapes.selectAll("text").style("text-anchor","start").each(function(){var a=this.getBBox();d3.select(this).attr("transform","rotate(90,"+a.x+","+(a.y+a.height/2)+") translate(-5, 0)")})):(p=!1,b.shapes.selectAll("text").style("text-anchor","middle").attr("transform",""))):"x"===b.position&&(q=0,b.shapes.selectAll("text").each(function(){var a=this.getComputedTextLength();q=a>q?a:q}),q>j/b.shapes.selectAll("text")[0].length?(p=!0,b.shapes.selectAll("text").style("text-anchor","end").each(function(){var a=this.getBBox();d3.select(this).attr("transform","rotate(90,"+(a.x+a.width)+","+(a.y+a.height/2)+") translate(5, 0)")})):(p=!1,b.shapes.selectAll("text").style("text-anchor","middle").attr("transform","")))),null!==b.titleShape&&void 0!==b.titleShape&&b.titleShape.remove(),b.shapes.selectAll("text").each(function(){var a=this.getBBox();(null===r.l||-9-a.widthr.r)&&(r.r=a.x+a.width),p?((null===r.t||a.y+a.height-a.widthr.b)&&(r.b=a.height+a.width)):((null===r.t||a.yr.b)&&(r.b=9+a.height))}),"x"===b.position?(t=b===d?i+k+r.b+5:i+r.t-10,s=h+j/2):"y"===b.position&&(s=b===e?h+r.l-10:h+j+r.r+20,t=i+k/2,u="rotate(270, "+s+", "+t+")"),b.hidden||"x"!==b.position&&"y"!==b.position||null===b.title||(b.titleShape=this._group.append("text").attr("class","dimple-axis dimple-title"),b.titleShape.attr("x",s).attr("y",t).attr("text-anchor","middle").attr("transform",u).text(void 0!==b.title?b.title:null===b.categoryFields||void 0===b.categoryFields||0===b.categoryFields.length?b.measure:b.categoryFields.join("/")).each(function(){v.noFormats||d3.select(this).style("font-family","sans-serif").style("font-size",(k/35>10?k/35:10)+"px")}),b===d?b.titleShape.each(function(){d3.select(this).attr("y",t+this.getBBox().height/1.65)}):b===e&&b.titleShape.each(function(){d3.select(this).attr("x",s+this.getBBox().height/1.65)}))},this),this.series.forEach(function(b){b.plot.draw(this,b,a),this._registerEventHandlers(b)},this),this.legends.forEach(function(b){b._draw(a)},this),null!==this.storyboard&&void 0!==this.storyboard&&(this.storyboard._drawText(),this.storyboard.autoplay&&this.storyboard.startAnimation()),this},this.getColor=function(a){return(null===this._assignedColors[a]||void 0===this._assignedColors[a])&&(this._assignedColors[a]=this.defaultColors[this._nextColor],this._nextColor=(this._nextColor+1)%this.defaultColors.length),this._assignedColors[a]},this.setBounds=function(a,b,c,d){return this.x=a,this.y=b,this.width=c,this.height=d,this._xPixels=function(){return dimple._parseXPosition(this.x,this.svg.node())},this._yPixels=function(){return dimple._parseYPosition(this.y,this.svg.node())},this._widthPixels=function(){return dimple._parseXPosition(this.width,this.svg.node())},this._heightPixels=function(){return dimple._parseYPosition(this.height,this.svg.node())},this.draw(0,!0),this},this.setMargins=function(a,b,c,d){return this.x=a,this.y=b,this.width=0,this.height=0,this._xPixels=function(){return dimple._parseXPosition(this.x,this.svg.node())},this._yPixels=function(){return dimple._parseYPosition(this.y,this.svg.node())},this._widthPixels=function(){return dimple._parentWidth(this.svg.node())-this._xPixels()-dimple._parseXPosition(c,this.svg.node())},this._heightPixels=function(){return dimple._parentHeight(this.svg.node())-this._yPixels()-dimple._parseYPosition(d,this.svg.node())},this.draw(0,!0),this},this.setStoryboard=function(a,b){return this.storyboard=new dimple.storyboard(this,a),null!==b&&void 0!==b&&(this.storyboard.onTick=b),this.storyboard}},dimple.color=function(a,b,c){this.fill=a,this.stroke=null===b||void 0===b?d3.rgb(a).darker(.5).toString():b,this.opacity=null===c||void 0===c?.8:c},dimple.eventArgs=function(){this.seriesValue=null,this.xValue=null,this.yValue=null,this.zValue=null,this.colorValue=null,this.frameValue=null,this.seriesShapes=null,this.selectedShape=null},dimple.legend=function(a,b,c,d,e,f,g){this.chart=a,this.series=g,this.x=b,this.y=c,this.width=d,this.height=e,this.horizontalAlign=f,this.shapes=null,this._draw=function(a){var b,c=this._getEntries(),d=0,e=0,f=0,g=0,h=15,i=9,j=this;null!==this.shapes&&void 0!==this.shapes&&this.shapes.transition().duration(.2*a).attr("opacity",0).remove(),b=this.chart._group.selectAll(".dimple-dont-select-any").data(c).enter().append("g").attr("class",function(a){return"dimple-legend "+dimple._createClass(a.aggField)}).attr("opacity",0),b.append("text").attr("class",function(a){return"dimple-legend dimple-legend-text "+dimple._createClass(a.aggField)}).text(function(a){return a.key}).call(function(){j.chart.noFormats||this.style("font-family","sans-serif").style("font-size",(j.chart._heightPixels()/35>10?j.chart._heightPixels()/35:10)+"px").style("shape-rendering","crispEdges")}).each(function(){var a=this.getBBox();a.width>d&&(d=a.width),a.height>e&&(e=a.height)}),b.append("rect").attr("class",function(a){return"dimple-legend dimple-legend-key "+dimple._createClass(a.aggField)}).attr("height",i).attr("width",h),e=(i>e?i:e)+2,d+=h+20,b.each(function(a){f+d>j._widthPixels()&&(f=0,g+=e),g>j._heightPixels()?d3.select(this).remove():(d3.select(this).select("text").attr("x","left"===j.horizontalAlign?j._xPixels()+h+5+f:j._xPixels()+(j._widthPixels()-f-d)+h+5).attr("y",function(){return j._yPixels()+g+this.getBBox().height/1.65}).attr("width",j._widthPixels()).attr("height",j._heightPixels()),d3.select(this).select("rect").attr("class",function(a){return"dimple-legend dimple-legend-key "+dimple._createClass(a.aggField)}).attr("x","left"===j.horizontalAlign?j._xPixels()+f:j._xPixels()+(j._widthPixels()-f-d)).attr("y",j._yPixels()+g).attr("height",i).attr("width",h).style("fill",function(){return dimple._helpers.fill(a,j.chart,a.series)}).style("stroke",function(){return dimple._helpers.stroke(a,j.chart,a.series)}).style("opacity",function(){return dimple._helpers.opacity(a,j.chart,a.series)}).style("shape-rendering","crispEdges"),f+=d)}),b.transition().delay(.2*a).duration(.8*a).attr("opacity",1),this.shapes=b},this._getEntries=function(){var a=[];return null!==this.series&&void 0!==this.series&&this.series.forEach(function(b){var c=b._positionData;c.forEach(function(c){var d,e=-1;for(d=0;de.max&&(e.max=a[f.position+"Bound"])},this):null===g||null===g.categoryFields||0===g.categoryFields.length?j.forEach(function(a){!this._isStacked()||"x"!==f.position&&"y"!==f.position?(a[f.position+"Value"]e.max&&(e.max=a[f.position+"Value"])):a[f.position+"Value"]<0?e.min=e.min+a[f.position+"Value"]:e.max=e.max+a[f.position+"Value"]},this):(b=f.position+"Value",c=g.position+"Field",d=[],j.forEach(function(a){var e=a[c].join("/"),f=d.indexOf(e);-1===f&&(d.push(e),f=d.length-1),void 0===h[f]&&(h[f]={min:0,max:0},f>=i&&(i=f+1)),this.stacked?a[b]<0?h[f].min=h[f].min+a[b]:h[f].max=h[f].max+a[b]:(a[b]h[f].max&&(h[f].max=a[b]))},this),h.forEach(function(a){void 0!==a&&(a.mine.max&&(e.max=a.max))},this)),e},this._deepMatch=function(a){var b=!1;return this[a.position]===a?b=!0:void 0!==a._slaves&&null!==a._slaves&&a._slaves.length>0&&a._slaves.forEach(function(a){b=b||this._deepMatch(a) +},this),b},this._dropLineOrigin=function(){var a=0,b=0,c={x:null,y:null},d={x:null,y:null};return this.chart.axes.forEach(function(a){"x"===a.position&&null===d.x?d.x=a._hasTimeField()?this.chart._xPixels():a._origin:"y"===a.position&&null===d.y&&(d.y=a._hasTimeField()?this.chart._yPixels()+this.chart._heightPixels():a._origin)},this),this.chart.axes.forEach(function(e){"x"!==e.position||this.x.hidden?"y"!==e.position||this.y.hidden||(this._deepMatch(e)&&(0===b?c.x=d.x:1===b&&(c.x=this.chart._xPixels()+this.chart._widthPixels())),b+=1):(this._deepMatch(e)&&(0===a?c.y=d.y:1===a&&(c.y=this.chart._yPixels())),a+=1)},this),c},this._isStacked=function(){return this.stacked&&(this.x._hasCategories()||this.y._hasCategories())},this.addEventHandler=function(a,b){this._eventHandlers.push({event:a,handler:b})},this.addOrderRule=function(a,b){this._orderRules.push({ordering:a,desc:b})},this.getTooltipText=function(a){var b=[];return null!==this.categoryFields&&void 0!==this.categoryFields&&this.categoryFields.length>0&&this.categoryFields.forEach(function(c,d){null!==c&&void 0!==c&&null!==a.aggField[d]&&void 0!==a.aggField[d]&&b.push(c+(a.aggField[d]!==c?": "+a.aggField[d]:""))},this),this.x&&this.x._getTooltipText(b,a),this.y&&this.y._getTooltipText(b,a),this.z&&this.z._getTooltipText(b,a),this.c&&this.c._getTooltipText(b,a),b.filter(function(a,c){return b.indexOf(a)===c})}},dimple.storyboard=function(a,b){null!==b&&void 0!==b&&(b=[].concat(b)),this.chart=a,this.categoryFields=b,this.autoplay=!0,this.frameDuration=3e3,this.storyLabel=null,this.onTick=null,this._frame=0,this._animationTimer=null,this._categories=[],this._cachedCategoryFields=[],this._orderRules=[],this._drawText=function(a){if(null===this.storyLabel||void 0===this.storyLabel){var b=this.chart,c=0;this.chart.axes.forEach(function(a){"x"===a.position&&(c+=1)},this),this.storyLabel=this.chart._group.append("text").attr("x",this.chart._xPixels()+.01*this.chart._widthPixels()).attr("y",this.chart._yPixels()+(this.chart._heightPixels()/35>10?this.chart._heightPixels()/35:10)*(c>1?1.25:-1)).call(function(){b.noFormats||this.style("font-family","sans-serif").style("font-size",(b._heightPixels()/35>10?b._heightPixels()/35:10)+"px")})}this.storyLabel.transition().duration(.2*a).attr("opacity",0),this.storyLabel.transition().delay(.2*a).attr("class","dimple-storyboard-label").text(this.categoryFields.join("\\")+": "+this.getFrameValue()).transition().duration(.8*a).attr("opacity",1)},this._getCategories=function(){return this._categoryFields!==this._cachedCategoryFields&&(this._categories=[],this.chart._getAllData().forEach(function(a){var b=-1,c="";null!==this.categoryFields&&(this.categoryFields.forEach(function(b,d){d>0&&(c+="/"),c+=a[b]},this),b=this._categories.indexOf(c),-1===b&&(this._categories.push(c),b=this._categories.length-1))},this),this._cachedCategoryFields=this._categoryFields),this._categories},this._goToFrameIndex=function(a){this._frame=a%this._getCategories().length,this.chart.draw(this.frameDuration/2)},this.addOrderRule=function(a,b){this._orderRules.push({ordering:a,desc:b})},this.getFrameValue=function(){var a=null;return this._frame>=0&&this._getCategories().length>this._frame&&(a=this._getCategories()[this._frame]),a},this.goToFrame=function(a){if(this._getCategories().length>0){var b=this._getCategories().indexOf(a);this._goToFrameIndex(b)}},this.pauseAnimation=function(){null!==this._animationTimer&&(window.clearInterval(this._animationTimer),this._animationTimer=null)},this.startAnimation=function(){null===this._animationTimer&&(null!==this.onTick&&this.onTick(this.getFrameValue()),this._animationTimer=window.setInterval(function(a){return function(){a._goToFrameIndex(a._frame+1),null!==a.onTick&&a.onTick(a.getFrameValue()),a._drawText(a.frameDuration/2)}}(this),this.frameDuration))},this.stopAnimation=function(){null!==this._animationTimer&&(window.clearInterval(this._animationTimer),this._animationTimer=null,this._frame=0)}},dimple.aggregateMethod.avg=function(a,b){return a.value=null===a.value||void 0===a.value?0:parseFloat(a.value),a.count=null===a.count||void 0===a.count?1:parseFloat(a.count),b.value=null===b.value||void 0===b.value?0:parseFloat(b.value),b.count=null===b.count||void 0===b.count?1:parseFloat(b.count),(a.value*a.count+b.value*b.count)/(a.count+b.count)},dimple.aggregateMethod.count=function(a,b){return a.count=null===a.count||void 0===a.count?0:parseFloat(a.count),b.count=null===b.count||void 0===b.count?0:parseFloat(b.count),a.count+b.count},dimple.aggregateMethod.max=function(a,b){return a.value=null===a.value||void 0===a.value?0:parseFloat(a.value),b.value=null===b.value||void 0===b.value?0:parseFloat(b.value),a.value>b.value?a.value:b.value},dimple.aggregateMethod.min=function(a,b){return null===a.value?parseFloat(b.value):parseFloat(a.value)c&&g>e&&(h=a[d],g=e));return b.push(h),g};for(d="step"===b.interpolation?"step-after":b.interpolation,m=dimple._getSeriesOrder(b.data||a.data,b),b.c&&(b.x._hasCategories()&&b.y._hasMeasure()||b.y._hasCategories()&&b.x._hasMeasure())&&(z=!0),b.x._hasCategories()?(s="x",t="y"):b.y._hasCategories()&&(s="y",t="x"),e=0;e0)for(f=0,g=0;f=n[0][s]&&B[f]<=n[n.length-1][s]&&(p={},p[s]=B[f],p[t]=A[B[f]],o.push(p),n[g][s]>B[f]?C.push(p):(C.push(n[g]),A[B[f]]=n[g][t],g+=1));else if(b._orderRules&&b._orderRules.length>0)C=n.concat(n[0]);else{n=n.sort(I),C.push(n[0]),r=0;do r=J(n,C,r);while(C.length<=n.length&&(C[0].x!==C[C.length-1].x||C[0].y!==C[C.length-1].y))}C=C.concat(o.reverse()).concat(C[0]),v[e].entry=H(d,"_previousOrigin")(C),v[e].update=H(d)(C),v[e].exit=H(d,"_origin")(C),v[e].color=a.getColor(v[e].key.length>0?v[e].key[v[e].key.length-1]:"All")}null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),w=null===b.shapes||void 0===b.shapes?a._group.selectAll("."+x).data(v):b.shapes.data(v,function(a){return a.key}),w.enter().append("path").attr("id",function(a){return a.key}).attr("class",function(a){return x+" dimple-line "+a.keyString}).attr("d",function(a){return a.entry}).call(function(){a.noFormats||this.attr("opacity",function(a){return z?1:a.color.opacity}).attr("fill",function(a){return z?"url(#fill-line-gradient-"+a.keyString+")":a.color.fill}).attr("stroke",function(a){return z?"url(#stroke-line-gradient-"+a.keyString+")":a.color.stroke}).attr("stroke-width",b.lineWeight)}).each(F),k=dimple._handleTransition(w,c).attr("d",function(a){return a.update}).each(F),l=dimple._handleTransition(w.exit(),c).attr("d",function(a){return a.exit}).each(F),dimple._postDrawHandling(b,k,l,c),b.shapes=w}},dimple.plot.bar={stacked:!0,supportedAxes:["x","y","c"],draw:function(a,b,c){var d,e,f=b._positionData,g=null,h=["dimple-series-"+a.series.indexOf(b),"dimple-bar"],i=!b._isStacked()&&b.x._hasMeasure(),j=!b._isStacked()&&b.y._hasMeasure();null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),g=null===b.shapes||void 0===b.shapes?a._group.selectAll("."+h.join(".")).data(f):b.shapes.data(f,function(a){return a.key}),g.enter().append("rect").attr("id",function(a){return a.key}).attr("class",function(a){var b=[];return b=b.concat(a.aggField),b=b.concat(a.xField),b=b.concat(a.yField),h.join(" ")+" "+dimple._createClass(b)}).attr("x",function(c){return dimple._helpers.x(c,a,b)}).attr("y",function(c){return dimple._helpers.y(c,a,b)+dimple._helpers.height(c,a,b)}).attr("width",function(c){return null!==c.xField&&c.xField.length>0?dimple._helpers.width(c,a,b):0}).attr("height",function(c){return null!==c.yField&&c.yField.length>0?dimple._helpers.height(c,a,b):0}).attr("opacity",function(c){return dimple._helpers.opacity(c,a,b)}).on("mouseover",function(c){dimple._showBarTooltip(c,this,a,b)}).on("mouseleave",function(c){dimple._removeTooltip(c,this,a,b)}).call(function(){a.noFormats||this.attr("fill",function(c){return dimple._helpers.fill(c,a,b)}).attr("stroke",function(c){return dimple._helpers.stroke(c,a,b)})}),d=dimple._handleTransition(g,c).attr("x",function(c){return i?dimple._helpers.cx(c,a,b)-b.x.floatingBarWidth/2:dimple._helpers.x(c,a,b)}).attr("y",function(c){return j?dimple._helpers.cy(c,a,b)-b.y.floatingBarWidth/2:dimple._helpers.y(c,a,b)}).attr("width",function(c){return i?b.x.floatingBarWidth:dimple._helpers.width(c,a,b)}).attr("height",function(c){return j?b.y.floatingBarWidth:dimple._helpers.height(c,a,b)}).call(function(){a.noFormats||this.attr("fill",function(c){return dimple._helpers.fill(c,a,b)}).attr("stroke",function(c){return dimple._helpers.stroke(c,a,b)})}),e=dimple._handleTransition(g.exit(),c).attr("x",function(c){return dimple._helpers.x(c,a,b)}).attr("y",function(c){return dimple._helpers.y(c,a,b)+dimple._helpers.height(c,a,b)}).attr("width",function(c){return null!==c.xField&&c.xField.length>0?dimple._helpers.width(c,a,b):0}).attr("height",function(c){return null!==c.yField&&c.yField.length>0?dimple._helpers.height(c,a,b):0}),dimple._postDrawHandling(b,d,e,c),b.shapes=g}},dimple.plot.bubble={stacked:!1,supportedAxes:["x","y","z","c"],draw:function(a,b,c){var d,e,f=b._positionData,g=null,h=["dimple-series-"+a.series.indexOf(b),"dimple-bubble"];null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),g=null===b.shapes||void 0===b.shapes?a._group.selectAll("."+h.join(".")).data(f):b.shapes.data(f,function(a){return a.key}),g.enter().append("circle").attr("id",function(a){return a.key}).attr("class",function(a){var b=[];return b=b.concat(a.aggField),b=b.concat(a.xField),b=b.concat(a.yField),b=b.concat(a.zField),h.join(" ")+" "+dimple._createClass(b)}).attr("cx",function(c){return b.x._hasCategories()?dimple._helpers.cx(c,a,b):b.x._previousOrigin}).attr("cy",function(c){return b.y._hasCategories()?dimple._helpers.cy(c,a,b):b.y._previousOrigin}).attr("r",0).attr("opacity",function(c){return dimple._helpers.opacity(c,a,b)}).on("mouseover",function(c){dimple._showPointTooltip(c,this,a,b)}).on("mouseleave",function(c){dimple._removeTooltip(c,this,a,b)}).call(function(){a.noFormats||this.attr("fill",function(c){return dimple._helpers.fill(c,a,b)}).attr("stroke",function(c){return dimple._helpers.stroke(c,a,b)})}),d=dimple._handleTransition(g,c).attr("cx",function(c){return dimple._helpers.cx(c,a,b)}).attr("cy",function(c){return dimple._helpers.cy(c,a,b)}).attr("r",function(c){return dimple._helpers.r(c,a,b)}).call(function(){a.noFormats||this.attr("fill",function(c){return dimple._helpers.fill(c,a,b)}).attr("stroke",function(c){return dimple._helpers.stroke(c,a,b)})}),e=dimple._handleTransition(g.exit(),c).attr("r",0).attr("cx",function(c){return b.x._hasCategories()?dimple._helpers.cx(c,a,b):b.x._origin}).attr("cy",function(c){return b.y._hasCategories()?dimple._helpers.cy(c,a,b):b.y._origin}),dimple._postDrawHandling(b,d,e,c),b.shapes=g}},dimple.plot.line={stacked:!1,supportedAxes:["x","y","c"],draw:function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n=b._positionData,o=[],p=null,q="dimple-series-"+a.series.indexOf(b),r=b.x._hasCategories()||b.y._hasCategories()?0:1,s=!1,t=function(){return function(a,b,c,d){d3.select(b).style("opacity",1),dimple._showPointTooltip(a,b,c,d)}},u=function(a){return function(b,c,d,e){d3.select(c).style("opacity",e.lineMarkers||a.data.length<2?dimple._helpers.opacity(b,d,e):0),dimple._removeTooltip(b,c,d,e)}},v=function(d){dimple._drawMarkers(d,a,b,c,q,s,t(d),u(d))},w=function(c,d){var e;return"step"===b.interpolation&&b[c]._hasCategories()?(b.barGap=0,b.clusterBarGap=0,e=dimple._helpers[c](d,a,b)+("y"===c?dimple._helpers.height(d,a,b):0)):e=dimple._helpers["c"+c](d,a,b),e},x=function(a,c){return d3.svg.line().x(function(a){return b.x._hasCategories()||!c?w("x",a):b.x[c]}).y(function(a){return b.y._hasCategories()||!c?w("y",a):b.y[c]}).interpolate(a)};for(d="step"===b.interpolation?"step-after":b.interpolation,l=dimple._getSeriesOrder(b.data||a.data,b),b.c&&(b.x._hasCategories()&&b.y._hasMeasure()||b.y._hasCategories()&&b.x._hasMeasure())&&(s=!0),e=0;e0?o[e].key[o[e].key.length-1]:"All");null!==a._tooltipGroup&&void 0!==a._tooltipGroup&&a._tooltipGroup.remove(),p=null===b.shapes||void 0===b.shapes?a._group.selectAll("."+q).data(o):b.shapes.data(o,function(a){return a.key}),p.enter().append("path").attr("id",function(a){return a.key}).attr("class",function(a){return q+" dimple-line "+a.keyString}).attr("d",function(a){return a.entry}).call(function(){a.noFormats||this.attr("opacity",function(a){return s?1:a.color.opacity}).attr("fill","none").attr("stroke",function(a){return s?"url(#fill-line-gradient-"+a.keyString+")":a.color.stroke}).attr("stroke-width",b.lineWeight)}).each(v),j=dimple._handleTransition(p,c).attr("d",function(a){return a.update}).each(v),k=dimple._handleTransition(p.exit(),c).attr("d",function(a){return a.exit}).each(v),dimple._postDrawHandling(b,j,k,c),b.shapes=p}},dimple._addGradient=function(a,b,c,d,e,f,g){var h=[].concat(a),i=e._group.select("#"+b),j=[],k=c.position+"Field",l=!0,m=[];d.forEach(function(a){-1===j.indexOf(a[k])&&a.aggField.join("_")===h.join("_")&&j.push(a[k])},this),j=j.sort(function(a,b){return c._scale(a)-c._scale(b)}),null===i.node()&&(l=!1,i=e._group.append("linearGradient").attr("id",b).attr("gradientUnits","userSpaceOnUse").attr("x1","x"===c.position?c._scale(j[0])+e._widthPixels()/j.length/2:0).attr("y1","y"===c.position?c._scale(j[0])-e._heightPixels()/j.length/2:0).attr("x2","x"===c.position?c._scale(j[j.length-1])+e._widthPixels()/j.length/2:0).attr("y2","y"===c.position?c._scale(j[j.length-1])-e._heightPixels()/j.length/2:0)),j.forEach(function(a,b){var c={},e=0;for(e=0;e=65&&90>=b&&(c=a.toLowerCase()),c};for(b=0;b=1&&(i.forEach(function(a){var b=null===a.desc||void 0===a.desc?!1:a.desc,c=a.ordering,d=[],f="string"==typeof c?c:null,h=function(a){var b,c=0;for(b=0;bb[0]&&(c=1):c=Date.parse(a[0])-Date.parse(b[0]):c=parseFloat(d)-parseFloat(e),c};"function"==typeof c?e.push(function(a,d){return(b?-1:1)*c(a,d)}):c instanceof Array?(c.forEach(function(a){d.push([].concat(a).join("|"))},this),e.push(function(a,c){var e,f,h,i="",j="";for(h=0;h0&&(i+="|",j+="|"),i+=a[g[h]],j+=c[g[h]];return e=d.indexOf(i),f=d.indexOf(j),e=0>e?b?-1:d.length:e,f=0>f?b?-1:d.length:f,(b?-1:1)*(e-f)})):e.push(function(a,c){var d=0;return void 0!==a[f]&&void 0!==c[f]&&(d=i([].concat(a[f]),[].concat(c[f]))),(b?-1:1)*d})}),d.sort(function(a,b){for(var c=0,d=0;c0&&(null!==b.c&&void 0!==b.c&&b.c._hasMeasure()&&c.push({ordering:b.c.measure,desc:!0}),b.x._hasMeasure()&&c.push({ordering:b.x.measure,desc:!0}),b.y._hasMeasure()&&c.push({ordering:b.y.measure,desc:!0}),e=dimple._getOrderedList(a,d,c)),e},dimple._getSeriesSortPredicate=function(a,b,c){return function(d,e){var f=0;return b.x._hasCategories()?f=dimple._helpers.cx(d,a,b)=2?c.x._scale(a.cx)+dimple._helpers.xGap(b,c)+(a.xOffset+.5)*(b._widthPixels()/c.x._max-2*dimple._helpers.xGap(b,c))*a.width:c.x._scale(a.cx)+b._widthPixels()/c.x._max/2},cy:function(a,b,c){var d=0;return d=null!==c.y.measure&&void 0!==c.y.measure?c.y._scale(a.cy):null!==c.y.categoryFields&&void 0!==c.y.categoryFields&&c.y.categoryFields.length>=2?c.y._scale(a.cy)-b._heightPixels()/c.y._max+dimple._helpers.yGap(b,c)+(a.yOffset+.5)*(b._heightPixels()/c.y._max-2*dimple._helpers.yGap(b,c))*a.height:c.y._scale(a.cy)-b._heightPixels()/c.y._max/2},r:function(a,b,c){var d=0;return d=null===c.z||void 0===c.z?5:c.z._hasMeasure()?c.z._scale(a.r):c.z._scale(b._heightPixels()/100)},xGap:function(a,b){var c=0;return(null===b.x.measure||void 0===b.x.measure)&&b.barGap>0&&(c=a._widthPixels()/b.x._max*(b.barGap>.99?.99:b.barGap)/2),c},xClusterGap:function(a,b,c){var d=0;return null!==c.x.categoryFields&&void 0!==c.x.categoryFields&&c.x.categoryFields.length>=2&&c.clusterBarGap>0&&!c.x._hasMeasure()&&(d=a.width*(b._widthPixels()/c.x._max-2*dimple._helpers.xGap(b,c))*(c.clusterBarGap>.99?.99:c.clusterBarGap)/2),d},yGap:function(a,b){var c=0;return(null===b.y.measure||void 0===b.y.measure)&&b.barGap>0&&(c=a._heightPixels()/b.y._max*(b.barGap>.99?.99:b.barGap)/2),c},yClusterGap:function(a,b,c){var d=0;return null!==c.y.categoryFields&&void 0!==c.y.categoryFields&&c.y.categoryFields.length>=2&&c.clusterBarGap>0&&!c.y._hasMeasure()&&(d=a.height*(b._heightPixels()/c.y._max-2*dimple._helpers.yGap(b,c))*(c.clusterBarGap>.99?.99:c.clusterBarGap)/2),d},x:function(a,b,c){var d=0;return d=c.x._hasTimeField()?c.x._scale(a.x)-dimple._helpers.width(a,b,c)/2:null!==c.x.measure&&void 0!==c.x.measure?c.x._scale(a.x):c.x._scale(a.x)+dimple._helpers.xGap(b,c)+a.xOffset*(dimple._helpers.width(a,b,c)+2*dimple._helpers.xClusterGap(a,b,c))+dimple._helpers.xClusterGap(a,b,c)},y:function(a,b,c){var d=0;return d=c.y._hasTimeField()?c.y._scale(a.y)-dimple._helpers.height(a,b,c)/2:null!==c.y.measure&&void 0!==c.y.measure?c.y._scale(a.y):c.y._scale(a.y)-b._heightPixels()/c.y._max+dimple._helpers.yGap(b,c)+a.yOffset*(dimple._helpers.height(a,b,c)+2*dimple._helpers.yClusterGap(a,b,c))+dimple._helpers.yClusterGap(a,b,c)},width:function(a,b,c){var d=0;return d=null!==c.x.measure&&void 0!==c.x.measure?Math.abs(c.x._scale(a.x<0?a.x-a.width:a.x+a.width)-c.x._scale(a.x)):c.x._hasTimeField()?c.x.floatingBarWidth:a.width*(b._widthPixels()/c.x._max-2*dimple._helpers.xGap(b,c))-2*dimple._helpers.xClusterGap(a,b,c)},height:function(a,b,c){var d=0;return d=c.y._hasTimeField()?c.y.floatingBarWidth:null!==c.y.measure&&void 0!==c.y.measure?Math.abs(c.y._scale(a.y)-c.y._scale(a.y<=0?a.y+a.height:a.y-a.height)):a.height*(b._heightPixels()/c.y._max-2*dimple._helpers.yGap(b,c))-2*dimple._helpers.yClusterGap(a,b,c)},opacity:function(a,b,c){var d=0;return d=null!==c.c&&void 0!==c.c?a.opacity:b.getColor(a.aggField.slice(-1)[0]).opacity},fill:function(a,b,c){var d=0;return d=null!==c.c&&void 0!==c.c?a.fill:b.getColor(a.aggField.slice(-1)[0]).fill},stroke:function(a,b,c){var d=0;return d=null!==c.c&&void 0!==c.c?a.stroke:b.getColor(a.aggField.slice(-1)[0]).stroke}},dimple._parentHeight=function(a){var b=a.offsetHeight;return(0>=b||null===b||void 0===b)&&(b=a.clientHeight),(0>=b||null===b||void 0===b)&&(b=null===a.parentNode||void 0===a.parentNode?0:dimple._parentHeight(a.parentNode)),b},dimple._parentWidth=function(a){var b=a.offsetWidth;return(0>=b||null===b||void 0===b)&&(b=a.clientWidth),(0>=b||null===b||void 0===b)&&(b=null===a.parentNode||void 0===a.parentNode?0:dimple._parentWidth(a.parentNode)),b},dimple._parseXPosition=function(a,b){var c,d=0;return null!==a&&void 0!==a&&(c=a.toString().split(","),c.forEach(function(c){void 0!==c&&null!==c&&(isNaN(c)?"%"===c.slice(-1)?d+=dimple._parentWidth(b)*(parseFloat(c.slice(0,c.length-1))/100):"px"===c.slice(-2)?d+=parseFloat(c.slice(0,c.length-2)):d=a:d+=parseFloat(c))},this)),d},dimple._parseYPosition=function(a,b){var c,d=0;return null!==a&&void 0!==a&&(c=a.toString().split(","),c.forEach(function(c){void 0!==c&&null!==c&&(isNaN(c)?"%"===c.slice(-1)?d+=dimple._parentHeight(b)*(parseFloat(c.slice(0,c.length-1))/100):"px"===c.slice(-2)?d+=parseFloat(c.slice(0,c.length-2)):d=a:d+=parseFloat(c))},this)),d},dimple._postDrawHandling=function(a,b,c,d){0===d?(b.each(function(b,c){null!==a.afterDraw&&void 0!==a.afterDraw&&a.afterDraw(this,b,c)}),c.remove()):(b.each("end",function(b,c){null!==a.afterDraw&&void 0!==a.afterDraw&&a.afterDraw(this,b,c)}),c.each("end",function(){d3.select(this).remove()}))},dimple._removeTooltip=function(a,b,c){c._tooltipGroup&&c._tooltipGroup.remove()},dimple._rollUp=function(a,b,c){var d=[];return b=null!==b&&void 0!==b?[].concat(b):[],a.forEach(function(a){var e=-1,f={},g=!0;d.forEach(function(c,d){-1===e&&(g=!0,b.forEach(function(b){g=g&&a[b]===c[b]},this),g&&(e=d))},this),-1!==e?f=d[e]:(b.forEach(function(b){f[b]=a[b]},this),d.push(f),e=d.length-1),c.forEach(function(c){-1===b.indexOf(c)&&(void 0===f[c]&&(f[c]=[]),f[c]=f[c].concat(a[c]))},this),d[e]=f},this),d},dimple._showBarTooltip=function(a,b,c,d){var e,f,g,h,i,j=5,k=10,l=750,m=d3.select(b),n=parseFloat(m.attr("x")),o=parseFloat(m.attr("y")),p=parseFloat(m.attr("width")),q=parseFloat(m.attr("height")),r=m.attr("opacity"),s=m.attr("fill"),t=d._dropLineOrigin(),u=d3.rgb(d3.rgb(s).r+.6*(255-d3.rgb(s).r),d3.rgb(s).g+.6*(255-d3.rgb(s).g),d3.rgb(s).b+.6*(255-d3.rgb(s).b)),v=d3.rgb(d3.rgb(s).r+.8*(255-d3.rgb(s).r),d3.rgb(s).g+.8*(255-d3.rgb(s).g),d3.rgb(s).b+.8*(255-d3.rgb(s).b)),w=d.getTooltipText(a),x=0,y=0,z=0;null!==c._tooltipGroup&&void 0!==c._tooltipGroup&&c._tooltipGroup.remove(),c._tooltipGroup=c.svg.append("g"),i=d._isStacked()?1:p/2,d.x._hasCategories()||null===t.y||c._tooltipGroup.append("line").attr("x1",ny?this.getBBox().width:y,z=this.getBBox().width>z?this.getBBox().height:z}),e.selectAll("text").attr("x",0).attr("y",function(){return x+=this.getBBox().height,x-this.getBBox().height/2}),f.attr("x",-j).attr("y",-j).attr("height",Math.floor(x+j)-.5).attr("width",y+2*j).attr("rx",5).attr("ry",5).style("fill",v).style("stroke",u).style("stroke-width",2).style("opacity",.95),n+p+j+k+y0?(g=n-(j+k+y),h=o+q/2-(x-(z-j))/2):o+q+x+k+j0?g:k,g=g+y0?g:k,g=g+yv?this.getBBox().width:v,w=this.getBBox().width>w?this.getBBox().height:w}),e.selectAll("text").attr("x",0).attr("y",function(){return u+=this.getBBox().height,u-this.getBBox().height/2}),f.attr("x",-i).attr("y",-i).attr("height",Math.floor(u+i)-.5).attr("width",v+2*i).attr("rx",5).attr("ry",5).style("fill",t).style("stroke",s).style("stroke-width",2).style("opacity",.95),m+o+i+j+v0?(g=m-o-(i+j+v),h=n-(u-(w-i))/2):n+o+u+j+i0?g:j,g=g+v0?g:j,g=g+v-1&&d.push(a)},this)),d},dimple.getUniqueValues=function(a,b){var c=[];return null!==b&&void 0!==b&&(b=[].concat(b),a.forEach(function(a){var d="";b.forEach(function(b,c){c>0&&(d+="/"),d+=a[b]},this),-1===c.indexOf(d)&&c.push(d)},this)),c},dimple.newSvg=function(a,b,c){var d=null;if((null===a||void 0===a)&&(a="body"),d=d3.select(a),d.empty())throw"The '"+a+"' selector did not match any elements. Please prefix with '#' to select by id or '.' to select by class";return d.append("svg").attr("width",b).attr("height",c)}}(); \ No newline at end of file diff --git a/src/methods/_showBarTooltip.js b/src/methods/_showBarTooltip.js index 085db84..93d0652 100644 --- a/src/methods/_showBarTooltip.js +++ b/src/methods/_showBarTooltip.js @@ -48,7 +48,7 @@ } chart._tooltipGroup = chart.svg.append("g"); - offset = (series.stacked ? 1 : width / 2); + offset = (series._isStacked() ? 1 : width / 2); // Add a drop line to the x axis if (!series.x._hasCategories() && dropDest.y !== null) { @@ -72,7 +72,7 @@ .attr("y2", (y < dropDest.y ? dropDest.y - 1 : dropDest.y + 1)); } - offset = (series.stacked ? 1 : height / 2); + offset = (series._isStacked() ? 1 : height / 2); // Add a drop line to the y axis if (!series.y._hasCategories() && dropDest.x !== null) { diff --git a/src/objects/chart/methods/_getSeriesData.js b/src/objects/chart/methods/_getSeriesData.js index 5d3d652..6fce729 100644 --- a/src/objects/chart/methods/_getSeriesData.js +++ b/src/objects/chart/methods/_getSeriesData.js @@ -316,7 +316,7 @@ value = (axis.showPercent ? ret[pos + "Value"] / totals[opp][ret[opp + "Field"].join("/")] : ret[pos + "Value"]); totalField = ret[opp + "Field"].join("/") + (ret[pos + "Value"] >= 0); cumValue = running[pos][totalField] = ((running[pos][totalField] === null || running[pos][totalField] === undefined || pos === "z") ? 0 : running[pos][totalField]) + value; - selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series.stacked) ? cumValue : value); + selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series._isStacked()) ? cumValue : value); ret[size] = value; ret[pos] = selectValue - (((pos === "x" && value >= 0) || (pos === "y" && value <= 0)) ? value : 0); } else { @@ -327,7 +327,7 @@ catTotals[totalField] = value + (addedCats.length > 0 ? catTotals[addedCats[addedCats.length - 1]] : 0); addedCats.push(totalField); } - selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series.stacked) ? catTotals[totalField] : value); + selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series._isStacked()) ? catTotals[totalField] : value); ret[size] = value; ret[pos] = selectValue - (((pos === "x" && value >= 0) || (pos === "y" && value <= 0)) ? value : 0); } else { diff --git a/src/objects/plot/area.js b/src/objects/plot/area.js index 3b6fdd2..7dc0ebb 100644 --- a/src/objects/plot/area.js +++ b/src/objects/plot/area.js @@ -35,6 +35,7 @@ basePoints, basePoint, cat, + lastAngle, catCoord, valCoord, onEnter = function () { @@ -70,6 +71,29 @@ .x(function (d) { return (series.x._hasCategories() || !originProperty ? d.x : series.x[originProperty]); }) .y(function (d) { return (series.y._hasCategories() || !originProperty ? d.y : series.y[originProperty]); }) .interpolate(inter); + }, + sortByX = function (a, b) { + return parseFloat(a.x) - parseFloat(b.x); + }, + addNextPoint = function (source, target, startAngle) { + // Given a point we need to find the next point clockwise from the start angle + var i, + point = target[target.length - 1], + thisAngle, + bestAngleSoFar = 9999, + returnPoint = point; + for (i = 0; i < source.length; i += 1) { + if (source[i].x !== point.x || source[i].y !== point.y) { + // get the angle in degrees since start angle + thisAngle = 180 - (Math.atan2(source[i].x - point.x, source[i].y - point.y) * (180 / Math.PI)); + if (thisAngle > startAngle && thisAngle < bestAngleSoFar) { + returnPoint = source[i]; + bestAngleSoFar = thisAngle; + } + } + } + target.push(returnPoint); + return bestAngleSoFar; }; // Handle the special interpolation handling for step @@ -171,32 +195,64 @@ dimple._addGradient(areaData[i].key, "fill-area-gradient-" + areaData[i].keyString, (series.x._hasCategories() ? series.x : series.y), data, chart, duration, "fill"); } - // Iterate the point array because we need to fill in zero points for missing ones, otherwise the areas - // will cross where an upper area has no value and a lower value has a spike Issue #7 - for (j = 0, k = 0; j < allPoints.length; j += 1) { - // We are only interested in points between the first and last point of this areas data (i.e. don't fill ends - important - // for grouped area charts) - if (allPoints[j] >= points[0][catCoord] && allPoints[j] <= points[points.length - 1][catCoord]) { - // Get a base point, this needs to go on the base points array as well as filling in gaps in the point array. - // Create a point using the coordinate on the category axis and the last recorded value - // position from the dictionary - basePoint = {}; - basePoint[catCoord] = allPoints[j]; - basePoint[valCoord] = catPoints[allPoints[j]]; - // add the base point - basePoints.push(basePoint); - // handle missing points - if (points[k][catCoord] > allPoints[j]) { - // If there is a missing point we need to in fill - finalPointArray.push(basePoint); - } else { - // They must be the same - finalPointArray.push(points[k]); - // Use this to update the dictionary to the new value coordinate - catPoints[allPoints[j]] = points[k][valCoord]; - k += 1; + // All points will only be populated if there is a category axis + if (allPoints && allPoints.length > 0) { + // Iterate the point array because we need to fill in zero points for missing ones, otherwise the areas + // will cross where an upper area has no value and a lower value has a spike Issue #7 + for (j = 0, k = 0; j < allPoints.length; j += 1) { + // We are only interested in points between the first and last point of this areas data (i.e. don't fill ends - important + // for grouped area charts) + if (allPoints[j] >= points[0][catCoord] && allPoints[j] <= points[points.length - 1][catCoord]) { + // Get a base point, this needs to go on the base points array as well as filling in gaps in the point array. + // Create a point using the coordinate on the category axis and the last recorded value + // position from the dictionary + basePoint = {}; + basePoint[catCoord] = allPoints[j]; + basePoint[valCoord] = catPoints[allPoints[j]]; + // add the base point + basePoints.push(basePoint); + // handle missing points + if (points[k][catCoord] > allPoints[j]) { + // If there is a missing point we need to in fill + finalPointArray.push(basePoint); + } else { + // They must be the same + finalPointArray.push(points[k]); + // Use this to update the dictionary to the new value coordinate + catPoints[allPoints[j]] = points[k][valCoord]; + k += 1; + } } } + } else { + // If there is no category axis we need to apply some custom logic. In order to avoid + // really jagged areas the default behaviour will be to draw from the left most point then rotate a line + // clockwise until it hits another point and continue from each point until back to where we started. This + // means it will not connect every point, but it will contain every point: + // E.g. + // D + // C + // A B E + // F G + // H + // + // Would draw A -> C -> D -> E -> G -> H -> A + // + // This may not be what everyone wants so if there is a series order specified we will just join + // the points in that order instead. This will not allow users to skip points and therefore not achieve + // the default behaviour explicitly. + if (series._orderRules && series._orderRules.length > 0) { + finalPointArray = points.concat(points[0]); + } else { + // Find the leftmost point + points = points.sort(sortByX); + finalPointArray.push(points[0]); + lastAngle = 0; + // Iterate until the first and last points match + do { + lastAngle = addNextPoint(points, finalPointArray, lastAngle); + } while (finalPointArray.length <= points.length && (finalPointArray[0].x !== finalPointArray[finalPointArray.length - 1].x || finalPointArray[0].y !== finalPointArray[finalPointArray.length - 1].y)); + } } // The final array of points for the entire outskirts of the area diff --git a/src/objects/plot/bar.js b/src/objects/plot/bar.js index dcff2a7..cd9cfeb 100644 --- a/src/objects/plot/bar.js +++ b/src/objects/plot/bar.js @@ -17,8 +17,8 @@ classes = ["dimple-series-" + chart.series.indexOf(series), "dimple-bar"], updated, removed, - xFloat = !series.stacked && series.x._hasMeasure(), - yFloat = !series.stacked && series.y._hasMeasure(); + xFloat = !series._isStacked() && series.x._hasMeasure(), + yFloat = !series._isStacked() && series.y._hasMeasure(); if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { chart._tooltipGroup.remove(); diff --git a/src/objects/series/methods/_axisBounds.js b/src/objects/series/methods/_axisBounds.js index 7bb85c1..8a0f885 100644 --- a/src/objects/series/methods/_axisBounds.js +++ b/src/objects/series/methods/_axisBounds.js @@ -43,7 +43,7 @@ } else if (secondaryAxis === null || secondaryAxis.categoryFields === null || secondaryAxis.categoryFields.length === 0) { aggData.forEach(function (d) { // If the primary axis is stacked - if (this.stacked && (primaryAxis.position === "x" || primaryAxis.position === "y")) { + if (this._isStacked() && (primaryAxis.position === "x" || primaryAxis.position === "y")) { // We just need to push the bounds. A stacked axis will always include 0 so I just need to push the min and max out from there if (d[primaryAxis.position + "Value"] < 0) { bounds.min = bounds.min + d[primaryAxis.position + "Value"]; diff --git a/src/objects/series/methods/_isStacked.js b/src/objects/series/methods/_isStacked.js new file mode 100644 index 0000000..28886c2 --- /dev/null +++ b/src/objects/series/methods/_isStacked.js @@ -0,0 +1,6 @@ + // Copyright: 2014 PMSI-AlignAlytics + // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" + // Source: /src/objects/series/methods/_isStacked.js + this._isStacked = function() { + return this.stacked && (this.x._hasCategories() || this.y._hasCategories()); + }; \ No newline at end of file diff --git a/tmp/dimple.js b/tmp/dimple.js index 1d0148f..4d656de 100644 --- a/tmp/dimple.js +++ b/tmp/dimple.js @@ -964,7 +964,7 @@ var dimple = { value = (axis.showPercent ? ret[pos + "Value"] / totals[opp][ret[opp + "Field"].join("/")] : ret[pos + "Value"]); totalField = ret[opp + "Field"].join("/") + (ret[pos + "Value"] >= 0); cumValue = running[pos][totalField] = ((running[pos][totalField] === null || running[pos][totalField] === undefined || pos === "z") ? 0 : running[pos][totalField]) + value; - selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series.stacked) ? cumValue : value); + selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series._isStacked()) ? cumValue : value); ret[size] = value; ret[pos] = selectValue - (((pos === "x" && value >= 0) || (pos === "y" && value <= 0)) ? value : 0); } else { @@ -975,7 +975,7 @@ var dimple = { catTotals[totalField] = value + (addedCats.length > 0 ? catTotals[addedCats[addedCats.length - 1]] : 0); addedCats.push(totalField); } - selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series.stacked) ? catTotals[totalField] : value); + selectValue = ret[pos + "Bound"] = ret["c" + pos] = (((pos === "x" || pos === "y") && series._isStacked()) ? catTotals[totalField] : value); ret[size] = value; ret[pos] = selectValue - (((pos === "x" && value >= 0) || (pos === "y" && value <= 0)) ? value : 0); } else { @@ -2164,7 +2164,7 @@ var dimple = { } else if (secondaryAxis === null || secondaryAxis.categoryFields === null || secondaryAxis.categoryFields.length === 0) { aggData.forEach(function (d) { // If the primary axis is stacked - if (this.stacked && (primaryAxis.position === "x" || primaryAxis.position === "y")) { + if (this._isStacked() && (primaryAxis.position === "x" || primaryAxis.position === "y")) { // We just need to push the bounds. A stacked axis will always include 0 so I just need to push the min and max out from there if (d[primaryAxis.position + "Value"] < 0) { bounds.min = bounds.min + d[primaryAxis.position + "Value"]; @@ -2318,6 +2318,12 @@ var dimple = { }; // Copyright: 2014 PMSI-AlignAlytics // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" + // Source: /src/objects/series/methods/_isStacked.js + this._isStacked = function() { + return this.stacked && (this.x._hasCategories() || this.y._hasCategories()); + }; + // Copyright: 2014 PMSI-AlignAlytics + // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" // Source: /src/objects/series/methods/addEventHandler.js // Help: http://github.com/PMSI-AlignAlytics/dimple/wiki/dimple.series#wiki-addEventHandler this.addEventHandler = function (event, handler) { @@ -2637,6 +2643,7 @@ var dimple = { basePoints, basePoint, cat, + lastAngle, catCoord, valCoord, onEnter = function () { @@ -2672,6 +2679,29 @@ var dimple = { .x(function (d) { return (series.x._hasCategories() || !originProperty ? d.x : series.x[originProperty]); }) .y(function (d) { return (series.y._hasCategories() || !originProperty ? d.y : series.y[originProperty]); }) .interpolate(inter); + }, + sortByX = function (a, b) { + return parseFloat(a.x) - parseFloat(b.x); + }, + addNextPoint = function (source, target, startAngle) { + // Given a point we need to find the next point clockwise from the start angle + var i, + point = target[target.length - 1], + thisAngle, + bestAngleSoFar = 9999, + returnPoint = point; + for (i = 0; i < source.length; i += 1) { + if (source[i].x !== point.x || source[i].y !== point.y) { + // get the angle in degrees since start angle + thisAngle = 180 - (Math.atan2(source[i].x - point.x, source[i].y - point.y) * (180 / Math.PI)); + if (thisAngle > startAngle && thisAngle < bestAngleSoFar) { + returnPoint = source[i]; + bestAngleSoFar = thisAngle; + } + } + } + target.push(returnPoint); + return bestAngleSoFar; }; // Handle the special interpolation handling for step @@ -2773,32 +2803,64 @@ var dimple = { dimple._addGradient(areaData[i].key, "fill-area-gradient-" + areaData[i].keyString, (series.x._hasCategories() ? series.x : series.y), data, chart, duration, "fill"); } - // Iterate the point array because we need to fill in zero points for missing ones, otherwise the areas - // will cross where an upper area has no value and a lower value has a spike Issue #7 - for (j = 0, k = 0; j < allPoints.length; j += 1) { - // We are only interested in points between the first and last point of this areas data (i.e. don't fill ends - important - // for grouped area charts) - if (allPoints[j] >= points[0][catCoord] && allPoints[j] <= points[points.length - 1][catCoord]) { - // Get a base point, this needs to go on the base points array as well as filling in gaps in the point array. - // Create a point using the coordinate on the category axis and the last recorded value - // position from the dictionary - basePoint = {}; - basePoint[catCoord] = allPoints[j]; - basePoint[valCoord] = catPoints[allPoints[j]]; - // add the base point - basePoints.push(basePoint); - // handle missing points - if (points[k][catCoord] > allPoints[j]) { - // If there is a missing point we need to in fill - finalPointArray.push(basePoint); - } else { - // They must be the same - finalPointArray.push(points[k]); - // Use this to update the dictionary to the new value coordinate - catPoints[allPoints[j]] = points[k][valCoord]; - k += 1; + // All points will only be populated if there is a category axis + if (allPoints && allPoints.length > 0) { + // Iterate the point array because we need to fill in zero points for missing ones, otherwise the areas + // will cross where an upper area has no value and a lower value has a spike Issue #7 + for (j = 0, k = 0; j < allPoints.length; j += 1) { + // We are only interested in points between the first and last point of this areas data (i.e. don't fill ends - important + // for grouped area charts) + if (allPoints[j] >= points[0][catCoord] && allPoints[j] <= points[points.length - 1][catCoord]) { + // Get a base point, this needs to go on the base points array as well as filling in gaps in the point array. + // Create a point using the coordinate on the category axis and the last recorded value + // position from the dictionary + basePoint = {}; + basePoint[catCoord] = allPoints[j]; + basePoint[valCoord] = catPoints[allPoints[j]]; + // add the base point + basePoints.push(basePoint); + // handle missing points + if (points[k][catCoord] > allPoints[j]) { + // If there is a missing point we need to in fill + finalPointArray.push(basePoint); + } else { + // They must be the same + finalPointArray.push(points[k]); + // Use this to update the dictionary to the new value coordinate + catPoints[allPoints[j]] = points[k][valCoord]; + k += 1; + } } } + } else { + // If there is no category axis we need to apply some custom logic. In order to avoid + // really jagged areas the default behaviour will be to draw from the left most point then rotate a line + // clockwise until it hits another point and continue from each point until back to where we started. This + // means it will not connect every point, but it will contain every point: + // E.g. + // D + // C + // A B E + // F G + // H + // + // Would draw A -> C -> D -> E -> G -> H -> A + // + // This may not be what everyone wants so if there is a series order specified we will just join + // the points in that order instead. This will not allow users to skip points and therefore not achieve + // the default behaviour explicitly. + if (series._orderRules && series._orderRules.length > 0) { + finalPointArray = points.concat(points[0]); + } else { + // Find the leftmost point + points = points.sort(sortByX); + finalPointArray.push(points[0]); + lastAngle = 0; + // Iterate until the first and last points match + do { + lastAngle = addNextPoint(points, finalPointArray, lastAngle); + } while (finalPointArray.length <= points.length && (finalPointArray[0].x !== finalPointArray[finalPointArray.length - 1].x || finalPointArray[0].y !== finalPointArray[finalPointArray.length - 1].y)); + } } // The final array of points for the entire outskirts of the area @@ -2935,488 +2997,6 @@ var dimple = { }; - // Copyright: 2014 PMSI-AlignAlytics - // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" - // Source: /src/objects/plot/area.js - dimple.plot.area_old = { - stacked: true, - - supportedAxes: ["x", "y", "c"], - - draw: function (chart, series, duration) { - // Get self pointer for inner functions - var self = this, - data = series._positionData, - uniqueValues = [], - firstAgg = 1, - graded = false, - seriesClass = "series" + chart.series.indexOf(series), - line, - catPoints = {}, - markers, - markerBacks; - - if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { - chart._tooltipGroup.remove(); - } - - // If there is a category axis we should draw a line for each aggField. Otherwise - // the first aggField defines the points and the others define the line - if (series.x._hasCategories() || series.y._hasCategories()) { - firstAgg = 0; - } - data.forEach(function (d) { - var filter = [], - match = false, - k; - for (k = firstAgg; k < d.aggField.length; k += 1) { - filter.push(d.aggField[k]); - } - uniqueValues.forEach(function (e) { - match = match || (e === filter.join("/")); - }, this); - if (!match) { - uniqueValues.push(filter.join("/")); - } - }, this); - - if (series.c !== null && series.c !== undefined && ((series.x._hasCategories() && series.y._hasMeasure()) || (series.y._hasCategories() && series.x._hasMeasure()))) { - graded = true; - uniqueValues.forEach(function (seriesValue) { - dimple._addGradient(seriesValue, "fill-area-gradient-" + seriesValue.join("_").replace(" ", ""), (series.x._hasCategories() ? series.x : series.y), data, chart, duration, "fill"); - dimple._addGradient(seriesValue, "stroke-area-gradient-" + seriesValue.join("_").replace(" ", ""), (series.x._hasCategories() ? series.x : series.y), data, chart, duration, "stroke"); - }, this); - } - - line = d3.svg.line() - .x(function (d) { return dimple._helpers.cx(d, chart, series); }) - .y(function (d) { return dimple._helpers.cy(d, chart, series); }); - - if (series.shapes === null || series.shapes === undefined) { - series.shapes = chart._group.selectAll(".area." + seriesClass) - .data(uniqueValues) - .enter() - .append("svg:path") - .attr("opacity", function(d) { return chart.getColor(d).opacity; }); - } - - series.shapes - .data(uniqueValues) - .transition() - .duration(duration) - .attr("class", function (d) { return seriesClass + " series area " + d.split(" ").join("_"); }) - .attr("d", function (d) { - var seriesData, - baseline = [], - max = 0, - row, - newObj, - j, - k, - m, - q, - r; - seriesData = dimple.filterData(data, "aggField", d); - seriesData.sort(function (a, b) { - var sortValue = 0; - if (series.x._hasCategories()) { - sortValue = (dimple._helpers.cx(a, chart, series) < dimple._helpers.cx(b, chart, series) ? -1 : 1); - } else if (series.y._hasCategories()) { - sortValue = (dimple._helpers.cy(a, chart, series) < dimple._helpers.cy(b, chart, series) ? -1 : 1); - } - return sortValue; - }); - for (j = seriesData.length - 1; j >= 0; j -= 1) { - row = seriesData[j]; - newObj = { cx: 0, cy: 0, height: 0, width: 0, xOffset: 0, yOffset: 0 }; - if (series.x._hasCategories()) { - // Fix the x properties - newObj.cx = row.cx; - newObj.width = row.width; - newObj.xOffset = row.xOffset; - // Find the largest value for the xField less than this value - if (catPoints[row.xField] === undefined) { - catPoints[row.xField] = []; - } else { - max = 0; - for (k = 0; k <= catPoints[row.xField].length; k += 1) { - q = catPoints[row.xField][k]; - if ((row.cy >= 0 && q >= 0) || (row.cy <= 0 && q <= 0)) { - if (Math.abs(q) <= Math.abs(row.cy) && Math.abs(q) > Math.abs(max)) { - max = q; - } - } - } - newObj.cy = max; - } - baseline.push(newObj); - catPoints[row.xField].push(row.cy); - } else if (series.y._hasCategories()) { - // Fix the y properties - newObj.cy = row.cy; - newObj.height = row.height; - newObj.yOffset = row.yOffset; - // Find the largest value for the xField less than this value - if (catPoints[row.yField] === undefined) { - catPoints[row.yField] = []; - } else { - max = 0; - for (m = 0; m <= catPoints[row.yField].length; m += 1) { - r = catPoints[row.yField][m]; - if ((row.cx >= 0 && r >= 0) || (row.cx <= 0 && r <= 0)) { - if (Math.abs(r) <= Math.abs(row.cx) && Math.abs(r) > Math.abs(max)) { - max = r; - } - } - } - newObj.cx = max; - } - baseline.push(newObj); - catPoints[row.yField].push(row.cx); - } - } - //return line(startPoint.concat(seriesData).concat(endPoint)); - return line(seriesData.concat(baseline).concat(seriesData[0])); - }) - .call(function () { - if (!chart.noFormats) { - this.attr("fill", function (d) { return (graded ? "url(#fill-area-gradient-" + d.join("_").replace(" ", "") + ")" : chart.getColor(d).fill); }) - .attr("stroke", function (d) { return (graded ? "url(#stroke-area-gradient-" + d.join("_").replace(" ", "") + ")" : chart.getColor(d).stroke); }) - .attr("stroke-width", series.lineWeight); - } - }); - - if (series.lineMarkers) { - if (series._markerBacks === null || series._markerBacks === undefined) { - markerBacks = chart._group.selectAll(".markerBacks." + seriesClass).data(data); - } else { - markerBacks = series._markerBacks.data(data, function (d) { return d.key; }); - } - // Add - markerBacks - .enter() - .append("circle") - .attr("id", function (d) { return d.key; }) - .attr("class", "markerBacks " + seriesClass) - .attr("cx", function (d) { return dimple._helpers.cx(d, chart, series); }) - .attr("cy", function (d) { return dimple._helpers.cy(d, chart, series); }) - .attr("r", 0) - .attr("fill", "white") - .attr("stroke", "none"); - - // Update - markerBacks - .transition().duration(duration) - .attr("cx", function (d) { return dimple._helpers.cx(d, chart, series); }) - .attr("cy", function (d) { return dimple._helpers.cy(d, chart, series); }) - .attr("r", 2 + series.lineWeight); - // Remove - markerBacks - .exit() - .transition().duration(duration) - .attr("r", 0) - .each("end", function () { - d3.select(this).remove(); - }); - series._markerBacks = markerBacks; - } - - // Deal with markers in the same way as main series to fix #28 - if (series._markers === null || series._markers === undefined) { - markers = chart._group.selectAll(".markers." + seriesClass).data(data); - } else { - markers = series._markers.data(data, function (d) { return d.key; }); - } - - - // Add the actual marker. We need to do this even if we aren't displaying them because they - // catch hover events - markers - .enter() - .append("circle") - .attr("id", function (d) { return d.key; }) - .attr("class", "markers " + seriesClass) - .on("mouseover", function (e) { - self.enterEventHandler(e, this, chart, series); - }) - .on("mouseleave", function (e) { - self.leaveEventHandler(e, this, chart, series); - }) - .attr("cx", function (d) { return dimple._helpers.cx(d, chart, series); }) - .attr("cy", function (d) { return dimple._helpers.cy(d, chart, series); }) - .attr("r", 0) - .attr("opacity", function (d) { return (series.lineMarkers ? chart.getColor(d).opacity : 0); }) - .call(function () { - if (!chart.noFormats) { - this.attr("fill", "white") - .style("stroke-width", series.lineWeight) - .attr("stroke", function (d) { - return (graded ? dimple._helpers.fill(d, chart, series) : chart.getColor(d.aggField[d.aggField.length - 1]).stroke); - }); - } - }); - - markers - .transition().duration(duration) - .attr("cx", function (d) { return dimple._helpers.cx(d, chart, series); }) - .attr("cy", function (d) { return dimple._helpers.cy(d, chart, series); }) - .attr("r", 2 + series.lineWeight) - .call(function () { - if (!chart.noFormats) { - this.attr("fill", "white") - .style("stroke-width", series.lineWeight) - .attr("stroke", function (d) { - return (graded ? dimple._helpers.fill(d, chart, series) : chart.getColor(d.aggField[d.aggField.length - 1]).stroke); - }); - } - }); - - markers - .exit() - .transition().duration(duration) - .attr("r", 0) - .each("end", function () { - d3.select(this).remove(); - }); - - // Save the shapes to the series array - series._markers = markers; - }, - - // Handle the mouse enter event - enterEventHandler: function (e, shape, chart, series) { - - // The margin between the text and the box - var textMargin = 5, - // The margin between the ring and the popup - popupMargin = 10, - // The popup animation duration in ms - animDuration = 750, - // Collect some facts about the highlighted bubble - selectedShape = d3.select(shape), - cx = parseFloat(selectedShape.attr("cx")), - cy = parseFloat(selectedShape.attr("cy")), - r = parseFloat(selectedShape.attr("r")), - opacity = dimple._helpers.opacity(e, chart, series), - fill = dimple._helpers.fill(e, chart, series), - dropDest = series._dropLineOrigin(), - // Fade the popup stroke mixing the shape fill with 60% white - popupStrokeColor = d3.rgb( - d3.rgb(fill).r + 0.6 * (255 - d3.rgb(fill).r), - d3.rgb(fill).g + 0.6 * (255 - d3.rgb(fill).g), - d3.rgb(fill).b + 0.6 * (255 - d3.rgb(fill).b) - ), - // Fade the popup fill mixing the shape fill with 80% white - popupFillColor = d3.rgb( - d3.rgb(fill).r + 0.8 * (255 - d3.rgb(fill).r), - d3.rgb(fill).g + 0.8 * (255 - d3.rgb(fill).g), - d3.rgb(fill).b + 0.8 * (255 - d3.rgb(fill).b) - ), - t, - y = 0, - w = 0, - h = 0, - box, - overlap, - rows = []; - - if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { - chart._tooltipGroup.remove(); - } - chart._tooltipGroup = chart.svg.append("g"); - - // On hover make the line marker visible immediately - selectedShape.style("opacity", 1); - // Add a ring around the data point - chart._tooltipGroup.append("circle") - .attr("cx", cx) - .attr("cy", cy) - .attr("r", r) - .attr("opacity", 0) - .style("fill", "none") - .style("stroke", fill) - .style("stroke-width", 1) - .transition() - .duration(animDuration / 2) - .ease("linear") - .attr("opacity", 1) - .attr("r", r + 4) - .style("stroke-width", 2); - - // Add a drop line to the x axis - if (dropDest.y !== null) { - chart._tooltipGroup.append("line") - .attr("x1", cx) - .attr("y1", (cy < dropDest.y ? cy + r + 4 : cy - r - 4)) - .attr("x2", cx) - .attr("y2", (cy < dropDest.y ? cy + r + 4 : cy - r - 4)) - .style("fill", "none") - .style("stroke", fill) - .style("stroke-width", 2) - .style("stroke-dasharray", ("3, 3")) - .style("opacity", opacity) - .transition() - .delay(animDuration / 2) - .duration(animDuration / 2) - .ease("linear") - // Added 1px offset to cater for svg issue where a transparent - // group overlapping a line can sometimes hide it in some browsers - // Issue #10 - .attr("y2", (cy < dropDest.y ? dropDest.y - 1 : dropDest.y + 1)); - } - - // Add a drop line to the y axis - if (dropDest.x !== null) { - chart._tooltipGroup.append("line") - .attr("x1", (cx < dropDest.x ? cx + r + 4 : cx - r - 4)) - .attr("y1", cy) - .attr("x2", (cx < dropDest.x ? cx + r + 4 : cx - r - 4)) - .attr("y2", cy) - .style("fill", "none") - .style("stroke", fill) - .style("stroke-width", 2) - .style("stroke-dasharray", ("3, 3")) - .style("opacity", opacity) - .transition() - .delay(animDuration / 2) - .duration(animDuration / 2) - .ease("linear") - // Added 1px offset to cater for svg issue where a transparent - // group overlapping a line can sometimes hide it in some browsers - // Issue #10 - .attr("x2", (cx < dropDest.x ? dropDest.x - 1 : dropDest.x + 1)); - } - - // Add a group for text - t = chart._tooltipGroup.append("g"); - // Create a box for the popup in the text group - box = t.append("rect") - .attr("class", "chartTooltip"); - - // Add the series categories - if (series.categoryFields !== null && series.categoryFields !== undefined && series.categoryFields.length > 0) { - series.categoryFields.forEach(function (c, i) { - if (c !== null && c !== undefined && e.aggField[i] !== null && e.aggField[i] !== undefined) { - // If the category name and value match don't display the category name - rows.push(c + (e.aggField[i] !== c ? ": " + e.aggField[i] : "")); - } - }, this); - } - - if (series.x._hasTimeField()) { - if (e.xField[0] !== null && e.xField[0] !== undefined) { - rows.push(series.x.timeField + ": " + series.x._getFormat()(e.xField[0])); - } - } else if (series.x._hasCategories()) { - // Add the x axis categories - series.x.categoryFields.forEach(function (c, i) { - if (c !== null && c !== undefined && e.xField[i] !== null && e.xField[i] !== undefined) { - // If the category name and value match don't display the category name - rows.push(c + (e.xField[i] !== c ? ": " + e.xField[i] : "")); - } - }, this); - } else { - // Add the axis measure value - if (series.x.measure !== null && series.x.measure !== undefined && e.width !== null && e.width !== undefined) { - rows.push(series.x.measure + ": " + series.x._getFormat()(e.width)); - } - } - - if (series.y._hasTimeField()) { - if (e.yField[0] !== null && e.yField[0] !== undefined) { - rows.push(series.y.timeField + ": " + series.y._getFormat()(e.yField[0])); - } - } else if (series.y._hasCategories()) { - // Add the y axis categories - series.y.categoryFields.forEach(function (c, i) { - if (c !== null && c !== undefined && e.yField[i] !== null && e.yField[i] !== undefined) { - rows.push(c + (e.yField[i] !== c ? ": " + e.yField[i] : "")); - } - }, this); - } else { - // Add the axis measure value - if (series.y.measure !== null && series.y.measure !== undefined && e.height !== null && e.height !== undefined) { - rows.push(series.y.measure + ": " + series.y._getFormat()(e.height)); - } - } - - if (series.z !== null && series.z !== undefined) { - // Add the axis measure value - if (series.z.measure !== null && series.z.measure !== undefined && e.zValue !== null && e.zValue !== undefined) { - rows.push(series.z.measure + ": " + series.z._getFormat()(e.zValue)); - } - } - - if (series.c !== null && series.c !== undefined) { - // Add the axis measure value - if (series.c.measure !== null && series.c.measure !== undefined && e.cValue !== null && e.cValue !== undefined) { - rows.push(series.c.measure + ": " + series.c._getFormat()(e.cValue)); - } - } - - // Get distinct text rows to deal with cases where 2 axes have the same dimensionality - rows = rows.filter(function(elem, pos) { - return rows.indexOf(elem) === pos; - }); - - // Create a text object for every row in the popup - t.selectAll(".textHoverShapes").data(rows).enter() - .append("text") - .attr("class", "chartTooltip") - .text(function (d) { return d; }) - .style("font-family", "sans-serif") - .style("font-size", "10px"); - - // Get the max height and width of the text items - t.each(function () { - w = (this.getBBox().width > w ? this.getBBox().width : w); - h = (this.getBBox().width > h ? this.getBBox().height : h); - }); - - // Position the text relative to the bubble, the absolute positioning - // will be done by translating the group - t.selectAll("text") - .attr("x", 0) - .attr("y", function () { - // Increment the y position - y += this.getBBox().height; - // Position the text at the centre point - return y - (this.getBBox().height / 2); - }); - - // Draw the box with a margin around the text - box.attr("x", -textMargin) - .attr("y", -textMargin) - .attr("height", Math.floor(y + textMargin) - 0.5) - .attr("width", w + 2 * textMargin) - .attr("rx", 5) - .attr("ry", 5) - .style("fill", popupFillColor) - .style("stroke", popupStrokeColor) - .style("stroke-width", 2) - .style("opacity", 0.95); - - // Shift the ring margin left or right depending on whether it will overlap the edge - overlap = cx + r + textMargin + popupMargin + w > parseFloat(chart.svg.node().getBBox().width); - - // Translate the shapes to the x position of the bubble (the x position of the shapes is handled) - t.attr("transform", "translate(" + - (overlap ? cx - (r + textMargin + popupMargin + w) : cx + r + textMargin + popupMargin) + " , " + - (cy - ((y - (h - textMargin)) / 2)) + - ")"); - }, - - // Handle the mouse leave event - leaveEventHandler: function (e, shape, chart, series) { - // Return the opacity of the marker - d3.select(shape).style("opacity", (series.lineMarkers ? dimple._helpers.opacity(e, chart, series) : 0)); - if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { - chart._tooltipGroup.remove(); - } - } - }; - - // Copyright: 2014 PMSI-AlignAlytics // License: "https://github.com/PMSI-AlignAlytics/dimple/blob/master/MIT-LICENSE.txt" // Source: /src/objects/plot/bar.js @@ -3436,8 +3016,8 @@ var dimple = { classes = ["dimple-series-" + chart.series.indexOf(series), "dimple-bar"], updated, removed, - xFloat = !series.stacked && series.x._hasMeasure(), - yFloat = !series.stacked && series.y._hasMeasure(); + xFloat = !series._isStacked() && series.x._hasMeasure(), + yFloat = !series._isStacked() && series.y._hasMeasure(); if (chart._tooltipGroup !== null && chart._tooltipGroup !== undefined) { chart._tooltipGroup.remove(); @@ -4714,7 +4294,7 @@ var dimple = { } chart._tooltipGroup = chart.svg.append("g"); - offset = (series.stacked ? 1 : width / 2); + offset = (series._isStacked() ? 1 : width / 2); // Add a drop line to the x axis if (!series.x._hasCategories() && dropDest.y !== null) { @@ -4738,7 +4318,7 @@ var dimple = { .attr("y2", (y < dropDest.y ? dropDest.y - 1 : dropDest.y + 1)); } - offset = (series.stacked ? 1 : height / 2); + offset = (series._isStacked() ? 1 : height / 2); // Add a drop line to the y axis if (!series.y._hasCategories() && dropDest.x !== null) {