leftout
Posts: 20
Joined: Tue May 31, 2011 2:12 am

Boxplot is transparent...

I followed OHLC and Candlestick series to make boxplot series. I am having problem with the box, as it's transparent. If you look at the picture, the candlesticks are not transparent but the boxplots are transparent. What am I missing?
I extended column, Point, and column for defaultPlotOptions, BoxplotPoint, and BoxplotSeries respectively.
Can samebody help me?
Thank you.
Attachments
boxplot.JPG
boxplot.JPG (33.09 KiB) Viewed 7642 times
hfrntt
Posts: 6393
Joined: Mon Aug 30, 2010 8:41 am
Contact: Website

Re: Boxplot is transparent...

Could you post a link to your chart, or set up an example on jsfiddle.net?
Slawek Kolodziej
Highcharts support team
jlbriggs
Posts: 1465
Joined: Tue Sep 21, 2010 2:33 pm

Re: Boxplot is transparent...

leftout - would you mind sharing your method for achieving this?

It would be greatly appreciated.
fiddles: http://jsfiddle.net/jlbriggs/J9JLr/
leftout
Posts: 20
Joined: Tue May 31, 2011 2:12 am

Re: Boxplot is transparent...

Hey I have sent you the message. Check your inbox. And please let me know if you come up with something better.
jlbriggs
Posts: 1465
Joined: Tue Sep 21, 2010 2:33 pm

Re: Boxplot is transparent...

Great. I have got it up and working - thanks a lot.

As for the transparency issue - looking through the code, it appears that it takes 'color' to specify the border color, and borderColor to specify the fill color.
fiddles: http://jsfiddle.net/jlbriggs/J9JLr/
leftout
Posts: 20
Joined: Tue May 31, 2011 2:12 am

Re: Boxplot is transparent...

Yes that's right.
PratikHada
Posts: 4
Joined: Fri Dec 30, 2011 9:34 am

Re: Boxplot is transparent...

@leftout can you please share the method for achieving the implementation of boxplot with me too. I am really confused with this candelstick and ohlc. Please Help
Thanks
leftout
Posts: 20
Joined: Tue May 31, 2011 2:12 am

Re: Boxplot is transparent...

@PratikHada

No problem. I have messaged it to you. Please check it out. Also it might take a while cause as of now it's still in my outbox.
PratikHada
Posts: 4
Joined: Fri Dec 30, 2011 9:34 am

Re: Boxplot is transparent...

@leftout thanks, will share you if i came up with something better .
uhjish
Posts: 1
Joined: Thu Feb 16, 2012 7:33 pm

Re: Boxplot is transparent...

@leftout,
I'm also trying hack up boxplots based on highstock.
I would love to see your solution and help iterate it forward.
Thanks,
-'jish
hfrntt
Posts: 6393
Joined: Mon Aug 30, 2010 8:41 am
Contact: Website

Re: Boxplot is transparent...

@leftout if you want to share your solution with others, it's a good idea to post it here in the attachment :)
Slawek Kolodziej
Highcharts support team
jlbriggs
Posts: 1465
Joined: Tue Sep 21, 2010 2:33 pm

Re: Boxplot is transparent...

This is the modified file, built on the ohlc module, that I have used.
I didn't make the modifications myself, I used it as is from what I think are leftout's modifications.

Code: Select all

/* ohlc.src.js */
/**
* @license Highcharts JS v2.1.4 (2011-03-02)
* Candlestick/OHLC series module, Beta
*
* (c) 2010 Torstein H├©nsi
*
* License: http://www.highcharts.com/license
*/


(function(){ // encapsulate

// create shortcuts
var HC = Highcharts,
addEvent = HC.addEvent,
defaultOptions = HC.getOptions(),
defaultPlotOptions = defaultOptions.plotOptions,
seriesTypes = HC.seriesTypes,
extend = HC.extend,
each = HC.each,
map = HC.map,
merge = HC.merge,
math = Math,
mathRound = math.round;


/*****************************************************************************
* Start OHLC series code *
*****************************************************************************/

// 1 - Set default options
defaultPlotOptions.OHLC = merge(defaultPlotOptions.column, {
animation: false,
lineWidth: 1,
states: {
hover: {
//brightness: 0.1,
lineWidth: 3
}
}
});

// 2- Create the OHLCPoint object
var OHLCPoint = Highcharts.extendClass(Highcharts.Point, {
/**
* Apply the options containing the x and OHLC data and possible some extra properties.
* This is called on point init or from point.update. Extends base Point by adding
* multiple y-like values.
*
* @param {Object} options
*/
applyOptions: function(options) {
var point = this,
series = point.series,
n,
i = 0;


// object input for example:
// { x: Date(2010, 0, 1), open: 7.88, high: 7.99, low: 7.02, close: 7.65 }
if (typeof options == 'object' && typeof options.length != 'number') {

// copy options directly to point
extend(point, options);

point.options = options;
}

// array
else if (options.length) {
// with leading x value
if (options.length == 5) {
if (typeof options[0] == 'string') {
point.name = options[0];
} else if (typeof options[0] == 'number') {
point.x = options[0];
}
i++;
}
point.open = options[i++];
point.high = options[i++];
point.low = options[i++];
point.close = options[i++];
}

/*
* If no x is set by now, get auto incremented value. All points must have an
* x value, however the y value can be null to create a gap in the series
*/

point.y = point.high;
if (point.x === undefined) {
point.x = series.autoIncrement();
}

},

/**
* A specific OHLC tooltip formatter
*/
tooltipFormatter: function(useHeader) {
var point = this,
series = point.series;

return ['<span style="color:'+ series.color +';font-weight:bold">', (point.name || series.name), '</span><br/> ',
'Open: ', point.open, '<br/>',
'High: ', point.y, '<br/>',
'Low: ', point.low, '<br/>',
'Close: ', point.close].join('');

}

});

// 3 - Create the OHLCSeries object
var OHLCSeries = Highcharts.extendClass(seriesTypes.column, {
type: 'OHLC',
pointClass: OHLCPoint,

pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
stroke: 'color',
'stroke-width': 'lineWidth'
},


/**
* Translate data points from raw values x and y to plotX and plotY
*/
translate: function() {
var chart = this.chart,
series = this,
categories = series.xAxis.categories,
yAxis = series.yAxis,
stack = yAxis.stacks[series.type];

seriesTypes.column.prototype.translate.apply(series);

// do the translation
each(this.data, function(point) {
// the graphics
point.plotOpen = yAxis.translate(point.open, 0, 1);
point.plotClose = yAxis.translate(point.close, 0, 1);

});
},

/**
* Draw the data points
*/
drawPoints: function() {
var series = this, //state = series.state,
//layer = series.stateLayers[state],
seriesOptions = series.options,
seriesStateAttr = series.stateAttr,
data = series.data,
chart = series.chart,
pointAttr,
pointOpen,
pointClose,
crispCorr,
halfWidth,
path,
graphic,
crispX;


each(data, function(point) {
graphic = point.graphic;
if (point.plotY !== undefined &&
point.plotX >= 0 && point.plotX <= chart.plotSizeX &&
point.plotY >= 0 && point.plotY <= chart.plotSizeY) {

pointAttr = point.pointAttr[point.selected ? 'selected' : ''];

// crisp vector coordinates
crispCorr = (pointAttr['stroke-width'] % 2) / 2;
crispX = mathRound(point.plotX) + crispCorr;
plotOpen = mathRound(point.plotOpen) + crispCorr;
plotClose = mathRound(point.plotClose) + crispCorr;
halfWidth = mathRound(point.barW / 2);


path = [
'M',
crispX, mathRound(point.yBottom),
'L',
crispX, mathRound(point.plotY),
'M',
crispX, plotOpen,
'L',
crispX - halfWidth, plotOpen,
'M',
crispX, plotClose,
'L',
crispX + halfWidth, plotClose,
'Z'
];


if (graphic) {
graphic.animate({
d: path
});
} else {
point.graphic = chart.renderer.path(path)
.attr(pointAttr)
.add(series.group);
}

} else if (graphic) {
point.graphic = graphic.destroy();
}

});

}


});
seriesTypes.OHLC = OHLCSeries;
/*****************************************************************************
* End OHLC series code *
*****************************************************************************/


/*****************************************************************************
* Start Candlestick series code *
*****************************************************************************/

// 1 - set default options
defaultPlotOptions.candlestick = merge(defaultPlotOptions.column, {
animation: false,
lineColor: 'black',
lineWidth: 2,
upColor: 'white',
states: {
hover: {
lineWidth: 3
}
}
});

// 3 - Create the CandlestickSeries object
var CandlestickSeries = Highcharts.extendClass(OHLCSeries, {
type: 'candlestick',

/**
* One-to-one mapping from options to SVG attributes
*/
pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
fill: 'color',
stroke: 'lineColor',
'stroke-width': 'lineWidth'
},

/**
* Postprocess mapping between options and SVG attributes
*/
getAttribs: function() {
OHLCSeries.prototype.getAttribs.apply(this, arguments);
var series = this,
options = series.options,
stateOptions = options.states,
upColor = options.upColor,
seriesDownPointAttr = merge(series.pointAttr);

seriesDownPointAttr[''].fill = upColor;
seriesDownPointAttr.hover.fill = stateOptions.hover.upColor || upColor;
seriesDownPointAttr.select.fill = stateOptions.select.upColor || upColor;

each(series.data, function(point) {
if (point.open < point.close) {
point.pointAttr = seriesDownPointAttr;
}
});
},

/**
* Draw the data points
*/
drawPoints: function() {
var series = this, //state = series.state,
//layer = series.stateLayers[state],
seriesOptions = series.options,
seriesStateAttr = series.stateAttr,
data = series.data,
chart = series.chart,
pointAttr,
pointOpen,
pointClose,
topBox,
bottomBox,
crispCorr,
crispX,
graphic,
path,
halfWidth;


each(data, function(point) {

graphic = point.graphic;

if (point.plotY !== undefined &&
point.plotX >= 0 && point.plotX <= chart.plotSizeX &&
point.plotY >= 0 && point.plotY <= chart.plotSizeY) {

pointAttr = point.pointAttr[point.selected ? 'selected' : ''];

// crisp vector coordinates
crispCorr = (pointAttr['stroke-width'] % 2) / 2;
crispX = mathRound(point.plotX) + crispCorr;
plotOpen = mathRound(point.plotOpen) + crispCorr;
plotClose = mathRound(point.plotClose) + crispCorr;
topBox = math.min(plotOpen, plotClose);
bottomBox = math.max(plotOpen, plotClose);
halfWidth = mathRound(point.barW / 2);

// create the path
path = [
'M',
crispX - halfWidth, bottomBox,
'L',
crispX - halfWidth, topBox,
'L',
crispX + halfWidth, topBox,
'L',
crispX + halfWidth, bottomBox,
'L',
crispX - halfWidth, bottomBox,
'M',
crispX, bottomBox,
'L',
crispX, mathRound(point.yBottom),
'M',
crispX, topBox,
'L',
crispX, mathRound(point.plotY),
'Z'
];

if (graphic) {
graphic.animate({
d: path
});
} else {
point.graphic = chart.renderer.path(path)
.attr(pointAttr)
.add(series.group);
}

} else if (graphic) {
point.graphic = graphic.destroy();
}

});

}


});

seriesTypes.candlestick = CandlestickSeries;

/*****************************************************************************
* End Candlestick series code *
*****************************************************************************/


/*****************************************************************************
* Start BoxPlot series code *
*****************************************************************************/

// 1 - Set default options
defaultPlotOptions.boxplot = merge(defaultPlotOptions.column, {
animation: false,
borderWidth: 2,
states: {
hover: {
//brightness: 0.1,
borderWidth: 3
}
}
});

// 2- Create the OHLCPoint object
var BoxplotPoint = Highcharts.extendClass(Highcharts.Point, {
/**
* Apply the options containing the x and OHLC data and possible some extra properties.
* This is called on point init or from point.update. Extends base Point by adding
* multiple y-like values.
*
* @param {Object} options
*/
applyOptions: function(options) {
var point = this,
series = point.series,
n,
i = 0;


// object input for example:
// { x: Date(2010, 0, 1), open: 7.88, high: 7.99, low: 7.02, close: 7.65 }
if (typeof options == 'object' && typeof options.length != 'number') {

// copy options directly to point
extend(point, options);

point.options = options;
}

// array
else if (options.length) {
// with leading x value
if (options.length == 6) {
if (typeof options[0] == 'string') {
point.name = options[0];
} else if (typeof options[0] == 'number') {
point.x = options[0];
}
i++;
}
point.lowXtrm = options[i++];
point.Q1 = options[i++];
point.median = options[i++];
point.Q3 = options[i++];
point.uppXtrm = options[i++]
}

/*
* If no x is set by now, get auto incremented value. All points must have an
* x value, however the y value can be null to create a gap in the series
*/
point.low = point.lowXtrm;
point.y = point.uppXtrm;
if (point.x === undefined) {
point.x = series.autoIncrement();
}

},

/**
* A specific OHLC tooltip formatter
*/
tooltipFormatter: function(useHeader) {
var point = this,
series = point.series;

return ['<span style="color:'+ series.color +';font-weight:bold">', (point.name || series.name), '</span><br/> ',
'Upper Extreme: ', point.uppXtrm, '<br/>',
'Q3: ', point.Q3, '<br/>',
'Median: ', point.median, '<br/>',
'Q1: ', point.Q1, '<br/>',
'Lower Extreme: ', point.lowXtrm].join('');

}

});

// 3 - Create the OHLCSeries object
var BoxplotSeries = Highcharts.extendClass(seriesTypes.column, {
type: 'boxplot',
pointClass: BoxplotPoint,

pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
// fill: 'color',
// stroke: 'lineColor',
// 'stroke-width': 'lineWidth'
stroke: 'color',
'stroke-width': 'borderWidth',
fill: 'borderColor',
r: 'borderRadius'
},


/**
* Translate data points from raw values x and y to plotX and plotY
*/
translate: function() {
var chart = this.chart,
series = this,
categories = series.xAxis.categories,
yAxis = series.yAxis,
stack = yAxis.stacks[series.type];

seriesTypes.column.prototype.translate.apply(series);

// do the translation
each(this.data, function(point) {
// the graphics
point.plotQ1 = yAxis.translate(point.Q1, 0, 1);
point.plotQ3 = yAxis.translate(point.Q3, 0, 1);
point.plotMedian = yAxis.translate(point.median, 0, 1);

});
},

/**
* Draw the data points
*/
drawPoints: function() {
var series = this, //state = series.state,
//layer = series.stateLayers[state],
seriesOptions = series.options,
seriesStateAttr = series.stateAttr,
data = series.data,
chart = series.chart,
pointAttr,
pointQ1,
pointQ3,
crispCorr,
halfWidth,
path,
graphic,
crispX;


each(data, function(point) {
graphic = point.graphic;
if (point.plotY !== undefined &&
point.plotX >= 0 && point.plotX <= chart.plotSizeX &&
point.plotY >= 0 && point.plotY <= chart.plotSizeY) {

pointAttr = point.pointAttr[point.selected ? 'selected' : ''];

// crisp vector coordinates
crispCorr = (pointAttr['stroke-width'] % 2) / 2;
crispX = mathRound(point.plotX) + crispCorr;
plotQ1 = mathRound(point.plotQ1) + crispCorr;
plotQ3 = mathRound(point.plotQ3) + crispCorr;
plotMedian = mathRound(point.plotMedian) + crispCorr;
halfWidth = mathRound(point.barW / 2);

quarterWidth = mathRound(point.barW / 4);

path = [
'M',
crispX - halfWidth, plotQ1,
'L',
crispX - halfWidth, plotQ3,
'L',
crispX + halfWidth, plotQ3,
'L',
crispX + halfWidth, plotQ1,
'L',
crispX - halfWidth, plotQ1,
'M',
crispX, plotQ1,
'L',
crispX, mathRound(point.yBottom),
'M',
crispX - quarterWidth, mathRound(point.yBottom),
'L',
crispX + quarterWidth, mathRound(point.yBottom),
'M',
crispX, plotQ3,
'L',
crispX, mathRound(point.plotY),
'M',
crispX - quarterWidth, mathRound(point.plotY),
'L',
crispX + quarterWidth, mathRound(point.plotY),
'M',
crispX - halfWidth, plotMedian,
'L',
crispX + halfWidth, plotMedian,
'Z'
];


if (graphic) {
graphic.animate({
d: path
});
} else {
point.graphic = chart.renderer.path(path)
.attr(pointAttr)
.add(series.group);
}

} else if (graphic) {
point.graphic = graphic.destroy();
}

});

}


});
seriesTypes.boxplot = BoxplotSeries;

})();
fiddles: http://jsfiddle.net/jlbriggs/J9JLr/
amin.ghadersohi
Posts: 1
Joined: Tue Mar 13, 2012 2:51 am

ErrorBar series type for Highcharts

I went ahead and implemented an errorbar series type for high charts.

Code: Select all

/* errorbars.src.js */
/**
* 3/12/2012 Amin Ghadersohi
* Error Bar module for Highcharts, beta
*
* License: http://www.highcharts.com/license
*/


(function () { // encapsulate

    // create shortcuts
    var HC = Highcharts,
    addEvent = HC.addEvent,
    defaultOptions = HC.getOptions(),
    defaultPlotOptions = defaultOptions.plotOptions,
    seriesTypes = HC.seriesTypes,
    extend = HC.extend,
    each = HC.each,
    map = HC.map,
    merge = HC.merge,
    math = Math,
    mathRound = math.round;


    /*****************************************************************************
    * Start ErrorBar series code *
    *****************************************************************************/

    // 1 - Set default options
    defaultPlotOptions.ErrorBar = merge(defaultPlotOptions.column, {
        animation: false,
        lineWidth: 2,
        states: {
            hover: {
                //brightness: 0.1,
                lineWidth: 4
            }
        }
    });

    // 2- Create the ErrorBarPoint object
    var ErrorBarPoint = Highcharts.extendClass(Highcharts.Point, {
        /**
        * Apply the options containing the x and ErrorBar data and possible some extra properties.
        * This is called on point init or from point.update. Extends base Point by adding
        * multiple y-like values.
        *
        * @param {Object} options
        */
        applyOptions: function (options) {
            var point = this,
            series = point.series,
            n,
            i = 0;


            // object input for example:
            // { x: Date(2010, 0, 1), bottom: 0.1, top: 0.2  }
             if (typeof options == 'object' && typeof options.length != 'number') {

                // copy options directly to point
                extend(point, options);

                point.options = options;
            }

            // array
            else if (options.length) {
                // with leading x value
                if (options.length == 3) {
                    if (typeof options[0] == 'string') {
                        point.name = options[0];
                    } else if (typeof options[0] == 'number') {
                        point.x = options[0];
                    }
                    i++;
                }
                point.bottom = options[i++];
                point.top = options[i++];
            }

            /*
            * If no x is set by now, get auto incremented value. All points must have an
            * x value, however the y value can be null to create a gap in the series
            */
			
		 //  point.high = max(point.open, point.close);
		 //  point.low = max(point.open, point.close);
           point.y = point.bottom + ((point.top - point.bottom)/2);
            if (point.x === undefined) {
                point.x = series.autoIncrement();
            }

        },

        /**
        * A specific ErrorBar tooltip formatter
        */
        tooltipFormatter: function (useHeader) {
            var point = this,
            series = point.series;

            return ['<span style="color:' + series.color + ';font-weight:bold">', (point.name || series.name), '</span><br/> ',
            '+/-: ', (point.top-point.bottom)/2].join('');

        }

    });

    // 3 - Create the ErrorBarSeries object
    var ErrorBarSeries = Highcharts.extendClass(seriesTypes.column, {
        type: 'ErrorBar',
        pointClass: ErrorBarPoint,

        pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
            stroke: 'color',
            'stroke-width': 'lineWidth'
        },


        /**
        * Translate data points from raw values x and y to plotX and plotY
        */
        translate: function () {
            var chart = this.chart,
                series = this,
                categories = series.xAxis.categories,
                yAxis = series.yAxis,
                stack = yAxis.stacks[series.type];

            seriesTypes.column.prototype.translate.apply(series);

            // do the translation
            each(this.data, function (point) {
                // the graphics
                 point.plotOpen = yAxis.translate(point.bottom, 0, 1);
                 point.plotClose = yAxis.translate(point.top, 0, 1);

            });
        },

        /**
        * Draw the data points
        */
        drawPoints: function () {
		
            var series = this, //state = series.state,
            //layer = series.stateLayers[state],
                seriesOptions = series.options,
                seriesStateAttr = series.stateAttr,
                data = series.data,
                chart = series.chart,
                pointAttr,
                pointOpen,
                pointClose,
                crispCorr,
                halfWidth,
                path,
                graphic,
                crispX;


            each(data, function (point) {
                graphic = point.graphic;
                if (point.plotY !== undefined &&
                    point.plotX >= 0 && point.plotX <= chart.plotSizeX &&
                    point.plotY >= 0 && point.plotY <= chart.plotSizeY) {

                    pointAttr = point.pointAttr[point.selected ? 'selected' : ''];

                    // crisp vector coordinates
                    crispCorr = (pointAttr['stroke-width'] % 2) / 2;
                    crispX = mathRound(point.plotX) + crispCorr;
                    plotOpen = mathRound(point.plotOpen) + crispCorr;
                    plotClose = mathRound(point.plotClose) + crispCorr;
                    halfWidth = mathRound(point.barW / 20);


                    path = [
                    'M',
                    crispX, mathRound(point.plotOpen),
                    'L',
                    crispX, mathRound(point.plotClose),
                    'M',
                    crispX + halfWidth, point.plotOpen,
                    'L',
                    crispX - halfWidth, plotOpen,
					'M',
                    crispX + halfWidth, point.plotClose,
                    'L',
                    crispX - halfWidth, plotClose,
                    'Z'
                    ];


                    if (graphic) {
                        graphic.animate({
                            d: path
                        });
                    } else {
                        point.graphic = chart.renderer.path(path)
                                .attr(pointAttr)
                                .add(series.group);
                    }

                } else if (graphic) {
                    point.graphic = graphic.destroy();
                }

            });

        }


    });
    seriesTypes.ErrorBar = ErrorBarSeries;
    /*****************************************************************************
    * End ErrorBar series code *
    *****************************************************************************/
})();
Can be used as follows:

Code: Select all

var chartOptions = {
	chart: {
		width: 800,
		height: 600,
		renderTo: 'div-name' //you have to have a div with this name for this chart to render to
	},
	title: {
		text: 'Some random numbers',
		x: -20 //center
	},
	subtitle: {
		text: 'Source: abc',
		x: -20
	},
	xAxis: {
		categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
			'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
	},
	yAxis: {
		title: {
			text: 'Value'
		}
	},
	
	legend: {
		layout: 'vertical',
		align: 'right',
		verticalAlign: 'top',
		x: -10,
		y: 100,
		borderWidth: 0
	},
	series: [{
		type : 'ErrorBar',
		name: 'Std Err',
		data: [{x: 0, bottom:  0.9, top: 1.2}, {x: 1, bottom: 2.1, top: 2.2 }, {x: 2, bottom: 3.1, top: 3.2 }]
	},{
		type : 'line',
		name: 'Numbers',
		data: [1.05, 2.15, 3.15]
	}]
} ;


var chart = new Highcharts.Chart(chartOptions);
errorbars.png
errorbars.png (15.11 KiB) Viewed 7028 times
jakeoh
Posts: 40
Joined: Tue May 01, 2012 3:18 pm

Re: Boxplot is transparent...

I put Amin's code into jsFiddle and it works, as shown here:

http://jsfiddle.net/b74Tt/

However what if I have more than one series that needs to have error bars? How can one ErrorBar series be tied to a specific column series? My problem is shown here in this jsFiddle:

http://jsfiddle.net/FaYdK/1/
Fusher
Posts: 7912
Joined: Mon Jan 30, 2012 10:16 am

Re: Boxplot is transparent...

Just modify a little data for series: http://jsfiddle.net/Fusher/FaYdK/2/
Paweł Fus
Highcharts Developer

Return to “Highcharts Usage”