I have created box plot chart dynamically but would like to add a tooltip to the box plot chart so that when user mouse over the box plot series, the box plot series values will be displayed out in tooltip.
This is my code to create box plot chart:
Chart Chart1= new Chart();
Chart1.DataSource = dt;
Chart1.Width = 800;
Chart1.Height = 490;
Chart1.Series.Add(new Series());
Chart1.Series[0].ChartType = SeriesChartType.BoxPlot;
Chart1.Series.Add(new Series());
Chart1.Series[1].ChartType = SeriesChartType.Point;
List<object> List1 = dt.AsEnumerable().ToList<object>();
int Chart1_AVG = 0;
int Chart1_POINTINDEX = 0;
foreach (DataRow row in dt.Rows)
{
Chart1_AVG = (int)row["AVG"];
Chart1.Series[0].Points.AddXY(row["CUSTOMER"], new object[] { row["MIN"], row["MAX"], row["25TH_PCT_NUMBER"], row["75TH_PCT_NUMBER"], row["50TH_PCT_NUMBER"], row["AVG"] });
Chart1_POINTINDEX = Chart1.Series[1].Points.AddXY(row["CUSTOMER"], new object[] { row["AVG"] });
if ((Chart1_AVG >= AvgMinColorGreen) && (Chart1_AVG <= AvgMaxColorGreen))
{
Chart1.Series[1].Points[Chart1_POINTINDEX].MarkerColor = Color.Green;
}
else if ((Chart1_AVG >= AvgMinColorYellow) && (Chart1_AVG <= AvgMaxColorYellow))
{
Chart1.Series[1].Points[Chart1_POINTINDEX].MarkerColor = Color.Orange;
}
else if ((Chart1_AVG >= AvgMinColorRed) && (Chart1_AVG <= AvgMaxColorRed))
{
Chart1.Series[1].Points[Chart1_POINTINDEX].MarkerColor = Color.Red;
}
}
Chart1.Series[0]["BoxPlotShowMedian"] = "false"; //hide the average point
//create chartareas
ChartArea ca= new ChartArea();
//databind
Chart1.DataBind();
Chart1.Visible = true;
panel.Controls.Add(Chart1);
Please help me on this, thanks.
Use this
Chart1.Series[0].ToolTip = "#VAL"
Other possible tooltips are LegendToolTip, LabelToolTip ...
For keywords see https://msdn.microsoft.com/de-de/library/vstudio/dd456687%28v=vs.110%29.aspx
Related
On a horizontal bar chart, being fed from an external data source, I need to change the data values to text (for display purposes) on the valueAxis labels and tooltip text.
I've managed to find a way to change the valueAxis labels, which seems to work (although not sure if it's best practice?).
But I'm struggling to change the text on the valueAxis tooltip and series tooltip, as shown in the screenshot, where "3" needs to display as "FAIRLY IMPORTANT" as well as the other values when hovering over the chart.
EDIT
I've added this code which calls the amCharts adapter, and returns the valueAxis text as XXXXXX, but the target values are not working as they should.
I can't see where I'm going wrong though?
// This Adapter is to change the text in the valueAxis Tooltip
valueAxis.adapter.add("getTooltipText", (text, target) => {
if (target.dataItem && (target.dataItem.value == 0)) {
return "NOT NEEDED";
}
if (target.dataItem && (target.dataItem.value == 1)) {
return "UNSURE";
}
if (target.dataItem && (target.dataItem.value == 3)) {
return "NICE TO HAVE";
}
if (target.dataItem && (target.dataItem.value == 5)) {
return "MUST HAVE";
}
else {
return "XXXXXX";
}
});
Quick summary below.
The data source comes in as...
"Name": "Photographer",
"Category A": 3,
"Category B": 5,
"Category C": 1,
"Category D": 0,
"Category E": 3
On the chart, I want to display the numeric values as text...
0 to display as FAIRLY IMPORTANT
1 to display as NOT SURE
3 to display as FAIRLY IMPORTANT
5 to display as VERY IMPORTANT
Here's my code (so far) which I need to clean up a bit once I've finished working on it...
// Create chart instance
var chart = am4core.create("CHARTDIV", am4charts.XYChart);
// base64 encoded version of sample data as a data URI
function dataURI() {
return "data:application/json;base64,ewogICJyZWNvcmRzIjogWwogICAgewogICAgICAiaWQiOiAxLAogICAgICAiZmllbGRzIjogewogICAgICAgICJOYW1lIjogIlBob3RvZ3JhcGhlciIsCiAgICAgICAgIkNhdGVnb3J5IEEiOiAzLAogICAgICAgICJDYXRlZ29yeSBCIjogNSwKICAgICAgICAiQ2F0ZWdvcnkgQyI6IDEsCiAgICAgICAgIkNhdGVnb3J5IEQiOiAwLAogICAgICAgICJDYXRlZ29yeSBFIjogMwogICAgICB9LAogICAgICAiY3JlYXRlZFRpbWUiOiAiMjAxOC0wNC0xMlQxNzoyNzowNi4wMDBaIgogICAgfQogIF0KfQ==";
}
// Add data
chart.dataSource.url = dataURI(); //fake URL for demonstration purposes
// Always needed when using Airtable JSON output for amCharts compatibility
chart.dataSource.events.on("parseended", function(ev) {
// parsed data is assigned to data source's `data` property
ev.target.data = ev.target.data.records.map(function(dataItem) {
return {
"Category A": dataItem.fields["Category A"],
"Category B": dataItem.fields["Category B"],
"Category C": dataItem.fields["Category C"],
"Category D": dataItem.fields["Category D"],
"Category E": dataItem.fields["Category E"],
"Name": dataItem.fields.Name
}
});
});
// Needed when the Airtable rows and columns need transposing
chart.dataSource.events.on("parseended", function(ev) {
var questionMap = {}; //lookup table to map questions to data elements
ev.target.data.forEach(function(item) {
Object.keys(item).forEach(function(key) {
if (key.indexOf('Name') == -1) { //act on non-response keys
if (!questionMap[key]) {
questionMap[key] = {
"Name": key
}; //create an object containing the name/question pair if it doesn't exist
}
questionMap[key][item.Name] = item[key]; // assign response+value to the object (e.g. "Must Have": 75)
}
});
});
//remap lookup table as array
ev.target.data = Object.keys(questionMap).map(function(question) {
return questionMap[question];
});
});
// Set cell size in pixels
var cellSize = 50;
chart.events.on("datavalidated", function(ev) {
// Get objects of interest
var chart = ev.target;
var categoryAxis = chart.yAxes.getIndex(0);
// Calculate how we need to adjust chart height
var adjustHeight = chart.data.length * cellSize - categoryAxis.pixelHeight;
// get current chart height
var targetHeight = chart.pixelHeight + adjustHeight;
// Set it on chart's container
chart.svgContainer.htmlElement.style.height = targetHeight + "px";
});
// Create category axes
var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "Name";
categoryAxis.renderer.grid.template.location = 0;
// Bar or column width for category axis
categoryAxis.renderer.cellStartLocation = 0.1;
categoryAxis.renderer.cellEndLocation = 0.9;
// Create value axes
var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());
valueAxis.numberFormatter.numberFormat = "#";
valueAxis.min = 0;
valueAxis.max = 6;
valueAxis.cursorTooltipEnabled = true;
// Create value axes - LABELS DISABLED
valueAxis.renderer.grid.template.disabled = true;
valueAxis.renderer.labels.template.disabled = true;
// Create value axes - DEFINE GRID LINES
function createGrid(value) {
var range = valueAxis.axisRanges.create();
range.value = value;
range.label.text = "";
}
createGrid(0);
createGrid(1);
createGrid(3);
createGrid(5);
createGrid(6);
// Create value axes - DEFINE GRID LABELS
function createLabel(value, label, location) {
var range = valueAxis.axisRanges.create();
range.value = value;
range.grid.strokeOpacity = 0;
range.label.location = location | 0;
range.label.dataItem.text = label;
range.label.fillOpacity = 1;
}
createLabel("0", "NOT IMPORTANT");
createLabel("1", "NOT SURE");
createLabel("3", "FAIRLY IMPORTANT");
createLabel("5", "VERY IMPORTANT");
// This Adapter is to change the text in the valueAxis Tooltip
valueAxis.adapter.add("getTooltipText", (text, target) => {
if (target.dataItem && (target.dataItem.value >= 0)) {
return "NOT IMPORTANT";
}
if (target.dataItem && (target.dataItem.value == 1)) {
return "NOT SURE";
}
if (target.dataItem && (target.dataItem.value == 3)) {
return "FAIRLY IMPORTANT";
}
if (target.dataItem && (target.dataItem.value == 5)) {
return "VERY IMPORTANT";
}
else {
return "XXXXXX";
}
});
// Create series
function createSeries(field, name) {
// Set up series
var series = chart.series.push(new am4charts.ColumnSeries());
series.name = name;
series.dataFields.valueX = field;
series.dataFields.categoryY = "Name";
series.sequencedInterpolation = true;
// Make it stacked
series.stacked = true;
// Configure columns
series.tooltip.getFillFromObject = false;
series.tooltip.background.fill = am4core.color("#272d3a");
series.tooltip.background.strokeWidth = 0;
series.tooltipText = "{name}: [bold]{valueX}[/]";
series.tooltip.paddingTop = -1;
series.tooltip.fontSize = 16;
// Add label
var bullet = series.bullets.push(new am4charts.CircleBullet());
bullet.circle.stroke = am4core.color("#fff");
bullet.circle.strokeWidth = 2;
return series;
}
var series1 = createSeries("Photographer", "Photographer");
// Labels configuration for category axis
var categoryLabel = categoryAxis.renderer.labels.template;
categoryLabel.fill = am4core.color("#272d3a");
categoryLabel.fontSize = 16;
categoryLabel.fontWeight = 700;
categoryLabel.truncate = true;
// Labels configuration for value axis
var valueLabel = valueAxis.renderer.labels.template;
valueLabel.fill = am4core.color("#272d3a");
valueLabel.fontSize = 16;
// Tooltip configuration for category axis
var categoryTooltip = categoryAxis.tooltip;
categoryTooltip.background.fill = am4core.color("#272d3a");
categoryTooltip.fontSize = 16;
categoryTooltip.fontWeight = 700;
categoryTooltip.background.strokeWidth = 0;
categoryTooltip.background.cornerRadius = 3;
categoryTooltip.background.pointerLength = 4;
categoryTooltip.dy = 0;
categoryTooltip.dx = -2;
categoryTooltip.paddingTop = 0;
// Tooltip configuration for value axis
var valueTooltip = valueAxis.tooltip;
valueTooltip.background.fill = am4core.color("#272d3a");
valueTooltip.fontSize = 16;
valueTooltip.background.strokeWidth = 0;
valueTooltip.background.cornerRadius = 3;
valueTooltip.background.pointerLength = 4;
valueTooltip.dy = 2;
valueTooltip.dx = 0;
valueTooltip.paddingTop = 0;
// Tooltip configuration for value axis - DISABLED
valueTooltip.disabled = false;
// Add cursor
chart.cursor = new am4charts.XYCursor();
chart.cursor.behavior = "zoomXY";
chart.cursor.lineX.disabled = true;
<script src="//www.amcharts.com/lib/4/core.js"></script>
<script src="//www.amcharts.com/lib/4/charts.js"></script>
<div id="CHARTDIV" style="width: 100%; height: 600px;"></div>
I was struggling with something similar for that category axis, and found this tutorial: https://www.amcharts.com/docs/v4/tutorials/override-categoryaxis-tooltip-content-with-an-adapter/ that might help.
The relevant part:
categoryAxis.tooltip.label.adapter.add("text", function(text, target) {
if (target.dataItem) {
return target.dataItem.dataContext.axisLabel;
}
return text;
});
We were able to solve this like so:
import { ValueAxis } from "#amcharts/amcharts4/charts";
export default class CategoryValueAxis extends ValueAxis {
formatLabel(value) {
if (this.labelFunction) {
return this.labelFunction(value);
}
return super.formatLabel(value);
}
}
Simply define your labelFunction on the CategoryValueAxis when you inject it into the chart axes.
please, I'm trying to create with AmCharts 4 chart with multiple data sets. In previous version it is done this way: https://www.amcharts.com/demos/multiple-data-sets/
but I can't find anything how to make it in 4th version.
I use the code from their website.
Everything is ok, next chart I want to add in section starting with comment add ATR -> I need to show it under the original chart.
Thank you very much for any help.
Have a nice day!
var chart = am4core.create("candlestick-chart", am4charts.XYChart);
chart.paddingRight = 20;
// chart.dateFormatter.inputDateFormat = "YYYY-MM-dd";
chart.dateFormatter.inputDateFormat = "x";
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.grid.template.location = 0;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.tooltip.disabled = true;
/*
add default series
*/
var series = chart.series.push(new am4charts.CandlestickSeries());
series.dataFields.dateX = "date";
series.dataFields.valueY = "close";
series.dataFields.openValueY = "open";
series.dataFields.lowValueY = "low";
series.dataFields.highValueY = "high";
series.dataFields.atr = "atr";
series.dataFields.average_atr = "average_atr";
series.simplifiedProcessing = true;
series.tooltipText = "Open:${openValueY.value}\nLow:${lowValueY.value}\nHigh:${highValueY.value}\nClose:${valueY.value}\nATR:{atr.formatNumber('#.000')}\nAverage ATR:{average_atr.formatNumber('#.000')}";
series.riseFromPreviousState.properties.fillOpacity = 1;
series.dropFromPreviousState.properties.fillOpacity = 0;
chart.cursor = new am4charts.XYCursor();
/*
add scrollbar
*/
// a separate series for scrollbar
var scrollbarSeries = chart.series.push(new am4charts.LineSeries());
scrollbarSeries.dataFields.dateX = "date";
scrollbarSeries.dataFields.valueY = "close";
// need to set on default state, as initially series is "show"
scrollbarSeries.defaultState.properties.visible = false;
// hide from legend too (in case there is one)
scrollbarSeries.hiddenInLegend = true;
scrollbarSeries.fillOpacity = 0.5;
scrollbarSeries.strokeOpacity = 0.5;
var scrollbarX = new am4charts.XYChartScrollbar();
scrollbarX.series.push(scrollbarSeries);
chart.scrollbarX = scrollbarX;
/*
add ATR
-> I need to show it under the original chart
*/
var lineSeriesATR = chart.series.push(new am4charts.LineSeries());
lineSeriesATR.dataFields.dateX = "date";
lineSeriesATR.dataFields.valueY = "atr";
lineSeriesATR.defaultState.properties.visible = false;
// hide from legend too (in case there is one)
lineSeriesATR.hiddenInLegend = true;
lineSeriesATR.fillOpacity = 0.5;
lineSeriesATR.strokeOpacity = 0.5;
chart.data = {!! json_encode($candles) !!};
AmCharts 4 does not have the stock chart implemented yet. You can approximate panels and synced cursor and zoom by using the chart's containers to create additional charts and using the API to make the cursor and scrollbar affect all the charts.
You can create each chart and push them onto the chart container like so:
var container = am4core.create("chartdiv", am4core.Container); //create the container
container.width = am4core.percent(100); //set dimensions and layout
container.height = am4core.percent(100);
container.layout = "vertical";
// ... for each chart
var chart = container.createChild(am4charts.XYChart);
// ..set up as usual
While setting up each chart, you'll need to set up events to sync up zoom events:
// whenever any of the charts is zoomed, we should zoom all other charts
dateAxis.events.on("selectionextremeschanged", function (event) {
syncDateAxes(event.target);
})
// ...
function syncDateAxes(syncWithAxis) {
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
var dateAxis = chart.xAxes.getIndex(0);
if (dateAxis != syncWithAxis) {
dateAxis.events.disableType("selectionextremeschanged");
dateAxis.start = syncWithAxis.start;
dateAxis.end = syncWithAxis.end;
dateAxis.events.enableType("selectionextremeschanged");
}
}
}
You'll also want to set up each chart's cursor and sync each of them up:
function initCursorListeners() {
cursorShowDisposers = [];
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
var cursor = chart.cursor;
cursor.interactionsEnabled = true;
cursorShowDisposers.push(cursor.events.on("shown", function (event) {
handleShowCursor(event.target);
}));
}
}
var shownCursorChangeDisposer;
var shownCursorZoomStartedDisposer;
var shownCursorZoomEndedDisposer;
function handleShowCursor(shownCursor) {
// disable mouse for all other cursors
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
var cursor = chart.cursor;
if (cursor != shownCursor) {
cursor.interactionsEnabled = false;
}
// remove show listener
cursorShowDisposers[i].dispose();
}
// add change disposer to the hovered chart cursor
shownCursorChangeDisposer = shownCursor.lineX.events.on("positionchanged", function (event) {
syncCursors(shownCursor);
});
shownCursorZoomStartedDisposer = shownCursor.events.on("zoomstarted", function (event) {
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
var cursor = chart.cursor;
if (cursor != event.target) {
var point = { x: event.target.point.x, y: 0 };
cursor.triggerDown(point);
}
}
});
shownCursorZoomEndedDisposer = shownCursor.events.on("zoomended", function (event) {
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
var cursor = chart.cursor;
if (cursor != event.target) {
var point = { x: event.target.point.x, y: 0 };
cursor.triggerUp(point);
}
}
});
shownCursor.events.once("hidden", function (event) {
shownCursorChangeDisposer.dispose();
shownCursorZoomStartedDisposer.dispose();
shownCursorZoomEndedDisposer.dispose();
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
var cursor = chart.cursor;
cursor.hide(0);
cursorShowDisposers[i].dispose();
}
initCursorListeners();
});
}
function syncCursors(syncWithCursor) {
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
var cursor = chart.cursor;
var point = { x: syncWithCursor.point.x, y: 0 };
if (cursor != syncWithCursor) {
cursor.triggerMove(point);
}
}
}
There are other UI tweaks you can make like disabling the zoom out button on other charts except the top-most one as well as showing the date axis labels on just the last chart.
Here's a full demo on how to do all of this. This is also included in the examples folder in the AmCharts zip file.
If you're using Stock Chart, you might want to hold off.
Stock chart is not yet available for V4. We're planning it for the
second part of 2018. No exact ETA, yet. Sorry.
https://www.amcharts.com/docs/v4/getting-started/migrating-from-v3/#No_Stock_chart_yet
I have created a Box plot chart. However, the box of the box plot chart is very big. Does anyone know how can I adjust the size of the box plot? Secondly, The PointY Average Shape is now a straight line. How can I change it into a diamond shape?
This is what I have now: Please see the pic from this link: (http://i.stack.imgur.com/My7MT.png).
This is the output I want to achieve: (See here: http://i.stack.imgur.com/2ybT0.png).
This is my codes:
Chart1.DataSource = tg;
Chart1.Width = 600;
Chart1.Height = 350;
Chart1.Series.Add(new Series());
Chart1.Series[0].ChartType = SeriesChartType.BoxPlot;
List<object> lst = tg.AsEnumerable().ToList<object>();
foreach (DataRow row in tg.Rows)
Chart1.Series[0].Points.AddXY(row["Status"], new object[] { row["MAX"], row["MIN"], row["AVG"], row["PERCENTILE25"], row["PERCENTILE50"], row["PERCENTILE75"] });
Chart1.Series[0].Color = Color.White;
Chart1.Series[0].BorderColor = Color.MidnightBlue;
Chart1.Series[0].ChartType = SeriesChartType.BoxPlot;
if (tg.Rows.Count > 0)
{
string title = (tg.Rows[0]["Process"].ToString());
Chart1.Titles.Add(title);
}
//create chartareas
ChartArea ca = new ChartArea();
ca.Name = "ChartArea1";
ca.BackColor = Color.LightSkyBlue;
ca.BorderColor = Color.Gray;
ca.BorderWidth = 1;
ca.BorderDashStyle = ChartDashStyle.Solid;
ca.AxisX = new Axis();
ca.AxisX.MajorGrid.LineColor = Color.LightSkyBlue;
ca.AxisX.MajorTickMark.LineColor = Color.Gray;
ca.AxisY = new Axis();
ca.AxisY.MajorGrid.LineColor = Color.LightSkyBlue;
ca.AxisY.MajorTickMark.LineColor = Color.Gray;
Chart1.ChartAreas.Add(ca);
Chart1.ChartAreas[0].AxisX.Interval = 1;
Chart1.ChartAreas[0].AxisY.Interval = 5;
//databind
Chart1.DataBind();
Chart1.Visible = true;
Question: How to set the size of the box of box plot chart so that it is not this big?
How to change the shape of the PointY Average from straight line to a diamond shape?
Appreciate if someone can help me on this. Thanks.
I have a Chart that can add datapoints at runtime on clickevent. I am also putting the datapoints in asp:table using javascript. Is there anyway i can get the table values at the server side. I tried EnableViewState but no use.
Code:
protected void Page_Load(object sender, EventArgs e)
{
Data data = Utility.FromCSV();
Highcharts chart = new Highcharts("chart")
.InitChart(new Chart
{
DefaultSeriesType = ChartTypes.Scatter,
Margin = new[] { 70, 50, 60, 80 },
Events = new ChartEvents { Click = "ChartClickEvent" }
})
.AddJavascripFunction("ChartClickEvent", #"var x = Math.round(e.xAxis[0].value),
y = Math.round(e.yAxis[0].value),
series = this.series[0];
addNewData('Table1',x,y);
series.addPoint([x, y]);", "e")
.SetTitle(new Title { Text = "User supplied data" })
.SetSubtitle(new Subtitle { Text = "Click the plot area to add a point. Click a point to remove it." })
.SetXAxis(new XAxis
{
MinPadding = 0.2,
MaxPadding = 0.2
})
.SetYAxis(new YAxis
{
Title = new YAxisTitle { Text = "Value" },
MinPadding = 0.2,
MaxPadding = 0.2,
PlotLines = new[]
{
new YAxisPlotLines
{
Value = 0,
Width = 1,
Color = ColorTranslator.FromHtml("#808080")
}
}
})
.SetLegend(new Legend { Enabled = false })
.SetExporting(new Exporting { Enabled = false })
.SetPlotOptions(new PlotOptions
{
Series = new PlotOptionsSeries
{
LineWidth = 1,
Point = new PlotOptionsSeriesPoint
{
Events = new PlotOptionsSeriesPointEvents
{
Click = "function() { if (this.series.data.length > 1) this.remove(); }"
}
}
}
})
.SetSeries(new Series { Data = data });
for (int i = 0; i < data.DoubleArrayData.Length / 2; i++)
{
TableRow tr0 = Table1.Rows[0];
TableCell myTableCell = new TableCell();
myTableCell.Text = data.DoubleArrayData[i, 0].ToString();
tr0.Cells.Add(myTableCell);
TableRow tr1 = Table1.Rows[1];
myTableCell = new TableCell();
myTableCell.Text = data.DoubleArrayData[i, 1].ToString();
tr1.Cells.Add(myTableCell);
}
string chartstring = chart.ToHtmlString();
Literal lt = new Literal();
lt.Text = chartstring;
PlaceHolder1.Controls.Add(lt);
}
protected void Button1_Click(object sender, EventArgs e)
{
String[,] data = new String[Table1.Rows[0].Cells.Count-1, 2];
for(int i=1;i<Table1.Rows[0].Cells.Count;i++)
{
data[i-1, 0] = Table1.Rows[0].Cells[i].Text;
data[i-1, 1] = Table1.Rows[1].Cells[i].Text;
}
var Writer = new StreamWriter(File.OpenWrite(#"D:\logs\dataout.csv"));
for (int j = 0; j < data.Length / 2; j++)
Writer.WriteLine(data[j, 0] + "," + data[j, 1]);
Writer.Close();
}
asp.net page:
How do I make a page resize without resizing it?
I have a Javascript which runs to get data from a text file followed by plotting a graph on Amcharts. The problem is that some axis components of the chart are missing when it is first plotted and still missing when I attempt to refresh (F5).
The missing components all come out when I resize the browser, so I am wondering what is it that the resizing does and how do I mimic a resize after the chart has been drawn without actually resizing?
The full html version of the source is right here.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>amCharts Example</title>
<link rel="stylesheet" href="style.css" type="text/css">
<script src="javascript/amcharts.js" type="text/javascript"></script>
<script type="text/javascript">
var chart;
var chartData = [];
// declaring variables
var dataProvider;
// this method called after all page contents are loaded
var srcFrame;
window.onload = function() {
//generateChartData();
//createChart();
loadOuter('data.txt');
//loadOuter('Test.txt');
//loadCSV('data.txt');
}
//External content into a layer
function loadOuter(doc) {
srcFrame = document.getElementById("hiddenContent");
srcFrame.src = doc;
// workaround for missing onLoad event in IFRAME for NN6
if (!srcFrame.onload) {
if (srcFrame.contentDocument){
srcContent=srcFrame.contentDocument.getElementsByTagName("BODY")[0].innerHTML;
}
else if (srcFrame.contentWindow){
srcContent=srcFrame.contentWindow.document.body.innerHTML;
}
srcContent = srcContent.substring(5,srcContent.length-6)
parseCSV(srcContent);
//setTimeout("transferHTML()", 1000)
}
}
function parseCSV(data){
//replace UNIX new lines
data = data.replace (/\r\n/g, "\n");
//replace MAC new lines
data = data.replace (/\r/g, "\n");
//split into rows
var rows = data.split("\n");
// create array which will hold our data:
dataProvider = [];
// loop through all rows
for (var i = 0; i < rows.length; i++){
// this line helps to skip empty rows
if (rows[i]) {
// our columns are separated by comma
var column = rows[i].split(",");
// column is array now
// first item is date
var date = column[0];
var myDate= new Date();
var dateparse = date.split("-");
myDate.setFullYear(dateparse[0],dateparse[1],dateparse[2]);
//alert(myDate);
// second item is value of the second column
var value1 = column[1];
// third item is value of the fird column
var value2 = column[2];
// create object which contains all these items:
chartData.push({
date: myDate,
visits: value1,
hits: value2,
});
//var dataObject = {date:date, value1:value1, value2:value2};
// add object to dataProvider array
//dataProvider.push(dataObject);
}
}
// set data provider to the chart
chart.dataProvider = chartData;
// this will force chart to rebuild using new data
chart.validateData();
}
// generate some random data, quite different range
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 50);
//alert(firstDate);
//alert(firstDate.getDate());
for (var i = 0; i < 50; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
//alert(newDate);
var visits = Math.round(Math.random() * 40) + 100;
var hits = Math.round(Math.random() * 80) + 500;
chartData.push({
date: newDate,
visits: visits,
hits: hits,
});
}
}
//function createChart(){
AmCharts.ready(function () {
//loadOuter('data.txt');
// generate some random data first
//generateChartData();
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.pathToImages = "amcharts/images/";
chart.zoomOutButton = {
backgroundColor: '#000000',
backgroundAlpha: 0.15
};
chart.dataProvider = chartData;
chart.categoryField = "date";
// listen for "dataUpdated" event (fired when chart is inited) and call zoomChart method when it happens
chart.addListener("dataUpdated", zoomChart);
// AXES
// category
var categoryAxis = chart.categoryAxis;
categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
categoryAxis.minPeriod = "DD"; // our data is daily, so we set minPeriod to DD
categoryAxis.dashLength = 2;
categoryAxis.gridAlpha = 0.15;
categoryAxis.axisColor = "#DADADA";
// first value axis (on the left)
var valueAxis1 = new AmCharts.ValueAxis();
valueAxis1.axisColor = "#FF6600";
valueAxis1.axisThickness = 2;
valueAxis1.gridAlpha = 0;
chart.addValueAxis(valueAxis1);
// second value axis (on the right)
var valueAxis2 = new AmCharts.ValueAxis();
valueAxis2.position = "right"; // this line makes the axis to appear on the right
valueAxis2.axisColor = "#FCD202";
valueAxis2.gridAlpha = 0;
valueAxis2.axisThickness = 2;
chart.addValueAxis(valueAxis2);
// GRAPHS
// first graph
var graph1 = new AmCharts.AmGraph();
graph1.valueAxis = valueAxis1; // we have to indicate which value axis should be used
graph1.title = "red line";
graph1.valueField = "visits";
graph1.bullet = "round";
graph1.hideBulletsCount = 30;
chart.addGraph(graph1);
// second graph
var graph2 = new AmCharts.AmGraph();
graph2.valueAxis = valueAxis2; // we have to indicate which value axis should be used
graph2.title = "yellow line";
graph2.valueField = "hits";
graph2.bullet = "square";
graph2.hideBulletsCount = 30;
chart.addGraph(graph2);
// CURSOR
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorPosition = "mouse";
chart.addChartCursor(chartCursor);
// SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);
// LEGEND
var legend = new AmCharts.AmLegend();
legend.marginLeft = 110;
chart.addLegend(legend);
// WRITE
chart.write("chartdiv");
});
// this method is called when chart is first inited as we listen for "dataUpdated" event
function zoomChart() {
// different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
chart.zoomToIndexes(10, 20);
//chart.validateData();
//createChart();
}
</script>
<div id="outerDisplay"></div>
<iframe id="hiddenContent" width="200" height="200" style="position:absolute;visibility:hidden;" ></iframe>
<div id="chartdiv" style="width:600px; height:400px; background-color:#FFFFFF"></div>
</body>
</html>
Anyone has any idea on how to troubleshoot it to make it display on the first load instead of having to resize it?
Did you try calling chart.validateNow()? See Amcharts reference.
Chart will be redrawn, useful when a property changes.