graphael bar chart with text x-axis
Asked Answered
A

6

13

I was wondering how I can make a simple bar chart that perhaps has day as the x-axis, with values 'today' and 'yesterday', and the y-axis as perhaps 'time' with corresponding values '1' and '2'. I guess I'm confused as to how to set text as the values for the x-axis, how to show the y axis, and what exactly r.g.axis does... (I found an example using axis = r.g.axis(0,300,400,0,500,8,2) and I only know it's the xpos, ypos,width, ??, ?? num ticks, ??). Any insight would be great! Or a page with more fully featured bar chart examples (labels, etc). Thanks.

Amarette answered 13/1, 2011 at 12:1 Comment(1)
Any update on this? Marcus did you get an answer?Lynellelynett
B
30

For the sake of all those googling this:

r.g.axis(x_start, y_start, x_width, from, to, steps, orientation, labels, type, dashsize)

x_start and y_start: distance of the axis text from the bottom left corner

x_width: position of the end of the text along the x axis

from and to: used to specify and range to use instead of using the labels argument

steps: is the number of ticks - 1

orientation: seems to specify x-axis vs. y-axis

type: is the type of tick mark used.

This was all deduced from the source code. I think I'll be switching to a charting library with documentation now...

Boarer answered 19/7, 2011 at 19:26 Comment(4)
thank you, mate. a library without any documentation is really a nightmare, even it is good !!!Quicklime
+1 "I think I'll be switching to a charting library with documentation now..."Furtive
Can anybody guide me to create Stacked Bar chart with raphael library? Thanks in advance.Hannelorehanner
This answer served me well for a long time until Raphael and g.Raphael changed APIs in new releases. Now @pedroteixeira's answer is the correct one.Lucent
F
10

The current code (Raphaeljs 2.0) has changed and has to be slightly adapted to use Raphael.g.axis instead of r.g.axis:

Raphael.g.axis(85,230,310,null,null,4,2,["Today", "Yesterday", "Tomorrow", "Future"], "|", 0, r)

Fructificative answered 1/3, 2012 at 18:20 Comment(1)
The labels of the axis ("Today", "Yesterday", "Tomorrow", ...) appear above the axis instead of appearing below it. Do you know how can i solve it ?Quicklime
V
9

You're on the right track. You use g.axis and the positional arguments for setting the text is found in the 'text' arg (positional) and for toggling the y using the 'orientation' args. I added an example here,

Barchart with text x-axis

Vesicate answered 22/2, 2011 at 8:30 Comment(1)
This example file is no longer compatible with the most recent graphaelHipparchus
M
7

Reading this Q&A and a dozen like it, I still could not get gRaphaël to show proper labels for a bar chart. The recipes all seemed to refer to older versions of the library, or to github pages that are no longer there. gRaphaël produces some great looking output--but its docs leave much to be desired.

I was, however, able to use a combination of Firebug and Inspect This Element to follow the code and see what it produced. Diving into the barchart object, the required geometry is right there. To save others the frustration, here's how I solved the problem:

<script>

function labelBarChart(r, bc, labels, attrs) {
    // Label a bar chart bc that is part of a Raphael object r
    // Labels is an array of strings. Attrs is a dictionary
    // that provides attributes such as fill (text color)
    // and font (text font, font-size, font-weight, etc) for the
    // label text.

    for (var i = 0; i<bc.bars.length; i++) {
        var bar = bc.bars[i];
        var gutter_y = bar.w * 0.4;
        var label_x = bar.x
        var label_y = bar.y + bar.h + gutter_y;
        var label_text = labels[i];
        var label_attr = { fill:  "#2f69bf", font: "16px sans-serif" };

        r.text(label_x, label_y, label_text).attr(label_attr);
    }

}


// what follows is just setting up a bar chart and calling for labels
// to be applied

window.onload = function () {
    var r = Raphael("holder"),
        data3 = [25, 20, 13, 32, 15, 5, 6, 10],
        txtattr = { font: "24px 'Allerta Stencil', sans-serif", fill: "rgb(105, 136, 39)"};
    r.text(250, 10, "A Gratuitous Chart").attr(txtattr);
    var bc = r.barchart(10, 10, 500, 400, data3, {
            stacked: false,
            type: "soft"});
    bc.attr({fill: "#2f69bf"});
    var x = 1;

    labelBarChart(r, bc,
                 ['abc','b','card','d','elph','fun','gurr','ha'],
                 { fill:  "#2f69bf", font: "16px sans-serif" }
            );

};
</script>
<div id="holder"></div>

There are a bunch of little cleanups you could do to labelBarChart(), but this basically gets the job done.

Maximilien answered 17/1, 2013 at 3:43 Comment(3)
Thanks for sharing! It's not particularly elegant, but it's the only solution that seems to work with the latest version. Quite strange there is no r.axis anymore...Cruse
Thanks for this. The var x = 1; can be removed, but it works well.Neat
Yes, the var x = 1; serves no functional purpose. I believe that is just a "no op" statement to have a convenient place for a debugger breakpoint between the setup phase and the labeling work.Maximilien
S
2

Here's a function I wrote for adding the labels. It's not particularly elegant but it will add the labels:

Raphael.fn.labelBarChart = function(x_start, y_start, width, labels, textAttr) {
  var paper = this;

  // offset width and x_start for bar chart gutters
  x_start += 10;
  width -= 20;

  var labelWidth = width / labels.length;

  // offset x_start to center under each column
  x_start += labelWidth / 2;

  for ( var i = 0, len = labels.length; i < len; i++ ) {
    paper.text( x_start + ( i * labelWidth ), y_start, labels[i] ).attr( textAttr );
  }
};

Usage is as follows:

var paper = Raphael(0, 0, 600, 400);
var chart = paper.barchart(0, 0, 600, 380, [[63, 86, 26, 15, 36, 62, 18, 78]]);

var labels = ['Col 1', 'Col 2', 'Col 3', 'Col 4', 'Col 5', 'Col 6', 'Col 7', 'Col 8'];
paper.labelBarChart(0, 390, 600, labels, {'font-size': 14});
Synchromesh answered 30/3, 2013 at 21:58 Comment(0)
U
1

I would like to propose a solution of an issue of the labelBarChart function proposed by Jonathan Eunice. considering stacked bar-graphes (or other bar-graphes with more than one array of values), I added a test on bc.bars[0] in case the bc.bars.length means the number of arrays of values stacked.

This lead to the code :

<script>

function labelBarChart(r, bc, labels, attrs) {
    // Label a bar chart bc that is part of a Raphael object r
    // Labels is an array of strings. Attrs is a dictionary
    // that provides attributes such as fill (text color)
    // and font (text font, font-size, font-weight, etc) for the
    // label text.
    //Added test : replace bc.bars by generic variable barsRef 
    var barsRef = (typeof bc.bars[0].length === 'undefined') ? bc.bars : bc.bars[0];

    var bar, gutter_y, label_x, label_y, label_text;
    //Added consideration of set attrs (if set)
    var label_attr = (typeof attrs === 'undefined') ? {} : attrs;
    label_attr['fill'] = (typeof label_attr['fill'] === 'undefined') ? "#2f69bf" : label_attr['fill'];
    label_attr['font'] = (typeof label_attr['font'] === 'undefined') ? "16px sans-serif" : label_attr['font'];

    for (var i = 0; i<barsRef.length; i++) {
        bar = barsRef[i];
        gutter_y = bar.w * 0.4;
        label_x = bar.x
        label_y = bar.y + bar.h + gutter_y;
        label_text = labels[i];
        r.text(label_x, label_y, label_text).attr(label_attr);
    }
}


// what follows is just setting up a bar chart and calling for labels
// to be applied
// I added an array of data to illustrate : data4
window.onload = function () {
    var r = Raphael("holder"),
        data3 = [25, 20, 13, 32, 15, 5, 6, 10],
        data4 = [0, 2, 1, 40, 1, 65, 46, 11],
        txtattr = { font: "24px 'Allerta Stencil', sans-serif", fill: "rgb(105, 136, 39)"};
    r.text(250, 10, "A Gratuitous Chart").attr(txtattr);
    var bc = r.barchart(10, 10, 500, 400, [data3, data4] {
            stacked: true,
            type: "soft"});
    bc.attr({fill: "#2f69bf"});

    labelBarChart(r, bc,
                 ['abc','b','card','d','elph','fun','gurr','ha'],
                 { fill:  "#2f69bf", font: "16px sans-serif" }
            );

};
</script>
<div id="holder"></div>

I just tested it with 2 arrays of values stacked.

Umbilication answered 3/3, 2015 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.