I try create ComboChart where are bars and series of waterfall(candlestick) chart.
I dont know how to create data input for this.
Candlestick needs format like:
['Mon', 20, 28, 38, 45],
['Tue', 31, 38, 55, 66],
['Wed', 50, 55, 77, 80],
['Thu', 77, 77, 66, 50],
['Fri', 68, 66, 22, 15]
and bars in my case:
['name', 'value', { role: 'style' }],
['test1', 8, '#00f'],
['test2', 10,'#000'],
['test3', 19,'#f00'],
Is it even possible to do it ? Join bars and candlesticks ?
use the series option to control the chart type for each series
each series is represented by a column, or a set of columns, in the data
starting with the first column that is not the x-axis or a column role
example: the columns for the chart you describe might resemble the following...
"cols":[
// x-axis
{"label":"Category","type":"string"},
// bar series -- 0
{"label":"Bar 0","type":"number"},
// bar series -- 1
{"label":"Bar 1","type":"number"},
// waterfall series -- 2
{"label":"WF 2 - Bottom 1","type":"number"},
{"label":"WF 2 - Bottom 2","type":"number"},
{"label":"WF 2 - Top 1","type":"number"},
{"label":"WF 2 - Top 2","type":"number"},
{"role":"style","type":"string","p":{"role":"style"}},
// bar series -- 3
{"label":"Bar 3","type":"number"}
],
the candlestick chart requires 4 columns, in the above example, a style column role is also used,
as such, all five columns are considered part of series number 2
when building data for a combochart,
use null for the series values,
when they do not coincide with the same x-axis value
example data:
"rows":[
// bar (series 0 & 1) data
{"c":[{"v":"YTD"},{"v":14807893.054},{"v":11684139.912},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null}]},
{"c":[{"v":"Last Year"},{"v":16307893.054},{"v":20684139.912},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null}]},
// waterfall (series 2) data
{"c":[{"v":"Budget"},{"v":null},{"v":null},{"v":0},{"v":0},{"v":22707893.613},{"v":22707893.613},{"v":"#007fff"},{"v":null}]},
{"c":[{"v":"Contract Labor"},{"v":null},{"v":null},{"v":22707893.613},{"v":22707893.613},{"v":22534350.429},{"v":22534350.429},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Contract Non Labor"},{"v":null},{"v":null},{"v":22534350.429},{"v":22534350.429},{"v":22930956.493},{"v":22930956.493},{"v":"#922b21"},{"v":null}]},
{"c":[{"v":"Matls & Equip"},{"v":null},{"v":null},{"v":22930956.493},{"v":22930956.493},{"v":22800059.612},{"v":22800059.612},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Other"},{"v":null},{"v":null},{"v":22800059.612},{"v":22800059.612},{"v":21993391.103},{"v":21993391.103},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Labor"},{"v":null},{"v":null},{"v":21993391.103},{"v":21993391.103},{"v":21546003.177999996},{"v":21546003.177999996},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Travel"},{"v":null},{"v":null},{"v":21546003.177999996},{"v":21546003.177999996},{"v":21533258.930999994},{"v":21533258.930999994},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Training"},{"v":null},{"v":null},{"v":21533258.930999994},{"v":21533258.930999994},{"v":21550964.529999994},{"v":21550964.529999994},{"v":"#922b21"},{"v":null}]},
{"c":[{"v":"Actual"},{"v":null},{"v":null},{"v":0},{"v":0},{"v":21550964.52999999},{"v":21550964.52999999},{"v":"#007fff"},{"v":null}]},
// bar (series 3) data
{"c":[{"v":"FCST"},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":16182561.25}]}
]
following is a working example of a combo chart with bars and candlesticks
google.charts.load('current', {
callback: function () {
drawChart();
$(window).resize(drawChart);
},
packages:['corechart', 'table']
});
function drawChart() {
var dataChart = new google.visualization.DataTable({
"cols":[
// x-axis
{"label":"Category","type":"string"},
// bar series -- 0
{"label":"Bar 0","type":"number"},
// bar series -- 1
{"label":"Bar 1","type":"number"},
// waterfall series -- 2
{"label":"WF 2 - Bottom 1","type":"number"},
{"label":"WF 2 - Bottom 2","type":"number"},
{"label":"WF 2 - Top 1","type":"number"},
{"label":"WF 2 - Top 2","type":"number"},
{"role":"style","type":"string","p":{"role":"style"}},
// bar series -- 3
{"label":"Bar 3","type":"number"}
],
"rows":[
// bar (series 0 & 1) data
{"c":[{"v":"YTD"},{"v":14807893.054},{"v":11684139.912},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null}]},
{"c":[{"v":"Last Year"},{"v":16307893.054},{"v":20684139.912},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null}]},
// waterfall (series 2) data
{"c":[{"v":"Budget"},{"v":null},{"v":null},{"v":0},{"v":0},{"v":22707893.613},{"v":22707893.613},{"v":"#007fff"},{"v":null}]},
{"c":[{"v":"Contract Labor"},{"v":null},{"v":null},{"v":22707893.613},{"v":22707893.613},{"v":22534350.429},{"v":22534350.429},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Contract Non Labor"},{"v":null},{"v":null},{"v":22534350.429},{"v":22534350.429},{"v":22930956.493},{"v":22930956.493},{"v":"#922b21"},{"v":null}]},
{"c":[{"v":"Matls & Equip"},{"v":null},{"v":null},{"v":22930956.493},{"v":22930956.493},{"v":22800059.612},{"v":22800059.612},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Other"},{"v":null},{"v":null},{"v":22800059.612},{"v":22800059.612},{"v":21993391.103},{"v":21993391.103},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Labor"},{"v":null},{"v":null},{"v":21993391.103},{"v":21993391.103},{"v":21546003.177999996},{"v":21546003.177999996},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Travel"},{"v":null},{"v":null},{"v":21546003.177999996},{"v":21546003.177999996},{"v":21533258.930999994},{"v":21533258.930999994},{"v":"#1e8449"},{"v":null}]},
{"c":[{"v":"Training"},{"v":null},{"v":null},{"v":21533258.930999994},{"v":21533258.930999994},{"v":21550964.529999994},{"v":21550964.529999994},{"v":"#922b21"},{"v":null}]},
{"c":[{"v":"Actual"},{"v":null},{"v":null},{"v":0},{"v":0},{"v":21550964.52999999},{"v":21550964.52999999},{"v":"#007fff"},{"v":null}]},
// bar (series 3) data
{"c":[{"v":"FCST"},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":null},{"v":16182561.25}]}
]
});
var comboChart = new google.visualization.ChartWrapper({
chartType: 'ComboChart',
containerId: 'chart_div',
dataTable: dataChart,
options: {
animation: {
duration: 1500,
easing: 'inAndOut',
startup: true
},
backgroundColor: 'transparent',
bar: {
group: {
width: '85%'
}
},
chartArea: {
backgroundColor: 'transparent',
bottom: 42,
height: '100%',
left: 60,
top: 24,
width: '100%'
},
hAxis: {
textStyle: {
fontSize: 12
}
},
height: 400,
legend: 'none',
seriesType: 'bars',
series: {
2: {
type: 'candlesticks'
}
},
tooltip: {
isHtml: true,
trigger: 'both'
},
vAxis: {
format: 'short',
textStyle: {
color: '#616161'
},
viewWindow: {
min: 10000000,
max: 24000000
}
},
width: '100%'
}
});
comboChart.draw();
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="chart_div"></div>
note: you'll notice when running the snippet in full page mode,
the chart doesn't do a very good job of aligning the x-axis labels
you may be able to manipulate the options to get them to align better,
but it will take some manipulation...
you might have better results, creating three separate charts, side-by-side
just need to make sure each has the same vAxis values,
you could hide the extra vAxis labels if needed, etc...
again, manipulation is required
example: snippet displayed best in full page mode...
google.charts.load('current', {
callback: function () {
drawChart();
$(window).resize(drawChart);
},
packages:['corechart', 'table']
});
function drawChart() {
var dataBar0 = new google.visualization.DataTable({
"cols":[
{"label":"Category","type":"string"},
{"label":"Bar 0","type":"number"},
{"label":"Bar 1","type":"number"}
],
"rows":[
// bar 0 data
{"c":[{"v":"YTD"},{"v":22807893.054},{"v":18684139.912}]}
]
});
var barChart0 = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'bar_chart_0',
dataTable: dataBar0,
options: {
animation: {
duration: 1500,
easing: 'inAndOut',
startup: true
},
backgroundColor: 'transparent',
bar: {
gap: 20,
width: 60
},
chartArea: {
backgroundColor: 'transparent',
},
height: 400,
legend: 'none',
theme: 'maximized',
tooltip: {
isHtml: true,
trigger: 'both'
},
vAxis: {
format: 'short',
viewWindow: {
min: 10000000,
max: 24000000
}
}
}
});
barChart0.draw();
var dataWF0 = new google.visualization.DataTable({
"cols":[
{"label":"Category","type":"string"},
{"label":"WF 2 - Bottom 1","type":"number"},
{"label":"WF 2 - Bottom 2","type":"number"},
{"label":"WF 2 - Top 1","type":"number"},
{"label":"WF 2 - Top 2","type":"number"},
{"role":"style","type":"string","p":{"role":"style"}}
],
"rows":[
{"c":[{"v":"Budget"},{"v":0},{"v":0},{"v":22707893.613},{"v":22707893.613},{"v":"#007fff"}]},
{"c":[{"v":"Other"},{"v":22800059.612},{"v":22800059.612},{"v":21993391.103},{"v":21993391.103},{"v":"#1e8449"}]},
{"c":[{"v":"Labor"},{"v":21993391.103},{"v":21993391.103},{"v":21546003.177999996},{"v":21546003.177999996},{"v":"#1e8449"}]},
{"c":[{"v":"Travel"},{"v":21546003.177999996},{"v":21546003.177999996},{"v":21533258.930999994},{"v":21533258.930999994},{"v":"#1e8449"}]},
{"c":[{"v":"Training"},{"v":21533258.930999994},{"v":21533258.930999994},{"v":21550964.529999994},{"v":21550964.529999994},{"v":"#922b21"}]},
{"c":[{"v":"Actual"},{"v":0},{"v":0},{"v":21550964.52999999},{"v":21550964.52999999},{"v":"#007fff"}]}
]
});
var wfChart0 = new google.visualization.ChartWrapper({
chartType: 'CandlestickChart',
containerId: 'wf_chart_0',
dataTable: dataWF0,
options: {
animation: {
duration: 1500,
easing: 'inAndOut',
startup: true
},
backgroundColor: 'transparent',
bar: {
gap: 20,
width: 60
},
chartArea: {
backgroundColor: 'transparent'
},
height: 400,
legend: 'none',
theme: 'maximized',
tooltip: {
isHtml: true,
trigger: 'both'
},
vAxis: {
format: 'short',
viewWindow: {
min: 10000000,
max: 24000000
}
},
width: '100%'
}
});
wfChart0.draw();
var dataBar1 = new google.visualization.DataTable({
"cols":[
{"label":"Category","type":"string"},
{"label":"Bar 0","type":"number"},
{"label":"Bar 1","type":"number"}
],
"rows":[
// bar 0 data
{"c":[{"v":"YTD"},{"v":20807893.054},{"v":19684139.912}]}
]
});
var barChart1 = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'bar_chart_1',
dataTable: dataBar1,
options: {
animation: {
duration: 1500,
easing: 'inAndOut',
startup: true
},
backgroundColor: 'transparent',
bar: {
gap: 20,
width: 60
},
chartArea: {
backgroundColor: 'transparent',
},
height: 400,
legend: 'none',
theme: 'maximized',
tooltip: {
isHtml: true,
trigger: 'both'
},
vAxis: {
format: 'short',
viewWindow: {
min: 10000000,
max: 24000000
}
}
}
});
barChart1.draw();
}
.max-chart {
display: inline-block;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="max-chart" id="bar_chart_0"></div>
<div class="max-chart" id="wf_chart_0"></div>
<div class="max-chart" id="bar_chart_1"></div>
My charts works well on the same page but when I put on different pages, only the first one works fine.
ex:
Page1.html
<div class="wrapper">
<canvas id="pieChart" width="200px" height="200px"></canvas>
</div>
Page2.html
<div class="wrapper">
<canvas id="lineChart" width="200px" height="200px"></canvas>
</div>
JS
//page1.html
//piechart
var pieVar = {
type: 'pie',
data: {
labels: ["Yes", "No"],
datasets: [
{
data: [60, 40],
backgroundColor: [
"#FF6384",
"#36A2EB"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB"
]
}
]
},
options: {
scales: {
xAxes: [{
display: true
}]
}
}
}
//page2.html
//line chart
var lineVar = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fill: true,
lineTension: 0.2,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 10,
pointHoverBackgroundColor: "rgba(255,0,0,1)",
pointHoverBorderColor: "rgba(255,0,0,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: [65, 59, 80, 81, 56, 55, 40],
spanGaps: false,
}
]
},
options: {
scales: {
xAxes: [{
display: true
}]
}
}
}
window.onload = function(){
//piechart
var pieCtx = document.getElementById("pieChart");
var myPieChart = new Chart(pieCtx, pieVar);
//linechart
var lineCtx = document.getElementById("lineChart");
var myLineChart = new Chart(lineCtx, lineVar);
};
In this codepen works fine because it's the same page..
CODEPEN
It sounds like you're loading the same JavaScript file (which contains the configurations for both of your charts) in both of your pages. The problem is since you're using a single JavaScript file with two chart definitions, the chart you try to create that doesn't exist in the html is throwing an error because you are passing in an empty context.
window.onload = function(){
//piechart (this will be null on page2.html)
var pieCtx = document.getElementById("pieChart");
// You are passing in a null pieCtx on page2.html because there is no element with an id = "pieChart"
var myPieChart = new Chart(pieCtx, pieVar);
//linechart (this will be null on page1.html)
var lineCtx = document.getElementById("lineChart");
// You are passing in a null lineCtx on page1.html because there is no element with an id = "lineChart"
var myLineChart = new Chart(lineCtx, lineVar);
};
You should either split your JavaScript file into two files so that the first page only includes the definition for the first chart and the second page only includes the definition for the second chart. Or, add some conditions to prevent trying to create the empty chart (like this).
window.onload = function(){
//piechart (this will be null on page2.html)
var pieCtx = document.getElementById("pieChart");
if (pieChart) {
var myPieChart = new Chart(pieCtx, pieVar);
}
//linechart (this will be null on page1.html)
var lineCtx = document.getElementById("lineChart");
if (lineChart) {
var myLineChart = new Chart(lineCtx, lineVar);
}
};
I am trying to use the datasetFill option for the radar charts for chartjs and I noticed that the charts always stay filled even when I set datasetFill to false. Here is a link to a fiddle that gives an example of what I'm trying to do http://jsfiddle.net/5gHVY/143/. Here is the code below:
//line chart data
var lineData = {
labels: ["Jan", "Feb", "March", "April", "May", "June", "July"],
datasets: [{
fillColor: "rgba(255,255,0,100)",
strokeColor: "rgba(63,169,245,1)",
pointColor: "rgba(63,169,245,1)",
pointStrokeColor: "#fff",
data: [65, 59, 90, 81, 56, 55, 40]
}, {
fillColor: "rgba(255,255,255,0)",
strokeColor: "rgba(102,45,145,1)",
pointColor: "rgba(102,45,145,1)",
pointStrokeColor: "#fff",
data: [28, 48, 40, 19, 96, 27, 100]
}]
}
var lineOptions = {
animation: true,
pointDot: true,
scaleOverride : true,
scaleShowGridLines : false,
scaleShowLabels : true,
scaleSteps : 4,
scaleStepWidth : 25,
scaleStartValue : 25,
datasetFill: false,
};
var radarOptions = {
datasetFill: false,
};
//radar chart data
var radarData = {labels : ["Eating","Drinking","Sleeping","Designing","Coding","Partying","Running"],
datasets : [
{
fillColor: "rgba(102,45,145,.1)",
strokeColor: "rgba(102,45,145,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor: "rgba(63,169,245,.1)",
strokeColor: "rgba(63,169,245,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
}
//Create Line chart
var ctx = document.getElementById("lineChart").getContext("2d");
var myNewChart = new Chart(ctx).Line(lineData, lineOptions);
//Create Radar chart
var ctx2 = document.getElementById("radarChart").getContext("2d");
var myNewChart2 = new Chart(ctx2).Radar(radarData, radarOptions);
edit: A pull request was just merged to fix this issue (https://github.com/nnnick/Chart.js/pull/1127), you will need to build the chart.js main file though as it is only in the src for the moment, just clone the project and run the gulp build.
The radar draw method is not taking this option into acount. Until a fix is present in the main Chart js you can extend the radar chart and override the draw method to take this option into account
Chart.types.Radar.extend({
// Passing in a name registers this chart in the Chart namespace in the same way
name: "RadarAlt",
draw : function(ease){
var easeDecimal = ease || 1,
ctx = this.chart.ctx;
this.clear();
this.scale.draw();
Chart.helpers.each(this.datasets,function(dataset){
//Transition each point first so that the line and point drawing isn't out of sync
Chart.helpers.each(dataset.points,function(point,index){
if (point.hasValue()){
point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
}
},this);
//Draw the line between all the points
ctx.lineWidth = this.options.datasetStrokeWidth;
ctx.strokeStyle = dataset.strokeColor;
ctx.beginPath();
Chart.helpers.each(dataset.points,function(point,index){
if (index === 0){
ctx.moveTo(point.x,point.y);
}
else{
ctx.lineTo(point.x,point.y);
}
},this);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = dataset.fillColor;
if(this.options.datasetFill)
{
ctx.fill();
}
//Now draw the points over the line
//A little inefficient double looping, but better than the line
//lagging behind the point positions
Chart.helpers.each(dataset.points,function(point){
if (point.hasValue()){
point.draw();
}
});
},this);
}
});
here it is in action
Chart.types.Radar.extend({
// Passing in a name registers this chart in the Chart namespace in the same way
name: "RadarAlt",
draw: function(ease) {
var easeDecimal = ease || 1,
ctx = this.chart.ctx;
this.clear();
this.scale.draw();
Chart.helpers.each(this.datasets, function(dataset) {
//Transition each point first so that the line and point drawing isn't out of sync
Chart.helpers.each(dataset.points, function(point, index) {
if (point.hasValue()) {
point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
}
}, this);
//Draw the line between all the points
ctx.lineWidth = this.options.datasetStrokeWidth;
ctx.strokeStyle = dataset.strokeColor;
ctx.beginPath();
Chart.helpers.each(dataset.points, function(point, index) {
if (index === 0) {
ctx.moveTo(point.x, point.y);
} else {
ctx.lineTo(point.x, point.y);
}
}, this);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = dataset.fillColor;
if (this.options.datasetFill) {
ctx.fill();
}
//Now draw the points over the line
//A little inefficient double looping, but better than the line
//lagging behind the point positions
Chart.helpers.each(dataset.points, function(point) {
if (point.hasValue()) {
point.draw();
}
});
}, this);
}
});
var radarOptions = {
datasetFill: false,
};
//radar chart data
var radarData = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Partying", "Running"],
datasets: [{
fillColor: "rgba(102,45,145,.1)",
strokeColor: "rgba(102,45,145,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: [65, 59, 90, 81, 56, 55, 40]
}, {
fillColor: "rgba(63,169,245,.1)",
strokeColor: "rgba(63,169,245,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
data: [28, 48, 40, 19, 96, 27, 100]
}]
}
//Create Radar chart
var ctx2 = document.getElementById("radarChart").getContext("2d");
var myNewRadarChart = new Chart(ctx2).RadarAlt(radarData, radarOptions);
<script src="http://www.chartjs.org/assets/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="radarChart" width="800" height="650"></canvas>