Here is an example of google column chart built using static data : https://plnkr.co/edit/WBApWlwTIDa7HjOQMyxe?p=preview
I want to draw the chart dynamically.One issue i'm facing is how to dynamically assign the value for ticks:[..]
Please find the updated plunker https://plnkr.co/edit/EGzl2XdQfuMWldzPyfr6?p=preview.
I tried to assign the values for ticks:[..] later by creating a varibale dynamicTicks but it is not working .
PS: Reference tooltip is not shown as expected when customized
--EDITED--
Below is the updated code suggested by #WhiteHat in below thread.
Below is the js code to dynamically get the data and display the chart.Issue is with the below code the h-axis dynamicTrick is not displayed, on h-axis it is showing the values given in f: property of {"v": i, "f": hAxisValue}
app.controller('myController', ['$scope', '$uibModal', 'MyService', function ($scope, $uibModal, MyService) {
$scope.chart = {};
$scope.chart.type = "ColumnChart";
$scope.chart.displayed = false;
var dynamicTicks = [];
$scope.chart.options = {
focusTarget: 'category',
"fill": 20,
"displayExactValues": true,
"isStacked": 'true',
tooltip: {text: 'value',textStyle: {fontName: '"Arial"'}},
hAxis: {
titleTextStyle: {bold: 'true'},
slantedText: false,
ticks: dynamicTicks
},
};
$scope.chart.view = {
columns: [0, 1, 2, 3]
};
$scope.chart.data = {
"cols": [
{id: "label", label: "Label", type: "string"},
{id: "count", label: "Count", type: "number"},
{id: "pizza", label: "Pizza", type: "number"},
{id: "softDrink", label: "SoftDrink", type: "number"},
]
};
$scope.loadMyChart = function () {
MyService.getChartData().then(
function (response) {
$scope.myResponse= response;
//check for error
var count = 0;
var pizza = 0;
var softDrink = 0;
var myRows = [];
$scope.chart.data.rows = {};
var i = 0; var cData=[];
angular.forEach($scope.myResponse, function (value, key) {
count = value.myData.count;
pizza = value.myData.pizza;
softDrink = value.myData.softDrnk;
hAxisValue = value.myData.title;
cData = {
"c": [{"v": i, "f": hAxisValue}, {"v": passsed},
{"v": failed},
{"v": notExecute}, {"v": key}]
};
myRows.push(cData); i++;
});
alert("cData.length " + i);
for (var j = 0; j < i; j++) {
alert("in for" + j + "Series" + (j+1)); //This alert is being executed..
dynamicTicks.push({
v: j, /*cData[j].c[0].v */
f: 'Series ' + (j + 1)
});
}
$scope.chart.data.rows = weekRows;
},
}
$scope.loadMyChart();
}]);
When used the statement cData[j].c[0].v, following error is displayed on browser console and no chart is shown on UI.
angular.min.js:sourcemap:119 TypeError: Cannot read property 'c' of undefined
wouldn't you build dynamic ticks where the chart data and options are created?
something like...
var createChart = function (rows, label) {
return {
"type": "ColumnChart",
"data": {
"cols": [
{"id": label, "label": label, "type": "number"},
{"id": "count", "label": "count", "type": "number"},
{"id": "pizza", "label": "Pizza", "type": "number"},
{"id": "softdrink", "label": "Softdrink", "type": "number"}
],
"rows": rows
},
"options": {
"title": label,
"isStacked": "true",
focusTarget: 'category',
hAxis: {
baselineColor: 'transparent',
gridlines: {
color: 'transparent'
},
slantedText: false,
"ticks": dynamicTicks,
},
tooltip: {
text: 'value'
}
}
}
};
var data = [
{"c":[{"v": 0, "f":"Jan - July"},{"v":63},{"v":"30"},{"v":"33"}]},
{"c":[{"v": 1, "f":"Aug - Sept"},{"v":70},{"v":"35"},{"v":"35"}]},
{"c":[{"v": 2, "f":"Oct - Dec"},{"v":80},{"v":"40"},{"v":"40"}]}
];
var dynamicTicks = [];
for (var i = 0; i < data.length; i++) {
dynamicTicks.push({
v: data[i].c[0].v,
f: 'Series ' + (i + 1)
});
}
$scope.myChart = createChart(data, "Data Series");
Related
When user click on Hide Laptop stacked bar radio button, the stacked bar displayed for Laptop(blue color) should be hidden and when clicked on ALL radio button all bars should be displayed. But currently when i click on Hide Laptop stacked bar, the Shipping data is not dispalyed and even the Legend name for shipping is showing wrong when clicked on ALL radio button after Hide Laptop radio button.
Please find the demo here
js code:
angular.module('myApp', ['googlechart'])
.controller('myController', function($scope) {
var chart1 = {};
var variableCol = {
id: "laptop-id",
label: "Laptop",
type: "number"
};
chart1.type = "ColumnChart";
chart1.displayed = false;
var valueSelected;
$scope.newValue = function(value) {
console.log(value);
console.log(chart1.data.cols.length);
valueSelected = value;
if(value == 'few' && chart1.data.cols.length == 5) {
alert("Laptop data should not be shown" );
chart1.data.cols.pop();
} else {
chart1.data.cols.push(variableCol);
}
}
//if the ALL radio button is selected all the stacked bars should be shown
//if SDL radio button is selected, show only server,desktop,laptop but onmouse over show the shipping details tooo
chart1.data = {
"cols": [{
id: "month",
label: "Month",
type: "string"
},variableCol,
{
id: "desktop-id",
label: "Desktop",
type: "number"
}, {
id: "server-id",
label: "Server",
type: "number"
}, {
id: "cost-id",
label: "Shipping",
type: "number"
}],
"rows": [{
c: [{
v: "January"
}, {
v: 19,
f: "42 items"
}, {
v: 12,
f: "Ony 12 items"
}, {
v: 7,
f: "7 servers"
}, {
v: 4
}]
}, {
c: [{
v: "February"
}, {
v: 13
}, {
v: 1,
f: "1 unit (Out of stock this month)"
}, {
v: 12
}, {
v: 2
}]
}, {
c: [{
v: "March"
}, {
v: 24
}, {
v: 5
}, {
v: 11
}, {
v: 6
}
]
}]
};
chart1.options = {
"title": "Sales per month",
"isStacked": "true",
focusTarget: 'category',
"fill": 20,
"displayExactValues": true,
colors: ['blue', 'green', 'pink', 'brown'],
"vAxis": {
"title": "Sales unit",
"gridlines": {
"count": 10
}
},
"hAxis": {
"title": "Date"
}
};
$scope.myChart = chart1;
}).value('googleChartApiConfig', {
version: '1.1',
optionalSettings: {
packages: ['bar'],
language: 'en'
}
});
You are calling array.pop, which removes the last element from the array. The laptop element is at position 1. Here's a snippet of how you would search for the variableCol index, and then splice the array removing that element. That's the safest way to do this since you'll ensure you are finding that particular column.
So far, these solutions are not solving for the data
Without regard for colors
if(value == 'few' && chart1.data.cols.length == 5) {
//alert("Laptop data should not be shown" );
var idx = chart1.data.cols.indexOf(variableCol);
chart1.data.cols.splice(idx, 1);
console.log("var col at " + idx);
}
Here's a working plnkr
Keeping Blue Color for laptop
This version will keep the laptop being blue (position does change though).
if (value == 'few' && chart1.data.cols.length == 5) {
//alert("Laptop data should not be shown" );
var colIdx = chart1.data.cols.indexOf(variableCol);
chart1.data.cols.splice(colIdx, 1);
var colorIdx = chart1.options.colors.indexOf("blue");
chart1.options.colors.splice(colorIdx, 1);
} else {
chart1.data.cols.push(variableCol);
chart1.options.colors.push("blue");
}
<!DOCTYPE HTML>
<html>
<head>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
theme: "theme2",//theme1
title:{
text: "Basic Column Chart - CanvasJS"
},
animationEnabled: false, // change to true
data: [
{
// Change type to "bar", "area", "spline", "pie",etc.
type: "column",
dataPoints: [
{ label: "apple", y: 10 },
{ label: "orange", y: 15 },
{ label: "banana", y: 25 },
{ label: "mango", y: 30 },
{ label: "grape", y: 28 }
]
}
]
});
chart.render();
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
</body>
</html>
Can I use vaadin code to generate code dynamically using JavaScript?
I have not tried the append part.
enter code here
//stackchange.js
function calc2DArrMulti(dArr) {
let vLen = dArr.length;
let eLen = dArr[0].length;
const result = [];
const flip = new Array(eLen);
for (let j = 0; j < eLen; j++) {
flip[j] = new Array(vLen);
for (let i = 0; i < vLen; i++) {
flip[j][i] = dArr[i][j];
if (result[i] == null) result[i] = new Array(eLen);
}
}
for (let i = 0; i < eLen; i++) {
let min = Math.min.apply(null, flip[i]);
for (let j = 0; j < vLen; j++) {
let v = flip[i][j];
result[j][i] = v / min;
}
}
return {
origin: dArr,
calc: result
};
};
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<!--Vaadin-charts-->
<script src="js/jquery.js"></script>
<script src="js/stackchange.js"></script>
<script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="bower_components/vaadin-charts/vaadin-charts.html">
<!-- <link rel="import" href="bower_components/vaadin-charts/ybtest.html">-->
<!--stacked-->
<script>
//----------------임의 데이터 만들기------------------//
var fab1 = [5, 2200, 100000, 6000000, 5200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var fab2 = [7, 2200, 130000, 4600000, 4200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var fab3 = [7, 2200, 100700, 5600000, 9200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var fab4 = [7, 2200, 100700, 5600000, 9200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var fab5 = [7, 2200, 100700, 5600000, 9200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var test = new Array(5);
// var test2 = new Array(4);
//2차원 배열 선언!!
for (var i = 0; i < test.length; i++) { //2
test[i] = new Array(5);
}
for (var i = 0; i < fab1.length; i++) {
test[0][i] = fab1[i];
test[1][i] = fab2[i];
test[2][i] = fab3[i];
test[3][i] = fab4[i];
test[4][i] = fab4[i];
}
//2차원 배열에 1차원 배열 넣기!!
//----------------임의 데이터 만들기------------------//
var test2 = calc2DArrMulti(test);
var test3 = stackchange(test);
</script>
<!-- <script>
$("#test-chart").append("<template><vaadin-column-chartid='dateAxisAndClickEvent'on-point-click='pointClickListener'><x-axis><categories>Fab1,Fab2,Fab3,Fab4,Fab5</categories></x-axis><y-axisallow-decimals='false'min='0'><stack-labelsenabled='false'></stack-labels></y-axis><tooltipformatter='function(){return(test3.origin[this.series.index][this.point.x])}'></tooltip><plot-options><chart-areastacking='percent'></chart-area><columnstacking='percent'><data-labelsenabled='true'color='white'formatter='function(){return(test3.origin[this.series.index][this.point.x])}'></data-labels></column></plot-options><legendlayout='vertical'align='right'vertical-align='top'x='-40'y='80'floating='true'border-width='1'background-color='#FFFFFF'shadow='true'></legend><data-seriesname='1'id='mytib'data='[[mytib]]'></data-series><data-seriesname='2'id='myext'data='[[myext]]'></data-series><data-seriesname='3'id='mybxt'data='[[mybxt]]'></data-series><data-seriesname='4'id='mycxt'data='[[mycxt]]'></data-series><data-seriesname='5'id='mydxt'data='[[mydxt]]'></data-series><data-seriesname='6'id='mydxx'data='[[mydxx]]'></data-series><data-seriesname='7'id='mydxz'data='[[mydxz]]'></data-series><data-seriesname='8'id='mydxy'data='[[mydxy]]'></data-series><data-seriesname='9'id='mydxr'data='[[mydxr]]'></data-series><data-seriesname='10'id='mydxh'data='[[mydxh]]'></data-series><data-seriesname='11'id='mydx1'data='[[mydx1]]'></data-series><data-seriesname='12'id='mydx2'data='[[mydx2]]'></data-series><data-seriesname='13'id='mydx3'data='[[mydx3]]'></data-series><data-seriesname='14'id='mydx4'data='[[mydx4]]'></data-series><data-seriesname='15'id='mydx5'data='[[mydx5]]'></data-series></vaadin-column-chart></template>");
</script>-->
<dom-module id=test-chart>
<template>
<vaadin-column-chart id='dateAxisAndClickEvent' on-point-click='pointClickListener'>
<x-axis>
<categories>Fab1,Fab2,Fab3,Fab4,Fab5</categories>
</x-axis>
<y-axis allow-decimals='false' min='0'>
<stack-labels enabled='false'></stack-labels>
</y-axis>
<tooltip formatter= 'function() { return (test3.origin[this.series.index][this.point.x])}'></tooltip>
<plot-options>
<chart-area stacking='percent'>
</chart-area>
<column stacking='percent'>
<data-labels enabled='true' color='white' formatter= 'function() { return (test3.origin[this.series.index][this.point.x])}'></data-labels>
</column>
</plot-options>
<legend layout='vertical' align='right' vertical-align='top' x='-40' y='80' floating='true' border-width='1' background-color='#FFFFFF' shadow='true'></legend>
<data-series name='1'id='mytib' data='[[mytib]]'></data-series>
<data-series name='2'id='myext' data='[[myext]]'></data-series>
<data-series name='3'id='mybxt' data='[[mybxt]]'></data-series>
<data-series name='4'id='mycxt' data='[[mycxt]]'></data-series>
<data-series name='5'id='mydxt' data='[[mydxt]]'></data-series>
<data-series name='6'id='mydxx' data='[[mydxx]]'></data-series>
<data-series name='7'id='mydxz' data='[[mydxz]]'></data-series>
<data-series name='8'id='mydxy' data='[[mydxy]]'></data-series>
<data-series name='9'id='mydxr' data='[[mydxr]]'></data-series>
<data-series name='10' id='mydxh' data='[[mydxh]]'></data-series>
<data-series name='11' id='mydx1' data='[[mydx1]]'></data-series>
<data-series name='12' id='mydx2' data='[[mydx2]]'></data-series>
<data-series name='13' id='mydx3' data='[[mydx3]]'></data-series>
<data-series name='14' id='mydx4' data='[[mydx4]]'></data-series>
<data-series name='15' id='mydx5' data='[[mydx5]]' ></data-series>
</vaadin-column-chart>
</template>
</dom-module>
<script>
Polymer({
is: 'test-chart',
properties: {
mytib: {
type: Array,
value: test3.calc[0]
},
myext: {
type: Array,
value: test3.calc[1]
},
mybxt: {
type: Array,
value: test3.calc[2]
},
mycxt: {
type: Array,
value: test3.calc[3]
},
mydxt: {
type: Array,
value: test3.calc[4]
},
mydxx: {
type: Array,
value: test3.calc[5]
},
mydxz: {
type: Array,
value: test3.calc[6]
},
mydxy: {
type: Array,
value: test3.calc[7]
},
mydxr: {
type: Array,
value: test3.calc[8]
},
mydxh: {
type: Array,
value: test3.calc[9]
},
mydx1: {
type: Array,
value: test3.calc[10]
},
mydx2: {
type: Array,
value: test3.calc[11]
},
mydx3: {
type: Array,
value: test3.calc[12]
},
mydx4: {
type: Array,
value: test3.calc[13]
},
mydx5: {
type: Array,
value: test3.calc[14]
},
},
pointClickListener: function(a) {
var b = a.detail.originalEvent,
c = a.detail.point,
d = b.chartX,
f = b.chartY;
this.showLabel(c.series.name+':' + test3.origin[c.series.index][c.x], d, f)
},
showLabel: function(a, b, c) {
var d = this.$.dateAxisAndClickEvent.chart.renderer.label(a, b, c).attr({
fill: 'red',
// Highcharts.getOptions().colors[5],
padding: 5,
r: 5,
zIndex: 8
}).css({
color: '#FFFFFF'
}).add();
this.async(function() {
d.fadeOut()
}, 1e3)
}
});
</script>
<test-chart></test-chart>
</body>
</html>
I have not tried the append part.
I want to code the vaadin chart like a canvas.
Is it possible?
What should I do if possible?
You will get results on the fusioncharts website if you search up what I asked, but it is not exactly what I am looking for.
I am querying data from a MySQL database, and putting this data into a fusion chart to display on my webpage. I want there to be 2 graphs on the same page, and when you click on one of the datapoints on the parent graph, the child graph will display the "drilled down" graph. How can I do this? As of right now I can press on the parent graph and it will open the child graph on a new webpage. This is the code for the home page with the parent graph. The file is named "dept.php".
<?php
/*Include the `fusioncharts.php` file that contains functions
to embed the charts.
*/
include("includes/fusioncharts.php");
// Establish a connection to the database. Variables defined before
$dbhandle = new mysqli($hostdb, $userdb, $passdb, $namedb);
// Render an error message, to avoid abrupt failure, if the database connection parameters are incorrect
if ($dbhandle->connect_error) {
exit("There was an error with your connection: ".$dbhandle->connect_error);
}
?>
<html>
<head>
<title>FusionCharts XT - Column 2D Chart - Data from a database</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<!-- Include the `fusioncharts.js` file. This file is needed to render the chart. Ensure that the path to this JS file is correct. Otherwise, it may lead to JavaScript errors. -->
<script src="fusioncharts/js/fusioncharts.js"></script>
</head>
<body>
<?php
// Form the SQL query that returns the top 10 most populous countries
$strQuery = "SELECT Department, SUM(Quantity) AS Quantity FROM Scrap GROUP BY Department ORDER BY Department";
// Execute the query, or else return the error message.
$result = $dbhandle->query($strQuery) or exit("Error code ({$dbhandle->errno}): {$dbhandle->error}");
// If the query returns a valid response, prepare the JSON string
if ($result) {
// The `$arrData` array holds the chart attributes and data
$arrData = array(
"chart" => array(
"caption" => "Sample Chart",
"paletteColors" => "#0075c2",
"bgColor" => "#ffffff",
"borderAlpha"=> "20",
"canvasBorderAlpha"=> "0",
"usePlotGradientColor"=> "0",
"plotBorderAlpha"=> "10",
"showXAxisLine"=> "1",
"xAxisLineColor" => "#999999",
"showValues"=> "0",
"divlineColor" => "#999999",
"divLineIsDashed" => "1",
"showAlternateHGridColor" => "0"
)
);
$arrData["data"] = array();
// Push the data into the array
while($row = mysqli_fetch_array($result)) {
array_push($arrData["data"], array(
"label" => $row["Department"],
"value" => $row["Quantity"],
"link" => "deptDrillDown.php?Department=".$row["Department"]
)
);
}
/*JSON Encode the data to retrieve the string containing the JSON representation of the data in the array. */
$jsonEncodedData = json_encode($arrData);
/*Create an object for the column chart. Initialize this object using the FusionCharts PHP class constructor. The constructor is used to initialize
the chart type, chart id, width, height, the div id of the chart container, the data format, and the data source. */
$columnChart = new FusionCharts("column2D", "myFirstChart" , 600, 300, "chart-1", "json", $jsonEncodedData);
// Render the chart
$columnChart->render();
// Close the database connection
$dbhandle->close();
}
?>
<div id="chart-1"><!-- Fusion Charts will render here--></div>
</body>
</html>
And then here is the other page that contains the child graph. The file is named "deptDrillDown.php".
<?php
/* Include the `includes/fusioncharts.php` file that contains functions to embed the charts.*/
include("includes/fusioncharts.php");
// Establish a connection to the database. Variables defined earlier
$dbhandle = new mysqli($hostdb, $userdb, $passdb, $namedb);
/*Render an error message, to avoid abrupt failure, if the database connection parameters are incorrect */
if ($dbhandle->connect_error) {
exit("There was an error with your connection: ".$dbhandle->connect_error);
}
?>
<html>
<head>
<title>FusionCharts XT - Column 2D Chart</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<!-- Include the `fusioncharts.js` file. This file is needed to render the chart. Ensure that the path to this JS file is correct. Otherwise, it may lead to JavaScript errors. -->
<script src="fusioncharts/js/fusioncharts.js"></script>
</head>
<body>
<?php
// Get the country code from the GET parameter
$countryCode = $_GET["Department"];
// Form the SQL query that returns the top 10 most populous cities in the selected country
$cityQuery = "SELECT ScrapDate, SUM(Quantity) AS Quantity FROM Scrap WHERE Department = ? GROUP BY ScrapDate ORDER BY ScrapDate";
// Prepare the query statement
$cityPrepStmt = $dbhandle->prepare($cityQuery);
// If there is an error in the statement, exit with an error message
if($cityPrepStmt === false) {
exit("Error while preparing the query to fetch data from City Table. ".$dbhandle->error);
}
// Bind the parameters to the query prepared
$cityPrepStmt->bind_param("s", $countryCode);
// Execute the query
$cityPrepStmt->execute();
// Get the results from the query executed
$cityResult = $cityPrepStmt->get_result();
// If the query returns a valid response, prepare the JSON string
if ($cityResult) {
/* Form the SQL query that will return the country name based on the country code. The result of the above query contains only the country code.
The country name is needed to be rendered as a caption for the chart that shows the 10 most populous cities */
$countryNameQuery = "SELECT ScrapDate FROM Scrap WHERE Department = ?";
// Prepare the query statement
$countryPrepStmt = $dbhandle->prepare($countryNameQuery);
// If there is an error in the statement, exit with an error message
if($countryPrepStmt === false) {
exit("Error while preparing the query to fetch data from Country Table. ".$dbhandle->error);
}
// Bind the parameters to the query prepared
$countryPrepStmt->bind_param("s", $countryCode);
// Execute the query
$countryPrepStmt->execute();
// Bind the country name to the variable `$countryName`
$countryPrepStmt->bind_result($countryName);
// Fetch the result from prepared statement
$countryPrepStmt->fetch();
// The `$arrData` array holds the chart attributes and data
$arrData = array(
"chart" => array(
"caption" => "Top 10 Most Populous Cities in ".$countryName,
"paletteColors" => "#0075c2",
"bgColor" => "#ffffff",
"borderAlpha"=> "20",
"canvasBorderAlpha"=> "0",
"usePlotGradientColor"=> "0",
"plotBorderAlpha"=> "10",
"showXAxisLine"=> "1",
"xAxisLineColor" => "#999999",
"showValues"=> "0",
"divlineColor" => "#999999",
"divLineIsDashed" => "1",
"showAlternateHGridColor" => "0"
)
);
$arrData["data"] = array();
// Push the data into the array
while($row = $cityResult->fetch_array()) {
array_push($arrData["data"], array(
"label" => $row["ScrapDate"],
"value" => $row["Quantity"]
)
);
}
/*JSON Encode the data to retrieve the string containing the JSON representation of the data in the array. */
$jsonEncodedData = json_encode($arrData);
/*Create an object for the column chart using the FusionCharts PHP class constructor. Syntax for the constructor is `FusionCharts("type of chart",
"unique chart id", "width of chart", "height of chart", "div id to render the chart", "data format", "data source")`.*/
$columnChart = new FusionCharts("column2D", "myFirstChart" , 600, 300, "chart-1", "json", $jsonEncodedData);
// Render the chart
$columnChart->render();
// Close the database connection
$dbhandle->close();
}
?>
Back
<div id="chart-1"><!-- Fusion Charts will render here--></div>
</body>
</html>
n number of charts can be rendered in a single page using FusionCharts.
Store their chart references, e.g. in an associative array.
Use the dataplotClick event to capture the event being generated by clicking on a data.
Inside the callback, use the setJSONData to update the child chart, one wanna update.
A dummy code for this would be:
FusionCharts.ready(function () {
var chart1 = new FusionCharts({
type: 'msstackedcolumn2d',
renderAt: 'chart-container1',
width: '550',
height: '350',
dataFormat: 'json',
dataSource: {
// enter the json data here
},
"events": {
"dataplotClick": function(eventObj, dataObj) {
/* so every time a dataClickEvent is being triggered from the data plot,
a new json `json2` is fetched from a sql query and
chart2 is updated with it.*/
chart2.setJSONData(json2);
}
}
}
}).render();
});
Couple of days back I created this fiddle, hope this becomes useful here too. Instead of doing a SQL query, here we have a generalised data, every time a click is made, it internally makes a function call, and creates a data dynamically out of it. Lot of function calls for making it entirely dynamic might make the code look complex. But the basic philosophy I shared in the dummy code avobe is the same here.
The snippet version for the code for a quick reference.Better to run the result in full page to check whats exactly happening.
function getData() {
var arr = [{
seriesname: "Book A",
data: [{
"label": "Paper",
"value": 100
}, {
"label": "Promotion",
"value": 150
}, {
"label": "Transportation",
"value": 175
}, {
"label": "Royality",
"value": 200
}, {
"label": "Printing",
"value": 250
}, {
"label": "Binding",
"value": 275
}]
}, {
seriesname: "Book B",
data: [{
"label": "Paper",
"value": 130
}, {
"label": "Promotion",
"value": 110
}, {
"label": "Transportation",
"value": 155
}, {
"label": "Royality",
"value": 250
}, {
"label": "Printing",
"value": 210
}, {
"label": "Binding",
"value": 215
}]
}, {
seriesname: "Book C",
data: [{
"label": "Paper",
"value": 70
}, {
"label": "Promotion",
"value": 180
}, {
"label": "Transportation",
"value": 125
}, {
"label": "Royality",
"value": 150
}, {
"label": "Printing",
"value": 290
}, {
"label": "Binding",
"value": 245
}]
}, {
seriesname: "Book D",
data: [{
"label": "Paper",
"value": 150
}, {
"label": "Promotion",
"value": 100
}, {
"label": "Transportation",
"value": 105
}, {
"label": "Royality",
"value": 125
}, {
"label": "Printing",
"value": 278
}, {
"label": "Binding",
"value": 235
}]
}, {
seriesname: "Book E",
data: [{
"label": "Paper",
"value": 60
}, {
"label": "Promotion",
"value": 250
}, {
"label": "Transportation",
"value": 115
}, {
"label": "Royality",
"value": 189
}, {
"label": "Printing",
"value": 190
}, {
"label": "Binding",
"value": 285
}]
}, {
seriesname: "Book F",
data: [{
"label": "Paper",
"value": 190
}, {
"label": "Promotion",
"value": 200
}, {
"label": "Transportation",
"value": 160
}, {
"label": "Royality",
"value": 148
}, {
"label": "Printing",
"value": 178
}, {
"label": "Binding",
"value": 295
}]
}];
return arr;
}
function getValues(componentName) {
var i,
j,
arr = getData(),
valueArr = [],
len1;
for (i = 0, len = arr.length; i < len; i += 1) {
for (j = 0, len1 = arr[i].data.length; j < len1; j += 1) {
if (arr[i].data[j].label === componentName) {
valueArr.push({
value: arr[i].data[j].value
});
break;
}
}
}
return [{
seriesname: componentName,
data: valueArr
}];
}
function getProducts(componentName) {
var arr = getData(),
productArr = [];
for (i = 0, len = arr.length; i < len; i += 1) {
for (j = 0; j < arr[i].data.length; j += 1) {
if (arr[i].data[j].label === componentName) {
productArr.push({
"label": arr[i].seriesname,
"value": arr[i].data[j].value
});
break;
}
}
}
return productArr;
}
function getComponents(label, value) {
var arr = getData(),
sum,
i,
j,
len,
len1,
obj =
componentArr = [];
if (label === undefined) {
label = true;
}
if (value === undefined) {
value = true;
}
for (i = 0, len = arr[0].data.length; i < len; i += 1) {
sum = 0;
obj = {};
for (j = 0, len1 = arr.length; j < len1; j += 1) {
sum += arr[j].data[i].value;
}
if (label) {
obj.label = arr[0].data[i].label;
}
if (value) {
obj.value = sum;
}
componentArr.push(obj);
}
return componentArr;
}
function getSeriesNames() {
var arr = getData(),
seriesName = [];
for (i = 0, len = arr.length; i < len; i += 1) {
seriesName.push({
"label": arr[i].seriesname
});
}
return seriesName;
}
function getMode() {
var e = document.getElementById("interaction");
return e.options[e.selectedIndex].value;
}
FusionCharts.ready(function() {
var lastClickedId = true;
var pieChart = new FusionCharts({
type: 'pie2d',
renderAt: 'pieContainer',
width: '600',
height: '400',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Expenditures Incurred in Publishing a Book",
"subCaption": "Component-wise BreakUp",
"enableMultiSlicing": "0",
"bgcolor": "FFFFFF",
"showvalues": "1",
"showpercentvalues": "1",
"showborder": "0",
"showplotborder": "0",
"showlegend": "1",
"legendborder": "0",
"legendposition": "bottom",
"enablesmartlabels": "1",
"use3dlighting": "0",
"showshadow": "0",
"legendbgcolor": "#CCCCCC",
"legendbgalpha": "20",
"legendborderalpha": "0",
"legendshadow": "0",
"legendnumcolumns": "3",
"palettecolors": "#f8bd19,#e44a00,#008ee4,#33bdda,#6baa01,#583e78"
},
"data": getComponents()
},
"events": {
"dataplotClick": function(eventObj, dataObj) {
if (getMode() === 'pie') {
var json = stackedChart.getJSONData(),
categoryLabel = dataObj.categoryLabel;
json.chart.subCaption = "BreakUp of " + categoryLabel + " in different product";
json.categories[0].category = getSeriesNames();
json.dataset = getValues(dataObj.categoryLabel);
stackedChart.setJSONData(json);
}
}
}
}).render();
var stackedChart = new FusionCharts({
type: 'stackedBar2D',
renderAt: 'barContainer',
width: '600',
height: '400',
dataFormat: 'json',
dataSource: {
"chart": {
"bgcolor": "FFFFFF",
"outcnvbasefontcolor": "666666",
"caption": "Expenditures Incurred in Publishing a Book",
"subCaption": "Product-wise BreakUp",
"xaxisname": "Expenditures Cost",
"yaxisname": "Cost",
"numberprefix": "$",
"showvalues": "0",
"numvdivlines": "10",
"showalternatevgridcolor": "1",
"alternatevgridcolor": "e1f5ff",
"divlinecolor": "e1f5ff",
"vdivlinecolor": "e1f5ff",
"basefontcolor": "666666",
"tooltipbgcolor": "F3F3F3",
"tooltipbordercolor": "666666",
"canvasbordercolor": "666666",
"canvasborderthickness": "1",
"showplotborder": "1",
"plotfillalpha": "80",
"showborder": "0",
"legendbgcolor": "#CCCCCC",
"legendbgalpha": "20",
"legendborderalpha": "0",
"legendshadow": "0",
"legendnumcolumns": "3"
},
"categories": [{
"category": getComponents(true, false)
}],
"dataset": getData()
},
"events": {
"dataplotClick": function(eventObj, dataObj) {
if (getMode() === 'stackedBar') {
var JSON = pieChart.getJSONData(),
categoryLabel = dataObj.categoryLabel;
JSON.chart.subCaption = "BreakUp of " + categoryLabel + " in different product";
JSON.data = getProducts(categoryLabel);
pieChart.setJSONData(JSON);
pieChart.slicePlotItem(dataObj.datasetIndex);
}
}
}
}).render();
function resetFN() {
var json = pieChart.getJSONData();
json.chart.subCaption = "Component-wise BreakUp";
json.data = getComponents();
pieChart.setJSONData(json);
json = stackedChart.getJSONData();
json.chart.subCaption = "Product-wise BreakUp";
json.categories[0].category = getComponents(true, false);
json.dataset = getData();
stackedChart.setJSONData(json);
}
document.getElementById('reset').addEventListener('click', resetFN);
document.getElementById('interaction').addEventListener('change', resetFN);
});
h4 {
font-size: 20px;
margin-bottom: 10px
}
.intro {
margin: 0 auto;
background-color: #fff280;
padding: 15px
}
em {
font-style: italic
}
#interactionWrapper {
margin: 5px 10px;
}
button {
border: 1px solid #0b77bc;
background-color: #0d83ce;
color: #ffffff;
margin: 10px 0 0 15px;
padding: 5px 10px;
font-size: 14px;
cursor: pointer
}
.centerAlign {
text-align: center;
}
<script src="http://static.fusioncharts.com/code/latest/fusioncharts.js"></script>
<script src="http://static.fusioncharts.com/code/latest/themes/fusioncharts.theme.fint.js"></script>
<div class="intro">
<h4>Expenditures incurred while publishing books</h4>
<p><em>A company has 6 books to publish for this quater. The stacked chart shows component prices stacked as per different books. While the pie chart, shows the cumilative component price.</em></p>
<p>
<em>There are two interaction modes - namely "Interact in stacked chart" and "Interact in pie chart".On clicking in any plot on stacked chart, it shows the book-wise distribution of that component in the pie chart. Whereas on clicking the pie chart, for a component being clicked, it shows the book-wise distribution in the bar chart</em>
</p>
</div>
<div id="interactionWrapper">
<span>Interaction Mode:</span>
<span>
<select id="interaction">
<option value="stackedBar">Interact in stacked bar</option>
<option value="pie">Interact in the pie chart</option>
</select>
</span>
</div>
<div class="centerAlign">
<span id="barContainer">FusionCharts XT will load here!</span>
<span id="pieContainer">FusionCharts XT will load here!</span>
</div>
<button id="reset">Reset</button>
I need to create a multi leveled that is dynamic because I have to drill down to hundreds or even thousands of data providers that will load from the database. The flow goes like this: I have 1, 2, 3, 4, and 5 years that will drill down to 16 Departments each and will drill down to Courses 10 or more courses. Doing it manually is tedious and I need it to be dynamic. Please help me.
The variables:
var ccs_final_data = AmCharts.loadJSON("<?php echo base_url();?>index.php/osa/final_ccs_data");
//VAR CCS AVERAGE_FINAL
var drill_down_to_ccs_courses_average_final = AmCharts.loadJSON("<?php echo base_url();?>index.php/osa/ccs_courses_data_average_final");
var drill_down_to_ccs_sections_BSIT_average_final = AmCharts.loadJSON("<?php echo base_url();?>index.php/osa/ccs_sections_data_BSIT_average_final");
var drill_down_to_ccs_sections_ACT_average_final = AmCharts.loadJSON("<?php echo base_url();?>index.php/osa/ccs_sections_data_ACT_average_final");
var drill_down_to_ccs_sections_BSCS_average_final = AmCharts.loadJSON("<?php echo base_url();?>index.php/osa/ccs_sections_data_BSCS_average_final");
The graph:
var chart2 = AmCharts.makeChart( "ccs2", {
"theme": "light",
type: "serial",
pathToImages: "http://cdn.amcharts.com/lib/3/images/",
dataProvider: ccs_final_data,
categoryField: "category",
categoryAxis: {
labelRotation: 0,
gridPosition: "start"
},
valueAxes: [ {
title: "CCS FINAL TERM - Passing"
} ],
graphs: [ {
valueField: "value",
colorField: "color",
type: "column",
lineAlpha: 100,
fillAlphas: 1
} ],
chartScrollbar: {
"updateOnReleaseOnly": true
},
chartCursor: {
bulletsEnabled: "enabled",
bulletSize: 15,
cursorAlpha: 100,
cursorColor: "#CC0000",
zoomable: true,
categoryBalloonEnabled: true
},
export: {
enabled: true
}
} );
Here's the drill down stuff:
chart2.addListener("clickGraphItem", function (event) {
if(event.item.category == "Average"){
event.chart.dataProvider = drill_down_to_ccs_courses_average_final;
event.chart.validateData();
chart2.addListener("clickGraphItem", function (event) {
if(event.item.category == "BSIT"){
event.chart.dataProvider = drill_down_to_ccs_sections_BSIT_average_final;
event.chart.validateData();
}
else if(event.item.category == "ACT"){
event.chart.dataProvider = drill_down_to_ccs_sections_ACT_average_final;
event.chart.validateData();
}
else if(event.item.category == "BSCS"){
event.chart.dataProvider = drill_down_to_ccs_sections_BSCS_average_final;
event.chart.validateData();
}
});
}
I'd say the best way to make it dynamic is to include some custom field for each data point in your data that would be passed in to server-side script so it knows which data to load.
I'm assuming your data looks like this now:
[ {
"category": "BSIT",
"value": 100
}, {
"category": "ACT",
"value": 200
}, {
"category": "BSCS",
"value": 150
} ]
You could easily add a third field to hold the information for drill-down data load:
[ {
"category": "BSIT",
"value": 100,
"drill": "ccs_sections_data_BSIT_average_final"
}, {
"category": "ACT",
"value": 200,
"drill": "ccs_sections_data_ACT_average_final"
}, {
"category": "BSCS",
"value": 150,
"drill": "ccs_sections_data_BSCS_average_final"
} ]
Then, when clickGraphItem event occurs, you could just take that info and pass it to load script dynamically:
chart2.addListener( "clickGraphItem", function( event ) {
if ( event.item.dataContext.drill !== undefined ) {
event.chart.dataProvider = AmCharts.loadJSON( "<?php echo base_url();?>index.php/osa/" + event.item.dataContext.drill );
event.chart.validateData();
}
} );
This way, you could have any number of drill-down levels, with each level data containing info about where to look for the data for the next level.
Also, I'm not sure as you haven't posted the code for it, so I'm assuming that AmCharts.loadJSON method is synchronous. If it's not (for example if you are using method from Data Loader), you will need to assign the chart's dataProvider after the data is loaded.
i am passing data as JSON to highcharts this JSON comes from a java method so i cant change this...so please dont suggest to change JSON format...
my code for highchart is below...
var json = [{
"value": 12,
"name": "platform1",
"key": "event4"
}, {
"value": 10,
"name": "platform1",
"key": "event1"
}, {
"value": 14,
"name": "platform1",
"key": "event3"
}, {
"value": 9,
"name": "platform1",
"key": "event2"
}, {
"value": 13,
"name": "platform3",
"key": "event4"
}, {
"value": 13,
"name": "platform3",
"key": "event1"
}];
var processed_json = new Array();
$.map(json, function (obj, i) {
processed_json.push([obj.key, parseInt(obj.value), obj.name]);
});
$('#container').highcharts({
chart: {
type: 'column'
},
xAxis: {
type: "category"
},
tooltip: {
formatter: function () {
return 'Branch: <b>' + this.series.name +
'</b><br/>Platform: ' + this.point.y;
}
},
series: [{
name: 'Data',
data: processed_json
}]
});
i am trying to put platform name on the tooltip as i hover over...but i can not find any way to do that...plus is there any way i can create legends as number of platforms...right now i only have one legend named "Data".
jfiddle can be found here : http://jsfiddle.net/QTJb7/
You need to use object instead of array, in point definition and add paramter in your $.map.
$.map(json, function (obj, i) {
processed_json.push({name: obj.key,y: parseInt(obj.value),customName : obj.name });
});
tooltip:
tooltip: {
formatter: function () {
return 'Branch: <b>' + this.series.name +
'</b><br/>Platform: ' + this.point.name + ' <br> name ' + this.point.customName;
}
},
http://jsfiddle.net/QTJb7/1/