Here I'm getting date as 1970-01-01 by default.Can anyone please help me out in converting "2015-10-01" to timestamp.
My date :
"date": "2015-10-01"
xAxis: {
axisLabel: 'Months',
ticks: d3.time.months,
tickFormat: function (d) {
return d3.time.format('%Y %b')(new Date(d));
}
I did this thing,which solved my issue
x: function (d) { return d3.time.format('%Y-%m-%d').parse(d.date); },
y: function (d) { return d.trendingValue; },
useInteractiveGuideline: true,
xScale: d3.time.scale(),
xAxis: {
axisLabel: 'Months',
ticks: d3.time.months,
tickFormat: function (d) {
return d3.time.format('%Y-%m-%d')(new Date(d));
}
}
Related
Having trouble binding new data to a D3 BubbleChart. My AJAX call to the API is getting a good JSON reply. I checked the reply and it is getting data in the same format as defined in the hardcoded data used to initially setup the chart. I must be missing something because my chart does not show the new data. Do I need to redraw the chart? Here is the code:
$(document).ready(function () {
var uri = 'api/testing';
$.getJSON(uri, function (data, error) {
//DATA BIND/START - NOT UPDATING CHART
d3.selectAll("bubbleChart")
.data(data)
.enter().append("bubbleChart")
.attr("text", function (d) { return d.text; })
.attr("count", function (d) { return d.count; });
//DAT BIND/END
});
var bubbleChart = new d3.svg.BubbleChart({
supportResponsive: true,
size: 600,
innerRadius: 600 / 3.5,
radiusMin: 50,
data: {
items: [
{ text: "aaa", count: "236" },
{ text: "bbb", count: "382" },
{ text: "ccc", count: "170" },
{ text: "ddd", count: "123" },
{ text: kk, count: ll}
],
eval: function (item) { return item.count; },
classed: function (item) { return item.text.split(" ").join(""); }
},
plugins: [
{
name: "central-click",
options: {
text: "(See more detail)",
style: {
"font-size": "12px",
"font-style": "italic",
"font-family": "Source Sans Pro, sans-serif",
"text-anchor": "middle",
"fill": "white"
},
attr: { dy: "65px" },
centralClick: function () {
alert("Here is more details!!");
}
}
},
{
name: "lines",
options: {
format: [
{// Line #0
textField: "count",
classed: { count: true },
style: {
"font-size": "28px",
"font-family": "Source Sans Pro, sans-serif",
"text-anchor": "middle",
fill: "white"
},
attr: {
dy: "0px",
x: function (d) { return d.cx; },
y: function (d) { return d.cy; }
}
},
{// Line #1
textField: "text",
classed: { text: true },
style: {
"font-size": "14px",
"font-family": "Source Sans Pro, sans-serif",
"text-anchor": "middle",
fill: "white"
},
attr: {
dy: "20px",
x: function (d) { return d.cx; },
y: function (d) { return d.cy; }
}
}
],
centralFormat: [
{// Line #0
style: { "font-size": "50px" },
attr: {}
},
{// Line #1
style: { "font-size": "30px" },
attr: { dy: "40px" }
}
]
}
}]
});
});
function formatItem(item)
{
return 'text:' + item.text + ', count:' + item.count;
}
I have been using NVD3 but have decided to add some on-click events. I found an example using a horizontal bar chart.
vm.qcoptions = {
chart: {
type: 'multiBarHorizontalChart',
//type: 'discreteBarChart',
height: 450,
margin: {
top: 20,
right: 20,
bottom: 50,
left: 55
},
x: function (d) { return d.label; },
y: function (d) { return d.value + (1e-10); },
showValues: true,
valueFormat: function (d) {
return d3.format(',.4f')(d);
},
duration: 500,
xAxis: {
axisLabel: ''
},
yAxis: {
axisLabel: '',
axisLabelDistance: -10
},
callback: function (chart) {
chart.multibar.dispatch.on('elementClick', function (e) {
console.log('elementClick in callback', e.data);
});
}
}
};
The example above works when using the multiBarHorizonatChart, but when I switch to the discreteBarChart it throws this error "Cannot read property 'dispatch' of undefined" at this line
chart.multibar.dispatch.on('elementClick', function (e) {
I have tried to inspect chart and determine what I should in in place of chart.multibar for the bar chart but I am stumped. Can anyone shed any light on this?
You are referring now to the discrete bar chart. You will need to reflect that in the callback function as follows:
chart.discretebar.dispatch.on('elementClick', function (e) {
console.log('elementClick in callback', e.data);
});
I suggest that you always refer to this page with the extended radio button selected in order to see the appropriate property names.
I have the following line chart: http://jsfiddle.net/cp3fV/2/
var data = [
{
"days_to_expiry": 0,
"close": "7.1120000000"
},
{
"days_to_expiry": 1,
"close": "8.4580000000"
},
{
"days_to_expiry": 2,
"close": "7.2830000000"
},
{
"days_to_expiry": 3,
"close": "12.2820000000"
},
{
"days_to_expiry": 4,
"close": "7.1820000000"
}
]
nv.addGraph(function() {
var chart = nv.models.lineChart()
.margin({left: 100, right:50})
.useInteractiveGuideline(true)
.transitionDuration(350)
.showLegend(false)
.showYAxis(true)
.showXAxis(true)
//.forceY([0, 19])
.y(function (d) { return d.close })
.x(function (d) { return d.days_to_expiry })
;
console.log(data);
chart.xAxis
.axisLabel('Date')
.ticks(10);
chart.yAxis
.axisLabel('Close')
.tickFormat(d3.format('.03f'));
var testData = [{key:"Test", color: '#2ca02c', values: data}];
d3.select('#chart svg')
.datum(testData)
.call(chart);
nv.utils.windowResize(function() { chart.update() }); // Update on resize
return chart;
});
I just want to order the Y axis from minimum to maximum. It works fine if all the values are <10
I know I can use forceY(min, max) but I don't want to calculate the minimum every time(I'm planning to use AJAX to update the chart)
It works if you use the numbers as numbers and not as strings:
data.forEach(function(d) { d.close = +d.close; });
Complete example here.
I am working with JSON like the following:
[
{
"source": "Google",
"date": "2014-02-01",
"spend": 21,
"clicks": 1000
},
{
"source": "Bing",
"date": "2014-02-01",
"spend": 5,
"clicks": 541
},
{
"source": "Google",
"date": "2014-02-02",
"spend": 24,
"clicks": 1029
},
{
"source": "Bing",
"date": "2014-02-02",
"spend": 12,
"clicks": 754
}
]
And want to feed it into Crossfilter to create a line chart with NVD3. I don't know where to start, but I want the line chart to use the following:
X Axis - Date
Y Axis - Clicks
1 line per source
This is what I've been able to build without Crossfilter:
(function () {
var ymdFormat = d3.time.format('%Y-%m-%d');
d3.json('./data.json', function (err, json) {
nv.addGraph(function () {
var chart = nv.models.lineChart()
chart.margin({ left: 100 })
.useInteractiveGuideline(true)
.transitionDuration(350)
.showLegend(true)
.showYAxis(true).showXAxis(true);
chart.xAxis
.axisLabel('Date')
.tickFormat(function (d) {
return d3.time.format('%b %Y')(new Date(d));
});
chart.yAxis
.axisLabel('Clicks')
.tickFormat(d3.format(','));
data = parseData(json);
d3.select('#graph').append('svg')
.datum(data).call(chart);
});
})
function parseData(json) {
var data, result, key;
data = {};
json.forEach(function (elmt) {
if (!(elmt.source in data)) {
data[elmt.source] = { values: [] }
}
data[elmt.source].values.push({ x: ymdFormat.parse(elmt.date), y: elmt.clicks })
});
result = [];
for (key in data) {
if (data.hasOwnProperty(key)) {
result.push({
key: key,
values: data[key].values
});
}
}
console.log(result);
return result;
}
})()
I have this problem. I have a solution for this, not very nice, however.
var filterByMonthSource = filter.dimension(function(d) { return d.date + ':' + d.source });
var clicksGroup = filterByMonth.group().reduceSum(function(d) { return d.clicks });
var clicksData = clicksGroup.all();
clicksData will have [{key: "2014-02-01:Google", value: ...}, ...]
I then have to break clicksData into array of 3 fields.
I want to create a timeseries by passing a dictionary in the function. The code from the examples is this:
d3.csv("data.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain(d3.extent(data, function(d) { return d.close; }));
//etc...
What I'm trying to do is to convert this into a function which takes an object with date and close rows (data) and produces the chart from this, i.e.
function makeGraph(timeseriesdata){
// create chart above from data
// what format??
}
d3.csv does most of the hard work for you. It takes a csv and coverts it to an array of objects, each corresponding to a row of the csv.
https://github.com/mbostock/d3/wiki/CSV has some examples.
After calling d3.csv and cleaning up the data with parseDate, you can pass data to makeGraph.
d3.csv("data.csv", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
makeGraph(data);
});
function makeGraph(timeseriesdata){
}
To create a line path given a dictionary make a list with a dict, such as:
var parseDate = d3.time.format("%Y-%m-%d").parse;
var lineData = [ { "date": "2013-04-01", "close": 5}, { "date": "2013-03-28", "close": 20},
{ "date": "2013-03-27", "close": 10}, { "date": "2013-03-26", "close": 40},
{ "date": "2013-03-25", "close": 5}, { "date": "2013-03-24", "close": 60}];
lineData.forEach(function(d,i) {
d.date = parseDate(d.date);
d.close = +d.close;
});
makeGraph(lineData);