Chart.js - get base 64 encoded string as variable - javascript

I'm creating a chart using the Chart.js library and it's working well. I'm using the .toBase64Image() function to generate a base 64 encoded string of the chart (png data url).
I can see this when I inspect the chart in my browser developer tools, e.g.:
data:image/png;base64,iVBORw0KGgoAAAA etc
I now need to call a URL to another application that will pass the data url as a parameter - I'm just stuck at how to get the data url as a parameter to pass to my URL that I will then call.
Here's my script as it currently stands:
var radarChartData = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [3, 2, 1, 5, 6, 8, 5]
},
]
};
window.onload = function() {
window.myRadar = new Chart(document.getElementById("canvas").getContext("2d")).Radar(radarChartData, {
responsive: true,
scaleOverride: true,
scaleSteps: 10,
scaleStepWidth: 1,
scaleStartValue: 0,
onAnimationComplete: function() {
document.getElementById("canvas").innerHTML = myRadar.toBase64Image();
theURL = "fmp://$/chartingFile?script=getChartToContainer&param=";
window.location = theURL;
}
});
}
I need to append the "data:image/png;base64,iVBORw0KGgoAAAA" string to the 'theURL' variable but can't figure out how to get this as a string?

Managed to work this out as follows:
onAnimationComplete: function() {
document.getElementById("canvas").innerHTML = myRadar.toBase64Image();
var x = document.getElementById("canvas").innerHTML = myRadar.toBase64Image();
theParam = encodeURIComponent(x);
theURL = "fmp://$/chartingFile?script=getChartToContainer&param=" + theParam;
window.location = theURL;
Not sure if it's optimal etc but it's working well so far.

Related

Dynamically generated dropdown list breaks web service call

I have an ASPX dropdown list, that is used in a web service call to generate a graph.
If I manually enter the drop down list entries, the code executes fine, however if I dynamically generate the dropdown list from the SQL server the web service call fails.
Here is how I am generating the dropdown list:
//Populate Customers DDL
string constr = ConfigurationManager.ConnectionStrings["Indigo2.Properties.Settings.ConstrNW"].ConnectionString;
DataTable customers = new DataTable();
using (SqlConnection con = new SqlConnection(constr))
{
try
{
SqlDataAdapter adapter = new SqlDataAdapter("SELECT DISTINCT custid from [Indigo].[dbo].[invoices] WHERE custid='ACC001'", con);
adapter.Fill(customers);
//ddlCustA.DataSource = customers;
//ddlCustA.DataTextField = "custid";
//ddlCustA.DataValueField = "custid";
//ddlCustA.DataBind();
}
catch (Exception ex)
{
// Handle the error
}
}
Here is the HTML
<asp:DropDownList ID="ddlCustA" runat="server" Height="17px" Width="100px" AutoPostBack="True">
</asp:DropDownList>
This is where I call the Web Service
//Code for graph (all in document ready)
$("#btn_line_chart").on('click', function () {
var CustA = $("#ddlCustA").val();
var CustB = $("#ddlCustB").val();
var getYear = $("#ddlYear").val();
var jsonData = JSON.stringify({
custA: CustA,
custB: CustB,
year: getYear
});
$.ajax({
type: "POST",
url: "WebService1.asmx/getLineChartData",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess_,
error: OnErrorCall_
});
function OnSuccess_(reponse) {
var aData = reponse.d;
var aLabels = aData[0];
var aDatasets1 = aData[1];
var aDatasets2 = aData[2];
var data = {
labels: aLabels,
datasets: [{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: aDatasets1
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: aDatasets2
}]
};
var ctx = $("#myChart").get(0).getContext('2d');
ctx.canvas.width = 750; // setting width of canvas
ctx.canvas.height = 400; // setting height of canvas
var lineChart = new Chart(ctx, {
type: "line",
data: data,
bezierCurve: false
});
}
function OnErrorCall_(repo) {
alert("Woops something went wrong, pls try later !");
}
});
If I manually choose the dropdown list options (like below), it works fine.
<select id="ddlCustA">
<option>ACC001</option>
</select>
When the dropdown list is generated from the SQL server, the web service call fails with the folowing error:
HTTP500: SERVER ERROR - The server encountered an unexpected condition
that prevented it from fulfilling the request. (XHR)POST -
https://localhost:44338/WebService1.asmx/getLineChartData
Any help greatly appreciated.
UPDATE: It seems to be a timing issue. If I add an alert just before the web service calls the ddlCustA variable, ddlCustA shows as "Undefined"
alert($("#ddlCustA").val());
In case it helps anyone else, my solution was the way I was calling the object from Javasctipt. The below code fixed it.
var CustA = document.getElementById('<%= ddlCustA.ClientID %>').value

Looping inside variable (json data)

Anyone know how looping json data INSIDE varibale?? Example
var data = {
$.each(data, function(i, item) {
console.log(data[i].PageName);
});​
labels: [dateLoop],
datasets: [{
}]
};
Well that code is didnt work for me. I want looping inside that varibale. Anyway this coding for Chart.js
Why i need looping?? cuase i have filter buyer and date range, if i choose 3 buyer, and date range from january 2016 to May 2016. On data will show data buyer, each data buyer will have value from date range. Exmaple data json
data [Buyer 1] : ["167404", "129770", "113598", "127301", "156868", "634789", "242188", "166312", "169418"];
data [Buyer 2] : ["9580", "22250", "3500", "5558", "254556", "268500", "77750", "69850", "55"];
So what i need how too looping inside variable?? Sorry my bad languange.
Edit probbaly someone dont know what i mean,
example i have pick 2 buyer, Buyer A (Json["data"][0]) and Buyer B (Json["data"][1]) and each that buyer have value (wich this value order by month if i pick January and May, it will show "222","555")
and the code i mean like this :
var data = {
labels: [dateLoop], #ignore this
datasets: [{ label : (Json["data"][0])
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [(value orderby month in Json["data"][0]]
},
{ label : (Json["data"][1])
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [(value orderby month in Json["data"][1]]
}
]
};
That i want it. But i sue each make error. :/
try this, you need 2 loop first loop is for keys and second is for the values inside array
var data = {
'Buyer 1': ["167404", "129770", "113598", "127301", "156868", "634789", "242188", "166312", "169418"],
'Buyer 2': ["9580", "22250", "3500", "5558", "254556", "268500", "77750", "69850", "55"]
}
for(var key in data) {
for (var x in data[key]) {
console.log(data[key][x]);
}
}

Chart.js custom tooltipTemplate index

I have this chart made with Chart.js.
var data = {
labels: ["", "", "", "2015-08-28", "2015-08-29", "2015-08-30", "2015-08-31", ],
websites: ["", "", "", "gamesoutletCrawler", "gamesoutletCrawler", "G2PLAY", "instantgaming", ],
datasets: [{
label: "Best price last 7 days",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [0, 0, 0, 34.5, 36.8, 37.3, 37.99, ]
}]
};
window.onload = function() {
var ctx = document.getElementById("chartkeys").getContext("2d");
window.myLine = new Chart(ctx).Line(data, {
responsive: true,
tooltipTemplate: "<%= data.websites[idx] %>",
scaleLabel: "<%= Number(value).toFixed(2).replace('.', ',') + ' €'%>"
});
}
On my tooltip template, I want to use values from data.websites but I don't know how to pass in the index for my tooltip array. This is not working:
<%= data.websites[idx] %>
idx is wrong, it's not the index the system is using. Any idea what I have to write here to show the index tooltip when you hover on the graph?
If I write <%= data.websites %>, it's showing me all the websites in the array, not the one hovered.
You can use a function instead of a template string
...
tooltipTemplate: function (d) {
return data.websites[data.labels.indexOf(d.label)]
},
...
Note that this requires the labels to be unique, or if there are duplicate labels that it not matter which one is active (for instance, in your data, the first 3 labels are the same but that won't cause any problems because the first 3 entries in the websites array too are the same. If they were different this method will not work)

Avoid data resetting when toggling series

In this fiddle when you toggle a serie the others reset to their inital values, instead of adding new values to themselves.
How to avoid this behaviour?
You need to store the current state of the data for each series before blanking or resetting the corresponding dataset in enableCheck. Then use this saved state.
Example for the SP dataset
Initialization of the state (spData). I also initialize the dataset (SP)
var spData = [1, 2, 3, 4, 5, 6, 7, 8]
var SP = {}
Saving the state (in enableCheck()) - I get the values from the actual data points
if (SP.data) currentChart.datasets.forEach(function (d) {
if (d.label === 'My First dataset') {
spData = d.points.map(function (e) {
return e.value
});
}
})
Using this saved state (in enableCheck())
SP = {
label: "My First dataset",
fillColor: "rgba(0,0,0,0)",
strokeColor: "rgba(220,0,0,1)",
pointColor: "rgba(220,0,0,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,0,0,1)",
data: spData
};
And if you want the new values to be inserted for the hidden series as well, update your data insertion statements in your setTimeout
var d = []
if (First) d.push(randomScalingFactor())
else {
spData.shift()
spData.push(randomScalingFactor())
}
if (Second) d.push(randomScalingFactor())
else {
ncData.shift()
ncData.push(randomScalingFactor())
}
if (Third) d.push(randomScalingFactor())
else {
spaData.shift()
spaData.push(randomScalingFactor())
}
Working fiddle - http://jsfiddle.net/Lsg37amf/

Chart.js - Where to put global chart configuration?

I am trying to set up a Chart.js line graph with the following code. Where in this do I place the Chart.defaults.global = {} or Chart.defaults.global.responsive = true; code?
Chart.js docs can be found here: http://www.chartjs.org/docs/
<!-- Chart.js -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js"></script>
<script>
var ctx = document.getElementById("myChart").getContext("2d");
var data = {
labels: ["Week 1", "Week 2", "Week 3", "Week 4", "Week 5", "Week 6", "Week 7"],
datasets: [
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [86, 74, 68, 49, 42]
}
]
};
var options = {
...
};
var myLineChart = new Chart(ctx).Line(data, options);
</script>
There are two ways to accomplish what you're looking for. This way
var myLineChart = new Chart(ctx).Line(data, options);
var options = Chart.defaults.global = {
responsive: true,
maintainAspectRatio: true
};
or, this way
var myLineChart = new Chart(ctx).Line(data, {
responsive: true,
maintainAspectRatio: true
});
However, to make it responsive you'll have to add some extra CSS
canvas{
width: 100% !important;
height: auto !important;
}
so there's no need for inline CSS
Working demo
In accordance with the comment of #JustinXL below and the latest version of Chart.js there's no need for extra CSS, so check out the updated version.
Updated demo
You could set the options of your chart, but you can also set the global (as you asked) to avoid setting this specific property for each chart you want to instantiate.
You just have to set
Chart.defaults.global.elements.responsive = true;
before instantiating the chart, in your case, before
var myLineChart = new Chart(ctx).Line(data, options);
(P.S.: Chartjs V2)

Categories

Resources