Using react-google-charts, I would like to specify which years should be displayed on the horizontal axis of a Google Timeline Chart. The screenshot shows an example that uses automatically generated values, based on the given time range of the rows.
The example uses the following data:
[
[ 'Washington', new Date(1789, 3, 30), new Date(1797, 2, 4) ],
[ 'Adams', new Date(1797, 2, 4), new Date(1801, 2, 4) ],
[ 'Jefferson', new Date(1801, 2, 4), new Date(1809, 2, 4) ]
]
I already tried the following options with no joy:
hAxis: {
title: 'Year',
minValue: new Date(1785, 3, 15),
maxValue: new Date(1825, 3, 15),
ticks: [
{ v: new Date(1792, 3, 15), f: '1792' },
{ v: new Date(1818, 3, 15), f: '1818' },
{ v: new Date(1824, 3, 15), f: '1824' }
]
}
I would expect to have the x-Axis labelled with "Years" and showing 1792, 1818 and 1824 instead of 1790 and 1800.
The minValue and maxValue options seem to get ignored, too.
According to the readme it should be working.
Is the problem related to the value being date-objects instead of integers?
Edit: Added a jsfiddle: http://jsfiddle.net/s4zg7mxt/
It is not using react-google-charts, but the problem remains the same: ticks (and title) options still have no effect. Interestingly, the minValue and maxValue options are taken into account though.
Is it possible at all to adapt the jsfiddle, in order to show the specified years on the horizontal axis?
i've found if the configuration option, or other feature, isn't listed on the guide for that particular chart,
the chart doesn't support it.
except for options added in more recent releases,
in which the guide for that chart hasn't been updated.
as such, the only hAxis options available on a Timeline chart are minValue and maxValue
made available with the October 2, 2015 release
Timeline:
-- Durations are now localized.
-- Now supports minValue and maxValue for the horizontal axis.
The library automatically calculates the scaling of x-axis based on the start date, end date and browser's display area.
Please paste full code, will check and update you whether it is possible to do the custom scaling of the x-axis.
Related
I have a page displaying multiple charts. I set the theme to be used for all charts according to the code below:
Highcharts.theme = {
colors: ["#E37B25", "F5BF36", "#7C1C1D", "#458744", "#3E7FA3", "#0C9BD7", "#265667"],
...
}
Highcharts.setOptions(Highcharts.theme);
I then have a bunch of specific options for each chart and create the charts in a set interval.
var chart;
chart = new Highcharts.Chart(chartOptions);
The problem is that every time a chart is created it has the first color in the array, instead of rotating through them. I thought setOptions() would manage this for each chart but apparently it doesn't. How can this be done so every time i create a new chart using new Highcharts.Chart(chartOptions) it selects the next color in the array?
As #wegeld commented, colors in the array are given as list option which are used by series elements of the chart rather than charts in successive manner.
But if that is the requirement, you can create a colorIterator and do following. I have create a codepen example for you here: https://codepen.io/mikhilraj/pen/KrjzxN/
var colorIterator = 0;
function getColor() {
var color = Highcharts.getOptions().colors[colorIterator%Highcharts.getOptions().colors.length];
colorIterator++;
return color;
};
And add following in as options while creating the chart.
series: [{
name: 'John',
data: [0, 1, 4, 4, 5, 2, 3, 7],
fillColor: getColor()
}]
How to create Google Histogram Chart [1] that works with dates?
I've placed sample code (with working number and non-working date examples): http://jsfiddle.net/Qquse/417/ and code below [2]
[1] https://developers.google.com/chart/interactive/docs/gallery/histogram
[2]
google.load("visualization", "1", {
packages: ["corechart"]
});
google.setOnLoadCallback(drawChart);
function str_to_utcdate(d) {
return new Date(d.substr(0, 4), d.substr(5, 2) - 1, d.substr(9, 2));
}
function drawChart() {
var data = google.visualization.arrayToDataTable([
['item', 'date'],
['a', str_to_utcdate('2001-07-01')],
['b', str_to_utcdate('2001-07-01')],
['c', str_to_utcdate('2001-07-01')], ]);
var chart = new google.visualization.Histogram(document.getElementById('chart_div1'));
chart.draw(data);
var data = google.visualization.arrayToDataTable([
['item', 'date'],
['a', 10],
['b', 20],
['c', 30], ]);
var chart = new google.visualization.Histogram(document.getElementById('chart_div2'));
chart.draw(data);
}
5 years now and Histograms still don't support dates. Since I ain't got time and I need my stuff done, I made a workaround (so ugly it hurts) but works.
First, I defined a format just to put a keyword at the start of each label. In my case, since I have only one chart in my page, I just used the keyword 'date'.
const keyword = 'date';
const options = {
// ...
hAxis: {
format: `'${keyword}'#`
},
}
If you have multiple charts in your page and you want them to behave differently, you might want to define different keyword to each one.
Now, using query selector, I selected all the label elements that are of my interest
let labels = Array.from(document.querySelectorAll('#chart svg g:nth-of-type(3) g:nth-of-type(3) g text'));
In my case, my chart was set in a DIV with id 'chart'. If you're using any other id, just replace #chart with your id;
Then I will filter only the labels which start with my keyword 'date'
labels = labels.filter(g => g.innerHTML.startsWith(keyword));
With that, I replace the innerHTML of each element to the date format I wish.
labels.forEach(g => {
const date = new Date(+g.substring(keyword.length));
// you can apply any format method you wish
// .toLocaleDateString()
g.innerHTML = date.toLocaleDateString();
// moment.js
g.innerHTML = moment(date).format('DD/MM/YYYY HH:MM');
});
Also, I'm using interactive charts, so the labels refresh on each user interaction. Therefore, I put everything inside an interval, and the final result is as follows:
const keyword = 'date';
const options = {
// ...
hAxis: {
format: `'${keyword}'#`
},
}
// ... chart setup
setInterval(() => {
let labels = Array.from(document.querySelectorAll('#chart svg g:nth-of-type(3) g:nth-of-type(3) g text'));
labels = labels.filter(g => g.innerHTML.startsWith(keyword));
labels.forEach(g => {
const date = new Date(+g.substring(keyword.length));
g.innerHTML = date.toLocaleDateString();
});
}, 100);
Use this answer with caution. Using query selectors to modify third party generated content is very unsafe because it relies on the hope that the third-party developers won't modify the way the content is generated.
Try out this column chart:
public histogramChart: GoogleChartInterface = {
chartType: 'ColumnChart',
dataTable: [
['Date', 'Number'],
[new Date(2015, 1, 1), 5],
[new Date(2015, 1, 2), 5.1],
[new Date(2015, 1, 3), 6.2],
[new Date(2015, 1, 4), 7]
];,
//opt_firstRowIsData: true,
options: {
title: 'Shooting history',
legend: { position: 'none' },
colors: ['#4285F4'],
},
};
Is it possible to create a line chart with just one data series, showing just one line, but two different vertical axes? The axes differ by a scalar.
Think of a data series of income at different points in time. The first v-axis would correspond the the income levels. The second v-axis would show what percentage that income is of some target or comparison figure. So the values of the second v-axis are just the values of the first divided by the (constant) target values.
I'm currently able to build a chart that is based on two data series, showing two different lines: An income line plotted against the first v-axis, and a percent-of-target line plotted against the second v-axis. These lines follow the same path and are usually almost right on top of each other. The reason they are not directly on top of one another seems to be how the API tends to pick "nice" numbers for the max and min values of each axis. But I think the two lines are confusing and hard to look at. This data can be represented with a single line.
If it is not possible to do directly, can it be hacked? If I have to stick with two different data series, is there a way I can get at the max value for the first v-axis and then set the max-value for the second v-axis so that the two lines fall directly on top of each other? How then might I clean it up so it only looks like there is one line?
There is no way to make it happen with just one series of data. The easy way to get the two lines to align is to set the max value of the income-level axis as the income target used for the percentage (so it corresponds to 100%), and set the min value equal to the min percentage of that income level that you want to show (0% is the easiest to make work, generally). Something like this:
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Year');
data.addColumn('number', 'Income');
data.addRows([
[2000, 35000],
[2001, 38000],
[2002, 42000],
[2003, 44000],
[2004, 47000],
[2005, 51000],
[2006, 55000],
[2007, 60000],
[2008, 61000],
[2009, 65000],
[2010, 59000],
[2011, 62000],
[2012, 63000]
]);
var targetIncome = 80000;
var minIncomePercent = 0;
var view = new google.visualization.DataView(data);
view.setColumns([0, {
type: 'number',
label: 'Percent of Target',
calc: function (dt, row) {
return dt.getValue(row, 1) / targetIncome;
}
}, 1]);
var chart = new google.visualization.LineChart(document.querySelector('#chart_div'));
chart.draw(view, {
height: 400,
width: 600,
hAxis: {
format: '####'
},
vAxes: {
0: {
title: 'Income Level',
format: '$#,###',
minValue: targetIncome * minIncomePercent,
maxValue: targetIncome
},
1: {
title: 'Income Percentage of Target',
format: '#%',
minValue: minIncomePercent,
maxValue: 1
}
},
series: {
0: {
targetAxisIndex: 1,
enableInteractivity: false,
pointSize: 0,
lineWidth: 0,
visibleInLegend: false
},
1: {
targetAxisIndex: 0
}
}
});
}
See http://jsfiddle.net/asgallant/6N5mZ/
I have an Annotated Timeline that I would like to update in realtime (similar to how Google Finance does it). However, I am having trouble getting the chart to not flicker and not re-zoom when data is added.
I couldn't get the code to work in JSFiddle (I think because annotated timeline is flash based?) but here is some basic code that you can plug in to Google's Visualization Playground. You can see a saved example here but unfortunately can't modify the code, you'll have to go to the playground to do that.
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'My Data');
data.addRows([
[new Date(2009, 1 ,1), 30000],
[new Date(2009, 1 ,2), 14045],
[new Date(2009, 1 ,3), 55022],
[new Date(2009, 1 ,4), 75284],
[new Date(2009, 1 ,5), 41476],
[new Date(2009, 1 ,6), 33322]
]);
var annotatedtimeline = new google.visualization.AnnotatedTimeLine(
document.getElementById('visualization'));
var options = {
'allowRedraw' : true ,
'displayAnnotations' : true,
'zoomStartTime': new Date(2009, 1 ,2),
'zoomEndTime': new Date(2009, 1 ,10)
};
annotatedtimeline.draw(data, options);
// let's add some more data in 3 seconds
setTimeout(function() {
again(annotatedtimeline, data, options);
}, 3000);
}
function again(timeline, data, options) {
data.addRow([new Date(2009, 1 ,7), 30000]);
timeline.draw(data, options);
}
google.setOnLoadCallback(drawVisualization);
What's weird is that I get pretty different flicker behavior depending on how I set displayAnnotations
displayAnnotations = true : Chart flickers but does not re-zoom
displayAnnotations = false : No chart flicker but it re-zooms to the new data (try it on the playground to see)
Setting allowRedraw = false causes the chart to flicker regardless. Any idea how to get no flicker and no re-zoom?
From the docs:
allowRedraw must be true
displayAnnotations must be false (that is, you cannot show annotations)
That's your problem.
I want to draw graph in java script. Let me share my problem with simple example.
Ind vs Aus cricket match.
X axis- Overs
Y axis- Runs
I want to show runs scored in each over by both teams in same graph. Can i show them together?
your experience will be useful to me. hoping for help.
would be grateful for help...thanks in advance,,
Try the Google Visualization API:
It includes classes to build datatables and then visualize them with different types of charts:
Example from the Google Visualiation Code Playground:
function drawVisualization() {
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'x');
data.addColumn('number', 'Cats');
data.addColumn('number', 'Blanket 1');
data.addColumn('number', 'Blanket 2');
data.addRow(["A", 1, 1, 0.5]);
data.addRow(["B", 2, 0.5, 1]);
data.addRow(["C", 4, 1, 0.5]);
data.addRow(["D", 8, 0.5, 1]);
data.addRow(["E", 7, 1, 0.5]);
data.addRow(["F", 7, 0.5, 1]);
data.addRow(["G", 8, 1, 0.5]);
data.addRow(["H", 4, 0.5, 1]);
data.addRow(["I", 2, 1, 0.5]);
data.addRow(["J", 3.5, 0.5, 1]);
data.addRow(["K", 3, 1, 0.5]);
data.addRow(["L", 3.5, 0.5, 1]);
data.addRow(["M", 1, 1, 0.5]);
data.addRow(["N", 1, 0.5, 1]);
// Create and draw the visualization.
new google.visualization.LineChart(document.getElementById('visualization')).
draw(data, {curveType: "function",
width: 500, height: 400,
vAxis: {maxValue: 10}}
);
}
This will create a line chart with the X and Y axis which is what you are try to do.
gRaphael is a great choice for charts for web. It uses javascript to produce graphs in SVG and, in old versions of IE, VML, which makes it a great cross-browser starting point - it works in IE6 and above and doesn't need flash. Another good advantage is, using SVG/VML DOM elements controlled by a javascript object means your graph elements can be made highly interactive and manipulated in javascript at any time.
Example code (from doc barchart examples):
r.hbarchart(10, 250, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55]]).hover(fin, fout);
That line creates a two-variable bar chart which calls mousein and mouseout callback functions on each element which you could use to show related information e.g., in their example, the exact values. A two variable bar chart is probably a good way to represent two teams' scoring by over for one innings. A graphael dot chart might be a better good option if there are multiple overs and multiple innings - one for each team. There are other chart types supported too - see the demo examples on the main project page above.