Skip to content

Commit

Permalink
Worked on polar charts
Browse files Browse the repository at this point in the history
  • Loading branch information
TorsteinHonsi committed May 8, 2012
1 parent ab7d489 commit cd97ec3
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 68 deletions.
172 changes: 150 additions & 22 deletions js/highcharts-more.src.js
Expand Up @@ -37,11 +37,12 @@ var radialAxisMixin = {
/**
* The default options extend defaultYAxisOptions
*/
defaultCircularAxisOptions: {
defaultRadialGaugeOptions: {
center: ['50%', '50%'],
labels: {
align: 'center',
x: 0
x: 0,
y: null // auto
},
minorGridLineWidth: 0,
minorTickInterval: 'auto',
Expand All @@ -59,6 +60,31 @@ var radialAxisMixin = {
zIndex: 2 // behind dials, points in the series group
},

defaultRadialXOptions: {
center: ['50%', '50%'],
labels: {
align: 'center',
distance: 15,
x: 0,
y: null // auto
},
maxPadding: 0,
minPadding: 0,
size: ['90%']

},

defaultRadialYOptions: {
center: ['50%', '50%'],
labels: {
align: 'left',
x: 2,
y: -2
},
size: ['90%'],
tickWidth: 0
},

/**
* The default background options
*/
Expand Down Expand Up @@ -89,7 +115,7 @@ var radialAxisMixin = {

axis.options = options = merge(
axis.defaultOptions,
axis.defaultCircularAxisOptions,
axis.defaultRadialOptions,
userOptions
);

Expand Down Expand Up @@ -151,16 +177,15 @@ var radialAxisMixin = {
setAxisTranslation: function () {

axisProto.setAxisTranslation.call(this);

var m = this.minPixelPadding;

if (this.center) { // it's not defined the first time
this.transA = this.isCircular ?
(this.endAngleRad - this.startAngleRad) / ((this.max - this.min + (this.closestPointRange || 0)) || 1) :
(this.center[2] / 2) / ((this.max - this.min) || 1);


this.minPixelPadding = this.transA * ((this.pointRange || 0) / 2);
}

this.minPixelPadding = 0; // TODO: handle this
},

/**
Expand Down Expand Up @@ -188,18 +213,27 @@ var radialAxisMixin = {
value = this.min;
}

var chart = this.chart,
center = this.center,
angle = this.startAngleRad + this.translate(value),
radius = pick(length, center[2] / 2) - this.offset;
return this.postTranslate(
this.translate(value),
pick(length, this.center[2] / 2) - this.offset
);
},

/**
* Translate from intermediate plotX (angle), plotY (axis.len - radius) to final chart coordinates.
*/
postTranslate: function (angle, radius) {

var chart = this.chart,
center = this.center;

angle = this.startAngleRad + angle;

return {
x: chart.plotLeft + center[0] + Math.cos(angle) * radius,
y: chart.plotTop + center[1] + Math.sin(angle) * radius
};


},

/**
Expand Down Expand Up @@ -295,7 +329,7 @@ var radialAxisMixin = {
axisProto.init = (function (func) {
return function (chart, userOptions) {
var angular = chart.angular,
polar = chart.options.chart.polar,
polar = chart.polar,
isX = userOptions.isX,
isCircular,
options;
Expand All @@ -305,11 +339,15 @@ axisProto.init = (function (func) {
//extend(this, isX ? gaugeXAxisMixin : radialAxisMixin);
extend(this, isX ? gaugeXAxisMixin : radialAxisMixin);
isCircular = !isX;
if (isCircular) {
this.defaultRadialOptions = this.defaultGaugeOptions;
}

} else if (polar) {
//extend(this, userOptions.isX ? radialAxisMixin : radialAxisMixin);
extend(this, radialAxisMixin);
isCircular = isX;
this.defaultRadialOptions = isX ? this.defaultRadialXOptions : this.defaultRadialYOptions;
}

// Run prototype.init
Expand Down Expand Up @@ -356,6 +394,7 @@ tickProto.getLabelPosition = (function (func) {
var axis = this.axis,
labelOptions = axis.options.labels,
label = this.label,
optionsY = labelOptions.y,
ret;

if (axis.isRadial) {
Expand All @@ -368,11 +407,12 @@ tickProto.getLabelPosition = (function (func) {
});

// Vertically centered
} else if (labelOptions.y === null) {
// TODO: new fontMetric logic
ret.y += pInt(label.styles.lineHeight) * 0.9 - label.getBBox().height / 2;
} else if (optionsY === null) {
optionsY = pInt(label.styles.lineHeight) * 0.9 - label.getBBox().height / 2;
}

ret.x += labelOptions.x;
ret.y += optionsY;

} else {
ret = func.apply(this, arguments);
Expand Down Expand Up @@ -849,28 +889,116 @@ seriesTypes.gauge = Highcharts.extendClass(seriesTypes.line, GaugeSeries);/**
* - http://jsfiddle.net/highcharts/2Y5yF/
*/

var seriesProto = Series.prototype,
columnProto = seriesTypes.column.prototype;

Series.prototype.translate = (function (func) {

/**
* Override translate. The plotX and plotY values are computed as if the polar chart were a
* cartesian plane, where plotX denotes the angle in radians and (yAxis.len - plotY) is the pixel distance from
* center.
*/
seriesProto.translate = (function (func) {
return function () {

// Run uber method
func.apply(this, arguments);

// Postprocess plot coordinates
if (this.xAxis.getPosition) {
if (this.xAxis.getPosition && this.type !== 'column') { // TODO: do not use this.type
var points = this.points,
i = points.length,
point,
chart = this.chart,
xy;
while (i--) {
point = points[i];
xy = this.xAxis.getPosition(point.x, this.yAxis.len - point.plotY);
point.plotX = xy.x - chart.plotLeft;
point.plotY = xy.y - chart.plotTop;

// save rectangular plotX, plotY for later computation
point.rectPlotX = point.plotX;
point.rectPlotY = point.plotY;

// find the polar plotX and plotY
xy = this.xAxis.postTranslate(point.plotX, this.yAxis.len - point.plotY);
point.plotX = point.polarPlotX = xy.x - chart.plotLeft;
point.plotY = point.polarPlotY = xy.y - chart.plotTop;
}
}
};
}(seriesProto.translate));

columnProto.translate = (function (func) {
return function () {

var xAxis = this.xAxis,
len = this.yAxis.len,
center = xAxis.center,
startAngleRad = xAxis.startAngleRad,
renderer = this.chart.renderer;

// Run uber method
func.apply(this, arguments);

// Postprocess plot coordinates
if (xAxis.isRadial) {
each(this.points, function (point) {
point.shapeType = 'path';
point.shapeArgs = renderer.symbols.arc(
center[0],
center[1],
len - point.plotY,
null,
{
start: startAngleRad + point.barX,
end: startAngleRad + point.barX + point.pointWidth,
//open: true,
innerR: 0
}
);
});
}
};
}(columnProto.translate));


/*seriesProto.getSegmentPath = (function (func) {
return function () {
var segmentPath,
i,
xy,
chart = this.chart,
isRadial = this.xAxis.isRadial;
// To rectangle coordinate system
if (isRadial) {
each(this.points, function (point) {
point.plotX = point.rectPlotX;
point.plotY = point.rectPlotY;
});
}
// Run uber method
segmentPath = func.apply(this, arguments);
if (isRadial) {
for (i = 0; i < segmentPath.length; i++) {
if (typeof segmentPath[i] === 'number') {
xy = this.xAxis.postTranslate(segmentPath[i], this.yAxis.len - segmentPath[i + 1]);
segmentPath[i] = xy.x - chart.plotLeft;
segmentPath[i + 1] = xy.y - chart.plotTop;
i = i + 1;
}
}
// To polar coordinate system
each(this.points, function (point) {
point.plotX = point.polarPlotX;
point.plotY = point.polarPlotY;
});
}
return segmentPath;
};
}(Series.prototype.translate));
}(seriesProto.getSegmentPath));*/

}(Highcharts));
19 changes: 11 additions & 8 deletions js/highcharts.src.js
Expand Up @@ -10189,7 +10189,7 @@ Chart.prototype = {
value;


each(['inverted', 'angular'], function (key) {
each(['inverted', 'angular', 'polar'], function (key) {

// The default series type's class
klass = seriesTypes[optionsChart.type || optionsChart.defaultSeriesType];
Expand Down Expand Up @@ -11736,7 +11736,8 @@ Series.prototype = {
pointStackTotal;

// get the plotX translation
point.plotX = mathRound(xAxis.translate(xValue, 0, 0, 0, 1) * 10) / 10; // Math.round fixes #591
//point.plotX = mathRound(xAxis.translate(xValue, 0, 0, 0, 1) * 10) / 10; // Math.round fixes #591
point.plotX = xAxis.translate(xValue, 0, 0, 0, 1); // Math.round fixes #591

// calculate the bottom y value for stacked series
if (stacking && series.visible && stack && stack[xValue]) {
Expand Down Expand Up @@ -13300,14 +13301,15 @@ var ColumnSeries = extendClass(Series, {
// the number of column series in the plot, the groupPadding
// and the pointPadding options
var points = series.points,
categoryWidth = mathAbs(xAxis.translationSlope) * (xAxis.ordinalSlope || xAxis.closestPointRange || 1),
categoryWidth = mathAbs(xAxis.transA) * (xAxis.ordinalSlope || xAxis.closestPointRange || 1),
groupPadding = categoryWidth * options.groupPadding,
groupWidth = categoryWidth - 2 * groupPadding,
pointOffsetWidth = groupWidth / columnCount,
optionPointWidth = options.pointWidth,
pointPadding = defined(optionPointWidth) ? (pointOffsetWidth - optionPointWidth) / 2 :
pointOffsetWidth * options.pointPadding,
pointWidth = mathCeil(mathMax(pick(optionPointWidth, pointOffsetWidth - 2 * pointPadding), 1 + 2 * borderWidth)),
pointWidth = pick(optionPointWidth, pointOffsetWidth - 2 * pointPadding), // exact point width, used in polar charts
barW = mathCeil(mathMax(pointWidth, 1 + 2 * borderWidth)), // rounded and postprocessed for border width
colIndex = (reversedXAxis ? columnCount -
series.columnIndex : series.columnIndex) || 0,
pointXOffset = pointPadding + (groupPadding + colIndex *
Expand All @@ -13329,7 +13331,7 @@ var ColumnSeries = extendClass(Series, {

// Record the offset'ed position and width of the bar to be able to align the stacking total correctly
if (stacking && series.visible && stack && stack[point.x]) {
stack[point.x].setOffset(pointXOffset, pointWidth);
stack[point.x].setOffset(pointXOffset, barW);
}

// handle options.minPointLength
Expand All @@ -13346,16 +13348,17 @@ var ColumnSeries = extendClass(Series, {
extend(point, {
barX: barX,
barY: barY,
barW: pointWidth,
barH: barH
barW: barW,
barH: barH,
pointWidth: pointWidth
});

// create shape type and shape args that are reused in drawPoints and drawTracker
point.shapeType = 'rect';
shapeArgs = {
x: barX,
y: barY,
width: pointWidth,
width: barW,
height: barH,
r: options.borderRadius,
strokeWidth: borderWidth
Expand Down

0 comments on commit cd97ec3

Please sign in to comment.