nvd3 multibarchart height and label issue - javascript
I am using the reusable NVD3 multibarchart, I have 4 serious and 250+ categories. this chart is working but the rectangles are very small and some of the labels are overlapping.
the out see below.
nvd3 multibarchart
the code which i am using is
var data = [{"key":"Ready","total":135,"values":[{"label":"111","value":1},{"label":"136","value":1},{"label":"155","value":2},{"label":"525","value":2},{"label":"RD ","value":7}, {"label":"601","value":3},{"label":"624","value":2},{"label":"155","value":1},{"label":"ADC","value":2},{"label":"177","value":2},{"label":"152","value":2},{"label":"026","value":3}, {"label":"623","value":2},{"label":"800","value":1},{"label":"067","value":2},{"label":"096","value":2},{"label":"133","value":1},{"label":"Mer","value":1},{"label":"Mer","value":2},{"label":"050","value":1},{"label":"138","value":1},{"label":"098","value":4},{"label":"080","value":2},{"label":"010","value":1},{"label":"034","value":1},{"label":"069","value":1},{"label":"020","value":1},{"label":"060","value":1},{"label":"037","value":1},{"label":"006","value":3},{"label":"167","value":2},{"label":"117","value":1},{"label":"143","value":1},{"label":"IDP","value":1},{"label":"185","value":1},{"label":"575","value":2},{"label":"146","value":2},{"label":"173","value":1},{"label":"171","value":3},{"label":"633","value":1},{"label":"010","value":4},{"label":"040","value":2},{"label":"068","value":2},{"label":"175","value":2},{"label":"054","value":3},{"label":"096","value":1},{"label":"096","value":5},{"label":"154","value":2},{"label":"050","value":7},{"label":"096","value":4},{"label":"096","value":2},{"label":"034","value":3},{"label":"069","value":2},{"label":"020","value":2},{"label":"060","value":3},{"label":"118","value":1},{"label":"164","value":3},{"label":"415","value":3},{"label":"138","value":3},{"label":"126","value":1},{"label":"037","value":2},{"label":"065","value":3},{"label":"157","value":2},{"label":"SCC","value":2}]},{"key":"Not Started","total":19890,"values":[{"label":"111","value":22},{"label":"136","value":216},{"label":"155","value":300},{"label":"525","value":174},{"label":"RD ","value":1253},{"label":"601","value":797},{"label":"624","value":271},{"label":"155","value":60},{"label":"ADC","value":272},{"label":"177","value":159},{"label":"152","value":426},{"label":"026","value":519},{"label":"623","value":562},{"label":"800","value":69},{"label":"067","value":643},{"label":"096","value":135},{"label":"133","value":272},{"label":"Mer","value":97},{"label":"Mer","value":303},{"label":"050","value":119},{"label":"138","value":54},{"label":"098","value":644},{"label":"080","value":384},{"label":"010","value":121},{"label":"034","value":21},{"label":"069","value":99},{"label":"020","value":42},{"label":"060","value":31},{"label":"037","value":54},{"label":"006","value":337},{"label":"167","value":303},{"label":"117","value":221},{"label":"143","value":88},{"label":"IDP","value":282},{"label":"185","value":102},{"label":"575","value":313},{"label":"146","value":139},{"label":"173","value":93},{"label":"171","value":210},{"label":"633","value":103},{"label":"010","value":733},{"label":"040","value":356},{"label":"068","value":475},{"label":"175","value":301},{"label":"054","value":466},{"label":"096","value":42},{"label":"096","value":739},{"label":"154","value":295},{"label":"050","value":679},{"label":"096","value":423},{"label":"096","value":165},{"label":"034","value":380},{"label":"069","value":350},{"label":"020","value":560},{"label":"060","value":665},{"label":"118","value":112},{"label":"164","value":762},{"label":"415","value":174},{"label":"138","value":346},{"label":"126","value":101},{"label":"037","value":346},{"label":"065","value":563},{"label":"157","value":416},{"label":"SCC","value":131}]},{"key":"Obsolet","total":861,"values":[{"label":"111","value":1},{"label":"136","value":16},{"label":"155","value":16},{"label":"525","value":3},{"label":"RD ","value":32},{"label":"601","value":23},{"label":"624","value":17},{"label":"155","value":1},{"label":"ADC","value":10},{"label":"177","value":5},{"label":"152","value":23},{"label":"026","value":25},{"label":"623","value":25},{"label":"800","value":1},{"label":"067","value":31},{"label":"096","value":3},{"label":"133","value":14},{"label":"Mer","value":1},{"label":"Mer","value":9},{"label":"050","value":2},{"label":"138","value":2},{"label":"098","value":15},{"label":"080","value":9},{"label":"010","value":7},{"label":"069","value":7},{"label":"020","value":5},{"label":"006","value":16},{"label":"167","value":23},{"label":"117","value":8},{"label":"143","value":5},{"label":"IDP","value":20},{"label":"185","value":10},{"label":"575","value":22},{"label":"146","value":12},{"label":"173","value":2},{"label":"171","value":12},{"label":"633","value":7},{"label":"010","value":27},{"label":"040","value":21},{"label":"068","value":23},{"label":"175","value":19},{"label":"054","value":19},{"label":"096","value":1},{"label":"096","value":26},{"label":"154","value":18},{"label":"050","value":31},{"label":"096","value":19},{"label":"096","value":10},{"label":"034","value":21},{"label":"069","value":21},{"label":"020","value":26},{"label":"060","value":22},{"label":"118","value":7},{"label":"164","value":19},{"label":"415","value":8},{"label":"138","value":17},{"label":"126","value":6},{"label":"037","value":15},{"label":"065","value":22},{"label":"157","value":17},{"label":"SCC","value":6}]},{"key":"Started","total":379,"values":[{"label":"111","value":2},{"label":"136","value":8},{"label":"155","value":5},{"label":"525","value":6},{"label":"RD ","value":9},{"label":"601","value":5},{"label":"624","value":5},{"label":"155","value":4},{"label":"ADC","value":5},{"label":"177","value":5},{"label":"152","value":6},{"label":"026","value":6},{"label":"623","value":8},{"label":"800","value":5},{"label":"067","value":10},{"label":"096","value":7},{"label":"133","value":5},{"label":"Mer","value":4},{"label":"Mer","value":9},{"label":"050","value":1},{"label":"138","value":1},{"label":"098","value":11},{"label":"080","value":5},{"label":"010","value":1},{"label":"069","value":3},{"label":"060","value":1},{"label":"006","value":10},{"label":"167","value":5},{"label":"117","value":7},{"label":"143","value":4},{"label":"IDP","value":5},{"label":"185","value":4},{"label":"575","value":7},{"label":"146","value":4},{"label":"173","value":5},{"label":"171","value":5},{"label":"633","value":4},{"label":"010","value":7},{"label":"040","value":7},{"label":"068","value":7},{"label":"175","value":5},{"label":"054","value":10},{"label":"096","value":5},{"label":"096","value":15},{"label":"154","value":6},{"label":"050","value":10},{"label":"096","value":11},{"label":"096","value":11},{"label":"034","value":8},{"label":"069","value":7},{"label":"020","value":9},{"label":"060","value":8},{"label":"118","value":4},{"label":"164","value":8},{"label":"415","value":7},{"label":"138","value":6},{"label":"126","value":4},{"label":"037","value":5},{"label":"065","value":8},{"label":"157","value":7},{"label":"SCC","value":7}]}];
(function(data) {
nv.addGraph(function() {
var chart = nv.models.multiBarHorizontalChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.forceY([0])// To make 10 to be starting point.
//.margin({top: 30, right: 20, bottom: 50, left: 175})
.showValues(true)
.height(2500)
.showControls(true);
chart.yAxis.tickFormat(d3.format(','));
d3.select('#chart1 svg')
.datum(data)
.call(chart)
.attr('height', 5500);
nv.utils.windowResize(chart.update);
return chart;
});})(data);
The overlap is because:
In a key example Ready:
Has value 2 for label 155
{
"label": "155",
"value": 2
}
later it has value 1 for value 155
, {
"label": "155",
"value": 1
}
this is the reason for overlap (it is trying to show 2 and 1 on label 155).
Fix:
Ensure that for a label there is only one value for a given key.
Increase the size of the svg like here
Related
NVD3 chart shows tooltip for wrong data
I have a chart in NVD3 with a date on the X axis and a float on the Y axis. It displays fine, but when I hover over the chart to make the tooltip pop up, it doesn't show it for the dataset I'm currently hovering over. Here's a GIF to make it more clear, hopefully: This is the code I've used: <script> var data = function() { return [ { values: [ {x:"2018-09-08", y:19.98},{x:"2018-09-07", y:11.99},{x:"2018-09-06", y:9.98},{x:"2018-09-05", y:4.99},{x:"2018-09-03", y:9.98},{x:"2018-09-02", y:14.99}, ], key: 'Turnover' } ]; } nv.addGraph(function() { var chart = nv.models.lineChart() .useInteractiveGuideline(true) .xScale(d3.time.scale()) .x( function(d){return d3.time.format('%Y-%m-%d').parse(d.x);} ); ; chart.xAxis .axisLabel('Date') .tickFormat(function(d) {return d3.time.format("%Y-%m-%d")(new Date(d))}); ; chart.yAxis .axisLabel('Sales') .tickFormat(d3.format('.02f')) ; chart.showLegend(false); d3.select('#nvd3 svg') .datum(data()) .transition().duration(500) .call(chart) ; nv.utils.windowResize(chart.update); return chart; }); </script> Edit 1: When I do not use the .useInteractiveGuideline(true) function, it does work and the tooltip is presented on the correct set of data. However, I do want to use this function. So any help here?
Looking at the examples of the NVD3 site they work with a Linear Scale for time axis. Converting the code to this too shows the requested behavior. You have to set the tick positions yourself because the automatic ticks for a linear scale are not on dates var data = function() { return [ { values: [ {x:"2018-09-02", y:14.99}, {x:"2018-09-03", y:9.98}, {x:"2018-09-05", y:5.99}, {x:"2018-09-06", y:9.98}, {x:"2018-09-07", y:11.99}, {x:"2018-09-08", y:19.98} ], key: 'Turnover' } ]; }; var formatDate = d3.time.format("%Y-%m-%d"); nv.addGraph(function () { var chart = nv.models.lineChart() .useInteractiveGuideline(true) ; var mydata = data(); mydata[0].values.forEach(e => { e.x = Date.parse(e.x); }); chart.xAxis .axisLabel('Date') .tickFormat(function(d) {return formatDate(new Date(d))}) .tickValues(mydata[0].values.map( d => d.x )) ; chart.yAxis .axisLabel('Sales') .tickFormat(d3.format('.02f')) ; chart.showLegend(false); d3.select('#nvd3 svg') .datum(mydata) .transition().duration(500) .call(chart) ; nv.utils.windowResize(chart.update); return chart; });
Create scatter plot with unequal intervals on x-axis using d3.js
I am trying to create a scatter plot with unequal intervals on the X-axis using d3.js. My CSV data is shown here partially: chr,pos,val 22,8947,8.58891099252 22,8978,4.65541559632 22,8996,6.33685790218 22,8997,9.00384002282 22,9006,4.39533823989 MT,9471,5.0655064583 MT,9472,7.83798949399 MT,9473,0.587797595352 MT,9474,4.6475160648 MT,9475,2.52382097771 MT,9476,7.8431366396 MT,9477,1.71519736769 MT,9478,2.61168595179 MT,9479,4.15061022346 MT,9470,7.1477707428 The number of pos values for each chr value may be different. In some cases, it could be 20, in others 100 and so on. I need to create a plot of val on the y-axis vs chr on the x-axis, with the x-interval for each chr being equal to the number of pos values for that chr. Although ordinal scale for the x-axis seems suitable here, it probably doesn't support unequal intervals. With linear scale, unequal intervals can be shown using polylinear scales, but the presence of alphabetic characters in chr mean no ticks are shown. Does anyone know how I can show unequal intervals in d3.js? UPDATE: I have some code here for the domain and ticks using a linear scale: const x = d3.scale.linear() .domain(input.map((d) => { if (d.chr === 'MT') { return 23; } if (d.chr === 'X') { return 24; } return d.chr; })) .range(xTicks); I can't understand how to show the ticks now.With this it shows 23 and 24 instead of MT and X. I am not sure of this part: const xAxis = d3.svg.axis().scale(x).orient('bottom').tickValues(input.map((d) => { if (d.chr === 'MT') { // returning a string here shows NaN return 23; } if (d.chr === 'X') { return 24; } return d.chr; }));
Here is an example of how conditionally formatting the ticks using tickFormat (not tickValues). Suppose the data is: 19, 20, 21, 22, 23, 24; But we are going to change 23 for "X" and 24 for "MT" in the ticks. Click "run code snippet": var data = [19, 20, 21, 22, 23, 24]; var width = 400, height = 100; var svg = d3.select("body") .append("svg") .attr("width", width) .attr("heigth", height); var xScale = d3.scale.linear() .domain(d3.extent(data)) .range([0, width*.9]); var xAxis = d3.svg.axis() .orient("bottom") .ticks(6) .tickFormat(function(d){ if(d == 23){ return "X" } else if(d==24){ return "MT" } else { return d } }) .scale(xScale); svg.append("g") .attr("class", "axis") .attr("transform", "translate(20,20)") .call(xAxis); .axis path, .axis line { fill: none; stroke: #aaa; shape-rendering: crispEdges; } <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> I started at chromosome 19 just to save some space, but you can get the general idea.
How to add JSON data to nvd3 charts
I am new to Javascript and couldn't find error in my code. I am using NVD3 charts here. It is a time series based chart with date and closing prices of a particular stock. Data ranges from 2005 till now. Here is the code var data= JSON.parse("Data.JSON") nv.addGraph(function() { var chart = nv.models.lineChart() .margin({top: 70, right: 70, bottom: 70, left: 70}) .useInteractiveGuideline(true) .transitionDuration(100) .showYAxis(true) .showXAxis(true) ; //Chart x-axis settings chart.xAxis .axisLabel('date') .tickFormat(function(d) {return new Date((data.Date - (25567 + 1))*86400*1000); chart.yAxis //Chart y-axis settings .axisLabel('close') .tickFormat(d3.scale.linear(data.Close)); d3.select('#Charts svg') //Selecting the <svg> element where i want to render the chart in. .datum(data) //Populating the <svg> element with chart data... .call(chart); //Finally, rendering the chart! //Update the chart when window resizes. }) ; //Data { "Date": [13089, 13094, 13095, 13096, 13097, 13098, 13101, 13103, 13104, 13105, 13108, 13109, 13110] "Close": [ 2419.1, 2461.6, 2492.7, 2489.1, 2500.7, 2548.7, 2558.7, 2582.8, 2603.9, 2620.1, 2602.5, 2572.8] }
The number of array elements in "Close" are less compared to "Date". Here is a possible solution that you might be looking for: nv.addGraph(function () { var chart = nv.models.lineChart(); chart.xAxis.axisLabel('date') .tickFormat(d3.format('')); chart.yAxis.axisLabel('close') .tickFormat(d3.format('')); d3.select('#dateChart') .datum(chartData()) .transition().duration(500) .call(chart); nv.utils.windowResize(function () { d3.select('#dateChart').call(chart) }); return chart; }); function chartData() { var myData = { "Date": [13089, 13094, 13095, 13096, 13097, 13098, 13101, 13103, 13104, 13105, 13108, 13109, 13110], "Close": [2419.1, 2461.6, 2492.7, 2489.1, 2500.7, 2548.7, 2558.7, 2582.8, 2603.9, 2620.1, 2602.5, 2572.8, 2588.8] //The number of array elements in Close were less compared to Date. Hence added 2588.8 as the last element }; var result = []; for (var i = 0; i < myData.Date.length; i++) { result.push({ x: myData.Date[i], y: myData.Close[i] }); } return [{ values: result, key: 'Date Chart', color: '#ff7f0e' }]; } JS Fiddle: https://jsfiddle.net/m7oaxjue/3/
Only end tick mark is showing on dc.js bubble chart
I have the following bubble chart coded with dc.js which is built upon d3.js. All is good, but for some reason I cannot see the tick marks. When I inspect the DOM I can see that they are present: <line y2="6" x2="0"></line> And I have applied CSS styles to them, but still they do not show! #referrals-bubble-chart .axis .tick line { fill: none; stroke: #000; shape-rendering: crispEdges; } I even added a stroke-width of 2px and still nothing shows! I know I'm targeting the right elements in my CSS because when I give it a stroke width of 10px and hover (Chrome Inspector), I see that the line is now 10px wide. Why is this happening? Chart Code is below: // define the referrals bubble chart attributes referralsChart .width(700) .height(400) .transitionDuration(1500) // (optional) define chart transition duration, :default = 750 .margins({top: 10, right: 50, bottom: 40, left: 50}) .dimension(diagnosisDimension) //Bubble chart expect the groups are reduced to multiple values which would then be used //to generate x, y, and radius for each key (bubble) in the group .group(diagnosisDimensionGroup) .colors(colorbrewer.RdYlGn[9]) // (optional) define color function or array for bubbles .colorDomain([0, 100]) //(optional) define color domain to match your data domain if you want to bind data or color .colorAccessor(function (d) { // color - mapped to internal scale return d.value.cost % 100; }) .keyAccessor(function (p) { // x-axis return p.value.avgrtt / p.value.referrals; }) .valueAccessor(function (p) { // y-axis return p.value.cost / 1000; }) .radiusValueAccessor(function (p) { // radius size - default is [0, 100] return p.value.referrals; }) .maxBubbleRelativeSize(0.1) // .x(d3.scale.linear().domain([0, 5000])) .x(d3.scale.linear().domain([1, 15])) .y(d3.scale.linear().domain([1000, 10000])) .r(d3.scale.linear().domain([0, 4000])) //##### Elastic Scaling //`.elasticX` and `.elasticX` determine whether the chart should rescale each axis to fit data. //The `.yAxisPadding` and `.xAxisPadding` add padding to data above and below their max values in the same unit domains as the Accessors. .elasticY(true) .elasticX(false) .yAxisPadding(200) .xAxisLabel('Average Waiting Time - (weeks)') // (optional) render an axis label below the x axis .yAxisLabel('Cost - (£1K)') // (optional) render a vertical axis lable left of the y axis //#### Labels and Titles //Labels are displaed on the chart for each bubble. Titles displayed on mouseover. .renderLabel(true) // (optional) whether chart should render labels, :default = true .label(function (p) { return p.key; }) .renderTitle(true) // (optional) whether chart should render titles, :default = false .title(function (p) { return [p.key, "Referrals: " + p.value.referrals, "Cost: £" + p.value.cost, "RTT: " + p.value.avgrtt / p.value.referrals + " weeks"] .join("\n"); }) //#### Customize Axis //Set a custom tick format. Note `.yAxis()` returns an axis object, so any additional method chaining applies to the axis, not the chart. .yAxis().tickFormat(function (v) { return v; });
As mentioned in the comments, it's hard to help you without a complete example, but this works for me. Since I don't have your data I made my own very simple data and adjusted a few things on my bubble chart. var data = []; for (var i = 1; i < 10; i++) { data.push({ val: i }); } var ndx = crossfilter(data); var dim = ndx.dimension(function(d) { return d.val; }); var group = dim.group().reduceSum(function(d) { return d.val; }); bubbleChart = dc.bubbleChart("#bubbleChart"); bubbleChart .width(700) .height(400) .transitionDuration(1500) .margins({top: 10, right: 50, bottom: 40, left: 50}) .dimension(dim) .group(group) .keyAccessor(function (p) { return p.value; }) .valueAccessor(function (p) { return p.value; }) .maxBubbleRelativeSize(0.1) .x(d3.scale.linear().domain([-1, 10])) .y(d3.scale.linear().domain([0, 10])) .radiusValueAccessor(function (p) { return p.value; }) .r(d3.scale.linear().domain([0, 100])) .elasticY(true) .elasticX(false) .yAxisPadding(200) .xAxisLabel('Average Waiting Time - (weeks)') .yAxisLabel('Cost - (£1K)') .renderLabel(true) .label(function (p) { return p.key; }) .renderTitle(true) .title(function (p) { return "This is the title"; }) .yAxis().tickFormat(function (v) { return v; }); dc.renderAll();
NVD3 chart: Plot toggle with muiltiChart / multiple yScales causes axis to disappear, but not the plot
I'm trying to get two lines to use two different scales. When I try to toggle a plot, the grid lines disappear, instead of the plot. Can you figure out what I'm doing wrong? http://jsfiddle.net/3ZP3S/ var dataset1 = { values : [], key : "Math.cos", type: "line", color: '#2ca02c', yAxis: 1 }; var dataset2 = { values : [], key : "sin", type: "line", color : "#ff7f0e", yAxis: 2 }; for (var i = -3.14; i < 3.1415; i+= .01){ dataset1.values.push( { x: i , y : Math.cos(i) }); dataset2.values.push( { x: i , y : Math.sin(i) * 3 }); } var data = [dataset1, dataset2]; nv.addGraph( function() { var chart = nv.models.multiChart() .margin({top: 30, right: 60, bottom: 50, left: 70}) .color(d3.scale.category10().range()); chart.xAxis .tickFormat(d3.format(',.2f')); chart.yAxis1 .tickFormat(d3.format(',.1f')); chart.yAxis2 .tickFormat(d3.format(',.1f')); d3.select('#chart svg') .datum(data) .transition().duration(500).call(chart); return chart; });
This was a bug with nvd3. I tried several "previous" versions of nvd3, and d3, and this always occurred. We also decided to drop nvd3 and switch to C3.js, which seems to be "much" more mature in terms of stability...