Reputation: 796
I am trying to load in data from two Viewbags one containing data for a barchart and the other containing data for a linechart both of which contain data from a database query the code that I am using is shown below:
var outcomeData = "@Html.Raw(@ViewBag.ChartOutput)";
var avgDaysUseData = "@Html.Raw(@ViewBag.AvgDaysUseChartOutput)";
var outcomeArray = outcomeData.replace(/\[/g, "").replace(/\]/g, "").replace(/\'/g, "").split(',');
var avgDaysUseArray = avgDaysUseData.replace(/\[/g, "").replace(/\]/g, "").replace(/\'/g, "").split(',');
var reportingPeriods = [];
var outcomeNames = [];
var outcomeValues = [];
var avgDaysUseValues = [];
$.each(avgDaysUseArray,
function (index, value) {
if (Number.isNaN(value) === false) {
value = parseFloat(value);
avgDaysUseValues.push(value);
}
});
$.each(outcomeArray,
function (index, value) {
var reportingPeriod = new RegExp('\\d{4}(\/)\\d{2}');
var isReportingPeriod = reportingPeriod.test(value);
if (isReportingPeriod) {
reportingPeriods.push(value);
}
else {
var outcomeName = new RegExp('[a-zA-Z]');
var isOutcomeName = outcomeName.test(value);
if (isOutcomeName) {
if (value !== "Outcomes") {
outcomeNames.push(value);
}
} else {
value = parseInt(value);
outcomeValues.push(value);
}
}
});
var ctx = document.getElementById('chart');
var outcomeChart = new Chart(ctx,
{
type: 'bar',
data: {
labels: reportingPeriods,
datasets: [
{
type: 'line', fill: false, lineTension: 0,
label: 'Average days of use at start',
data: [avgDaysUseValues[4], avgDaysUseValues[7], avgDaysUseValues[10]],
yAxisId: 'y-axis-1',
borderColor: 'Black',
backgroundColor: 'Black',
borderWidth: 2
},
{
type: 'line', fill: false, lineTension: 0,
label: 'Average days of use at review',
data: [avgDaysUseValues[5], avgDaysUseValues[8], avgDaysUseValues[11]],
yAxisId: 'y-axis-1',
borderColor: 'Blue',
backgroundColor: 'Blue',
borderWidth: 2
},
{
type: 'bar',
label: outcomeNames[0],
data: [outcomeValues[0], outcomeValues[4], outcomeValues[8]],
yAxisID: 'y-axis-2',
borderColor: '#FF9900',
backgroundColor: '#FF9900',
borderWidth: 2
},
{
type: 'bar',
label: outcomeNames[1],
data: [outcomeValues[1], outcomeValues[5], outcomeValues[9]],
yAxisID: 'y-axis-2',
borderColor: '#FF6400',
backgroundColor: '#FF6400',
borderWidth: 2
},
{
type: 'bar',
label: outcomeNames[2],
data: [outcomeValues[2], outcomeValues[6], outcomeValues[10]],
yAxisID: 'y-axis-2',
borderColor: '#FF0000',
backgroundColor: '#FF0000',
borderWidth: 2
},
{
type: 'bar',
label: outcomeNames[3],
data: [outcomeValues[3], outcomeValues[7], outcomeValues[11]],
yAxisID: 'y-axis-2',
borderColor: '#9A0033',
backgroundColor: '#9A0033',
borderWidth: 2
}
]
},
options: { scales: {
xAxes: [
{
gridLines: {
display: false
},
scaleLabel: { display: true, labelString: 'Reporting Period', fontStyle: 'italic' },
position: 'bottom',
ticks: { fontStyle: 'italic' },
barPercentage: 0.95,
categoryPercentage: 0.15
}
],
yAxes: [
{
scaleLabel: { display: true, labelString: 'Average no. of days', fontStyle: 'italic' },
position: 'right', id: 'y-axis-1', type: 'linear',
ticks: { min: 0, beginAtZero: true, max: 28 },
gridLines: {display: true}
},
{
scaleLabel: { display: true, labelString: 'No. of clients', fontStyle: 'italic' },
position: 'left', id: 'y-axis-2',type: 'linear',
gridLines: { display: false }
}]
},
responsive: true,
maintainAspectRatio: false,
legend: {
position: 'right',
display: true,
onClick: null,
labels: {
fontColor: '#000000'
}
}
}
});
outcomeChart.aspectRatio = 0;
$('#chart').bind('contextmenu',
function(e) {
return false;
});
I have provided a working example in a codepen to show what is being produced and how I want it to look, the example data I have provided in codepen is what is contained in the ViewBag:
https://codepen.io/gameloregeek/pen/GPXBdp
How do I use the data in the two viewbags to create a multichart like the example in codepen?
as examples here is the format of the data in each viewbag:
Bar chart data
var outcomeData = "['Outcomes','Abstinent','Improved','Unchanged','Deteriorated'],['2015/16',18036,11414,14430,1880],['2016/17',17642,11688,14010,1738],['2017/18',17282,10796,13542,1686]";
Line chart data
var avgDaysUseData = "['year','AvgDaysUseAtStart','AvgDaysUseAtReview'],['2015/16',21.6,8.3],['2016/17',22.2,8.5],['2017/18',22.1,8.6]";
Have revised my code but I can't use the Json Encoded data as it contains values that include forward slashes which are being interpreted as escape values:
<script type="text/javascript">
var outcomeData = "@Html.Raw(Json.Encode(@ViewBag.ChartOutput))";
var avgDaysUseData = "@Html.Raw(Json.Encode(@ViewBag.AvgDaysUseChartOutput))";
outcomeArray = [];
for (var i = 0; i < outcomeData.length; i++) {
outcomeArray[i] = outcomeData[i];
}
var ctx = document.getElementById('chart');
var outcomeChart = new Chart(ctx,
{
type: 'bar',
data: outcomeArray,
options: { scales: {
xAxes: [
{
gridLines: {
display: false
},
scaleLabel: { display: true, labelString: 'Reporting Period', fontStyle: 'italic' },
position: 'bottom',
ticks: { fontStyle: 'italic' },
barPercentage: 0.95,
categoryPercentage: 0.15
}
],
yAxes: [
{
scaleLabel: { display: true, labelString: 'Average no. of days', fontStyle: 'italic' },
position: 'right', id: 'y-axis-1', type: 'linear',
ticks: { min: 0, beginAtZero: true, max: 28 },
gridLines: {display: true}
},
{
scaleLabel: { display: true, labelString: '@Model.XAxis', fontStyle: 'italic' },
position: 'left', id: 'y-axis-2',type: 'linear',
gridLines: { display: false }
}]
},
responsive: true,
maintainAspectRatio: false,
legend: {
position: 'right',
display: true,
onClick: null,
labels: {
fontColor: '#000000'
}
}
}
});
outcomeChart.aspectRatio = 0;
$('#chart').bind('contextmenu',
function(e) {
return false;
});
</script>
the data after encoding looks like this:
var outcomeData = ""[\u0027Outcomes\u0027,\u0027Abstinent\u0027,\u0027Improved\u0027,\u0027Unchanged\u0027,\u0027Deteriorated\u0027],[\u00272015/16\u0027,18036,11414,14430,1880],[\u00272016/17\u0027,17642,11688,14010,1738],[\u00272017/18\u0027,17282,10796,13542,1686]"";
and the error in the console is as follow SyntaxError: invalid escape sequence
Upvotes: 0
Views: 554
Reputation: 3952
If it is an C# Array in the ViewBag:
var outcomeData = @Html.Raw(Json.Encode(@ViewBag.ChartOutput));
use Json.Encode
and Html.Raw
Usefull Links:
If it is a String in the Viewbag: You can use the value from the ViewBag in JS like this:
var outcomeData = '@ViewBag.ChartOutput';
then you dont need the Html.Raw
Upvotes: 1