I use Chart.js to render a scattered line chart, which works pretty well.
For the rendering algorithm I need to find out the highest value shown on the y-axis, so let's say my "largest" point in the dataset has y = 248, so the y-axis shows 250 as the largest value. I need to find out that it's 250.
I tried to inspect the chart object at runtime, like so:
lineChart.options.scales[0].ticks.??
but it seems that I can only find out the settings I set myself programmatically.
Also looking at the comprehensive Chart.js docs did not point me to the solution.
Any advice how to figure out this value?
There is callback method in which you can get the array of values which will show on yAxes.
The first element of that array will be the highest value for the yAxes. Below is the sample code for the same.
var yAxesticks = [];
var highestVal;
var chartInstanceHoverModeNearest = new Chart(ctx, {
type: 'bar',
data: data,
options:{
scales: {
yAxes : [{
ticks : {
beginAtZero : true,
callback : function(value,index,values){
yAxesticks = values;
return value;
}
}
}]
}
}
});
highestVal = yAxesticks[0];
When creating an InputSurface, I am unable to get various properties to work, such as autofocus or maxLength.
this.email = new InputSurface({
classes: ['login-form'],
content: '',
size: [300, 40],
placeholder:'email',
properties: {
autofocus:'autofocus',
maxLength:'5',
textAlign: 'left'
}
});
The rendered div is missing the properties I set.
<input class="famous-surface login-form" placeholder="email" type="text" name="" style="-webkit-transform-origin: 0% 0%; opacity: 0.999999; -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 614.5, 273.5, 0, 1); text-align: left; width: 300px; height: 40px;">
Obviously a maxLength for email of 5 is silly, but I was just trying to see if it would work, but I can continue to type well beyond 5, and when the surface is rendered, it is not focused. Any ideas? I looked at the examples/demos but couldn't find one that used either of these properties, or an input surface that was autofocused.
As suggested by dmvaldman this is not a feature yet, so the below hack will make it a feature now.
Obviously not a long term solution, but I added a few lines in InputSurface.js, the attributes now get consumed.
First I added the single line assigning _attributes
function InputSurface(options) {
this._placeholder = options.placeholder || '';
this._value = options.value || '';
this._type = options.type || 'text';
this._name = options.name || '';
this._attributes = options.attributes || '';
Surface.apply(this, arguments);
this.on('click', this.focus.bind(this));
}
Then I added the for-loop consumption part to deploy.
InputSurface.prototype.deploy = function deploy(target) {
if (this._placeholder !== '') target.placeholder = this._placeholder;
target.value = this._value;
target.type = this._type;
target.name = this._name;
for (var n in this._attributes) {
target[n] = this._attributes[n];
}
};
So now I can do the following:
this.email = new InputSurface({
classes: ['login-form'],
content: '',
size: [300, 40],
placeholder:'email',
attributes: {
autofocus:'autofocus',
maxLength:5
}
});
Again, I realize modifying core code isn't a long term solution, I just needed something right now, and until someone has an "official" answer, this will work for me.
The properties object is for CSS properties only, not for HTML attributes, such as maxLength and autoFocus. Famo.us will be supporting generic attributes soon, currently inputSurface only supports placeholder, value, type and name.
I am using Ignite UI grid.
The columns is dynamically build from the database like this:-
$.post('/Main/GetColumns',function(data){
$("#mygrid").igGrid({
columns: data,
width: "100%",
height: "100%",
})
});
The problem is that i dont know which of the column will be of datatype number since data is comming from database for columns and i have to right align the numeric columns.
The only code i have found is
args.owner.element.find("tr td:nth-child(3)").css("text-align", "right");
to set 3rd column as right align.
Since i dont know the column order, i am only left to check for datatype and right align the column,
Is there any way to align column on basis of datatype or any other method to do this?
The data type if the column is used for it's representation(formatting) and editing behavior, but there's no extra markup generated that you can use to target with styling.
However, you are building column definitions server side, where you know exactly what type each column is while creating its definition, no?
Update: It's been a while since the original answer and for future reference you can use the columnCssClass to apply your class to the actual TD rather than the template. The latter is still a valid option for advanced tinkering.
Easiest way I can think of is through Column templates - this way you can add whatever styling / formatting to the columns. For example, based of whatever logic you need, you return some columns as:
{
key: 'status',
dataType: 'bool',
headerText: 'Status',
template: '<div class="rightAlign"> ${status} </div>'
}
You apply "text-align:right;" though the class and skip adding template for columns that should be with default look. Since this definition is generated on the server (imagine my example uses Node.js :P ) you can have those templates static, or create them differently each time - it's up to you.
JSFiddle: http://jsfiddle.net/damyanpetev/wsZ8c/
Note: Make sure you use a block (div,p) in this case as you need something that will take up the entire grid cell in order to align text inside.
If that solution doesn't fit, you will have to go through columns and apply styling on the client in a similar way you were thinking of.
Here is how I dynamically align the text in the columns in the infragistics igHierarchicalGrid according to their data types:
$("#grid1").on("iggriddatarendered", function (event, args) {
var columns = $("#grid1").igHierarchicalGrid("option", "columns");
//var RDate = $("#grid1").igHierarchicalGrid("getCellValue", 1, 1);
var columnIndex = 0;
var trtd = 2;
for (var idx = 0; idx < columns.length; idx++) {
if (columns[idx].dataType == "number" || columns[idx].dataType == "double")
args.owner.element.find("tr td:nth-child(" + trtd + ")").css("text-align", "right");
if (columns[idx].dataType == "string" || columns[idx].dataType == "date")
args.owner.element.find("tr td:nth-child(" + trtd + ")").css("text-align", "left");
columnIndex++;
trtd = columnIndex + 2;
}
});
As you see I am starting with vartd = 2 and this is because there are 2 elements in the table
(I use hierachcical grid) before the columns in the grid are available. You must debug and investigate if in your case
the columns of the grid are coming after the second DOM element or after the first.
In easy way you can add css into columnCssClass property and applied into grid where you were define column information
Style:
<style>
.right-align {
text-align: right;
}
.left-align {
text-align: left;
}
.center-align {
text-align: center;
}
</style>
and grid code snippet:
{ headerText: 'Option', key: "Option", dataType: "string", width: "10%", hidden: true },
{ headerText: 'ID', key: "Program_Id", dataType: "string", width: "10%", columnCssClass: "right-align" },
{ headerText: 'Desc', key: "Program_Des", dataType: "string", width: "10%", columnCssClass: "left-align" },
{ headerText: 'Status', key: "program_Status", dataType: "Bool", width: "10%", columnCssClass: "center-align" },
I have my chart working ok, however I would like to use a custom step for my vertical y-axis. At the moment it seems to be automatic and is spaced out as below:
1,500,000
3,000,000
4,500,000
I would prefer it to be:
100,000
200,000
300,000
and so on...
Is there any way I can set this, I have looked through all the documentation but can't figure it out.
Here is my code:
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(chartData, { width: 1600, height: 900, title: 'Company Performance',
yAxis: { gridlineColor: '#ff0000' },
xAxis: { gridlineColor: '#ff0000' }
}
);
My data is company profit for each week of the year, y-axis is profit, x-axis is the week number.
Hope somebody can help.
Paul
this is how I do it:
var options = {
vAxis: { // same thing for horisontal, just use hAxis
viewWindow: { // what range will be visible
max: 120,
min: 0
},
gridlines: {
count: 12 // how many gridlines. You can set not the step, but total count of gridlines.
}
}
};
all the best ;)
For as far as I know this cannot be done automatically with Google Charts settings.
I've written a javascript function to do this.
To use it you can create a nice sequence that can be used as ticks for the vertical axis:
var prettyTicks = getChartTicks(0, chartData.getColumnRange(1).max);
The line for the xAxis should be changed to apply the ticks:
yAxis: { gridlineColor: '#ff0000', ticks: prettyTicks },
Here is the javascript method to create the ticks. It will create a tick for each value of 10 and if that creates too many ticks then it will do this for each 100 or 1000 etc.
// Creates an array of values that can be used for the tick property of the Google Charts vAxis
// The values provide a nice scale to have a clean view.
var getChartTicks = function (min, max) {
// settings
var maxTicks = 8;
var tickSize = 10;
// determine the range of the values and the number of ticks
var newMin;
var newMax;
var nrOfTicks;
var appliedTickSize = 1;
while (newMin == null || nrOfTicks > maxTicks) {
appliedTickSize *= tickSize;
newMin = Math.floor(min / appliedTickSize) * appliedTickSize;
newMax = Math.ceil(max / appliedTickSize) * appliedTickSize;
nrOfTicks = (newMax - newMin) / appliedTickSize;
}
// generate the tick values which will be applied to the axis
var ticks = new Array();
var i = 0;
for (var v = newMin; v <= newMax; v += appliedTickSize) {
ticks[i++] = v;
}
return ticks;
}
So to summarize, after adding this method your code could then be changed to:
var prettyTicks = getChartTicks(0, chartData.getColumnRange(1).max);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(chartData, { width: 1600, height: 900, title: 'Company Performance',
yAxis: { gridlineColor: '#ff0000', ticks: prettyTicks },
xAxis: { gridlineColor: '#ff0000' }
}
);
Hi Please refer google chart api.There are several parameters available according to your requirement like
chbh = Bar width and spacing ...
chco = Series colors ...
chd = Chart data string...
chdl,chdlp, chdls=Chart legend text and style...
chds Scale for text format with custom range...
chem = Dynamic icon markers...
for more information
http://code.google.com/apis/chart/image/docs/chart_params.html
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.
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...
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)
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
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.
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});
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.