I have a line graph with date axis and data being displayed in intervals for 30 or 15 minutes for a day. Since data is dynamic, for some cases data starts around 12 noon or some other time and hence the x-axis does not always starts from the 00:00. Similarly data might end before 12:00 Mid night.
I want to always show the dateAxis to start from 00:00 then some fix step for lets say a label for every one or two hours and end at 12:00 mid night. How can i do this?
I tried DateAxis.min and DateAxis.max. But these are only accepting numeric values. not sure how to set it to appropriate numeric value to represent the start and end of day.
I also tried setting DateAxis.extraMin and DateAxis.extraMax but these are working on percentage and its a but hard to find appropriate values for the dynamic data.
This is how current graph renders
This is how i want to display (notice the empty labels at the start)
The min/max properties in DateAxis objects take millisecond timestamps. You can use the result of getTime() from a JavaScript Date object:
dateAxis.min = (new Date(2019,7,10)).getTime();
dateAxis.max = (new Date(2019,7,10,23)).getTime();
There isn't a way to explicitly set a step, though. You can tweak minGridDistance to influence the step but that's about it. The only workaround you can use is insert guides (Axis Ranges) at each timestamp with the appropriate label and disable the DateAxis' default labels.
range.date = new Date(2019, 7, 10, 0);
range.grid.strokeOpacity = .5;
range.grid.stroke = "#cecece";
range.label.text = "00:00";
Note that axis won't adjust label visibility in this case, so you may need to set a rotation on the range label as well.
Demo below:
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);
// Add data
chart.data = generateData();
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.startLocation = 0.5;
dateAxis.endLocation = 0.5;
// Create value axis
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = "value";
series.dataFields.dateX = "date";
series.name = "Sales";
series.strokeWidth = 3;
series.fillOpacity = 0.5;
dateAxis.baseInterval = {
timeUnit: "minute",
count: 15
}
dateAxis.renderer.grid.template.disabled = true;
dateAxis.renderer.labels.template.disabled = true;
dateAxis.min = (new Date(2019, 7, 10, 0)).getTime();
dateAxis.max = (new Date(2019, 7, 10, 23)).getTime();
generateRanges(dateAxis);
function generateRanges(axis) {
var firstDate = new Date(2019, 7, 10, 0);
for (var i = 0; i < 24; ++i) {
var range = axis.axisRanges.create();
var nextDate = new Date(firstDate);
nextDate.setHours(i);
range.date = nextDate;
range.grid.strokeOpacity = .5;
range.grid.stroke = "#cecece";
range.label.text = ("0" + nextDate.getHours()).substr(-2) + ":" + ("0" + nextDate.getMinutes()).substr(-2);
range.label.rotation = 90;
}
}
function generateData() {
var data = [];
var firstDate = new Date(2019, 7, 10, 10);
for (var i = 0; i < 32; ++i) {
var nextDate = new Date(firstDate);
nextDate.setMinutes(i * 15);
data.push({
date: nextDate,
value: Math.floor(Math.random() * 15 + 5)
})
}
return data;
}
<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: 98vh;"></div>
Related
The following (Epplus 6.06) code segment successfully creates a line graph (eLineChartType.Line) in a spreadsheet, with three lines of data shown on the graph. The third line obeys the color I have requested (brown). The first two lines show in black (should be blue and green). AN image of the chart is attached.
Am I doing something wrong, or is this a bug in Epplus?
var chart = chartWs.Drawings.AddLineChart(ChartName, eLineChartType.Line);
chart.SetPosition(0, 0, StandardChartCols, 0);
chart.To.Column = 2 * StandardChartCols;
chart.To.Row = StandardChartRows;
chart.StyleManager.SetChartStyle(ePresetChartStyle.LineChartStyle1);
chart.Title.Text = "Drone Altitude and Ground/Surface Elevations (M)";
chart.Title.Font.Size = MediumTitleFontSize;
chart.Title.Font.Bold = true;
chart.YAxis.MinValue = minAltitude;
var serie1 = chart.Series.Add(dataWs.Cells[1, AltCol, lastRow, AltCol], dataWs.Cells[1, SectionCol, lastRow, SectionCol]);
serie1.Header = "Altitude";
serie1.Marker.Fill.Color = Color.LightBlue;
serie1.Border.Fill.Color = Color.LightBlue;
serie1.Border.Width = 2;
var serie2 = chart.Series.Add(dataWs.Cells[1, DsmCol, lastRow, DsmCol], dataWs.Cells[1, SectionCol, lastRow, SectionCol]);
serie2.Header = "DSM";
serie2.Marker.Fill.Color = Color.Green;
serie2.Border.Fill.Color = Color.Green;
serie2.Border.Width = 2;
var serie3 = chart.Series.Add(dataWs.Cells[1, DemCol, lastRow, DemCol], dataWs.Cells[1, SectionCol, lastRow, SectionCol]);
serie3.Header = "DEM";
serie3.Marker.Fill.Color = Color.Brown;
serie3.Border.Fill.Color = Color.Brown;
serie3.Border.Width = 2;
Drone Altitude and Ground/Surface Elevations (M)
I'm a new ILNumerics Visualization Engine user and I'm still coming up to speed on how to use it well. I've searched extensively for how to update the z-values of an ILSurface and read the posts, but I'm still not clear on how to do this.
I'm able to generate a surface and set up a camera to view it (Hamyo Kutschbach told me that's the best way to ensure that the aspect ratios of the surface don't change when rotating the surface, which is important in my application). Here's the code that displays a sin(x)/x function:
// Generate the data
ILArray<double> z = SincFunc(rows, cols, 10, 50);
ILArray<double> x = new double[cols];
ILArray<double> y = new double[rows];
for (int i = 0; i < cols; i++)
x[i] = (double)i;
for (int i = 0; i < rows; i++)
y[i] = (double)i;
// create the scene
scene = new ILScene();
pointCloudSurface = new ILSurface(z, x, y)
{
Colormap = Colormaps.Jet,
UseLighting = true,
Wireframe = { Visible = false },
Children = { new ILColorbar()
{
Height = 0.5f,
Location = new PointF(0.95f, 0.05f),
Children = { new ILLabel("microns") { Position = new Vector3(0.5,1,0), Anchor = new PointF(0.5f,0) } } }
},
Alpha = 1.0f
};
// Configure the surface and display it
scene.Camera.Add(pointCloudSurface);
scene.Camera.Position = new Vector3(50, 50, 700);
scene.Camera.LookAt = new Vector3(50, 50, 0);
scene.Camera.Top = new Vector3(0, 0, 700);
scene.Camera.Projection = Projection.Perspective;
scene.Camera.ZNear = 1.0f;
scene.Camera.ZFar = 0.0f;
scene.Camera.Top = new Vector3(1, 0, 0);
// Turn off the Powered by ILNumerics label
scene.Screen.First<ILLabel>().Visible = false;
ilPanel1.Scene = scene;
ilPanel1.Configure();
ilPanel1.Refresh();
And it works well. So now I want to change the z-values and update the plot without closing ilPanel1 because this plot is embedded in a Windows Form. Advice would be appreciated! Hopefully other newbies will find this post useful as well.
After further rummaging around, I came across a method, UpdateColormapped(), that does the trick. It's placed near the end of the code above like this:
scene.Camera.First<ILSurface>().UpdateColormapped(z);
ilPanel1.Scene = scene;
ilPanel1.Configure();
ilPanel1.Refresh();
It can be found in the API documentation here: UpdateColormapped()
It can also change the x and y data and perform other mods, but it requires that the z data be a float array, so if you're working double precision, you'll have to take the appropriate steps to get it into a float array.
I’m having 2 problems with a simple XYSeries line graph.
When the absolute value of the difference between the last plotted point and the next plotted point is less than 11 the label on the next plotted point goes missing. I want all the labels to display.
I have some (not all) missing vertical grid lines and don’t see why. I want a vertical grid line for every XY coordinate.
Thanks for the help. Here's the code.
String glucoseLegendText = getString(R.string.glucose_legend_text);
XYSeries series = new XYSeries(glucoseLegendText);
datasource = new HistoryDataSource(this);
datasource.open();
Cursor c = datasource.getQuery();
c.moveToFirst();
int cnt = c.getCount();
int minValue = 0;
int maxValue = 0;
for (int i = 0; i < cnt; i++) {
int glucoseValue = c.getInt(2);
series.add(i, glucoseValue);
if (i == 0 || glucoseValue < minValue)
minValue = glucoseValue;
if (glucoseValue > maxValue)
maxValue = glucoseValue;
c.moveToNext();
}
datasource.close();
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
dataset.addSeries(series);
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setColor(Color.BLUE);
renderer.setPointStyle(PointStyle.CIRCLE);
renderer.setFillPoints(true);
renderer.setLineWidth(3);
renderer.setDisplayChartValues(true);
renderer.setChartValuesTextSize(15);
renderer.setChartValuesTextAlign(Align.LEFT);
XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
mRenderer.addSeriesRenderer(renderer);
mRenderer.setShowGrid(true);
mRenderer.setGridColor(Color.BLACK);
mRenderer.setXLabels(cnt); // to control number of grid lines
mRenderer.setYLabels(cnt); // to control number of grid lines
mRenderer.setXLabelsColor(Color.YELLOW);
mRenderer.setPointSize(5);
mRenderer.setYLabelsAlign(Align.RIGHT);
mRenderer.setLegendTextSize(15);
mRenderer.setZoomButtonsVisible(true);
mRenderer.setYAxisMin(minValue - 2); // buffer bottom
mRenderer.setYAxisMax(maxValue + 3); // buffer top
// Populate the X labels with the dates and times
c.moveToFirst();
for (int d = 0; d < cnt; d++) {
timeStamp = c.getString(1);
date = timeStamp.substring(0, 5);
time = timeStamp.substring(9, 14);
if (date.equals(dateLast)) {
mRenderer.addXTextLabel(d, "\n" + time);
} else
mRenderer.addXTextLabel(d, "\n" + time + "\n" + date);
dateLast = date;
c.moveToNext();
}
c.close();
GraphicalView gview = ChartFactory.getTimeChartView(this, dataset,
mRenderer, "");
LinearLayout layout = (LinearLayout) findViewById(R.id.Chart);
layout.addView(gview);
For the first question, you can control the labels display using
renderer.setXLabels(approximateNumberOfLabels);
For the second question, the grid lines are displayed along the labels.
I just want to display several Charts in the same Panel. It doesn't matter which chart types I use (Column, Line, Pie etc). The result is that only the first chart has labels, no matter how many charts I try to display. See this screen shot:
On the second chart, the x- and y-axis labels are missing as well as the labels for the data sets. I tested in Chrome, Firefox and IE. Always the same.
Here is the code I use:
VerticalPanel panel=new VerticalPanel();
final int height = 400;
final int width = 1200;
Date d = new Date();
//message data
final DataTable msgData = DataTable.create();
msgData.addColumn(ColumnType.DATE, "date");
msgData.addColumn(ColumnType.NUMBER, "data one");
msgData.addColumn(ColumnType.NUMBER, "data two");
msgData.addRows(6);
for (int i = 0; i < 6; i++)
{
d.setTime(d.getTime() + (1000 * 60 * 60 * 24));
msgData.setValue(i, 0, d);
msgData.setValue(i, 1, i + 11);
msgData.setValue(i, 2, i + 12);
}
final Options options = Options.create();
options.setWidth(width);
options.setHeight(height);
options.setIsStacked(true);
options.setTitle("Chart One");
panel.add(new ColumnChart(msgData, options));
d = new Date();
//new data
final DataTable newData = DataTable.create();
newData.addColumn(ColumnType.DATE, "date");
newData.addColumn(ColumnType.NUMBER, "data three");
newData.addColumn(ColumnType.NUMBER, "data four");
newData.addRows(5);
for (int i = 0; i < 5; i++)
{
d.setTime(d.getTime() + (1000 * 60 * 60 * 24));
newData.setValue(i, 0, d);
newData.setValue(i, 1, i + 3);
newData.setValue(i, 2, i + 4);
}
final Options options_new = Options.create();
options_new.setWidth(width);
options_new.setHeight(height);
options_new.setIsStacked(true);
options_new.setTitle("Chart two");
panel.add(new ColumnChart(newData, options_new));
I checked the generated html with firebug. The charts are rendered using SVG and in the second chart there are just no svg-tags for the labels, while they exist in the first chart. So the missing labels are not cut off or hidden, but are not even created.
Thanks for your help
I have successfully used the C++ example project to draw graphs from my C++ project using ZedGraph. However there is no example with Date axis for C++.
The following code is taken from the C# example found at
http://zedgraph.org/wiki/index.php?title=Tutorial:Date_Axis_Chart_Demo. Please see my comments with the text //JEM// to see where my problem is
PointPairList list = new PointPairList();
for ( int i=0; i<36; i++ )
{
double x = (double) new XDate( 1995, 5, i+11 );
> //JEM //This line above doesn't work in
> C++.
double y = Math.Sin( (double) i * Math.PI / 15.0 );
list.Add( x, y );
}
....missing code...
// Set the XAxis to date type
myPane.XAxis.Type = AxisType.Date;
//JEM //This one also doesn't work even if I change it to the
//syntax that C++ understands, that is,
myPane->XAxis->Type = AxisType->Date;
Maybe C++ has some problems with the anonymous variables?
Try to create a XDate object first before converting it to double.
XDate date = new XDate( 1995, 5, i+11 );
double x = (double)date;
Thanks Gacek.
This is how it finally went down. Your answer was the turning point!!!
for ( int i = 0; i < basin.DY; i++ ){
XDate dato(1995,9,i,0,0,0); //date
double x = (double)dato;
//double x = i;
double y = basin.Qsim[i];
double y2 = basin.Qobs[i];
list->Add( x, y );
list2->Add( x, y2 );
}
//set the XAXis to date type
myPane->XAxis->Type = AxisType::Date;
here is the constructor for the Xdate type for c++ from sourceforge dot net documentation/html/M_ZedGraph_XDate__ctor_3.htm.
XDate (int year, int month, int day, int hour, int minute, double second)
I have also found a detailed example on this link http://www.c-plusplus.de/forum/viewtopic-var-t-is-186422-and-view-is-next.html
with the following code
/// ZedGraph Kurve //////////
private: void CreateGraph( ZedGraphControl ^zgc )
{
GraphPane ^myPane = zgc->GraphPane;
// Set the titles and axis labels
myPane->Title->Text = "Gewichtskurve";
myPane->XAxis->Title->Text = "Tag";
myPane->YAxis->Title->Text = "Gewicht in Kg";
// Make up some data points from the Sine function
double x,y;
PointPairList ^list = gcnew PointPairList();
for ( int i=0; i<36; i++ )
{
x = (double) gcnew XDate( 1995, 5, i+11 );
y = Math::Sin( (double) i * Math::PI / 15.0 );
list->Add( x, y );
}
// Generate a blue curve with circle symbols, and "My Curve 2" in the legend
LineItem ^myCurve = myPane->AddCurve( "Trainingskurve", list, Color::Blue,
SymbolType::Circle );
XDate ^xdatum = gcnew XDate ( 1995, 1, 1);
xdatum->AddDays ( 1 );
myPane->XAxis->Type = AxisType::Date;