How to make scale of both Y-axes same in Composite chart in dc.js - scale

I am plotting a composite chart in dc with two y-axis to compare two values (this year and last year) using the following code:
compositeChart.width(1200)
.height(240)
.margins({top: 10, right: 100, bottom: 70, left:80})
.transitionDuration(800)
.dimension(depValue)
.elasticY(true)
.x(d3.scale.ordinal().domain(["AUTO & TIRES","BABY", "CLOTHING", "ELECTRONICS", "GARDEN", "GROCERY", "HEALTH", "HOME", "HOME IMPROVEMENT", "PHOTO", "SPORTS", "TOYS", "VIDEO GAMES"]))
.xUnits(dc.units.ordinal)
.renderHorizontalGridLines(true)
.compose([
dc.barChart(compositeChart)
.group(group,"This Year")
.clickFilterBehavior("replace")
.valueAccessor(function (d) {
console.log(d.value);
return d.value;
}),
dc.barChart(compositeChart)
.group(group1,"Last Year")
.valueAccessor(function (d) {
console.log(d.value);
return d.value;
})
.clickFilterBehavior("replace")
.title(function (d) {
var value = d.data.value ? d.data.value : d.data.value;
if (isNaN(value)) value = 0;
return dateFormat(d.data.key) + "\n" + numberFormat(value);
})
.colors(["orange"])
.useRightYAxis(true)
])
.yAxisLabel("This Year")
.rightYAxisLabel("Last Year")
.renderHorizontalGridLines(true)
.renderlet(function (chart) {
chart.selectAll("g._1").attr("transform", "translate(" + 100 + ", 0)");
});
The charts are fine but the issue is that the scale of both the Y-axes(right and left) is not same and hence even though the value for last year is lesser than this year, the bar looks higher than that of this year.Is there a way I can set the scale of the graph to be the same?Any help would be appreciated.!!!

Related

D3.js how to merge my real data into a pie chart

I am new to D3 and data visualizing and I'm having some troubles loading my real data.
You'll find my code in the below sections.
Right now I have some data stored in an array, and now what I want to do is, store my actual data from my database into pie charts.
Also if I do this :
var mydata=d3.json("mydatafile");
console.log(mydata);
It shows me all the data I have retrieved from database in a promise array.
Is there any way possible I can get these data and put them in my charts?
The code for my pie chart written in D3js is below:
var aColor = [
'rgb(127, 212, 123)', //green
'rgb(240, 149, 164)', // red
'rgb(181, 174, 175)' //gray
]
var data = [{
"platform": "Yes",
"percentage": 87.00
}, //skyblue
{
"platform": "No",
"percentage": 1.00
}, //darkblue
{
"platform": "N/A",
"percentage": 17.00
}]; //orange
var svgWidth = 200,
svgHeight = 200,
radius = Math.min(svgWidth, svgHeight) / 2;
var svg = d3.select('#graph1').append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
//Create group element to hold pie chart
var g = svg.append("g")
.attr("transform", "translate(" + radius + "," + radius + ")");
var pie = d3.layout.pie().value(function (d) {
return d.percentage;
});
var path = d3.svg.arc()
.outerRadius(80)
.innerRadius(40);
var arc = g.selectAll("arc")
.data(pie(data))
.enter()
.append("g")
.sort((a, b) => b.data.percentage - a.data.percentage);
arc.append("path")
.attr("d", path)
.attr("fill", function (d, i) { return aColor[i]; });
var label = d3.svg.arc()
.outerRadius(20)
.innerRadius(100);
arc.append("text")
.attr("transform", function (d) {
return "translate(" + label.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.text(function (d) {
return +d.data.percentage;
});
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id="graph1"></div>
On the other hand as per my backend, I have this project written on asp.net .net framework and I have this function which retrieves all the data on JSON format, which is cool.
public JsonResult BarChart()
{
string query = "select e.ProjectName,cyn.Name From Events e left join ConstYesNoes cyn on cyn.ID = e.ApproveId";
IEnumerable<BarChartsViewModel> ListResults = db.Database.SqlQuery<BarChartsViewModel>(query).ToList();
return Json(ListResults.Select(x => new { Name = x.Name, ApprovedId = x.ApprovedId, ID = x.ID, ProjectName = x.ProjectName }).ToList(), JsonRequestBehavior.AllowGet);
}

inner radius polar Highcharter

I'm trying to change the inner radius of a polar chart using highcharter so I can visualize the data by hoving the tooltip like in this awesome D3 charts from fivethirtyeight.
I know that it's possible to visualize data with solid gauge like in this example, but I want to the data to be visible in a polar.
I've tried changing innerSize and innerRadius parameters but I'm not able to accomplish it.
Here's my R code:
library(tidyverse)
library(highcharter)
highchart() %>%
hc_chart(polar = T, type = "bar") %>%
hc_title(text = "Athlete 1 vs Athlete 2") %>%
hc_xAxis(categories = c("Total Score", "Avg. Score", "Sum Score",
"Best Score"),
tickmarkPlacement = "on",
plotLines = list(
list(label = list(
rotation = 90))
)
) %>%
hc_yAxis(min = 0) %>%
hc_series(
list(
name = "Athlete 1",
data = c(43000, 19000, 60000, 35000)
),
list(
name = "Athlete 2",
data = c(50000, 39000, 42000, 31000)
)
) %>%
hc_colors(c("firebrick", "steelblue"))
The desired output would be something like:
Thank you!
EDIT
After #ppotaczek's answer I've updated with his chart, so the desired updated would look like this:
To achieve similar result in Highcharts polar chart, you should set pointPadding and groupPadding to 0. To create an empty space in the middle of the graph you can use Highcharts.SVGRenderer and offset for yAxis.
Highcharts.chart('container', {
chart: {
polar: true,
type: 'bar',
events: {
render: function() {
var chart = this,
middleElement = chart.middleElement;
if (middleElement) {
middleElement.destroy();
}
chart.middleElement = chart.renderer.circle(chart.plotSizeX / 2 + chart.plotLeft, chart.plotHeight / 2 + chart.plotTop, 20).attr({
zIndex: 3,
fill: '#ffffff'
}).add();
}
}
},
yAxis: {
offset: 20
},
series: [{
pointPadding: 0,
groupPadding: 0,
name: "Athlete 1",
data: [43000, 19000, 60000, 35000]
}, {
pointPadding: 0,
groupPadding: 0,
name: "Athlete 2",
data: [50000, 39000, 42000, 31000]
}]
});
Live demo: http://jsfiddle.net/BlackLabel/y6uL180j/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#circle
EDIT:
To display value from hovered point in the middle of the chart, use tooltip with proper options:
tooltip: {
borderWidth: 0,
backgroundColor: 'none',
shadow: false,
style: {
fontSize: '16px'
},
headerFormat: '',
pointFormatter: function() {
return this.y / 1000 + 'k'
},
positioner: function(labelWidth, labelHeight) {
return {
x: (this.chart.plotSizeX - labelWidth) / 2 + this.chart.plotLeft,
y: (this.chart.plotSizeY - labelHeight) / 2 + this.chart.plotTop
};
}
}
Live demo: http://jsfiddle.net/BlackLabel/5ybhtrmz/

Two different data range for Y-axis in DotNet Highchart

Dears,
I need to have two different range for y-axis when i'm using Dotnet highcharts in my code. here is an example in excel to show you what is the two range for y. I could add two data source to my chart already. one of them is area chart and another is line. but the line chart data range is between 80 to 90 and the area data range is between 5000 to 8000. with a single range for y-axis, the line chart cannot be display good because of different data range.
can some one help me in this case?
Many thanks
enter image description here
I find the solution. you should use this code in your yAxis prop, and add YAxis= 1 to prop of setseries of one of your charts dataseries. it will give the priority to your charts. for example if you have 3 charts, one area, two line. then you should add YAxis = 1 to the setseries object of area chart, then add yAxis = 2 to the setseries prop of one of line charts.
.SetYAxis(new[]
{
new YAxis
{
TickInterval = 100,
Labels = new YAxisLabels
{
Formatter = "function() { return this.value +'°C'; }",
Style = "color: '#89A54E'"
},
Title = new YAxisTitle
{
Text = "Temperature",
Style = "color: '#89A54E'"
}
},
new YAxis
{
Min= 60,
Max=100,
TickInterval=2,
Labels = new YAxisLabels
{
Formatter = "function() { return this.value; }",
Style = "color: '#4572A7'"
},
Title = new YAxisTitle
{
Text = "Rainfall",
Style = "color: '#4572A7'"
},
Opposite = true
}
})

Add vertical line to line chart in rChart NVD3 (nPlot)

I would like to add several vertical lines indicating particular events in a line chart created with nPlot. Any suggestions?
library(reshape2)
library(ggplot2)
library(rCharts)
ecm <- reshape2::melt(economics[,c('date', 'uempmed', 'psavert')], id = 'date')
p7 <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'lineWithFocusChart')
Final goal: add vertical lines with labels at 'date' = '1967-11-30', '2001-11-30', '1968-01-31', etc.
Ok, so this should answer the question. I think you will notice that this is generally considered well beyond the skill level of an average R user. Eventually, it would be nice to write a custom chart to handle this behavior well and make easy and available to the general R user. I would like to generalize both the dashed and the vertical lines to handle in R. Here is the rCharts viewer demo and the live code example.
library(reshape2)
library(ggplot2)
library(rCharts)
ecm <- reshape2::melt(economics[,c('date', 'uempmed', 'psavert')], id = 'date')
p7 <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'lineWithFocusChart')
#let's add this to make date handling easier
p7$xAxis( tickFormat="#!function(d) {return d3.time.format('%b %Y')(new Date( d * 86400000 ));}!#" )
#grab template from
#https://github.com/ramnathv/rCharts/blob/master/inst/libraries/nvd3/layouts/chart.html
#modify to add callback on graph render
p7$setTemplate(script = sprintf("
<script type='text/javascript'>
$(document).ready(function(){
draw{{chartId}}( );
});
function draw{{chartId}}( ){
var opts = {{{ opts }}};
var data = {{{ data }}};
if(!(opts.type==='pieChart' || opts.type==='sparklinePlus' || opts.type==='bulletChart')) {
var data = d3.nest()
.key(function(d){
//return opts.group === undefined ? 'main' : d[opts.group]
//instead of main would think a better default is opts.x
return opts.group === undefined ? opts.y : d[opts.group];
})
.entries(data);
}
if (opts.disabled != undefined){
data.map(function(d, i){
d.disabled = opts.disabled[i]
})
}
nv.addGraph(function() {
chart = nv.models[opts.type]()
.width(opts.width)
.height(opts.height)
if (opts.type != 'bulletChart'){
chart
.x(function(d) { return d[opts.x] })
.y(function(d) { return d[opts.y] })
}
{{{ chart }}}
{{{ xAxis }}}
{{{ x2Axis }}}
{{{ yAxis }}}
d3.select('#' + opts.id)
.append('svg')
.datum(data)
.transition().duration(500)
.call(chart);
chart.dispatch.brush.on('brushstart',function(){ drawVerticalLines( opts ) });
chart.dispatch.brush.on(
'brushend',
function(){ window.setTimeout(
function() {drawVerticalLines( opts )},
250
)}
);
nv.utils.windowResize(chart.update);
return chart;
},%s);
};
%s
</script>
"
,
#here is where you can type your vertical line/label function
"function() { drawVerticalLines( opts ) }"
,
#add the afterScript here if using with shiny
"
function drawVerticalLines( opts ){
if (!(d3.select('#' + opts.id + ' .nvd3 .nv-focus .nv-linesWrap').select('.vertical-lines')[0][0])) {
d3.select('#' + opts.id + ' .nvd3 .nv-focus .nv-linesWrap').append('g')
.attr('class', 'vertical-lines')
}
vertLines = d3.select('#' + opts.id + ' .nvd3 .nv-focus .nv-linesWrap').select('.vertical-lines').selectAll('.vertical-line')
.data(
[
{ 'date' : new Date('1967-11-30'),
'label' : 'something to highlight 1967'
} ,
{ 'date' : new Date('2001-11-30'),
'label' : 'something to highlight 2001'
}
] )
var vertG = vertLines.enter()
.append('g')
.attr('class', 'vertical-line')
vertG.append('svg:line')
vertG.append('text')
vertLines.exit().remove()
vertLines.selectAll('line')
.attr('x1', function(d){
return chart.xAxis.scale()(d.date/60/60/24/1000)
})
.attr('x2', function(d){ return chart.xAxis.scale()(d.date/60/60/24/1000) })
.attr('y1', chart.yAxis.scale().range()[0] )
.attr('y2', chart.yAxis.scale().range()[1] )
.style('stroke', 'red')
vertLines.selectAll('text')
.text( function(d) { return d.label })
.attr('dy', '1em')
//x placement ; change dy above for minor adjustments but mainly
// change the d.date/60/60/24/1000
//y placement ; change 2 to where you want vertical placement
//rotate -90 but feel free to change to what you would like
.attr('transform', function(d){
return 'translate(' +
chart.xAxis.scale()(d.date/60/60/24/1000) +
',' +
chart.yAxis.scale()(2) +
') rotate(-90)'
})
//also you can style however you would like
//here is an example changing the font size
.style('font-size','80%')
}
"
))
p7
Let me know your thoughts.

Adding a legend title

I am new to Leaflet and I am currently struggling with tutorials. So far I managed to create an interactive clorophet map, like in the example http://leafletjs.com/examples/choropleth.html.
Is it possible to add a title (simple text, not dynamic) to the legged located on the bottomright of the page? Could anyone tell me how, by just referring to the linked example?
You just need to add your title under "THE TITLE"...
var legend = L.control({position: 'topleft'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = [50, 100, 150, 200, 250, 300],
labels = ['<strong> THE TITLE </strong>'],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades [i];
to = grades[i+1]-1;
labels.push(
'<i style="background:' + getColor(from + 1) + '"></i> ' +
from + (to ? '–' + to : '+'));
}
div.innerHTML = labels.join('<br>');
return div;
};

Resources