I am trying to get a super basic nvd3 chart rendering. The code looks something like this (fiddle here):
<div id="chart" class="chart with-transitions">
<svg></svg>
</div>
and
nv.addGraph({
generate: function() {
var chart = nv.models.line()
.margin({top: 20, right: 20, bottom: 20, left: 20})
d3.select('#chart')
.datum(sinAndCos())
.call(chart);
return chart;
}});
function sinAndCos() {
var sin = [],
cos = [];
for (var i = 0; i < 100; i++) {
sin.push({x: i, y: Math.sin(i/10)});
cos.push({x: i, y: .5 * Math.cos(i/10)});
}
return [
{
values: sin,
key: "Sine Wave",
color: "#ff7f0e"
},
{
values: cos,
key: "Cosine Wave",
color: "#2ca02c"
}
];
}
But when I run this nothing happens. No errors generated, no chart displayed. I copied/modified this code from the most basic example they offer, but I can't seem to figure out what I broke. Can anyone see what I am doing wrong here?
FIDDLE
<div id="chart" class="chart with-transitions">
<svg height="500"></svg>
</div>
...
d3.select('#chart svg')
Demo Fiddle
You forgot to select the svg element that you want to render your chart in. Also, call lineChart() instead of line() if you want to display the axis and other information:
var chart = nv.models.lineChart() <-- lineChart()
.margin({top: 20, right: 20, bottom: 20, left: 20});
d3.select('#chart svg') <-- include svg
.datum(sinAndCos())
.call(chart);
Related
I'm having trouble trying to figure out the correct setup to have a ChartJS Bar Chart that has a fixed canvas height but allows the width be overflow-x. I have found an example here...http://jsfiddle.net/mbhavfwm/ which uses ChartJS 1.0, but I'm using ChartJS 2.6. So, I found another example here http://jsfiddle.net/jmpxgufu/ which uses ChartJS 2, but this example shows the chart rendered with only a few values and then ADDS more to it using javascript which then causes the width to overflow. Not quite the same.
My problem is I can not figure out how to make the chart render at the fixed height with all the data already in it, but NOT try to constrain the canvas to the width of the parent container. I want it to overflow.
Here is what I have so far.
https://jsfiddle.net/fed79b7t/
HTML
<div class="chartWrapper">
<div class="chartAreaWrapper">
<canvas id="chart-FuelSpend" height="300" width="1200"></canvas>
</div>
<canvas id="axis-FuelSpend" height="300" width="0"></canvas>
</div>
CSS
.chartWrapper {
position: relative;
}
.chartWrapper > canvas {
position: absolute;
left: 0;
top: 0;
pointer-events: none;
}
.chartAreaWrapper {
width: 600px;
overflow-x: scroll;
}
JAVASCRIPT
function generateLabels() {
var chartLabels = [];
for (x = 0; x < 100; x++) {
chartLabels.push("Label" + x);
}
return chartLabels;
}
function generateData() {
var chartData = [];
for (x = 0; x < 100; x++) {
chartData.push(Math.floor((Math.random() * 100) + 1));
}
return chartData;
}
var chartData = {
labels: generateLabels(),
datasets: [{
label: "Test Data Set",
data: generateData()
}]
};
$(function() {
var canvasFuelSpend = $('#chart-FuelSpend');
var chartFuelSpend = new Chart(canvasFuelSpend, {
type: 'bar',
data: chartData,
maintainAspectRatio: false,
responsive: true,
options: {
tooltips: {
titleFontSize: 0,
titleMarginBottom: 0,
bodyFontSize: 12
},
legend: {
display: false
},
scales: {
xAxes: [{
ticks: {
fontSize: 12,
display: false
}
}],
yAxes: [{
ticks: {
fontSize: 12,
beginAtZero: true
}
}]
},
animation: {
onComplete: function() {
var sourceCanvas = chartFuelSpend.chart.canvas;
var copyWidth = chartFuelSpend.scales['y-axis-0'].width - 10;
var copyHeight = chartFuelSpend.scales['y-axis-0'].height + chartFuelSpend.scales['y-axis-0'].top + 10;
var targetCtx = document.getElementById("axis-FuelSpend").getContext("2d");
targetCtx.canvas.width = copyWidth;
targetCtx.drawImage(sourceCanvas, 0, 0, copyWidth, copyHeight, 0, 0, copyWidth, copyHeight);
}
}
}
});
});
So, my goal is to have the chart the full 1200 pixels as defined by the canvas width, but for the container div to only show the 600 pixel amount where I can scroll the container to see the rest of the chart while keeping the Y-axis in place.
Can anyone shed some light on what I'm doing wrong? What am I missing?
Thank you!!!!!
It seems to have something to do with the fact you're missing a wrapper around the canvas. Here's an updated version of your fiddle. I've added a function called addData that takes the number of new entries you want to add and the chart variable. It's not as good as it can be (because i'm not 100% sure how you want to add new data) but it's a great starting point. The trick is to not initialize the chart with all data included, you want to create the chart and then add to it later to expand the canvas, otherwise the initial render will work to fit all of the data in at that width.
https://jsfiddle.net/qmqmg82z/3/
Additional JavaScript code:
function addData(numData, chart){
for (var i = 0; i < numData; i++){
chart.data.datasets[0].data.push(Math.random() * 100);
chart.data.labels.push("Label" + i);
var newwidth = $('.chartAreaWrapper2').width() +60;
$('.chartAreaWrapper2').width(newwidth);
}
}
and then at the end of your page load function (or wherever you want to be adding new data) add this function call:
addData(5, chartFuelSpend);
But bear in mind this will require however much data you want to add and the chart instance.
And the HTML:
<div class="chartWrapper">
<div class="chartAreaWrapper">
<div class="chartAreaWrapper2">
<canvas id="chart-FuelSpend" height="300" width="1200"></canvas>
</div>
</div>
<canvas id="axis-FuelSpend" height="300" width="0"></canvas>
</div>
I'm guessing the problem was that because the width of the single wrapper you had was changing along with the chart, it meant that the horizontal scroll wasn't being applied, this way the outer wrapper has the fixed width while the inside one and the canvas can expand.
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
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.
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 have this code to produce a lineplusBarChart
HTML
<div id="chart1" class='with-3d-shadow with-transitions'>
<svg> </svg>
</div>
Scripts
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/linePlusBarChart.js"></script>
<script>
var time="1134345600000";
var quantity="12332212"
var testdata = [
{
"key" : "Quantity" ,
"bar": true,
"values" : [ [ 1136005200000 , 1271000.0] ]
}
].map(function(series) {
series.values = series.values.map(function(d) { return {x: d[0], y: d[1] } });
return series;
});
testdata[0].values.push([time, quantity]);//NOT SHOWING THE BAR
var chart;
nv.addGraph(function() {
chart = nv.models.linePlusBarChart()
.margin({top: 30, right: 60, bottom: 50, left: 70})
.x(function(d,i) { return i })
.color(d3.scale.category10().range());
chart.xAxis.tickFormat(function(d) {
var dx = testdata[0].values[d] && testdata[0].values[d].x || 0;
return dx ? d3.time.format('%x')(new Date(dx)) : '';
})
.showMaxMin(false);
chart.y1Axis
.tickFormat(d3.format(',f'));
chart.y2Axis
.tickFormat(function(d) { return '$' + d3.format(',.2f')(d) });
chart.bars.forceY([0]).padData(false);
//chart.lines.forceY([0]);
d3.select('#chart1 svg')
.datum(testdata)
.transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
});
</script>
Now i want to add some variables to the graph from javascript. Let say i have two variables var time="1134345600000" and var quantity="12332212". i want some how to push these two variables into var testdata.values.
Is there an possible way?
DEMO (js code after line 23240)
In your particular case, you need to push the data like this:
testdata[0].values.push({x: +time, y: +quantity});
Demo here.