I am new to Leaflet and I am currently struggling with tutorials. So far I managed to create an interactive clorophet map, like in the example http://leafletjs.com/examples/choropleth.html.
Is it possible to add a title (simple text, not dynamic) to the legged located on the bottomright of the page? Could anyone tell me how, by just referring to the linked example?
You just need to add your title under "THE TITLE"...
var legend = L.control({position: 'topleft'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = [50, 100, 150, 200, 250, 300],
labels = ['<strong> THE TITLE </strong>'],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades [i];
to = grades[i+1]-1;
labels.push(
'<i style="background:' + getColor(from + 1) + '"></i> ' +
from + (to ? '–' + to : '+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
Related
I have a RelativeLayout, and multiple polygons/labels in it. Now I want to place the labels inside the polygons, in the center of it. However, I don't know the width and height of the label, so placing them in the center results in something like this:
However, this is wrong, as I want the label to be in the exact middle of the polygon (of which the width and height is known), no matter what the text is.
I've looked into methods to try to center it, for example using HorizontalTextAlignment and VerticalTextAlignment, but so far no success. What is the right way to do that? HorizontalOptions doesn't work either, as it's not relative to a parent or something.
Code I'm currently using:
var MainGrid = new RelativeLayout();
var path = new PointCollection();
// add points to path
var coords = new Point(100, 100);
var TILE_WIDTH = 70;
var TILE_HEIGHT = 80;
// Here the real code begins
polygon = new Polygon
{
Points = path,
<other arguments>
};
var text = new Label
{
Text = "5",
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
TextColor = Color.Black,
};
MainGrid.Children.Add(
polygon,
Constraint.Constant(coords.X),
Constraint.Constant(coords.Y)
);
MainGrid.Children.Add(
text,
Constraint.Constant(coords.X + TILE_WIDTH / 2),
Constraint.Constant(coords.Y + TILE_HEIGHT / 2)
);
set an arbitrary width and height on the label, as long as it is big enough to fit your text and smaller than the polygon. Also set a background color to help visualize the placement of the label (remove this once you get the alignment right)
var text = new Label
{
Text = "5",
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
TextColor = Color.Black,
BackgroundColor = Color.White,
HeightRequest = 50,
WidthRequest = 50
};
then factor in the label width and height when placing it
MainGrid.Children.Add(
text,
Constraint.Constant(coords.X + (TILE_WIDTH / 2) - 25),
Constraint.Constant(coords.Y + (TILE_HEIGHT / 2) - 25)
);
I want to put multi pie chart on d3 map but I'm confused how to do it.
I'm noob at d3 so I searched about the issue and made below code.
Someone suggested that I should make two seperate svgs so I did it.
There are two svgs. one has a map, and the other has multiple pie chart.
Now I have a problem with mapping these pies on map.
I don't know how to map these pies with geo coordinates...
It's just browser(?) coordinates so I want to change it.
and I want to zoom and pan map correctly with pies...
hope your help...
summary
I have two problems
putting multiple pie charts on right map place
zoom and pan correctly
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v0.min.js"></script>
<script>
var width = 960, height = 500;
var projection = d3.geo.mercator().center([ 127.46, 36.00 ])
.scale(4000).translate([ width / 2, height / 2 ]);
var color = d3.scale.category20();
//first svg
var svg = d3.select("body").append("svg").attr("width", width).attr(
"height", height);
var path = d3.geo.path().projection(projection);
var radius = 30;
var arc = d3.svg.arc().innerRadius(radius - 100).outerRadius(
radius - 20);
var g = svg.append("g");
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "/tourdata.txt", false);
var allText;
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4) {
if (rawFile.status === 200 || rawFile.status == 0) {
allText = rawFile.responseText;
}
}
}
rawFile.send(null);
var lines = allText.split('\n');
var timeTable = new Array();
var res = lines[0].split(", ");
var currentTime = res[1];
var currentDate = res[0];
var timeInformation = new Array();
var corInformation = new Array();
var timeCorTable = new Array();
for ( var i = 0; i < lines.length; i++) {
var res = lines[i].split(", ");
if (currentDate != res[0] || currentTime != res[1]) {
currentDate = res[0];
currentTime = res[1];
timeTable[currentDate + ":" + currentTime] = timeInformation;
timeCorTable[currentDate + ":" + currentTime] = timeCorTable;
timeInformation = new Array();
corInformation = new Array();
}
if (timeInformation[res[2] + "," + res[3]] == undefined) {
corInformation.push(res[2] + "," + res[3]);
timeInformation.push([ res[4], res[5], res[6], res[7], res[8],
res[9], res[10], res[11], res[12], res[13] ]);
}
}
timeTable.push(timeInformation);
timeCorTable.push(corInformation);
var data = timeTable;
console.log(timeCorTable[0]);
// load and display the World
d3.json("kor.json",
function(error, topology) {
// load and display the cities
var geo = topojson.object(topology,
topology.objects['kor.geo']).geometries;
g.selectAll('path').data(geo).enter().append('path').attr(
'd', path)
});
console.log(data[0]);
//second svg that has multiple pies
var svgSvg = d3.select("body").select("svg").selectAll("g").data(timeTable[0]).enter().append("svg:svg").attr(
"width", width).attr("height", height).append("svg:g").style(//svg:g make pie group
"opacity", 0.8).attr("transform", function(d, i) {
var split = timeCorTable[0][i].split(",");
//console.log(split[0]);
var point = [split[0], split[1]];
console.log(projection(point[0], point[1])[0]);
return ("translate(" + projection(point[0], point[1])[0] + "," + projection(point[0], point[1])[1] + ")");
});
svgSvg.selectAll("path").data(d3.layout.pie()).enter().append(
"svg:path").attr("d",
d3.svg.arc().innerRadius(10).outerRadius(30)).style("fill", function(d, i) { return color(i); });
// zoom and pan
var zoom = d3.behavior.zoom().on(
"zoom",
function() {
g.attr("transform", "translate("
+ d3.event.translate.join(",") + ")scale("
+ d3.event.scale + ")");
g.selectAll("path").attr("d", path.projection(projection));
svgSvg.attr("transform", "translate("
+ d3.event.translate.join(",") + ")scale("
+ d3.event.scale + ")");
});
svg.call(zoom)
</script>
I am quite new to ASP.NET Charting and have a question about adding custom component to a bar chart. I am trying to create a custom legend in a tabular format. What I mean is my legend style is table. And I am creating each LegendItem from database values and adding it to chart.Legends[0].CustomItems collection.
I get the data but I am getting all the LegendItems in one row. I want to display each LegendItem on new row. My current code look like this -
chart.Legends.Add(new Legend
{
LegendStyle = LegendStyle.Table,
BorderColor = Color.Black,
BorderWidth = 1,
BorderDashStyle = ChartDashStyle.Solid,
Alignment = StringAlignment.Center,
DockedToChartArea = areaCounter.ToString(),
Docking = Docking.Bottom,
Name = "CustomLegend",
IsTextAutoFit = true,
InterlacedRows = true,
TableStyle = LegendTableStyle.Auto,
IsDockedInsideChartArea = false
});
LegendItem newItem = new LegendItem();
newItem.Cells.Add(LegendCellType.Text, " - value1 - ", ContentAlignment.MiddleCenter);
newItem.Cells.Add(LegendCellType.Text, " - State Average = - ", ContentAlignment.MiddleCenter);
newItem.Cells[1].CellSpan = 2;
newItem.BorderColor = Color.Black;
newItem.Cells.Add(LegendCellType.Text, " - ", ContentAlignment.MiddleCenter);
newItem.Cells.Add(LegendCellType.Text, " - top - ", ContentAlignment.MiddleCenter);
chart.Legends[1].CustomItems.Add(newItem);
LegendItem newItem1 = new LegendItem();
newItem1.Cells.Add(LegendCellType.Text, "value1", ContentAlignment.MiddleCenter);
newItem1.Cells.Add(LegendCellType.Text, "State Average =", ContentAlignment.MiddleCenter);
newItem1.Cells[1].CellSpan = 2;
newItem1.BorderColor = Color.Black;
newItem1.Cells.Add(LegendCellType.Text, "", ContentAlignment.MiddleCenter);
newItem1.Cells.Add(LegendCellType.Text, "top", ContentAlignment.MiddleCenter);
chart.Legends[1].CustomItems.Add(newItem1);
newItem and newItem1 both appear on same row as legend. Can you please help me solve this issue ? I'd really appreciate your help.
Found out that once I add HeaderSeparator to my custom Legend object and handle the chat object's CustomizeLegend event it worked as I wanted. The custom items are displayed on separate rows. Here are the changes that I did.
chart.Legends.Add(new Legend
{
LegendStyle = LegendStyle.Table,
BorderColor = Color.Black,
BorderWidth = 1,
BorderDashStyle = ChartDashStyle.Solid,
Alignment = StringAlignment.Center,
DockedToChartArea = areaCounter.ToString(),
Docking = Docking.Bottom,
Name = "CustomLegend",
IsTextAutoFit = true,
InterlacedRows = true,
TableStyle = LegendTableStyle.Tall,
HeaderSeparator = LegendSeparatorStyle.Line,
HeaderSeparatorColor = Color.Gray,
IsDockedInsideChartArea = false
});
LegendItem newItem3 = new LegendItem();
var strVal = item.Value;
foreach (var val in strVal)
{
newItem3.Cells.Add(LegendCellType.Text, val, ContentAlignment.BottomCenter);
}
chart.Legends["CustomLegend"].CustomItems.Add(newItem3);
chart.CustomizeLegend += chart_CustomizeLegend;
void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e)
{
Chart chart = sender as Chart;
if (chart == null) return;
foreach (var item in e.LegendItems)
{
item.SeparatorType = LegendSeparatorStyle.Line;
item.SeparatorColor = Color.Black;
}
}
I am using asp.net chart control to display chart on my website , below is the snippet of it:
The issue is i want to add the text and an arrow line on each point , so for instance on the point (60,october) I want to write text at this point: projection was highest and an arrow image.
Is it possible to acheive something like this, any suggestion or assistance will be highly appreciated, below is the code i have used to generate this chart:
double[] yValues = { 15, 60, 12, 13 };
string[] xValues = { "September", "October", "November", "December" };
chart.Width = 500;
chart.Height = 200;
chart.BorderSkin.SkinStyle = BorderSkinStyle.FrameThin1;
ChartArea ca = new ChartArea();
ca.Name = "Default";
ca.AxisX.LineColor = System.Drawing.ColorTranslator.FromHtml("#FEFEFE");
ca.AxisX.LineWidth = 3;
ca.AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dash;
ca.AxisX.MajorGrid.Enabled = false;
ca.AxisX.MajorTickMark.LineWidth = 2;
ca.AxisX.LabelStyle.Format = "L";
ca.AxisY.LineColor = System.Drawing.ColorTranslator.FromHtml("#FEFEFE");
ca.AxisY.LineWidth = 3;
ca.AxisY.MajorGrid.Enabled = true;
ca.AxisY.MajorTickMark.LineWidth = 2;
ca.AxisY.Title = "yaxis";
chart.ChartAreas.Add(ca);
Legend legend = new Legend();
chart.Legends.Add(legend);
Series series = new Series("Series1");
series.IsValueShownAsLabel = false;
series.MarkerStyle = MarkerStyle.Circle;
series.BorderWidth = 5;
series.ChartType = SeriesChartType.Line;
series.ShadowOffset = 2;
series.XValueType = ChartValueType.String;
series.YValueType = ChartValueType.Double;
series.Font = new System.Drawing.Font("Trebuchet MS", 8);
series.BorderColor = System.Drawing.ColorTranslator.FromHtml("#33CCFF");
series.Color = System.Drawing.ColorTranslator.FromHtml("#33CCFF");
chart.Series.Add(series);
chart.Series["Series1"].Points.DataBindXY(xValues, yValues);
chart.DataManipulator.InsertEmptyPoints(1, System.Web.UI.DataVisualization.Charting.IntervalType.Days, "Series1");
You need to search for the largest data point and use property
datapoint.Label = "projection was highest";
Also easiest way to highlight the point is to use datapoint.MarkerStyle property. You can draw an arrow but I dont think its worth the hassle.
In ZedGraph, how do I show text labels for each point and in the XAxis all together?
If I do
myPane.XAxis.Type = AxisType.Text;
myPane.XAxis.Scale.TextLabels = array_of_string;
I get labels on the XAxis like this
And if I do
for (int i = 0; i < myCurve.Points.Count; i++)
{
PointPair pt = myCurve.Points[i];
// Create a text label from the Y data value
TextObj text = new TextObj(
pt.Y.ToString("f0"), pt.X, pt.Y + 0.1,
CoordType.AxisXYScale, AlignH.Left, AlignV.Center);
text.ZOrder = ZOrder.A_InFront;
text.FontSpec.Angle = 0;
myPane.GraphObjList.Add(text);
}
I get labels on the curve, like this
But if I do both at the same time, labels on the curve disappear.
Is there a way to combine both kind of labels?
I've changed my answer after you clarified the question.
You just have to remember to position the labels correctly:
<%
System.Collections.Generic.List<ZedGraphWebPointPair> points = new System.Collections.Generic.List<ZedGraphWebPointPair>();
for (int i = 0; i < 15; i++)
{
// Let's have some fun with maths
points.Add(new ZedGraphWebPointPair
{
X = i,
Y = Math.Pow(i - 10, 2) * -1 + 120
});
}
System.Collections.Generic.List<string> XAxisLabels = new System.Collections.Generic.List<string>();
TestGraph.CurveList.Add(new ZedGraphWebLineItem { Color = System.Drawing.Color.Red });
TestGraph.XAxis.Scale.FontSpec.Size = 9;
int j = 1;
foreach (ZedGraphWebPointPair point in points)
{
// Add the points we calculated
TestGraph.CurveList[0].Points.Add(point);
// Add the labels for the points
TestGraph.GraphObjList.Add(new ZedGraphWebTextObj
{
Location =
{
CoordinateFrame = ZedGraph.CoordType.XChartFractionYScale,
// Make sure we position them according to the CoordinateFrame
X = Convert.ToSingle(j) / points.Count - 0.05f,
Y = Convert.ToSingle(point.Y) + 3f,
AlignV = ZedGraph.AlignV.Top
},
Text = point.Y.ToString(),
FontSpec = { Angle = 90, Size = 9, Border = { IsVisible = false } }
});
// Add the labels for the XAxis
XAxisLabels.Add(String.Format("P{0}", j));
j++;
}
TestGraph.RenderGraph += delegate(ZedGraphWeb zgw, System.Drawing.Graphics g, ZedGraph.MasterPane mp)
{
ZedGraph.GraphPane gp = mp[0];
gp.XAxis.Type = ZedGraph.AxisType.Text;
gp.XAxis.Scale.TextLabels = XAxisLabels.ToArray();
};
%>
That code will produce this graph:
If the axis type is text, the code below is easier to get x-coordinates of the points ;)
for (int tPoint = 0; tPoint < curve.Points.Count; tPoint++)
{
TextObj text = new TextObj(curve.Points[tPoint].Y.ToString(), curve.Points[tPoint].X, curve.Points[tPoint].Y + 10);
}