I have two row charts and need to show the 2nd chart after i clicked (selectetd one) on the first row chart. how can i make it?
I can't add a js fiddle, because i'm getting my data from a database.
var TestCaseRow = dc.rowChart("#TestCaserowchart");
var TestCaseDim = perfData.dimension(function (d) {
return d.TestCase;
});
var clickGroup = TestCaseDim.group().reduceCount(function (d) {
return d.x;
});
var filtered_groupTestCase = remove_empty_bins(clickGroup);
TestCaseRow
.width(1100)
.height(filtered_groupTestCase.all().length*18)
.margins({ top: 5, left: 10, right: 10, bottom: 20 })
.dimension(TestCaseDim)
.group(filtered_groupTestCase)
.elasticX(true);
//my other row chart
var testscriptRow = dc.rowChart("#testscriptrowchart");
var testscriptDim = perfData.dimension(function (d) {
return d.TestScript;
});
var ClickTestscriptGroup = testscriptDim.group().reduceCount(function (d) {
return d.x;
});
var filtered_groupTestScript = remove_empty_bins(ClickTestscriptGroup);
testscriptRow
.width(1100)
.height(filtered_groupTestScript.all().length*40)
.margins({ top: 5, left: 10, right: 10, bottom: 20 })
.dimension(testscriptDim)
.group(filtered_groupTestScript)
.elasticX(true);
Register an event-handler on the first chart with .on('filtered', function(chart, filter){...}). Within that function, check if the 2nd chart is displayed and if it is not, do whatever you need to do to display it.
Related
I tried to erase negative ticks from my NVD3 line chart (with data includes 0 only)
but It seems impossible what I wanted to do...
I want to set the line bottom when I throw data what includes 0 only.
Is there another way? or just I had a mistake?
code:
nv.addGraph(function() {
//DATA.B includes only 0 data, the value must be "data>0"
data = DATA.A,DATA.B;
var chart = nv.models.linePlusBarChart()
.margin({top: 30, right: 60, bottom: 50, left: 70})
.x(function(d,i) { return i })
.y(function(d,i) { return d[1] });
chart.xAxis.tickFormat(function(d) {
var dx = data[0].values[d] && data[0].values[d][0] || 0;
return d3.time.format('%Y-%m-%d')(new Date(dx))
});
chart.y1Axis
.tickFormat(d3.format(',f'))
.tickSize(0,6);
chart.y2Axis
.tickFormat(function(d) { return d3.format(',f')(d) + '%' });
chart.bars.forceY([0]);
d3.select($node).datum(data).transition().duration(0).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
thanks
Used DC.js to create stacked bar chart with ordinal x-axis.
Versions used:
DC.js version 1.7.5
crossfilter.js version 1.3.12
D3.js version 3.5.17
The problem is that the chart's x-axis labels are not aligned with bars. They are actually shifted two ticks to right so last two labels have no bars above them.
Edit to remove - Also can't select the right most bar to filter data eg hover over bar doesn't show selector to click and activate cross filter. - it was just two chart margins overlapping blocking cursor.
Here is screenshot of chart indicating problems.
The x-axis is ordinal set using .xUnits(dc.units.ordinal)
I used a renderlet to change x-axis label orientation so they are vertical. If I remove renderlet it doesn't change the problems above.
Here is my chart div and javascript code.
<div id="month-chart"></div>
<script type="text/javascript">
d3.csv("merged_hostname.csv", function(data) {
var parseDate = d3.time.format("%Y-%m-%d").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
d.sessions = +d.sessions;
d.ad_requests = +d.ad_requests;
d.bounceRate = +d.bounceRate;
d.clicks = +d.clicks;
d.earnings = +d.earnings;
d.newUsers = +d.newUsers;
d.sessionDuration = +d.sessionDuration;
d.sessionsPerUser = +d.sessionsPerUser;
d.twitterSessions = +d.twitterSessions;
d.users = +d.users;
});
var ndx = crossfilter(data);
var yyyymmDim = ndx.dimension(function(d) { return d["yyyymm"]; });
var PPCCByYYYYMM = yyyymmDim.group().reduceSum(function(d) {
if (d.PPCC === "PPCC") {
return +d.sessions;
}else{
return 0;
}
});
var otherByYYYYMM = yyyymmDim.group().reduceSum(function(d) {
if (d.PPCC === "Other") {
return +d.sessions;
}else{
return 0;
}
});
monthChart = dc.barChart("#month-chart");
monthChart
.height(200)
.width(500)
.margins({top: 10, right: 10, bottom: 50, left: 40})
.dimension(yyyymmDim)
.group(PPCCByYYYYMM)
.stack(otherByYYYYMM)
.transitionDuration(500)
.brushOn(true)
.elasticY(true)
.yAxisLabel('sessions')
.x(d3.scale.ordinal())
.xUnits(dc.units.ordinal)
.renderlet(function (chart) {
chart.selectAll("g.x text")
.attr('dx', '-30')
.attr('transform', "rotate(-90)");
});
dc.renderAll();
});
</script>
Any ideas what can causes these issues and how to resolve?
You can move the left position with this:
.attr('transform', "translate(-20,0) rotate(-90)");
Change 20 if its necessary
Plnkr example:
http://plnkr.co/edit/19D5cnrVYdUrMlblQARy?p=preview
Screenshot from my app:
I've tried modifying the CSS, however I was only able to remove the 2nd (right Y axis line), but not the first left Y axis line.
What I've tried:
.nv-y {
display: none;
}
As well as all the lines from this answer: Alter first vertical grid line in nvd3
d3.selectAll('.nv-y').attr('display','none')
d3.selectAll('.nv-y path').attr('opacity','0.1')
d3.selectAll('.nv-y path').attr('display','none')
My current drawChart function:
function drawChart(res) {
console.log(' ');
console.log('drawChart res = ',res);
nv.addGraph(function() {
var chart = nv.models.linePlusBarChart()
.margin({top: 30, right: 40, bottom: 50, left: 40})
.x(function(d,i) { return i })
.y(function(d) { return d[1] })
.color(d3.scale.category10().range());
chart.xAxis.tickFormat(function(d) {
var dx = res[0].values[d] && res[0].values[d][0] || 0;
return d3.time.format('%x')(new Date(dx))
});
chart.y1Axis
.tickFormat(d3.format(',f'));
chart.y2Axis
.tickFormat(function(d) { return '$' + d3.format(',f')(d) });
chart.bars.forceY([0]);
// https://stackoverflow.com/questions/23754188/nvd3-js-how-to-disable-tooltips-for-one-serie-only
chart.lines.interactive(false);
// http://nvd3-community.github.io/nvd3/examples/documentation.html#line
chart.height(280);
// If not chart data is avaliable to display:
chart.noData("There is no Data to display at the moment.");
// Remove legend:
chart.showLegend(false);
d3.select('#chart svg')
.datum(res)
.transition().duration(500)
.call(chart);
d3.selectAll('.nv-y path').attr('display','none');
nv.utils.windowResize(chart.update);
return chart;
});
}
if you want to hide the 1st y axis do:
.nv-y1{
display:none;
}
if you want to hide the 2nd y axis do:
.nv-y2{
display:none;
}
http://plnkr.co/edit/IgFh1rV4a6ubAMe0VqT2?p=preview
Use this :
.domain {
display: none;
}
I'm trying to make a simple dashboard using dc.js and bootstrap. The charts I'm showing are a simple series chart with three different series taken from a csv with approximately 9000 lines, a pie chart to select from those series and a bar chart to act as a date range selector.
It all works correctly but the performance is horrible. I assume it must be due to my lack of experience with crossfilter, as the example (http://nickqizhu.github.io/dc.js/) uses 6000 records and performs really fast. Any ideas? I'm sorry for the lack of concreteness but I'm a bit lost here.
My code is here:
d3.csv(sourceFile, function(error, data) {
data = data.splice(min,max);
var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
data.forEach(function(d) {
d.Date = parseDate(d.date);
d.Year=d.Date.getFullYear();
d.Day = d3.time.day(d.Date);
});
var ndx2 = crossfilter(melt(data,["Date","Year","Day","date"],"Resource"));
var meltedDim = ndx2.dimension(function(d) {return d.Resource;});
var dateDim = ndx2.dimension(function(d) {return d.Date;});
var dateTypeDim = ndx2.dimension (function(d) {return [d.Date,d.Resource];});
var valueGroup = dateTypeDim.group().reduceSum(function(d){return d.value});
var dayDim = ndx2.dimension(function(d) {return d.Day;});
var volumeByDayGroup = dayDim.group().reduceSum(function (d) {
return d.value/50;
});
var yearDim = ndx2.dimension(function(d) {return +d.Year;});
var year_total = yearDim.group().reduceSum(function(d) {return d.value;});
var resourceDim = ndx2.dimension(function(d) {return d.Resource;});
var value_resource = resourceDim.group().reduceSum(function(d) {return 1;});
var minDate = dateDim.bottom(1)[0].Date;
var maxDate = dateDim.top(1)[0].Date;
var xAxisWidth = 1000;
var dateRangePicker = dc.barChart("#rangeTable");
dateRangePicker
.width(xAxisWidth).height(80)
.margins({top: 0, right: 10, bottom: 20, left: 65})
.dimension(dayDim)
.group(volumeByDayGroup)
.x(d3.time.scale().domain([minDate,maxDate]))
.gap(1)
.round(d3.time.day.round)
.elasticY(true)
.xUnits(d3.time.days)
.yAxis().ticks(4);
var chart = dc.seriesChart(htmlID);
chart
.width(xAxisWidth).height(600)
.dimension(dateDim)
.group(valueGroup)
.seriesAccessor(function(d) {return d.key[1]})
.keyAccessor(function(d) {return d.key[0]})
.valueAccessor(function (d) {return d.value})
.elasticY(false)
.ordinalColors(["#56B2EA","#E064CD","#F8B700"])
.x(d3.time.scale().domain([minDate,maxDate]))
.y(d3.scale.linear().domain([0,100]))
.elasticX(true)
.margins({top: 10, right: 10, bottom: 00, left: 10})
.brushOn(false)
.transitionDuration(1000)
.renderHorizontalGridLines(true)
.renderVerticalGridLines(true)
.rangeChart(dateRangePicker)
.mouseZoomable(false)
.legend(dc.legend().x(xAxisWidth-65).y(10).itemHeight(13).gap(5))
.margins({ top: 10, left: 50, right: 10, bottom: 50 })
.yAxisLabel("Resource Percentage");
var resourceRingChart = dc.pieChart("#chart-ring-resource");
resourceRingChart
.width(170).height(170)
.ordinalColors(["#56B2EA","#E064CD","#F8B700"])
.dimension(resourceDim)
.group(value_resource)
.legend(dc.legend().x(75).y(63).itemHeight(13).gap(5))
.renderLabel(false)
.renderTitle(false)
.innerRadius(50);
//dc.renderAll();
dateRangePicker.render();
chart.render();
resourceRingChart.render();
function getvalues(d){
var str=d.key.getDate() + "/" + (d.key.getMonth() + 1) + "/" + d.key.getFullYear()+"\n";
var key_filter = dateDim.filter(d.key).top(Infinity);
var total=0;
key_filter.forEach(function(a) {
str+=a.Resource+": "+a.value+"%\n";
total+=a.value;
});
dateDim.filterAll();
return str;
}
$("#resetButton").on("click",function(){
chart.filterAll();
chart.y(d3.scale.linear().domain([0,100]));
chart.render();
dateRangePicker.filterAll();
resourceRingChart.filterAll();
dc.redrawAll();
$("#rangeSlider").slider("destroy");
$("#rangeSlider").slider({
range: true,
min: 0,
max: 100,
values: [0,100],
});
});
$("#axisButton").on("click",function(){
var min = $('#rangeSlider').slider("option", "values")[0];
var max = $('#rangeSlider').slider("option", "values")[1];
chart.y(d3.scale.linear().domain([min,max]));
chart.render();
});
$("#rangeSlider").slider({
range: true,
min: 0,
max: 100,
values: [0,100],
});
})
Any help would be appreciated. Thanks in advance.
When using dimensions, it's best to avoid strings,dates and complex objects. Turn everything you can into integers, as it sorts the contents of the data based on your variables.
In my line chart, initially all data needed for plot line. There is two button Make and sell, If I click on any one of the button, data related to that button should be plotted for line with transition effect as shown in this link . I have tried to make this work, but I can't. I tried to make relation between button and line chart as given below(code), its not working. I have hard coded buttonId in my code with sell to have data related to sell, if I change it to Make I will get data related to Make but I need to hard coded here. what I want is when a Make button clicked data related to Make should come with transition as above link shown. My code is
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="d3.v3.min.js"></script>
<script type="text/javascript" src="d3.chart.min.js"></script>
</head>
<body>
<div id="vis"></div>
<button id="Make">Make</button>
<button id="sell">sell</button>
<script type="text/javascript">
d3.chart("linechart", {
initialize: function() {
// create a base scale we will use later.
var chart = this;
chart.w = chart.base.attr('width') || 200;
chart.h = chart.base.attr('height') || 150;
chart.w = +chart.w;
chart.h = +chart.h;
buttonId = 'sell'
chart.x = d3.scale.linear()
.range([0, chart.w]);
chart.y = d3.scale.linear()
.range([chart.h,0]);
chart.base.classed('line', true);
this.areas = {};
chart.areas.lines = chart.base.append('g')
.classed('lines', true)
.attr('width', chart.w)
.attr('height', chart.h)
chart.line = d3.svg.line()
.x(function(d) { return chart.x(d.x);})
.y(function(d) { return chart.y(d.y);});
this.layer("lines", chart.areas.lines, {
dataBind: function(data) {
// update the domain of the xScale since it depends on the data
chart.y.domain([d3.min(data,function(d){return d.y}),d3.max(data,function(d){return d.y})])
var mydata=new Array();
if(buttonId)
{
var j=0;
for(var i in data)
{
if(data[i].custody === buttonId){mydata[j] = data[i]; j++;};
}
chart.x.domain(d3.extent(mydata, function(d) { return d.x; }));
}
else
{
chart.x.domain(d3.extent(data, function(d) { return d.x; }));
}
// return a data bound selection for the passed in data.
return this.selectAll("path").data([data]);
},
insert: function() {
return this.append("path")
.datum(data)
.attr("d", chart.line)
.attr('stroke','#1ABC9C')
.attr('stroke-width','2')
.attr('fill','none');
}
});
},
// configures the width of the chart.
// when called without arguments, returns the
// current width.
width: function(newWidth) {
if (arguments.length === 0) {
return this.w;
}
this.w = newWidth;
return this;
},
// configures the height of the chart.
// when called without arguments, returns the
// current height.
height: function(newHeight) {
if (arguments.length === 0) {
return this.h;
}
this.h = newHeight;
return this;
},
});
var data = [
{x: 0,y:190, custody: "Make"},
{x: 1,y:10, custody: "Make"},{x: 2,y:40, custody: "Make"},{x: 3,y:90, custody: "Make"},
{x: 4,y:30, custody: "sell"},{x: 5,y:20, custody: "sell"},{x: 6,y:10, custody: "sell"},
{x: 7,y:40, custody: "sell"}
];
var chart1 = d3.select("#vis")
.append("svg")
.chart("linechart")
.width(720)
.height(320)
chart1.draw(data);
</script>
</body>
</html>
Get d3.chart.min.js from d3.chart.min.js
and get d3.v3.min.js from d3.v3.min.js