dc.js number display not showing up - javascript

I'm displaying data using d3, dc.js etc. I have a working lineChart / geoChoroplethChart but for some reason I can't get the number display to work. I'm thinking the formatting might be to blame, I've got fairly large numbers ~billions. I tried setting the d3.format to ".0e" etc but no luck.
var ndx = crossfilter(tradeData);
var all = ndx.groupAll();
var tradeQuantityGroup = ndx.groupAll().reduceSum(function(d) {
return d["quantity"];
});
var totalTradeQuantity_ND = dc.numberDisplay("quantity-nd");
totalTradeQuantity_ND
.formatNumber(d3.format("d"))
.valueAccessor(function(d){return d; })
.group(tradeQuantityGroup)
.formatNumber(d3.format(".0e"));

Related

Subtract 1 from variable jQuery

Having some trouble getting this right. I'm very new to jQuery, so trying to get better and learn.
Currently I am getting 2 different values from a html table using the following code
var sellPrice = $('.qt').find("tr:eq(2)").find("td:eq(4)").html();
var buyPrice = $('.break .main-col .qt').find("tr:eq(2)").find("td:eq(4)").html();
These both output a value such as $13,000,000
I am then wanting to subtract 1 from these values (making it $12,999,999) before pasting them to an input as such
$('input[name="sell"]').val(sellPrice);
$('input[name="buy"]').val(buyPrice);
However, I am having some trouble with how to subtract $1 from these.
I tried using sellPrice--; but without success.
I've also tried adding - 1; at the end of each variable, but did not succeed either.
I tried to test something like this, but did not work either.
var minusOne = -1;
var getCurrentSellPrice = $('.qt').find("tr:eq(2)").find("td:eq(4)").html();
var getCurrentBuyPrice = $('.break .main-col .qt').find("tr:eq(2)").find("td:eq(4)").html();
var sellPrice = (getCurrentSellPrice - minusOne);
var buyPrice = (getCurrentBuyPrice - minusOne);
$('input[name="sell"]').val(sellPrice);
$('input[name="buy"]').val(buyPrice);`
Trying my best to familiarize myself with jQuery :)
Any help is much appreciated!
Solved using this
var getCurrentSellPrice = $('.qt').find("tr:eq(2)").find("td:eq(4)").html();
var getCurrentBuyPrice = $('.break .main-col .qt').find("tr:eq(2)").find("td:eq(4)").html();
var sellPrice = Number(getCurrentSellPrice.replace(/[^0-9\.]+/g,"")) - 1;
var buyPrice = Number(getCurrentBuyPrice.replace(/[^0-9\.]+/g,"")) + 1;
$('input[name="sell"]').val(sellPrice);
$('input[name="buy"]').val(buyPrice);
Since your numbers contain currency symbol and are strings, you need to convert them to proper numbers before subtracting them. See the answer below.
How to convert a currency string to a double with jQuery or Javascript?

How to get axis ticks out of d3 without rendering in SVG?

I'm implementing a 2d chart using canvas. I want to reuse d3's logic for generating the chart's axes. d3 does quite a lot of good work in generating axes and I'd like to take advantage of it.
(Note: For backward-compatibility reasons I'm stuck using d3v3 for the time being.)
Consider the following d3 code:
let scale = d3.time.scale()
.range([0, width])
.domain([lo, hi]);
let axis = d3.svg.axis()
.scale(scale)
.ticks(num_ticks)
.tickSize(10)
.orient("bottom");
I can render this into a chart div with:
svg.selectAll('.x-axis').call(axis);
I want to be able to programmatically get the tick data out of axis, including the formatted labels, by writing a function that behaves as follows:
ticks = get_axis_ticks(axis)
ticks should hold each tick position (as a Date in this particular case) and the corresponding d3-generated label.
[[Date(...), "Wed 19"],
[Date(...), "Fri 21"],
[Date(...), "Apr 23"],
[Date(...), "Tue 25"],
...]
I could then use this data to paint an axis on my canvas.
I've dug into d3v3 source (in particular here: https://github.com/d3/d3/blob/v3.5.17/src/svg/axis.js) but I find it very difficult to tease apart the logic from the SVG manipulation.
Help would be much appreciated.
One idea I have is to use the scale function you have created to generate the ticks you desire and push them into an array.
As a very simple example, if you would like 10 ticks, each incrementing by a unit of 1, you could do something like this: https://jsfiddle.net/Q5Jag/3148/
//define dummy values
var lo = 1;
var hi = 10;
var width = 512
var scale = d3.time.scale()
.range([0, width])
.domain([lo, hi]);
//define your function
var get_x_axis = function() {
let axisArr = [];
for(var i = 0; i < 10; i++ ) {
//calculate your value
axisArr.push(scale(i))
}
return axisArr
}
//call it
let axisTicks = get_x_axis()
//log it
console.log(axisTicks)
I'm not sure if this is what you're looking for, but if you need further help just ask.
I was able to get this working. I found the time formatting strategy in the d3 docs: https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format_multi I believe this is the strategy that d3 itself uses by default when users do not provide a custom format.
I learned that simply calling scale.ticks(N) will return Nish ticks suitable for rendering on an axis. These tick values are chosen on natural boundaries. E.g., if you're working with a time axis, these ticks will be aligned on minute, hour, day boundaries.
Here's a solution:
let time_format = d3.time.format.multi([
[".%L", d => d.getMilliseconds()],
[":%S", d => d.getSeconds()],
["%I:%M", d => d.getMinutes()],
["%I %p", d => d.getHours()],
["%a %d", d => d.getDay() && d.getDate() !== 1],
["%b %d", d => d.getDate() !== 1],
["%B", d => d.getMonth()],
["%Y", () => true]
]);
let get_ticks = (width, lo, hi, num_ticks) => {
let scale = d3.time.scale().range([0, width]).domain([lo, hi]);
return scale.ticks(num_ticks).map(t => [t, time_format(t)]);
};

how to create a time scale in d3

I'm new on d3,and I'm trying to create a time scale on the x-axis starting from this csv file
Anno,Italia
2003,46.9
2004,46.3
2005,54.0
2006,56.7
2007,56.9
2008,58.1
2009,59.0
2010,61.3
2011,62.6
2012,64.5
2013,67.2
but when I apply the d3.time.scale(),I get on the x-axis values such as .003,.004.What can I do to obtain 2003,2004 etc. on the axis?Here's my code :
var xScale = d3.time.scale().range([0,width]);
d3.csv("resources/diffusionesitiweb10anni.csv",function(data){
dataset = data;
xScale.domain(d3.extent(data,function(d){
return d["Anno"];
}));
Thanks in advance ! :)

NVD3 Cumulative line chart displays wrong y values

I have converted a line chart into a cumulative line chart and its y values are not displayed correctly. The range of the y axis should be 80.00 - 140.00 but instead I get -0.08 - 0.20. Has anyone managed to tweak their normalization code below to make it work with all kinds of ranges?
line.values = line.values.map(function(point, pointIndex) {
point.display = {
'y': (lines.y()(point, pointIndex) - v) / (1 + v)
};
return point;
})
Any help will be greatly appreciated.
I know that this question is somewhat old, but I am convinced that the normalization code for the cumulative line chart is not conceptually correct. Furthermore, the NVD3 cumulative line chart implementation is actually an index chart implementation (see Mike Bostock's example). A cumulative line chart would be more like this, I think. The cumulative chart can be easily achieved using the NVD3 line chart and some quick modifications to the underlying data.
If we take Bostock to be correct, and we really do wish to achieve an indexed line chart, then the indexify function in NVD3 should be changed to:
/* Normalize the data according to an index point. */
function indexify(idx, data) {
if (!indexifyYGetter) indexifyYGetter = lines.y();
return data.map(function(line, i) {
if (!line.values) {
return line;
}
var indexValue = line.values[idx];
if (indexValue == null) {
return line;
}
var v = indexifyYGetter(indexValue, idx);
// TODO: implement check below, and disable series if series
// causes a divide by 0 issue
if ((Math.abs(v) < 1e-6) && !noErrorCheck) {
// P.S. You may have to set a higher threshold (~1e-6?).
// I don't know I didn't run any tests...
line.tempDisabled = true;
return line;
}
line.tempDisabled = false;
line.values = line.values.map(function(point, pointIndex) {
point.display = {
'y': (indexifyYGetter(point, pointIndex) - v) / v
};
return point;
});
return line;
})
}
I asked a related question to the authors of NVD3 and plan to submit a pull request. Note that percentage change charts are really only meaningful when all of the underlying data is positive. When you start throwing negative values into the mix, percentage change loses all of its meaning.
What I found works is to insert another point with a y value of 0 at the beginning of the sequence of points.
Given a list of data points in the form [ [x1,y1], [x2,y2], ... [xn,yn]] ],
something like values.upshift([0,0]) works for me (the x value is arbitrary, but i just use 0 or values[0][0]) to insert to the front of the list.
(I'm getting the same thing with that chart. I'm still looking into it, but I hope this helped.)

dc.js dimension group ordering

I am trying to render a dc.js barChart where my y-axis is percentage 0-100% and my x-axis are numbers, however I want to order the x-axis by date.
My data looks like this:
date,trend,percent
01/01/2014 13:00,238,53.6
01/01/2014 13:15,239,64.2
01/01/2014 13:30,219,43.1
01/01/2014 13:45,219.2,43.1
01/01/2014 14:00,237.4,50.6
...
I am adding the data to crossfilter
data.forEach(function (d) { d.date = parseDate(d.date); });
var ndx = crossfilter(data);
var trendDimension = ndx.dimension(function (d) { return d.trend; });
var trendGroup = trendDimension.group().reduce(
function (p, v) {
p.time = v.date.getTime();
p.trend = +v.trend;
p.percent = +v.percent;
return p;
},
...
).order(function (p) { return p.time; }); // ??? order by time rather than trend
When I graph the dimension and group, my x-axis is sorted by trend as my x domain looks like:
var minTrend = trendDimension.bottom(1)[0].trend;
var maxTrend = trendDimension.top(1)[0].trend;
...
chart.x(d3.scale.linear().domain([minTrend, maxTrend]);
...
chart.render();
Everything plots, however the bars a sorted in order of trend and I would like them sorted in order of date/time.
Is this possible?
EDIT
I also tried:
chart.ordering(function (d) { return d.value.time; });
but that does not seem to have an effect on the ordering...
Do you want to graph percent versus trend or percent versus time?
Right now your dimension is on trend, so it will not be possible to order it by date. Crossfilter will create a bin for each trend value (which may have many dates), and the way you have written your reduce function, it will simply replace the date entry for the bin, with the last date it sees.
If you want to order by date and then use trend to affect some other aesthetic (color for example), you should use a date dimension, group by some quantization of the date, not do anything with the date in your reduce, and use date scale/xUnits.

Categories