Align annotation text on Google Chart - css

I am trying to nudge my annotation text to the top of my line chart rather than middle. The annotations that I want to shift are associated with the x-axis data so appear rotated on a vertical line so it would seem like all I need to do is align the text to the right.
I am aware of the annotations.textStyle configuration option but there are no examples of aligment changes shown in the documentation and I've been trying out some options that I thought would work but nothing shifts it from the centre.
For example in this Fiddler I thought textStyle: {align: 'right'} would work but it has no impact - the annotation 'boost' is still showing in the centre rather than at the top.

there are no options available to adjust the alignment,
but you can manually modify the chart's svg,
when the chart's 'ready' event fires...
here, I find the annotation <text> element and adjust the x coordinate (due to the transformation)
google.charts.load('current', {
packages: ['corechart']
}).then(drawVisualization);
function drawVisualization() {
// example copied from Google Visualization API playground,
// modified for category axis annotations
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'x');
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn({type: 'string', role: 'annotationText'});
data.addColumn('number', 'Cats');
data.addColumn('number', 'Blanket 1');
data.addColumn('number', 'Blanket 2');
data.addRow(["A", null, null, 1, 1, 0.5]);
data.addRow(["B", null, null, 2, 0.5, 1]);
data.addRow(["C", null, null, 4, 1, 0.5]);
data.addRow(["D", null, null, 8, 0.5, 1]);
data.addRow(["E", null, null, 7, 1, 0.5]);
data.addRow(["F", null, null, 7, 0.5, 1]);
data.addRow(["G", 'boost', 'Foo annotation', 8, 1, 0.5]);
data.addRow(["H", null, null, 4, 0.5, 1]);
data.addRow(["I", null, null, 2, 1, 0.5]);
data.addRow(["J", null, null, 3.5, 0.5, 1]);
data.addRow(["K", ' ', 'Bar annotation', 3, 1, 0.5]);
data.addRow(["L", null, null, 3.5, 0.5, 1]);
data.addRow(["M", null, null, 1, 1, 0.5]);
data.addRow(["N", null, null, 1, 0.5, 1]);
var chart = new google.visualization.LineChart(document.getElementById('visualization'));
google.visualization.events.addListener(chart, 'ready', function () {
var labels = chart.getContainer().getElementsByTagName('text');
Array.prototype.forEach.call(labels, function(label) {
if ((label.getAttribute('text-anchor') === 'middle') && (label.hasAttribute('transform'))) {
label.setAttribute('x', parseFloat(label.getAttribute('x')) + 100);
}
});
});
chart.draw(data, {
curveType: 'function',
width: 500,
height: 400,
vAxis: {
maxValue: 10
},
annotations: {
style: 'line',
}
});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="visualization"></div>
note: the jsapi loader is an old version, use loader.js instead, see above...

Related

How to draw month vs text label graph in google charts

How Can I create a google chart graph with month-year(Mar 2018) on h axis and label in V-axis(Database Module)
[
['Database Module', new Date(2018, 3, 30),1],
['HR Module', new Date(2018, 1, 4), 1],
['Finance Module', new Date(2018, 2, 4),4],
['Operations Module', new Date(2018, 2, 4), 6],
['PP Module', new Date(2018, 2, 4), 1]
]
not sure if this is the graph you're looking for,
but you could use a DataView to create a v-axis column for each label,
then use the group() method to sum by date...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Database Module', new Date(2018, 3, 30),1],
['HR Module', new Date(2018, 1, 4), 1],
['Finance Module', new Date(2018, 2, 4),4],
['Operations Module', new Date(2018, 2, 4), 6],
['PP Module', new Date(2018, 2, 4), 1]
], true);
var dataView = new google.visualization.DataView(data);
var labels = data.getDistinctValues(0);
var viewColumns = [1];
labels.forEach(function (label, index) {
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 0) === label) {
return dt.getValue(row, 2);
}
return null;
},
label: label,
type: 'number'
});
});
dataView.setColumns(viewColumns);
var aggColumns = [];
labels.forEach(function (label, index) {
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index + 1,
label: dataView.getColumnLabel(index + 1),
type: dataView.getColumnType(index + 1)
});
});
var dataGroup = google.visualization.data.group(dataView, [0], aggColumns);
var chartDiv = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(chartDiv);
chart.draw(dataGroup, {
legend: 'bottom'
});
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Can not read property "__" of undefined

I am currently working for my school project and using Meteor with AngularJs 1 and ES6. In one of my views I try to update some live data (with AngularCharts) every second which are currently randomly generated. I am new to the way of how Meteor and ES6 works, so I think a have a pretty easy error.
This is my code of the class from the view:
class View2 {
constructor($interval, $scope) {
'ngInject';
this.cardRow = [
{name: 'Drilling Heat', color: 'white', value: 0},
{name: 'Drilling Speed', color: 'white', value: 0},
{name: 'Milling Heat', color: 'white', value: 0},
{name: 'Milling Speed', color: 'white', value: 0}
];
this.type = ['bar', 'line', 'pie', 'doughnut', 'radar'];
this.chartRow = [
{
name: 'Chart1',
type: 'bar',
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
series: ['Series A'],
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
datasetOverride: [{yAxisID: 'y-axis-1'}],
options: {
animation: false,
scales: {
yAxes: [
{
id: 'y-axis-1',
type: 'linear',
display: true,
position: 'left'
}]
}
}
},
{
name: 'Chart2',
type: 'line',
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
series: ['Series A'],
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
datasetOverride: [{yAxisID: 'y-axis-1'}],
options: {
animation: false,
scales: {
yAxes: [
{
id: 'y-axis-1',
type: 'linear',
display: true,
position: 'left'
}]
}
}
}
];
$interval(this.update, 1000);
}
update() {
for (var i = 0; i < this.cardRow.length; i++) {
this.cardRow[i].value = Math.round((Math.random() * 10) * 10);
var value = this.cardRow[i].value;
switch (true) {
case (value > 80):
this.cardRow[i].color = 'red';
break;
case (value > 60):
this.cardRow[i].color = 'orange';
break;
case (value > 40):
this.cardRow[i].color = 'yellow';
break;
default:
this.cardRow[i].color = 'green';
break;
}
}
for (var y = 0; y < this.chartRow.length; y++) {
for (var z = 0; z < this.chartRow[y].data.length; z++) {
this.chartRow[y].data[z] = this.chartRow[y].data[z + 1];
}
this.chartRow[y].data[z - 1] = Math.round((Math.random() * 10) * 10);
}
}
}
The $interval should call the function "update" every second but then the variable is unknown. it throws an error like this:
TypeError: Cannot read property 'length' of undefined
at update (view2.js:74)
at callback (modules.js?hash=7db65c4…:46346)
at Scope.$eval (modules.js?hash=7db65c4…:51381)
at Scope.$digest (modules.js?hash=7db65c4…:51194)
at Scope.$apply (modules.js?hash=7db65c4…:51489)
at tick (modules.js?hash=7db65c4…:46336)
What can I do to solve this problem? And is there a way to use Meteor with the old Javascript Version?

AmCharts: Limit Y-Axs -Range and cut out non-periodical gaps

I have a problem with amCharts after trying a lot of settings.
I want to limit the range of the y-axis from 1-150 and do not want amCharts to plot data points with the value 0. There is no time-period in the x-range. I created a fiddle of my actual result: http://jsfiddle.net/zt9exqwq/5/
var chartData = [{"position":"114","datum":"20.12.2014"},{"position":"0","datum":"24.12.2014"},{"position":"127","datum":"29.12.2014"},{"position":"128","datum":"02.01.2015"},{"position":"125","datum":"05.01.2015"},{"position":"132","datum":"09.01.2015"},{"position":"0","datum":"13.01.2015"},{"position":"131","datum":"17.01.2015"},{"position":"0","datum":"20.01.2015"},{"position":"0","datum":"24.01.2015"},{"position":"88","datum":"28.01.2015"},{"position":"89","datum":"01.02.2015"},{"position":"94","datum":"04.02.2015"},{"position":"86","datum":"08.02.2015"},{"position":"80","datum":"12.02.2015"},{"position":"83","datum":"16.02.2015"},{"position":"82","datum":"19.02.2015"},{"position":"0","datum":"23.02.2015"},{"position":"109","datum":"27.02.2015"},{"position":"100","datum":"03.03.2015"},{"position":"98","datum":"06.03.2015"},{"position":"92","datum":"10.03.2015"},{"position":"99","datum":"14.03.2015"},{"position":"97","datum":"18.03.2015"},{"position":"93","datum":"21.03.2015"},{"position":"0","datum":"25.03.2015"},{"position":"0","datum":"29.03.2015"},{"position":"108","datum":"02.04.2015"},{"position":"106","datum":"06.04.2015"},{"position":"109","datum":"10.04.2015"},{"position":"0","datum":"14.04.2015"},{"position":"107","datum":"17.04.2015"},{"position":"114","datum":"21.04.2015"},{"position":"109","datum":"25.04.2015"},{"position":"0","datum":"29.04.2015"},{"position":"111","datum":"02.05.2015"},{"position":"101","datum":"06.05.2015"},{"position":"84","datum":"10.05.2015"},{"position":"0","datum":"14.05.2015"},{"position":"74","datum":"17.05.2015"},{"position":"71","datum":"21.05.2015"},{"position":"72","datum":"25.05.2015"},{"position":"72","datum":"29.05.2015"},{"position":"0","datum":"01.06.2015"},{"position":"66","datum":"05.06.2015"},{"position":"73","datum":"09.06.2015"},{"position":"78","datum":"13.06.2015"},{"position":"72","datum":"16.06.2015"},{"position":"65","datum":"20.06.2015"},{"position":"67","datum":"24.06.2015"},{"position":"72","datum":"28.06.2015"},{"position":"74","datum":"02.07.2015"},{"position":"68","datum":"05.07.2015"},{"position":"67","datum":"09.07.2015"},{"position":"72","datum":"13.07.2015"},{"position":"74","datum":"17.07.2015"},{"position":"73","datum":"21.07.2015"}];
var chart = AmCharts.makeChart("chartdiv", {
"type": "serial",
"dataDateFormat": "DD.MM.YYYY",
"balloon": {
"borderThickness": 1,
"shadowAlpha": 0
},
"graphs": [{
"bullet": "round",
"bulletBorderAlpha": 0.5,
"bulletColor": "#FFFFFF",
"bulletSize": 8,
"hideBulletsCount": 50,
"lineThickness": 2,
"useLineColorForBulletBorder": true,
"valueField": "position",
"balloonText": "<div style='margin:5px; font-size:19px;'><span style='font-size:13px;'>[[category]]</span><br>[[value]]</div>"
}],
"valueAxes": [{
"integersOnly": true,
"maximum": 150,
"minimum": 1,
"reversed": true,
"axisAlpha": 1,
"dashLength": 2,
"position": "left",
"title": "Position"
}],
"chartCursor": {
"valueLineEnabled": true,
"valueLineBalloonEnabled": true,
"cursorAlpha":0.2,
"valueLineAlpha":0.2
},
"categoryField": "datum",
"categoryAxis": {
"parseDates": true,
"dashLength": 1,
},
"dataProvider": chartData
});
chart.addListener("rendered", zoomChart);
zoomChart();
function zoomChart() {
chart.zoomToIndexes(chart.dataProvider.length - 40, chart.dataProvider.length - 1);
}
#chartdiv {
width : 100%;
height : 500px;
}
<script type="text/javascript" src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="http://www.amcharts.com/lib/3/serial.js"></script>
<div id="chartdiv"></div>
Here's what it actual looks like:
And here's what I want to have:
Has anybody an idea? Thanks very much.
Value axis
To set the the scale for the value axis, we can use its minimum and maximum properties. However, even if we set those two, the chart will try to round up value axis increments to "pretty" numbers, hence it will still display 0.
To work around that we will use another value axis property strictMinMax. It will ensure that our value axis scale is crisply cut at 0 and 15 values.
However we now lose the first and last labels. We'll use guides to add labels for 1 and 150 values.
Combined code for the above is this:
"valueAxes": [{
"integersOnly": true,
"maximum": 150,
"minimum": 1,
"strictMinMax": true,
"reversed": true,
"axisAlpha": 1,
"dashLength": 2,
"position": "left",
"title": "Position",
"guides": [{
"value": 1,
"label": "1"
}, {
"value": 150,
"label": "150"
}]
}]
Gaps
Zero is a valid number and a value. If you need to display a gap in place of the zero-value data points, you will need to set the value for those to null.
If you can't replace that directly in your data, you can add some custom code to iterate through the data and replace zero values with null:
for(var i = 0; i < chartData.length; i++) {
if (chartData[i].position == 0)
chartData[i].position = null;
}
In order to display gaps, we will also need to set connect: false for the graph.
And since your data is at irregular date intervals, we'll also set gapPeriod to some larger period (say 10) so that gaps are not displayed whenever you have a distance bigger than 1 day between two adjacent data points.
Here's combined working chart:
var chartData = [{"position":"114","datum":"20.12.2014"},{"position":"0","datum":"24.12.2014"},{"position":"127","datum":"29.12.2014"},{"position":"128","datum":"02.01.2015"},{"position":"125","datum":"05.01.2015"},{"position":"132","datum":"09.01.2015"},{"position":"0","datum":"13.01.2015"},{"position":"131","datum":"17.01.2015"},{"position":"0","datum":"20.01.2015"},{"position":"0","datum":"24.01.2015"},{"position":"88","datum":"28.01.2015"},{"position":"89","datum":"01.02.2015"},{"position":"94","datum":"04.02.2015"},{"position":"86","datum":"08.02.2015"},{"position":"80","datum":"12.02.2015"},{"position":"83","datum":"16.02.2015"},{"position":"82","datum":"19.02.2015"},{"position":"0","datum":"23.02.2015"},{"position":"109","datum":"27.02.2015"},{"position":"100","datum":"03.03.2015"},{"position":"98","datum":"06.03.2015"},{"position":"92","datum":"10.03.2015"},{"position":"99","datum":"14.03.2015"},{"position":"97","datum":"18.03.2015"},{"position":"93","datum":"21.03.2015"},{"position":"0","datum":"25.03.2015"},{"position":"0","datum":"29.03.2015"},{"position":"108","datum":"02.04.2015"},{"position":"106","datum":"06.04.2015"},{"position":"109","datum":"10.04.2015"},{"position":"0","datum":"14.04.2015"},{"position":"107","datum":"17.04.2015"},{"position":"114","datum":"21.04.2015"},{"position":"109","datum":"25.04.2015"},{"position":"0","datum":"29.04.2015"},{"position":"111","datum":"02.05.2015"},{"position":"101","datum":"06.05.2015"},{"position":"84","datum":"10.05.2015"},{"position":"0","datum":"14.05.2015"},{"position":"74","datum":"17.05.2015"},{"position":"71","datum":"21.05.2015"},{"position":"72","datum":"25.05.2015"},{"position":"72","datum":"29.05.2015"},{"position":"0","datum":"01.06.2015"},{"position":"66","datum":"05.06.2015"},{"position":"73","datum":"09.06.2015"},{"position":"78","datum":"13.06.2015"},{"position":"72","datum":"16.06.2015"},{"position":"65","datum":"20.06.2015"},{"position":"67","datum":"24.06.2015"},{"position":"72","datum":"28.06.2015"},{"position":"74","datum":"02.07.2015"},{"position":"68","datum":"05.07.2015"},{"position":"67","datum":"09.07.2015"},{"position":"72","datum":"13.07.2015"},{"position":"74","datum":"17.07.2015"},{"position":"73","datum":"21.07.2015"}];
for(var i = 0; i < chartData.length; i++) {
if (chartData[i].position == 0)
chartData[i].position = null;
}
var chart = AmCharts.makeChart("chartdiv", {
"type": "serial",
"dataDateFormat": "DD.MM.YYYY",
"balloon": {
"borderThickness": 1,
"shadowAlpha": 0
},
"graphs": [{
"bullet": "round",
"bulletBorderAlpha": 0.5,
"bulletColor": "#FFFFFF",
"bulletSize": 8,
"hideBulletsCount": 50,
"lineThickness": 2,
"useLineColorForBulletBorder": true,
"valueField": "position",
"balloonText": "<div style='margin:5px; font-size:19px;'><span style='font-size:13px;'>[[category]]</span><br>[[value]]</div>",
"connect": false,
"gapPeriod": 10
}],
"valueAxes": [{
"integersOnly": true,
"maximum": 150,
"minimum": 1,
"strictMinMax": true,
"reversed": true,
"axisAlpha": 1,
"dashLength": 2,
"position": "left",
"title": "Position",
"guides": [{
"value": 1,
"label": "1"
}, {
"value": 150,
"label": "150"
}]
}],
"chartCursor": {
"valueLineEnabled": true,
"valueLineBalloonEnabled": true,
"cursorAlpha":0.2,
"valueLineAlpha":0.2
},
"categoryField": "datum",
"categoryAxis": {
"parseDates": true,
"dashLength": 1,
},
"dataProvider": chartData
});
chart.addListener("rendered", zoomChart);
zoomChart();
function zoomChart() {
chart.zoomToIndexes(chart.dataProvider.length - 40, chart.dataProvider.length - 1);
}
#chartdiv {
width : 100%;
height : 500px;
}
<script type="text/javascript" src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="http://www.amcharts.com/lib/3/serial.js"></script>
<div id="chartdiv"></div>

Add vertical line for current year in google visualization

I need to add one vertical line in current year (x axis)
Configuration Options in my code follows.
var options = {
title: '*****',
curveType: 'function',
height: 300,
legend: { position: 'bottom' },
chartArea: {width: '80%'},
pointSize:5,
width: 500,
annotation: {
1: {
style: 'line'
}
}
}
Please note I have used annotation for this, but problem is a bit line alone visible. I need a line for full height .
My Full Code :
var options = {
title: 'Chart',
curveType: 'function',
height: 300,
legend: { position: 'bottom' },
chartArea: {width: '80%'},
pointSize:5,
annotation: { height: 300 }
},
chartData = JSON.parse(window._data.chartData), chartPoint = new Array(), i = 0, j = 0;
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Google');
data.addColumn('number', 'Yahoo');
data.addColumn({type: 'boolean', role: 'certainty'});
data.addColumn('number', 'Value');
data.addColumn({type: 'boolean', role: 'certainty'});
data.addColumn({type: 'string', role: 'annotation'});
if(Object.keys(chartData.myMap).length > 0) {
$.each(chartData.myMap, function(k, v) {
var val = Math.round(v * 100) / 100;
chartPoint[i] = new Array();
var cDate = new Date();
if(cDate.getFullYear()==k)
chartPoint[i] = [k, val, null, false, null, false,k];
else
chartPoint[i] = [k, val, null, false, null, false,null];
i++;
});
i--;
}
if(Object.keys(chartData.myDataMap).length > 0) {
$.each(chartData.myDataMap, function(k, v) {
var val = Math.round(v * 100) / 100;
var val1 = Math.round(chartData.averageMap[k] * 100) / 100;
if(j==0) {var l = val; j++; } else l = null;
chartPoint[i] = new Array();
chartPoint[i] = [k,l,val,false,val1, false, null];
i++;
});
}
data.addRows(chartPoint);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
It should be like in this page [http://jsfiddle.net/NC37X/][3]
I have three forks from your fiddle that might be along the lines of what you are looking for:
data.addRow(["G", ' ', 'Foo annotation', 8, 1, 0.5]);
http://jsfiddle.net/Balrog30/W2JWa/1/ -
Using annotations, but just placing a space makes nothing print, but still draws a line.
annotations: {
style: 'line',
textStyle: {
opacity: 0
}
}
http://jsfiddle.net/Balrog30/W2JWa/2/ -
Text is still in annotation, but text opacity set to 0 so that text is totally transparent.
google.load('visualization', '1', {packages: ['corechart']});
google.setOnLoadCallback(drawVisualization);
function drawVisualization() {
// example copied from Google Visualization API playground,
// modified for category axis annotations
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn({type: 'string', role: 'annotationText'});
data.addColumn('number', 'Cats');
data.addColumn('number', 'Blanket 1');
data.addColumn('number', 'Blanket 2');
data.addRow([{v: 0, f:"A"}, null, null, 1, 1, 0.5]);
data.addRow([{v: 1, f:"B"}, null, null, 2, 0.5, 1]);
data.addRow([{v: 2, f:"C"}, null, null, 4, 1, 0.5]);
data.addRow([{v: 3, f:"D"}, null, null, 8, 0.5, 1]);
data.addRow([{v: 4, f:"E"}, null, null, 7, 1, 0.5]);
data.addRow([{v: 5, f:"F"}, null, null, 7, 0.5, 1]);
data.addRow([{v: 6, f:"G"}, null, null, 8, 1, 0.5]);
data.addRow([{v: 7, f:"H"}, null, null, 4, 0.5, 1]);
data.addRow([{v: 8, f:"I"}, null, null, 2, 1, 0.5]);
data.addRow([{v: 9, f:"J"}, null, null, 3.5, 0.5, 1]);
data.addRow([{v: 10, f:"K"}, null, null, 3, 1, 0.5]);
data.addRow([{v: 11, f:"L"}, null, null, 3.5, 0.5, 1]);
data.addRow([{v: 12, f:"M"}, null, null, 1, 1, 0.5]);
data.addRow([{v: 13, f:"N"}, null, null, 1, 0.5, 1]);
// Create and draw the visualization.
new google.visualization.LineChart(document.getElementById('visualization')).
draw(data, {
curveType: 'function',
width: 500,
hAxis: {
ticks: [{v:6, f:"G"}, {v:10, f:"K"}]
},
height: 400,
vAxis: {
maxValue: 10
},
annotations: {
style: 'line'
}
});
}
http://jsfiddle.net/Balrog30/W2JWa/3/ -
The third one changes the horizontal axis to a continuous type axis so that I can add ticks. This only works if your x-axis is numberic or date/time in nature. This also kind of messes up your axis labeling because the labeling is tied to the ticks, but I'm not really sure what you're trying to display, so it may or may not matter to you.

d3.js: why don't the columns in my column chart contain the full data?

I am using a slightly modified reusable column chart script from https://gist.github.com/llad/3766585
Works great. However, I was just trying to add some tooltips on hover, that would display additional data from the JSON file for each column, but the additional data is not there. I look in the inspector and just see the two values used to calculate x and y. Is there something obvious in the way the script is written that is not binding the full data set?
The script:
function columnChart() {
var margin = {top: 30, right: 10, bottom: 50, left: 50},
width = 420,
height = 420,
xRoundBands = 0.2,
xValue = function(d) { return d[0]; },
yValue = function(d) { return d[1]; },
xScale = d3.scale.ordinal(),
yScale = d3.scale.linear(),
xFormat = '',
yFormat = '',
yAxis = d3.svg.axis().scale(yScale).orient("left"),
xAxis = d3.svg.axis().scale(xScale);
function chart(selection) {
selection.each(function(data) {
// Convert data to standard representation greedily;
// this is needed for nondeterministic accessors.
data = data.map(function(d, i) {
return [xValue.call(data, d, i), yValue.call(data, d, i)];
});
// Update the x-scale.
xScale
.domain(data.map(function(d) { return d[0];} ))
.rangeRoundBands([0, width - margin.left - margin.right], xRoundBands);
// Update the y-scale.
yScale
.domain(d3.extent(data.map(function(d) { return d[1];} )))
.range([height - margin.top - margin.bottom, 0])
.nice();
// Select the svg element, if it exists.
var svg = d3.select(this).selectAll("svg").data([data]);
// Otherwise, create the skeletal chart.
var gEnter = svg.enter().append("svg").append("g");
gEnter.append("g").attr("class", "bars");
gEnter.append("g").attr("class", "y axis");
gEnter.append("g").attr("class", "x axis");
gEnter.append("g").attr("class", "x axis zero");
// Update the outer dimensions.
svg .attr("width", width)
.attr("height", height);
// Update the inner dimensions.
var g = svg.select("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Update the bars.
var bar = svg.select(".bars").selectAll(".bar").data(data);
bar.enter().append("rect");
bar.exit().remove();
bar.attr("class", function(d, i) { return d[1] < 0 ? "bar negative" : "bar positive"; })
.attr("x", function(d) { return X(d); })
.attr("y", function(d, i) { return d[1] < 0 ? Y0() : Y(d); })
.attr("width", xScale.rangeBand())
.attr("height", function(d, i) { return Math.abs( Y(d) - Y0() ); })
.on("click", function(d, i)
{
d3.selectAll('.bar').classed('fade', true);
d3.select(this).classed("sel", true).classed("fade", false);
})
.on("mouseover", function(d, i)
{
d3.select(this).classed("hover", true);
})
.on("mouseout", function(d, i)
{
d3.select(this).classed("hover", false);
});
// x axis at the bottom of the chart
g.select(".x.axis")
.attr("transform", "translate(0," + (height - margin.top - margin.bottom) + ")")
.call(xAxis.orient("bottom").tickFormat(xFormat));
// zero line
g.select(".x.axis.zero")
.attr("transform", "translate(0," + Y0() + ")")
.call(xAxis.tickFormat("").tickSize(0));
// Update the y-axis.
g.select(".y.axis")
.call(yAxis);
// Horizontal grid
g.insert("g", ".bars")
.attr("class", "grid horizontal")
.call(d3.svg.axis().scale(yScale)
.orient("left")
.tickSize(-(width-margin.left-margin.right), 0, 0)
.tickFormat("")
);
});
}
// The x-accessor for the path generator; xScale ∘ xValue.
function X(d) {
return xScale(d[0]);
}
function Y0() {
return yScale(0);
}
// The x-accessor for the path generator; yScale ∘ yValue.
function Y(d) {
return yScale(d[1]);
}
chart.margin = function(_) {
if (!arguments.length) return margin;
margin = _;
return chart;
};
chart.width = function(_) {
if (!arguments.length) return width;
width = _;
return chart;
};
chart.height = function(_) {
if (!arguments.length) return height;
height = _;
return chart;
};
chart.x = function(_) {
if (!arguments.length) return xValue;
xValue = _;
return chart;
};
chart.y = function(_) {
if (!arguments.length) return yValue;
yValue = _;
return chart;
};
chart.yTickFormat = function(_) {
if (!arguments.length) return yFormat;
yFormat = _;
return chart;
};
chart.xTickFormat = function(_) {
if (!arguments.length) return xFormat;
xFormat = _;
return chart;
};
return chart;
}
The initialization:
function renderGraph(view){
var chartWidth = mainWidth();
var chartHeight = 400;
var parseDate = d3.time.format("%Y-%m-%d").parse;
var xFormat = d3.time.format("%b %e");
var data = [];
var req = $.ajax({
url: '/data/column-data.json',
type: 'GET',
dataType: 'json',
success: function(response) {
data = response;
}
});
$.when(req).done(function() {
d3.select("#columnChart")
.datum(data.widgets)
.call(columnChart()
.width(chartWidth)
.height(chartHeight)
.x(function(d, i) { return parseDate(d[0]); })
.xTickFormat(xFormat)
.y(function(d, i) {
var yData;
if (view === 'thisView'){
yData = d[1];
}else if (view === 'thatView'){
yData = d[2];
}
return yData;
}));
});
}
and the data looks like this:
{ "widgets" : [
["2013-09-15", 1, 66622, 1, 3],
["2013-09-16", 0, 0, 0, 0],
["2013-09-17", 2, 76316, 2, 2],
["2013-09-18", 4, 291244, 8, 12],
["2013-09-19", 1, 74674, 2, 2],
["2013-09-20", 5, 287965, 7, 5],
["2013-09-21", 0, 0, 0, 0],
["2013-09-22", 0, 0, 0, 0],
["2013-09-23", 7, 459249, 15, 22],
["2013-09-24", 2, 317320, 1, 6],
["2013-09-25", 3, 100269, 3, 10],
["2013-09-26", 4, 181080, 8, 4],
["2013-09-27", 1, 38056, 1, 1],
["2013-09-28", 0, 0, 0, 0],
["2013-09-29", 0, 0, 0, 0],
["2013-09-30", 3, 449334, 2, 13],
["2013-10-01", 9, 403929, 5, 15],
["2013-10-02", 4, 222512, 7, 12],
["2013-10-03", 1, 196012, 3, 9],
["2013-10-04", 2, 391716, 2, 8],
["2013-10-05", 0, 0, 0, 0],
["2013-10-06", 0, 0, 0, 0],
["2013-10-07", 4, 260312, 8, 14],
["2013-10-08", 1, 34350, 1, 1],
["2013-10-09", 3, 179067, 9, 18],
["2013-10-10", 2, 124250, 8, 19],
["2013-10-11", 2, 381186, 4, 9],
["2013-10-12", 0, 0, 0, 0],
["2013-10-13", 0, 0, 0, 0],
["2013-10-14", 5, 393400, 11, 17]
]
}
The tooltip should display the full data for any one column. The web inspector shows an array of 2 for each column (I'm expecting an array of 5)
How do I modify the script to bind the full data for each column?
Thanks!
UPDATE:
I still haven't solved this, though #adam-pearce got very close. I've put together a couple jsbin's to help.
A bin for the original script is here: http://jsbin.com/EjugosA/2/edit
and the script with Adam's answer is here: http://jsbin.com/IPoDutA/1/edit
this just has the following commented out:
//data = data.map(function(d, i) {
// return [xValue.call(data, d, i), yValue.call(data, d, i)];
//});
You can see in the second that both x and y axis fail to render, though the full data set I wanted is bound to each bar. The web inspector shows the following error:
'undefined' is not a function (evaluating 'd.getMonth()')" which points to line 8410 in d3.v3.js, in d3_time_formats.
How to I modify this script to get the full data without breaking the axis?
data = data.map(function(d, i) {
return [xValue.call(data, d, i), yValue.call(data, d, i)];
});
Removes everything but the first two columns from data. Looking over the code, I think it would still work if you commented out those three lines.
In responce to your comment:
// x axis at the bottom of the chart
g.select(".x.axis")
.attr("transform", "translate(0," + (height - margin.top - margin.bottom) + ")")
.call(xAxis.orient("bottom"));//.tickFormat(xFormat));
You're trying to print strings as dates which doesn't work without parsing the strings first.

Resources