gradient color fill with opacity in raphael - raphael

I'm having trouble keeping the same level of opacity on an element with a gradient filled color
var paper = Raphael(0, 0, 300, 300);
paper.path(["M", 20, 20, "h", 200, "v", 200, "h", -200, "z"]).attr({
"stroke-width": 3,
stroke: 'red',
"opacity": 0.5,
fill: "90-red-red"
});
http://jsfiddle.net/zhirkovski/vvAaz/1/
as you can see the gradient starts off at 0.5, but increases to 1 by the time it reaches the second color, why? Even if you change the colors, one of them renders at opacity = 1, is this a bug? if so is there a work-around, or is it something i'm doing wrong?

From my own investigation this looks like a limitation of VML and subsequently Raphael. You can find more information via the following bug report: https://github.com/DmitryBaranovskiy/raphael/issues/211
It really limits what you can do with gradients and fades which is a bane for all of us. The best way to do this would be with jQuery:
// Setting up defaults
var paper = Raphael("canvas", 200, 200);
var bgBottom = paper.rect(0, 0, 200, 200).attr({fill: "90-#999-#fff"});
var bgTop = paper.rect(0, 0, 200, 200).attr({fill: "90-#999-#fff"});
// New gradient to fade to
bgBottom.attr({fill: "90-#069-#000"});
$(bgTop.node).animate({opacity: 0}, 1000);
You can then animate the top in and out with fill changes:
bgTop.attr({fill: "90-#f0f-#fff"});
$(bgTop.node).animate({opacity: 1}, 1000);
Here's my jsfiddle to help demonstrate: http://jsfiddle.net/spQsf/
Hope this helps!

Related

How to adjust column width in google combo chart

How do I adjust the column width on a google combo chart? Below is my code, but I can't figure out how to set the column width. Depending on the data I enter, the api makes the columns different widths. I'd like them all 10px. I've been trying to set the with with bar.groupWidth but cannot. Any ideas?
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function getValueAt(column, dataTable, row) {
return dataTable.getFormattedValue(row, column);
}
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Time', 'Boluses', 'Total Volume', '30 mL/kg', { role: 'annotation' }], [0,0,0,1769.1, null],[9, 500, 500, 1769.1, null],[29, 250, 750, 1769.1, null],[44, 250, 1000, 1769.1, null],[114, 2000, 3000, 1769.1, null],[238, 0, 3000, 1769.1, null],[238, 0, 3000, 1769.1, null],[288, 85, 3085, 1769.1, null],[288, 6.8, 3091.8, 1769.1, null],[348, 100, 3191.8, 1769.1, null],[348, 8, 3199.8, 1769.1, null],[408, 100, 3299.8, 1769.1, null],[408, 8, 3307.8, 1769.1, null],[360, 0, 3307.8, 1769.1, null]
]);
var view = new google.visualization.DataView(data);
var options = {
title: 'sepsis treatment summary',
fontName: 'Lato',
titleTextStyle: {fontSize: 18},
annotation: {},
vAxis: {title: 'total fluids received (mL)', minValue: 0, gridlines: {count: 6}},
hAxis: {title: 'time after alert (minutes)', viewWindow: {min: 0, max: 360}, gridlines: {count: 6}},
seriesType: "bars",
series: {
1: {color: '#99CCFF', type: "area"},
2: {color: 'red', type: "line", lineDashStyle: [10, 2]},
3: {role: "annotation"}
},
annotations: {style: 'line'},
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart'));
chart.draw(view, options);
}
This code creates the following chart:
The API calculates a maximum width for each bar group that is roughly:
var chartWidth, // chart area width in pixels
axisRange, // axis max value - axis min value
data, // DataTable, assume axis values are in column 0 for this exercise, and that data is sorted ascending
minSeparation = axisRange, // will hold the minimum separation between daat points
barGroupWidth;
// calculate the minimum distance between any two adjacent points
for (var i = 1; i < data.getNumberOfRows(); i++) {
if (data.getValue(i, 0) - data.getValue(i - 1, 0) < minSeparation) {
minSeparation = data.getValue(i, 0) - data.getValue(i - 1, 0);
}
}
// calculate the maximum width of a bar group
barGroupWidth = chartWidth * minSeparation / axisRange;
Pleaase note that this function is a rough approximation of what the API does based on what I was able to reverse engineer.
So, if you have a chart that has a chart area 300 pixels wide with an axis range of 100 and a minimum separation between adjacent points of 10, your maximum bar group width will be 30 pixels. If you try to set the bar group width above this value, your setting will be ignored.
In your case, you have adjacent points with a separation of 0 (rows 5 and 6, 7 and 8, 9 and 10, 11 and 12), which would result in a bar group width of 0 by my rough approximation. The actual algorithm is more generous, and is likely giving you 1 pixel wide groups. There is no setting you can change to make the bar groups wider, your only recourse is to change your data set to space the values out more. This may not be easy to do, but I would suggest starting by thinking about what it means to have two events at the same time with different values, and how you might be able to represent that differently.

Raphael js chaining animations

I'm trying to force one animation to start after another ends, and according to documentation, I should include a callback function, which should be called at the end of animation.
However, both animations are performed simultaneously... what am I doing wrong?
http://jsfiddle.net/yBehH/
$(document).ready(function () {
function drawBonuses() {
bonus = [3, 9, 10, 17];
$.each(bonus,function(i,v) {
gameboard.circle( v*20+20, 20, 0).animate( { fill: "#f00", r: 5 } , 100);
});
};
gameboard = Raphael("gameboard", 440, 440);
gameboard.clear();
gameboard.rect(200, 200, 0, 0, 5).animate({fill: "#fff", height: 400, width: 400, x:20, y:20, stroke: "#000", "stroke-width": 20}, 2000, drawBonuses());
});
The dots should start animating when the board is completely animated...
Currently you have
obj.animate(..., drawBonuses());
i.e. drawBonuses is called immeadiately and the return value is passed to animate().
You want to pass the function itself:
obj.animate(..., drawBonuses);
http://jsfiddle.net/yBehH/2/

Raphael.js - How to programmatically generate element name?

I have a number of Raphael rectangle elements hard-coded into the page via php, which generates them on the fly depending on how many are needed when the page is called.
What I'm trying to do is write a javascript function that will take an id number and alter the relevant Raphael function's background color.
I know the below example won't work, but this is what I'm trying to achieve.
var rectangle_1 = paper.rect(100, 10, 200, 75);
var rectangle_2 = paper.rect(400, 10, 200, 75);
var rectangle_3 = paper.rect(700, 10, 200, 75);
change_color('1');
function change_color(id) {
variable_name = 'rectangle_' + id;
variable_name.attr({fill: 'blue', stroke: 'black', 'stroke-width': 3});
}
Clearly this doesn't work and any help and advice on how to generate an element name on the fly would be greatly appreciated,
regards,
Ste
Just use an array or an object to store the rects instead of named variables.
var rectangles = [];
rectangles[0] = paper.rect(100, 10, 200, 75);
rectangles[1] = paper.rect(400, 10, 200, 75);
rectangles[2] = paper.rect(700, 10, 200, 75);
change_color(1);
function change_color(id) {
rectangles[id].attr({fill: 'blue', stroke: 'black', 'stroke-width': 3});
}
If you need string IDs, you can do it as an object:
var rectangles = {};
rectangles['one'] = ...

Google Visualization API : Line Chart - Hide negative values in Y-axis

I use Google Visualization API to plot Line Chart. Here are the codes:
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawCharts);
function drawCharts() {
// Total Coupon View
var data_total_users = new google.visualization.DataTable();
data_total_users.addColumn('string', 'Total Users');
data_total_users.addColumn('number', 'User Count');
data_total_users.addRows(7);
data_total_users.setValue(0, 0, 'Sunday');
data_total_users.setValue(0, 1, 10);
data_total_users.setValue(1, 0, 'Monday');
data_total_users.setValue(1, 1, 4);
data_total_users.setValue(2, 0, 'Tuesday');
data_total_users.setValue(2, 1, 3);
data_total_users.setValue(3, 0, 'Wednesday');
data_total_users.setValue(3, 1, 7);
data_total_users.setValue(4, 0, 'Thursday');
data_total_users.setValue(4, 1, 8);
data_total_users.setValue(5, 0, 'Friday');
data_total_users.setValue(5, 1, 10);
data_total_users.setValue(6, 0, 'Saturday');
data_total_users.setValue(6, 1, 10);
var chart = new google.visualization.LineChart(document.getElementById('chart_users_total'));
chart.draw(data_total_users, {width: 1000, height: 400, title: '', hAxis: {title: ''}});
}
The result looks like this:
Question is: How can I remove the -0.5, -1.0 ? Also, I would like to have integers (e.g. 0, 1, 2, 3, ...) in Y-axis. Which parameter should I add?
In your chart.draw call, add:
vAxis:{viewWindow: {min: 0}}
if set options vAxis: {viewWindow: {min: 0}} did not work try to set vAxis:{viewWindow: {min: 0, max: 10}}

Google BarChart set width of bars?

I'm generating a BarChart with Google's javascript visualization libraries. I would like to make the bars in the chart to be wider than they currently are, but I can't find anything in the documentation which shows how to configure the width of the bars of each data set.
Any help?
Had this same question, figured I'd post for posterity. The bar.groupWidth appears to be the way to set this.
https://developers.google.com/chart/interactive/docs/gallery/barchart
For example:
var options = {
title: "Density of Precious Metals, in g/cm^3",
width: 600,
height: 400,
bar: {groupWidth: "95%"},
legend: { position: "none" },
};
var chart = new google.visualization.BarChart(document.getElementById("barchart_values"));
chart.draw(view, options);
Try below format so the graph will have decently look, its not fixed but this solved our issue.
options: {
titlePosition: "none",
bar: { groupWidth: "50%" }
// ...
}
data.push([" ", "t1","t2","t3","t4"]); // headings
data.push([" ", 0, 0, 0, 0]); // dummy bar so graph will display good
// push you actual data here
data.push([" ", 0, 0, 0, 0]); // dummy bar so graph will display good