Phonegap Camera API and Barcode Reader Relation - javascript

I try the add barcode reader in my application on Sencha Touch. I have used phonegap camera api . My capture code is here :
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
destinationType: Camera.DestinationType.FILE_URI,saveToPhotoAlbum : true
});
function onSuccess(imageData) {
try
{
var barcode =getBarcodeFromImage(imageData);
alert('The scanned barcode is: ' + barcode);
}
catch(error)
{
alert(error);
}
}
function onFail(message) {
alert('Failed because: ' + message);
}
I could open camera and take picture.Its working.But I want the reading barcode in this photo.
Its my barcode reader code:
(function(){
var UPC_SET = {
"3211": '0',
"2221": '1',
"2122": '2',
"1411": '3',
"1132": '4',
"1231": '5',
"1114": '6',
"1312": '7',
"1213": '8',
"3112": '9'
};
getBarcodeFromImage = function(imgOrId){
alert('girdi');
var doc = document,
img = "object" == typeof imgOrId ? imgOrId : doc.getElementById(imgOrId),
canvas = doc.createElement("canvas"),
ctx = canvas.getContext("2d"),
width = img.width,
height = img.height,
spoints = [1, 9, 2, 8, 3, 7, 4, 6, 5],
numLines = spoints.length,
slineStep = height / (numLines + 1);
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
while(numLines--){
console.log(spoints[numLines]);
var pxLine = ctx.getImageData(0, slineStep * spoints[numLines], width, 2).data,
sum = [],
min = 0,
max = 0;
for(var row = 0; row < 2; row++){
for(var col = 0; col < width; col++){
var i = ((row * width) + col) * 4,
g = ((pxLine[i] * 3) + (pxLine[i + 1] * 4) + (pxLine[i + 2] * 2)) / 9,
s = sum[col];
pxLine[i] = pxLine[i + 1] = pxLine[i + 2] = g;
sum[col] = g + (undefined == s ? 0 : s);
}
}
for(var i = 0; i < width; i++){
var s = sum[i] = sum[i] / 2;
if(s < min){ min = s; }
if(s > max){ max = s; }
}
var pivot = min + ((max - min) / 2),
bmp = [];
for(var col = 0; col < width; col++){
var matches = 0;
for(var row = 0; row < 2; row++){
if(pxLine[((row * width) + col) * 4] > pivot){ matches++; }
}
bmp.push(matches > 1);
}
var curr = bmp[0],
count = 1,
lines = [];
for(var col = 0; col < width; col++){
if(bmp[col] == curr){ count++; }
else{
lines.push(count);
count = 1;
curr = bmp[col];
}
}
var code = '',
bar = ~~((lines[1] + lines[2] + lines[3]) / 3),
u = UPC_SET;
for(var i = 1, l = lines.length; i < l; i++){
if(code.length < 6){ var group = lines.slice(i * 4, (i * 4) + 4); }
else{ var group = lines.slice((i * 4 ) + 5, (i * 4) + 9); }
var digits = [
Math.round(group[0] / bar),
Math.round(group[1] / bar),
Math.round(group[2] / bar),
Math.round(group[3] / bar)
];
code += u[digits.join('')] || u[digits.reverse().join('')] || 'X';
if(12 == code.length){ return code; break; }
}
if(-1 == code.indexOf('X')){ return code || false; }
}
return false;
}
})();
when the camera captured returns image uri. In the Barcode function throwing "cannot read property 'width' of null.
So function not reading my captured photo. How to fix this ?

I used phonegap barcode api and resolved problem

Related

using Damerau-Levenshtein distance to compare sets of text in code.org

Not very knowledgeable with coding, I usually use block coding and not typing.
I've used many different Levenshtein distance codes I've found online and most of them didn't work for one reason or another
var levDist = function (s, t) {
var d = []; //2d matrix
// Step 1
var n = s.length;
var m = t.length;
if (n == 0) return m;
if (m == 0) return n;
//Create an array of arrays in javascript (a descending loop is quicker)
for (var i = n; i >= 0; i--) d[i] = [];
// Step 2
for (i = n; i >= 0; i--) d[i][0] = i;
for (var j = m; j >= 0; j--) d[0][j] = j;
// Step 3
for (i = 1; i <= n; i++) {
var s_i = s.charAt(i - 1);
// Step 4
for (j = 1; j <= m; j++) {
//Check the jagged ld total so far
if (i == j && d[i][j] > 4) return n;
var t_j = t.charAt(j - 1);
var cost = (s_i == t_j) ? 0 : 1; // Step 5
//Calculate the minimum
var mi = d[i - 1][j] + 1;
var b = d[i][j - 1] + 1;
var c = d[i - 1][j - 1] + cost;
if (b < mi) mi = b;
if (c < mi) mi = c;
d[i][j] = mi; // Step 6
//Damerau transposition
if (i > 1 && j > 1 && s_i == t.charAt(j - 2) && s.charAt(i - 2) == t_j) {
d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost);
}
}
}
// Step 7
return d[n][m];
};
This is all the code I’ve written (including the most recent attempt of getting the levenshtein distance)
var levDist = function (s, t) {
var d = []; //2d matrix
// Step 1
var n = s.length;
var m = t.length;
if (n == 0) return m;
if (m == 0) return n;
//Create an array of arrays in javascript (a descending loop is quicker)
for (var i = n; i >= 0; i--) d[i] = [];
// Step 2
for (i = n; i >= 0; i--) d[i][0] = i;
for (var j = m; j >= 0; j--) d[0][j] = j;
// Step 3
for (i = 1; i <= n; i++) {
var s_i = s.charAt(i - 1);
// Step 4
for (j = 1; j <= m; j++) {
//Check the jagged ld total so far
if (i == j && d[i][j] > 4) return n;
var t_j = t.charAt(j - 1);
var cost = (s_i == t_j) ? 0 : 1; // Step 5
//Calculate the minimum
var mi = d[i - 1][j] + 1;
var b = d[i][j - 1] + 1;
var c = d[i - 1][j - 1] + cost;
if (b < mi) mi = b;
if (c < mi) mi = c;
d[i][j] = mi; // Step 6
//Damerau transposition
if (i > 1 && j > 1 && s_i == t.charAt(j - 2) && s.charAt(i - 2) == t_j) {
d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost);
}
}
}
// Step 7
return d[n][m];
};
var S = "Hello World";
var grossWPM;
var Transparency = 1;
var Timer = 60;
var InitialTime = Timer;
var Texts = getColumn("Texts", "Texts");
var TextLength = getColumn("Texts", "Number of Characters");
var Title = getColumn("Texts", "Titles");
var Author = getColumn("Texts", "Authors");
var TextSelector = randomNumber(0, 19);
console.log("Article #" + (TextSelector + 1));
console.log(TextLength[TextSelector] + " Characters in total");
console.log(Title[TextSelector]);
console.log("By: " + Author[TextSelector]);
var Countdown;
var Countdown = 6;
//Texts are obtained from
//https://data.typeracer.com/pit/texts
onEvent("button1", "click", function( ) {
timedLoop(1000, function() {
Countdown = Countdown - 1;
setText("button1", Countdown - 0);
timedLoop(100, function() {
setText("text_area2", "");
});
if (Countdown <= 1) {
stopTimedLoop();
setTimeout(function() {
setText("button1", "GO!");
setText("text_area1", Texts[TextSelector]);
if (getText("button1") == "GO!") {
var TransparentLoop = timedLoop(100, function() {
Transparency = Transparency - 0.1;
setProperty("Warning", "text-color", rgb(77,87,95, Transparency));
if (Transparency <= 0) {
deleteElement("Warning");
showElement("label2");
stopTimedLoop(TransparentLoop);
}
});
var TimerLoop = timedLoop(1000, function() {
Timer = Timer - 1;
setText("label2", Timer);
if (Timer <= 0) {
grossWPM = (TextLength[TextSelector] / 5) / ((InitialTime - Timer) / 60);
console.log(grossWPM);
setScreen("screen2");
if (Timer == 1) {
S = " second";
} else {
S = " seconds";
}
setText("label1", "Your typing speed was approximately " + (Math.round(grossWPM) + (" WPM* with " + (Timer + (S + " left")))));
stopTimedLoop(TimerLoop);
}
});
console.log("Timer Started");
timedLoop(10, function() {
var str = getText("text_area2");
if (str.length == TextLength[TextSelector]) {
stopTimedLoop(TimerLoop);
grossWPM = (TextLength[TextSelector] / 5) / ((InitialTime - Timer) / 60);
setScreen("screen2");
levDist(str, Texts[TextSelector]);
if (Timer == 1) {
S = " second";
} else {
S = " seconds";
}
setText("label1", "Your typing speed was approximately " + (Math.round(grossWPM) + (" WPM* with " + (Timer + (S + " left")))));
if (grossWPM == 69) {
setText("label4", "Nice");
}
stopTimedLoop();
}
});
}
}, 1000);
}
});
});
Obviously not that good at this so can anyone help?
I want to compare two sets of text
Something the user types in.
Paragraph that the user was supposed to type.
This is for a WPM test and I want a way to get a measurement for WPM that includes errors the user makes while typing.
If there is a way to check this besides the Levenshtein distance please tell me, I just looked up a way to do that and Levenshtein distance seemed like the way to do so
The error given by code.org says:
ERROR: Line: 50: TypeError: d[n] is undefined
I fixed the issue, I used this code
function levenshtein(s1, s2) {
if (s1 == s2) {
return 0;
}
var s1_len = s1.length;
var s2_len = s2.length;
if (s1_len === 0) {
return s2_len;
}
if (s2_len === 0) {
return s1_len;
}
// BEGIN STATIC
var split = false;
try {
split = !('0')[0];
} catch (e) {
// Earlier IE may not support access by string index
split = true;
}
// END STATIC
if (split) {
s1 = s1.split('');
s2 = s2.split('');
}
var v0 = new Array(s1_len + 1);
var v1 = new Array(s1_len + 1);
var s1_idx = 0,
s2_idx = 0,
cost = 0;
for (s1_idx = 0; s1_idx < s1_len + 1; s1_idx++) {
v0[s1_idx] = s1_idx;
}
var char_s1 = '',
char_s2 = '';
for (s2_idx = 1; s2_idx <= s2_len; s2_idx++) {
v1[0] = s2_idx;
char_s2 = s2[s2_idx - 1];
for (s1_idx = 0; s1_idx < s1_len; s1_idx++) {
char_s1 = s1[s1_idx];
cost = (char_s1 == char_s2) ? 0 : 1;
var m_min = v0[s1_idx + 1] + 1;
var b = v1[s1_idx] + 1;
var c = v0[s1_idx] + cost;
if (b < m_min) {
m_min = b;
}
if (c < m_min) {
m_min = c;
}
v1[s1_idx + 1] = m_min;
}
var v_tmp = v0;
v0 = v1;
v1 = v_tmp;
}
return v0[s1_len];
}
and I got that code from this question
This is levenshtein distance NOT damerau-levenshtein distance

How can pre-define a length of maze path when generating maze

I am trying create a maze of words with pre-defined length of found path, But have no clue about what algorithm would make it possible.
For ex: I want the length from cells start 1 to end [2] should be 11( the length of "onetwothree").
Here is the current code I am using to generate the maze:
var demotext = "onetwothree";
var widthmaze = (demotext.length + 5) / 2 + 1;
var heightmaze = (demotext.length + 5) / 2 - 1;
document.getElementById('out').innerHTML = display(maze(widthmaze, heightmaze));
function maze(x, y) {
var n = x * y - 1;
if (n < 0) {
alert("illegal maze dimensions");
return;
}
var horiz = [];
for (var j = 0; j < x + 1; j++) horiz[j] = [],
verti = [];
for (var j = 0; j < x + 1; j++) verti[j] = [],
here = [Math.floor(Math.random() * x), Math.floor(Math.random() * y)],
path = [here],
unvisited = [];
for (var j = 0; j < x + 2; j++) {
unvisited[j] = [];
for (var k = 0; k < y + 1; k++)
unvisited[j].push(j > 0 && j < x + 1 && k > 0 && (j != here[0] + 1 || k != here[1] + 1));
}
while (0 < n) {
var potential = [
[here[0] + 1, here[1]],
[here[0], here[1] + 1],
[here[0] - 1, here[1]],
[here[0], here[1] - 1]
];
var neighbors = [];
for (var j = 0; j < 4; j++)
if (unvisited[potential[j][0] + 1][potential[j][1] + 1])
neighbors.push(potential[j]);
if (neighbors.length) {
n = n - 1;
next = neighbors[Math.floor(Math.random() * neighbors.length)];
unvisited[next[0] + 1][next[1] + 1] = false;
if (next[0] == here[0])
horiz[next[0]][(next[1] + here[1] - 1) / 2] = true;
else
verti[(next[0] + here[0] - 1) / 2][next[1]] = true;
path.push(here = next);
} else
here = path.pop();
}
return {
x: x,
y: y,
horiz: horiz,
verti: verti
};
}
function display(m) {
var text = [];
for (var j = 0; j < m.x * 2 + 1; j++) {
var line = [];
if (0 == j % 2)
for (var k = 0; k < m.y * 4 + 1; k++)
if (0 == k % 4)
line[k] = '+';
else
if (j > 0 && m.verti[j / 2 - 1][Math.floor(k / 4)])
line[k] = ' ';
else
line[k] = '-';
else
for (var k = 0; k < m.y * 4 + 1; k++)
if (0 == k % 4)
if (k > 0 && m.horiz[(j - 1) / 2][k / 4 - 1])
line[k] = ' ';
else
line[k] = '|';
else
if (2 == k % 4)
line[k] = demotext[Math.floor(Math.random() * demotext.length)];
else
line[k] = ' ';
if (0 == j) {line[1] = line[3] = ' '; line[2] = '1'};
if (m.x * 2 - 1 == j) line[4 * m.y] = '2';
text.push(line.join('') + '\r\n');
}
return text.join('');
}
<pre id="out"></pre>
Moving start and end point to make the path length match with text maybe the solution but I do not know how to implement it. Any help would be great !
Ps: I would like the result can be like this:

Javascript while loop (Card deck simulation)

I am having an issue with the following code that simulates a card deck.
The deck is created properly (1 array containing 4 arrays (suits) containing 13 elements each (face values)) and when I use the G.test(); function it is correctly pulling 13 random cards but then returns 39x "Empty" (A total of 52).
I hate to ask for help, but I have left the problem overnight and then some and I still cannot find the reason that this is happening. I appreciate any and all insight that can be offered.
var G = {};
G.cards = [[], [], [], []];
G.newCard = function(v) { //currently a useless function, tried a few things
return v;
};
G.deck = {
n: function() { //new deck
var x; var list = [];
list.push(G.newCard("A"));
for (x = 2; x <= 10; x += 1) {
list.push(G.newCard(x.toString()));
}
list.push(G.newCard("J"), G.newCard("Q"), G.newCard("K"));
for (x = 0; x < G.cards.length; x += 1) {
G.cards[x] = list;
}
},
d: function() { //random card - returns suit & value
var s; var c; var v; var drawn = false; var n;
s = random(0, G.cards.length);
c = random(0, G.cards[s].length);
n = 0;
while (!drawn) {
if (G.cards[s].length > 0) {
if (G.cards[s][c]) {
v = G.cards[s].splice(c, 1);
drawn = true;
} else {
c = random(0, G.cards[s].length);
}
} else {
s = (s + 1 >= G.cards.length) ? 0 : s + 1;
n += 1;
console.log(s);
if (n >= G.cards.length) {
console.log(n);
return "Empty";
}
}
}
return {s: s, v: v[0]};
},
}; //G.deck
G.test = function() {
var x; var v;
G.deck.n();
for (x = 0; x < 52; x += 1) {
v = G.deck.d();
console.log(v);
}
};
Replace
for (x = 0; x < G.cards.length; x += 1) {
G.cards[x] = list;
}
with
for (x = 0; x < G.cards.length; x += 1) {
G.cards[x] = list.slice();
}
as this prevents all elements of G.cards[x] binding to the same (single) array instance.
If all elements bind to the same instance, mutating one element equals mutating all elements. list.slice() creates a new copy of list and thus a new array instance to prevent the aforementioned issue.
I won't go through your code, but I built a code that will do what you wanted. I only built this for one deck and not multiple deck play. There are two functions, one will generate the deck, and the other will drawn cards from the deck, bases on how many hands you need and how many cards you wanted for each hand. One a card is drawn, it will not be re-drawn. I might publish a short article for how a card dealing program work or similar in the short future at http://kevinhng86.iblog.website.
function random(min, max){
return Math.floor(Math.random() * (max - min)) + min;
}
function deckGenerate(){
var output = [];
var face = {1: "A", 11: "J", 12: "Q", 13: "K"};
// Heart Space Diamond & Club;
var suit = ["H", "S", "D", "C"];
// Delimiter between card identification and suit identification.
var d = "-";
for(i = 0; i < 4; i++){
output[i] = [];
for(ind = 0; ind < 13; ind++ ){
card = (ind + 1);
output[i][ind] = (card > 10) || (card === 1)? face[card] + d + suit[i] : card.toString() + d + suit[i];
}
}
return output;
}
function randomCard(deck, hand, card){
var output = [];
var randS = 0;
var randC = 0;
if( hand * card > 52 ) throw("Too many card, I built this for one deck only");
for(i = 0; i < hand; i++){
output[i] = [];
for(ind = 0; ind < card; ind++){
randS = random(0, deck.length);
randC = random(0, deck[randS].length);
output[i][ind] = deck[randS][randC];
deck[randS].splice(randC,1);
if(deck[randS].length === 0) deck.splice(randS,1);
}
}
document.write( JSON.stringify(deck, null, 2) );
return output;
}
var deck = deckGenerate()
document.write( JSON.stringify(deck, null, 2) );
document.write("<br><br>");
var randomhands = randomCard(deck, 5, 8);
document.write("<br><br>");
document.write("<br><br>");
document.write( JSON.stringify(randomhands, null, 2) );

Write patterns with javascript

i'm doing a "Steve Reich - Clapping Music" kinda thing with "xoxoxoxx" with x as the clapping. but i want it to write the pattern while it keep going to the right. so you'd have this kinda writing:
xoxoxoxxxoxoxoxxxoxoxoxxxoxoxoxx
xoxoxoxxoxoxoxxxoxoxxoxoxxxoxoxo
so it prints the X or O and then goes a bit to the right and prints again. I hope this is clear, english isn't my first language, so i'm sorry if it's hard to understand. here is the full code for 2 lines because i'm bad at explaining:
var noise, env;
var seq = "o x o x o x o x o x o x o x x x";
var steps = seq.split(" ");
var speed = 8;
var count = 0;
var count2 = 0;
var count3=0;
var shift = 0;
var repeat = 1;
var sf, sf2, sf3;
var f;
function preload() {
sf = loadSound("./files/clap.wav");
sf2 = sf;
sf3 = sf;
}
function setup() {
createCanvas(400, 400);
env = new p5.Env(0.01, 1, 0.2, 0.1);
env2 = new p5.Env(0.1, 0.8, 0.01, 0.1);
env3 = new p5.Env(0.05, 0.9, 0.1, 0.1);
}
function hitMeSteve(when, env, loc) {
if (when == 'x' && frameCount % speed == 0) {
env.play();
}
}
function draw() {
if (frameCount % speed == 0) {
count++;
}
if (frameCount % (steps.length * speed * repeat) == 0) {
shift++;
count2=count2+2;
count3=count3+4;
}
if(shift==4){
shift=0;
count2=0;
count3=0;
}
shift = shift % steps.length;
shift2 = shift + 2;
var now = steps[count % steps.length];
hitMeSteve(now, sf, 10);
var canon = steps[(count + shift) % steps.length];
hitMeSteve(canon, sf2, width / 2 + 10);
var canon2 = steps[(count + shift+count2) % steps.length];
hitMeSteve(canon2, sf3, width / 2 + 20);
textSize(30);
//1
for (var i = 0; i < steps.length; i++) {
if (i == count % steps.length) {
fill(255, 180, 0);
} else {
fill(0);
}
text(steps[i],10+ ( + i) * 15,20);
//text(steps[i], 110 + (shift / 2 + i) * 15, height / 2);
}
//2
for (var i = 0; i < steps.length; i++) {
if (i == (count + shift) % steps.length) {
fill(255, 180, 0);
} else {
fill(0);
}
text(steps[i],10+( + i)*15,40);
//text(steps[i], 110 + (-shift / 2 + i) * 15, height / 2 + 20);
}
}
Just a proposal with setInterval, maybe this works for you.
var content = "oxoxoxoxoxoxoxxx",
target = document.getElementById('ticker'),
i = 0,
timer = setInterval(addChar, 800);
function addChar() {
if (i < content.length) {
target.innerHTML += ' ' + content[i];
i++;
} else {
target.innerHTML = '';
i=0;
}
}
<div id="ticker"></div>

dygraph - how to change series names for bar chart

I have a bar chart with 3 series, but I cant change their names, I have only y1 y2 y2, not my own names from the code. As per example bar chartI see, that I should use Multi-columnBarChart, but how can I do that?
here is comment from example Multi-columnBarChart:
function multiColumnBarPlotter(e) {
// We need to handle all the series simultaneously.
if (e.seriesIndex !== 0) return;
var g = e.dygraph;
var ctx = e.drawingContext;
var sets = e.allSeriesPoints;
var y_bottom = e.dygraph.toDomYCoord(0);
// Find the minimum separation between x-values.
// This determines the bar width.
var min_sep = Infinity;
for (var j = 0; j < sets.length; j++) {
var points = sets[j];
for (var i = 1; i < points.length; i++) {
var sep = points[i].canvasx - points[i - 1].canvasx;
if (sep < min_sep) min_sep = sep;
}
}
var bar_width = Math.floor(2.0 / 3 * min_sep);
here is my code:
function barChartPlotter(e) {
var ctx = e.drawingContext;
var points = e.points;
var y_bottom = e.dygraph.toDomYCoord(0);
// The RGBColorParser class is provided by rgbcolor.js, which is
// packed in with dygraphs.
var color = new RGBColorParser(e.color);
color.r = Math.floor((255 + color.r) / 2);
color.g = Math.floor((255 + color.g) / 2);
color.b = Math.floor((255 + color.b) / 2);
ctx.fillStyle = color.toRGB();
// Find the minimum separation between x-values.
// This determines the bar width.
var min_sep = Infinity;
for (var i = 1; i < points.length; i++) {
var sep = points[i].canvasx - points[i - 1].canvasx;
if (sep < min_sep) min_sep = sep;
}
var bar_width = Math.floor(2.0 / 3 * min_sep);
// Do the actual plotting.
for (var i = 0; i < points.length; i++) {
var p = points[i];
var center_x = p.canvasx;
ctx.fillRect(center_x - bar_width / 2, p.canvasy,
bar_width, y_bottom - p.canvasy);
ctx.strokeRect(center_x - bar_width / 2, p.canvasy,
bar_width, y_bottom - p.canvasy);
}
}
data = [];
var x = js_array.length;
// CONVERTATION
pass = [];
fail = [];
tree = [];
for (var i=0; i<x; i++){
if (js_array[i] == 1) {
pass.push(js_array[i]);
fail.push(NaN);
tree.push(NaN);
}
else if (js_array[i] == 2) {
pass.push(NaN);
fail.push(js_array[i]);
tree.push(NaN);
}
else if (js_array[i] == 3) {
pass.push(NaN);
fail.push(NaN);
tree.push(js_array[i]);
}
}
// DATA
for (var i=0; i<x; i++){
var y = x - i - 1;
data.push([new Date(js_array_time[y]), pass[y], fail[y], tree[y]]);
}
seriesName = ['x','PASS', 'FAIL', 'TREE']
// OPTIONS
var start = new Date(js_array_time[9]);
var stop = new Date(js_array_time[0]);
start.setMinutes(start.getMinutes() - 10);
stop.setMinutes(stop.getMinutes() + 10);
s = document.getElementById("s");
g = new Dygraph(
document.getElementById("graphdiv"),
data,
{
width: 580,
includeZero: true,
animatedZooms: true,
plotter: barChartPlotter,
axisLineWidth: 0.001,
//labels: seriesName,
legend: 'always',
title: 'Test results',
drawYAxis:false,
valueRange: [0.5, 3.5],
dateWindow: [Date.parse(start), Date.parse(stop)],
pointClickCallback: function(e, p) {
//s.innerHTML += "<b>Point Click</b> " + p.name + ": " + p.xval + "<br/>";
window.open('../RUNNER/_VLOGS/launch' + p.xval + '.html','_blank');
window.open('../RUNNER/_LOGS/launch_log' + p.xval + '.txt','_blank');
},
//drawPoints: true,
//drawXGrid: false,
//drawYGrid: false,
//fillGraph: true
}
);
g.ready(function() {
g.setAnnotations([
{
}]);
});
For multiple series, you need to get allSeriesPoints instead of just points. Here is an example I put together for another SO question:
Here is a working DEMO at jsFiddle.com
The plotter code looks like this:
function multiColumnBarPlotter(e) {
// We need to handle all the series simultaneously.
if (e.seriesIndex !== 0) return;
var g = e.dygraph;
var ctx = e.drawingContext;
var sets = e.allSeriesPoints;
var y_bottom = e.dygraph.toDomYCoord(0);
// Find the minimum separation between x-values.
// This determines the bar width.
var min_sep = Infinity;
for (var j = 0; j < sets.length; j++) {
var points = sets[j];
for (var i = 1; i < points.length; i++) {
var sep = points[i].canvasx - points[i - 1].canvasx;
if (sep < min_sep) min_sep = sep;
}
}
var bar_width = Math.floor(2.0 / 3 * min_sep);
var fillColors = [];
var strokeColors = g.getColors();
for (var i = 0; i < strokeColors.length; i++) {
var color = new RGBColorParser(strokeColors[i]);
color.r = Math.floor((255 + color.r) / 2);
color.g = Math.floor((255 + color.g) / 2);
color.b = Math.floor((255 + color.b) / 2);
fillColors.push(color.toRGB());
}
for (var j = 0; j < sets.length; j++) {
ctx.fillStyle = fillColors[j];
ctx.strokeStyle = strokeColors[j];
for (var i = 0; i < sets[j].length; i++) {
var p = sets[j][i];
var center_x = p.canvasx;
var x_left = center_x - (bar_width / 1.3) * (1 - j/(sets.length-1));
ctx.fillRect(x_left, p.canvasy,
bar_width/sets.length, y_bottom - p.canvasy);
ctx.strokeRect(x_left, p.canvasy,
bar_width/sets.length, y_bottom - p.canvasy);
}
}
}
I then create 2 charts of the same data, one using CSV and the other an array. The CSV provides labels directly in the data, for the array, you can change labels with the labels property:
labels: ['x', 'series1', 'series2', 'series3'],
The whole chart code would then be
g2 = new Dygraph(document.getElementById("g_div2"),
theData,
{
// options go here. See http://dygraphs.com/options.html
legend: 'always',
labels: ['x', 'series1', 'series2', 'series3'],
animatedZooms: true,
plotter: multiColumnBarPlotter,
colors: ["#00A0B0", "#6A4A3C", "#CC333F", ],
dateWindow: [0, 8]
});

Categories

Resources