I am working in d3.js and have two pannable (but not zoomable) time axes. One axis has labels for days, one has labels for months. I use the same scale for both axes.
Currently, it looks like this: (pipe- and minus-symbol only for better visibility)
|November
1 2 3 4 5 6 7 8 9 10 11 12 13 ... 30
I want to move the name of the month to the middle of the interval, so that it looks like this:
|-------------November
1 2 3 4 5 6 7 8 9 10 11 12 13 ... 30
I already tried several ways to fix the issue, but without success. The core problem is that when panning, the text of the tick will disappear as soon as the tick itself disappears.
If I use post selection to move the text of the tick to the right position, the text will disappear too early when panning the axis to the left.
Initial (ok):
|-------------November
1 2 3 4 5 6 7 8 9 10 11 12 13 ... 30
After panning to the left (wrong):
(gone)
2 3 4 5 6 7 8 9 10 11 12 13 ... 30
I tried to change the interval to a date near "the middle". Instead of placing the Label with
.ticks(d3.time.months, 1);
I tried to set it using the following:
.ticks(d3.time.days, 15);
But this had not the desired effect. It generates the following:
|November-----November------November
1 2 3 4 5 6 7 8 9 10 11 12 13 ... 30
The following did not help me:
.style("text-anchor", "end/begin")
I found a way (as described in this example: http://bl.ocks.org/mbostock/6186172) to add a offset to the axis, so ticks that are too long will still be displayed. I was not able to get this working in a pannable graph.
var x = d3.time.scale()
.domain([t0, t3])
.range([t0, t3].map(d3.time.scale()
.domain([t1, t2])
.range([0, width])));
Is there any better working solution?
Writing a custom ticks() function worked for me. Using this, I am able to set the tick (and its label) to any given position.
I created a simple gist to show you my solution:
http://bl.ocks.org/kevinnoll/77430421843b940869ed
Related
I'm trying to make a group bar chart that gives the frequency of two group combos. I referred to this site for rollup and nest function reference:
http://bl.ocks.org/phoebebright/raw/3176159/
I'm trying to use my own dataset to create the following effect:
https://bl.ocks.org/bricedev/0d95074b6d83a77dc3ad
My current attempt with my own data, drug1.csv:
https://blockbuilder.org/lydiawawa/9efb5df76c08640316efbef702437db7
In the console, the grouped counts do not seem to generate the right distributions. Something is wrong with my rollup and nest
const nestedData = d3.nest()
.key(function(d){return d.s_category})
.key(function(d){return d.drug_cat})
.rollup(function(leaves) { return leaves.length; })
.entries(data);
Following is the desired cross tab distribution count of s_category x drug_cat :
1 2 3 4 5 6
2 367 35 8 1 1 1
3 223 24 4 4 2 2
4 29 5 9 1 2 3
5 37 1 3 3 2 26
Static chart:
In the animated bar graph that I attempted to create, cross tab count should be the y-axis, drug_c is the x-axis and s_category determines the groups of the bar graph. Thank you for any help!
The moment you use the nest generator you don't have drug_cat and count as properties anymore: you have key and values (or value for the inner arrays).
Here is your block builder changing the names of those properties: https://blockbuilder.org/GerardoFurtado/f4c825a5f8c92e87cc5a81591ba1f7c9
Currently I am working with a dynamic set of data and Chart.js. There is no standardised scale within the data I am using, so I have created a simple algorithm, for example:
3 out of 7 for question 1 [3 * (12 / 7)]
2 out of 9 for question 2 [2 * (12 / 9)]
6 out of 7 for question 3 [6 * (12 / 7)]
So that all the results for the Radar Graph are measured equally at 12.
By doing this the value is not going to be correct, even though the position of the point in respect to the rest of the graph will be.
[Label]Question 1 (3/7) : [Value]5.14
I have already included the true value in the label by combining the label with the data in the label array.
So I would like to show just the label when the mouse hovers over the spoke or dot on the chart.
Question 1 (3/7)
Is there a way of doing this without messing around with the Chart.js file?
Use the tooltipTemplate option
new Chart(ctx).Radar(data, {
tooltipTemplate: "<%=label%>",
});
Fiddle - http://jsfiddle.net/dz6mt4dy/
Today i have a hard work, and hard issue:
lets say i have js function which each time we call it, it return a number :
let's say i have list number from 1 to 100 in array, and make it into columns and rows:
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17
18 19 20 21 ...
each time call function, it return random number in 1 > 100, but i need to check:
if number is 1, 2, 3 or 7, 8, 9 ( because array number will sort to 6 columns each row, so i need to detect number return from function is one of 3 digis left, or 3 digis right ).
and because number range not fixed, i dont know what math or solution to detect this case.
anyone know it?
To get a column number (or, more precisely, "left 3 or right 3") subtract 1 and do a % modulus operator: (value-1) % 6. The result will be 0..2 (or "left column") or 3..5 (so "right column").
I want to find an index making the less possible yes/no questions in a x^2 array, for this I assumed a cool approach will be to find the col position by cutting at the half (or near the half) and asking is col <= half? depending on the answer, I will pick one of the halves and repeat this until the length == 1, then make the same but with is row <= half? to find the row.
This is my function (first time attempting a recursive function):
function recursiveFunc(indexPos, currentArrLen, moveIndexBy, countLoops){
var aproxHalf, relativeIndexPos;
relativeIndexPos = (indexPos-moveIndexBy);
aproxHalf = Math.floor(currentArrLen/2);
if(currentArrLen<2){
return (moveIndexBy+" "+countLoops);
}else{
countLoops++;
if(relativeIndexPos>=aproxHalf){
moveIndexBy += aproxHalf;
currentArrLen -= aproxHalf;
}else{
currentArrLen = (aproxHalf-moveIndexBy);
}
return recursiveFunc(indexPos, currentArrLen, moveIndexBy, countLoops);
}
}
The only var that seems non self explanatory might be relativeIndexPos, so I will explain it, the value of it is the index of the index we are trying to find but within only the smaller array (e.g if we had 5x5 finding index 2, the new array length after cutting it once is 3, the relative index of 2 in that array [0,1][<2>,3,4] is 0)
edit: okay maybe I should explain moveIndexBy, it basically is "the leftest index at the current working array"
It works on a 5x5 array, for example if I give x the values of 0 to 4 in recursiveFunc(x,5,0,0);, it will correctly find the index in the less possible questions <index/questions> 0:2, 1:2, 2:2, 3:3, 4:3.
But this fails with bigger arrays, for example, a 10x10 will give:
0 3
1 3
2 3
3 4
4 4
5 2
5 2
7 3
8 4
9 4
The 5 and others are wrong, it can't possibly find 5 in 2 steps: 0 1 2 3 4 (5 6 7 8 9) then 5 6 (7 8 9) you still need to see if the index is the left or right of 5 (6). Also it fails to even find the index 6
currentArrLen = (aproxHalf-moveIndexBy);
to
currentArrLen = aproxHalf;
I don't know what or why, but that fixed it:
0 3
1 3
2 3
3 4
4 4
5 3
6 3
7 3
8 4
9 4
edit: with that, an undocumented bug of length being sometimes 0 is fixed too, so change if(currentArrLen<2) to if(currentArrLen==1)
Backstory
I was playing around with finding large powers of 2. My method was splitting the large numbers into an array of smaller values and the multiplying each of them to get the next value. The size I chose for the smaller chunks was a maximum size of 1e15. Then I decided to see how performance changed if I used the new array buffers and had to reduce the maximum size down to 1e9. Something weird happened I got a performance boost not from using the array buffers, but from using a smaller integer. This doesn't make sense since the larger the number the fewer times the function has to cycle through the array.
Code
var i=3
function run(){
loop(50000,Math.pow(10,i),i++);
if(i<16)setTimeout(run,100)
}
run();
function loop(pin,lim,id){
var pow=110503;
pow=pin||pow;
var l=pow-1,val=[2];
var t1,t2;
//console.time(id);
t1=new Date();
while(l--){
val=multiply(val,lim);
}
//console.timeEnd(id);
t2=new Date();
console.log(id,' ',t2-t1);
}
function multiply(a,lim){
var l=a.length,val=0,carry=0;
while(l--){
val=a[l]*2+carry;
carry=0;
if(val>lim-1){
var b=val%lim;
carry=(val-b)/lim;
val=b;
}
a[l]=val;
}
if(carry>0){a.unshift(carry)}
return a;
}
Results
IE10
3 5539
4 4213
5 3329
6 2720
7 2341
8 2153
9 1948
10 1699
11 1508
12 1401
13 1309
14 1208
15 1133
Chrome
3 5962
4 4385
5 3851
6 3242
7 2533
8 2207
9 1940
10 1794
11 1542
12 1604
13 1560
14 1414
15 1331
Firefox
3 3651
4 2732
5 2279
6 1853
7 1615
8 1408
9 1256
10 2375
11 2034
12 1874
13 1723
14 1600
15 1504
Question
As you can see Firefox outperforms both IE10 and Chrome up til numbers that are 9 digits long and then it takes a sudden jump in time. So, why does it do this? I guess it may have something to do with switching between numbers that can by stored in 32 bytes. I suppose 32 byte numbers are more efficient to work with; so for smaller numbers they use them and then switch to a larger integer type if they need to. But if that is true why does it never catch up to Chrome's and IE's performance and would switching cause that much of a performance penalty?
Both SpiderMonkey (Firefox) and V8 (Chrome) use 32-bit integers when they can, switching to doubles (not larger integers) when the numbers no longer fit into a 32-bit int. But note that "can" is determined heuristically, because there are costs to mixing doubles and ints due to having to convert back and forth, so it's possible that V8 is not deciding to specialize to ints here.
Edit: deleted the part about needing the source, since it's all right there in the original post!