I am new to d3js, and I really like the library.
I intended to use Sunbrust and Icicle visualizations to show dependency trees of applications, in which the user can see the dependency hierarchy (who depends on who, etc...).
However, the icicle and sunburst visualizations always produce some "cells" that are too small, requiring the user to hover the cell to get the label.
Is it possible to tell d3 to create these cells with a minium height?
So that each cell can display the label inside and not require users to hover these cells?
See here:
See Observable code here:https://observablehq.com/#d3/icicle
See fiddle, here:
https://jsfiddle.net/68q0thc5/
<script src="https://d3js.org/d3.v7.min.js"></script>
<div id="chart"></div>
<script>
chart = Icicle(getData(), {
value: d => d.size, // size of each node (file); null for internal nodes (folders)
label: d => d.name, // display name for each cell
title: (d, n) => `${n.ancestors().reverse().map(d => d.data.name).join(".")}\n${n.value.toLocaleString("en")}`, // hover text
link: (d, n) => n.children
? `https://github.com/prefuse/Flare/tree/master/flare/src/${n.ancestors().reverse().map(d => d.data.name).join("/")}`
: `https://github.com/prefuse/Flare/blob/master/flare/src/${n.ancestors().reverse().map(d => d.data.name).join("/")}.as`,
width: 1152,
height: 2400
})
document.getElementById("chart").appendChild(chart)
// Copyright 2021 Observable, Inc.
// Released under the ISC license.
// https://observablehq.com/#d3/icicle
function Icicle(data, { // data is either tabular (array of objects) or hierarchy (nested objects)
path, // as an alternative to id and parentId, returns an array identifier, imputing internal nodes
id = Array.isArray(data) ? d => d.id : null, // if tabular data, given a d in data, returns a unique identifier (string)
parentId = Array.isArray(data) ? d => d.parentId : null, // if tabular data, given a node d, returns its parent’s identifier
children, // if hierarchical data, given a d in data, returns its children
format = ",", // format specifier string or function for values
value, // given a node d, returns a quantitative value (for area encoding; null for count)
sort = (a, b) => d3.descending(a.value, b.value), // how to sort nodes prior to layout
label, // given a node d, returns the name to display on the rectangle
title, // given a node d, returns its hover text
link, // given a node d, its link (if any)
linkTarget = "_blank", // the target attribute for links (if any)
width = 640, // outer width, in pixels
height = 400, // outer height, in pixels
margin = 0, // shorthand for margins
marginTop = margin, // top margin, in pixels
marginRight = margin, // right margin, in pixels
marginBottom = margin, // bottom margin, in pixels
marginLeft = margin, // left margin, in pixels
padding = 1, // cell padding, in pixels
round = false, // whether to round to exact pixels
color = d3.interpolateRainbow, // color scheme, if any
fill = "#ccc", // fill for node rects (if no color encoding)
fillOpacity = 0.6, // fill opacity for node rects
} = {}) {
// If id and parentId options are specified, or the path option, use d3.stratify
// to convert tabular data to a hierarchy; otherwise we assume that the data is
// specified as an object {children} with nested objects (a.k.a. the “flare.json”
// format), and use d3.hierarchy.
const root = path != null ? d3.stratify().path(path)(data)
: id != null || parentId != null ? d3.stratify().id(id).parentId(parentId)(data)
: d3.hierarchy(data, children);
// Compute the values of internal nodes by aggregating from the leaves.
value == null ? root.count() : root.sum(d => Math.max(0, value(d)));
// Compute formats.
if (typeof format !== "function") format = d3.format(format);
// Sort the leaves (typically by descending value for a pleasing layout).
if (sort != null) root.sort(sort);
// Compute the partition layout. Note that x and y are swapped!
d3.partition()
.size([height - marginTop - marginBottom, width - marginLeft - marginRight])
.padding(padding)
.round(round)
(root);
// Construct a color scale.
if (color != null) {
color = d3.scaleSequential([0, root.children.length - 1], color).unknown(fill);
root.children.forEach((child, i) => child.index = i);
}
const svg = d3.create("svg")
.attr("viewBox", [-marginLeft, -marginTop, width, height])
.attr("width", width)
.attr("height", height)
.attr("style", "max-width: 100%; height: auto; height: intrinsic;")
.attr("font-family", "sans-serif")
.attr("font-size", 10);
const cell = svg
.selectAll("a")
.data(root.descendants())
.join("a")
.attr("xlink:href", link == null ? null : d => link(d.data, d))
.attr("target", link == null ? null : linkTarget)
.attr("transform", d => `translate(${d.y0},${d.x0})`);
cell.append("rect")
.attr("width", d => d.y1 - d.y0)
.attr("height", d => d.x1 - d.x0)
.attr("fill", color ? d => color(d.ancestors().reverse()[1]?.index) : fill)
.attr("fill-opacity", fillOpacity);
const text = cell.filter(d => d.x1 - d.x0 > 10).append("text")
.attr("x", 4)
.attr("y", d => Math.min(9, (d.x1 - d.x0) / 2))
.attr("dy", "0.32em");
if (label != null) text.append("tspan")
.text(d => label(d.data, d));
text.append("tspan")
.attr("fill-opacity", 0.7)
.attr("dx", label == null ? null : 3)
.text(d => format(d.value));
if (title != null) cell.append("title")
.text(d => title(d.data, d));
return svg.node();
}
function getData() {
return { "name": "flare", "children": [{ "name": "analytics", "children": [{ "name": "cluster", "children": [{ "name": "AgglomerativeCluster", "size": 3938 }, { "name": "CommunityStructure", "size": 3812 }, { "name": "HierarchicalCluster", "size": 6714 }, { "name": "MergeEdge", "size": 743 }] }, { "name": "graph", "children": [{ "name": "BetweennessCentrality", "size": 3534 }, { "name": "LinkDistance", "size": 5731 }, { "name": "MaxFlowMinCut", "size": 7840 }, { "name": "ShortestPaths", "size": 5914 }, { "name": "SpanningTree", "size": 3416 }] }, { "name": "optimization", "children": [{ "name": "AspectRatioBanker", "size": 7074 }] }] }, { "name": "animate", "children": [{ "name": "Easing", "size": 17010 }, { "name": "FunctionSequence", "size": 5842 }, { "name": "interpolate", "children": [{ "name": "ArrayInterpolator", "size": 1983 }, { "name": "ColorInterpolator", "size": 2047 }, { "name": "DateInterpolator", "size": 1375 }, { "name": "Interpolator", "size": 8746 }, { "name": "MatrixInterpolator", "size": 2202 }, { "name": "NumberInterpolator", "size": 1382 }, { "name": "ObjectInterpolator", "size": 1629 }, { "name": "PointInterpolator", "size": 1675 }, { "name": "RectangleInterpolator", "size": 2042 }] }, { "name": "ISchedulable", "size": 1041 }, { "name": "Parallel", "size": 5176 }, { "name": "Pause", "size": 449 }, { "name": "Scheduler", "size": 5593 }, { "name": "Sequence", "size": 5534 }, { "name": "Transition", "size": 9201 }, { "name": "Transitioner", "size": 19975 }, { "name": "TransitionEvent", "size": 1116 }, { "name": "Tween", "size": 6006 }] }, { "name": "data", "children": [{ "name": "converters", "children": [{ "name": "Converters", "size": 721 }, { "name": "DelimitedTextConverter", "size": 4294 }, { "name": "GraphMLConverter", "size": 9800 }, { "name": "IDataConverter", "size": 1314 }, { "name": "JSONConverter", "size": 2220 }] }, { "name": "DataField", "size": 1759 }, { "name": "DataSchema", "size": 2165 }, { "name": "DataSet", "size": 586 }, { "name": "DataSource", "size": 3331 }, { "name": "DataTable", "size": 772 }, { "name": "DataUtil", "size": 3322 }] }, { "name": "display", "children": [{ "name": "DirtySprite", "size": 8833 }, { "name": "LineSprite", "size": 1732 }, { "name": "RectSprite", "size": 3623 }, { "name": "TextSprite", "size": 10066 }] }, { "name": "flex", "children": [{ "name": "FlareVis", "size": 4116 }] }, { "name": "physics", "children": [{ "name": "DragForce", "size": 1082 }, { "name": "GravityForce", "size": 1336 }, { "name": "IForce", "size": 319 }, { "name": "NBodyForce", "size": 10498 }, { "name": "Particle", "size": 2822 }, { "name": "Simulation", "size": 9983 }, { "name": "Spring", "size": 2213 }, { "name": "SpringForce", "size": 1681 }] }, { "name": "query", "children": [{ "name": "AggregateExpression", "size": 1616 }, { "name": "And", "size": 1027 }, { "name": "Arithmetic", "size": 3891 }, { "name": "Average", "size": 891 }, { "name": "BinaryExpression", "size": 2893 }, { "name": "Comparison", "size": 5103 }, { "name": "CompositeExpression", "size": 3677 }, { "name": "Count", "size": 781 }, { "name": "DateUtil", "size": 4141 }, { "name": "Distinct", "size": 933 }, { "name": "Expression", "size": 5130 }, { "name": "ExpressionIterator", "size": 3617 }, { "name": "Fn", "size": 3240 }, { "name": "If", "size": 2732 }, { "name": "IsA", "size": 2039 }, { "name": "Literal", "size": 1214 }, { "name": "Match", "size": 3748 }, { "name": "Maximum", "size": 843 }, { "name": "methods", "children": [{ "name": "add", "size": 593 }, { "name": "and", "size": 330 }, { "name": "average", "size": 287 }, { "name": "count", "size": 277 }, { "name": "distinct", "size": 292 }, { "name": "div", "size": 595 }, { "name": "eq", "size": 594 }, { "name": "fn", "size": 460 }, { "name": "gt", "size": 603 }, { "name": "gte", "size": 625 }, { "name": "iff", "size": 748 }, { "name": "isa", "size": 461 }, { "name": "lt", "size": 597 }, { "name": "lte", "size": 619 }, { "name": "max", "size": 283 }, { "name": "min", "size": 283 }, { "name": "mod", "size": 591 }, { "name": "mul", "size": 603 }, { "name": "neq", "size": 599 }, { "name": "not", "size": 386 }, { "name": "or", "size": 323 }, { "name": "orderby", "size": 307 }, { "name": "range", "size": 772 }, { "name": "select", "size": 296 }, { "name": "stddev", "size": 363 }, { "name": "sub", "size": 600 }, { "name": "sum", "size": 280 }, { "name": "update", "size": 307 }, { "name": "variance", "size": 335 }, { "name": "where", "size": 299 }, { "name": "xor", "size": 354 }, { "name": "_", "size": 264 }] }, { "name": "Minimum", "size": 843 }, { "name": "Not", "size": 1554 }, { "name": "Or", "size": 970 }, { "name": "Query", "size": 13896 }, { "name": "Range", "size": 1594 }, { "name": "StringUtil", "size": 4130 }, { "name": "Sum", "size": 791 }, { "name": "Variable", "size": 1124 }, { "name": "Variance", "size": 1876 }, { "name": "Xor", "size": 1101 }] }, { "name": "scale", "children": [{ "name": "IScaleMap", "size": 2105 }, { "name": "LinearScale", "size": 1316 }, { "name": "LogScale", "size": 3151 }, { "name": "OrdinalScale", "size": 3770 }, { "name": "QuantileScale", "size": 2435 }, { "name": "QuantitativeScale", "size": 4839 }, { "name": "RootScale", "size": 1756 }, { "name": "Scale", "size": 4268 }, { "name": "ScaleType", "size": 1821 }, { "name": "TimeScale", "size": 5833 }] }, { "name": "util", "children": [{ "name": "Arrays", "size": 8258 }, { "name": "Colors", "size": 10001 }, { "name": "Dates", "size": 8217 }, { "name": "Displays", "size": 12555 }, { "name": "Filter", "size": 2324 }, { "name": "Geometry", "size": 10993 }, { "name": "heap", "children": [{ "name": "FibonacciHeap", "size": 9354 }, { "name": "HeapNode", "size": 1233 }] }, { "name": "IEvaluable", "size": 335 }, { "name": "IPredicate", "size": 383 }, { "name": "IValueProxy", "size": 874 }, { "name": "math", "children": [{ "name": "DenseMatrix", "size": 3165 }, { "name": "IMatrix", "size": 2815 }, { "name": "SparseMatrix", "size": 3366 }] }, { "name": "Maths", "size": 17705 }, { "name": "Orientation", "size": 1486 }, { "name": "palette", "children": [{ "name": "ColorPalette", "size": 6367 }, { "name": "Palette", "size": 1229 }, { "name": "ShapePalette", "size": 2059 }, { "name": "SizePalette", "size": 2291 }] }, { "name": "Property", "size": 5559 }, { "name": "Shapes", "size": 19118 }, { "name": "Sort", "size": 6887 }, { "name": "Stats", "size": 6557 }, { "name": "Strings", "size": 22026 }] }, { "name": "vis", "children": [{ "name": "axis", "children": [{ "name": "Axes", "size": 1302 }, { "name": "Axis", "size": 24593 }, { "name": "AxisGridLine", "size": 652 }, { "name": "AxisLabel", "size": 636 }, { "name": "CartesianAxes", "size": 6703 }] }, { "name": "controls", "children": [{ "name": "AnchorControl", "size": 2138 }, { "name": "ClickControl", "size": 3824 }, { "name": "Control", "size": 1353 }, { "name": "ControlList", "size": 4665 }, { "name": "DragControl", "size": 2649 }, { "name": "ExpandControl", "size": 2832 }, { "name": "HoverControl", "size": 4896 }, { "name": "IControl", "size": 763 }, { "name": "PanZoomControl", "size": 5222 }, { "name": "SelectionControl", "size": 7862 }, { "name": "TooltipControl", "size": 8435 }] }, { "name": "data", "children": [{ "name": "Data", "size": 20544 }, { "name": "DataList", "size": 19788 }, { "name": "DataSprite", "size": 10349 }, { "name": "EdgeSprite", "size": 3301 }, { "name": "NodeSprite", "size": 19382 }, { "name": "render", "children": [{ "name": "ArrowType", "size": 698 }, { "name": "EdgeRenderer", "size": 5569 }, { "name": "IRenderer", "size": 353 }, { "name": "ShapeRenderer", "size": 2247 }] }, { "name": "ScaleBinding", "size": 11275 }, { "name": "Tree", "size": 7147 }, { "name": "TreeBuilder", "size": 9930 }] }, { "name": "events", "children": [{ "name": "DataEvent", "size": 2313 }, { "name": "SelectionEvent", "size": 1880 }, { "name": "TooltipEvent", "size": 1701 }, { "name": "VisualizationEvent", "size": 1117 }] }, { "name": "legend", "children": [{ "name": "Legend", "size": 20859 }, { "name": "LegendItem", "size": 4614 }, { "name": "LegendRange", "size": 10530 }] }, { "name": "operator", "children": [{ "name": "distortion", "children": [{ "name": "BifocalDistortion", "size": 4461 }, { "name": "Distortion", "size": 6314 }, { "name": "FisheyeDistortion", "size": 3444 }] }, { "name": "encoder", "children": [{ "name": "ColorEncoder", "size": 3179 }, { "name": "Encoder", "size": 4060 }, { "name": "PropertyEncoder", "size": 4138 }, { "name": "ShapeEncoder", "size": 1690 }, { "name": "SizeEncoder", "size": 1830 }] }, { "name": "filter", "children": [{ "name": "FisheyeTreeFilter", "size": 5219 }, { "name": "GraphDistanceFilter", "size": 3165 }, { "name": "VisibilityFilter", "size": 3509 }] }, { "name": "IOperator", "size": 1286 }, { "name": "label", "children": [{ "name": "Labeler", "size": 9956 }, { "name": "RadialLabeler", "size": 3899 }, { "name": "StackedAreaLabeler", "size": 3202 }] }, { "name": "layout", "children": [{ "name": "AxisLayout", "size": 6725 }, { "name": "BundledEdgeRouter", "size": 3727 }, { "name": "CircleLayout", "size": 9317 }, { "name": "CirclePackingLayout", "size": 12003 }, { "name": "DendrogramLayout", "size": 4853 }, { "name": "ForceDirectedLayout", "size": 8411 }, { "name": "IcicleTreeLayout", "size": 4864 }, { "name": "IndentedTreeLayout", "size": 3174 }, { "name": "Layout", "size": 7881 }, { "name": "NodeLinkTreeLayout", "size": 12870 }, { "name": "PieLayout", "size": 2728 }, { "name": "RadialTreeLayout", "size": 12348 }, { "name": "RandomLayout", "size": 870 }, { "name": "StackedAreaLayout", "size": 9121 }, { "name": "TreeMapLayout", "size": 9191 }] }, { "name": "Operator", "size": 2490 }, { "name": "OperatorList", "size": 5248 }, { "name": "OperatorSequence", "size": 4190 }, { "name": "OperatorSwitch", "size": 2581 }, { "name": "SortOperator", "size": 2023 }] }, { "name": "Visualization", "size": 16540 }] }] }
}
</script>
I'm trying to do something with Elasticsearch that should be quite simple. I have an index which contains documents of the shape: {"timestamp": int, "pricePerUnit": int, "units": int}. I want to visualize the average price over time in a histogram. Note that I don't want the average of the "pricePerUnit", I want the average price paid per unit, which means finding the total value in each time bucket by multiplying the "pricePerUnit" by the "units" for each document, and summing the total value sold in each document, then dividing by the sum of the total units sold in the time bucket to get the average price paid per unit. A standard Kibana line chart won't work. I can get the average "pricePerUnit * units", but can't divide this aggregation by the sum of the total units. Also can't be done in TSVB, as this doesn't allow for scripts/scripted fields. Can't use timelion, because the "timestamp" field isn't a time field (I know, but there's nothing I can do about it). I'm therefore trying to use Vega. However, I'm running into a problem with nested aggregations. Here's the ES query I'm running:
{
"$schema": "https://vega.github.io/schema/vega/v3.json",
"data": {
"name": "vals",
"url": {
"index": "index_name",
"body": {
"aggs": {
"2": {
"histogram": {
"field": "timestamp",
"interval": 2000,
"min_doc_count": 1
},
"aggs": {
"1": {
"avg": {
"field": "pricePerUnit",
"script": {
"inline": "doc['pricePerUnit'].value * doc['units'].value",
"lang": "painless"
}
}
}
}
}
},
"size": 0,
"stored_fields": [
"*"
],
"script_fields": {
"spend": {
"script": {
"source": "doc['pricePerUnit'].value * doc['units'].value",
"lang": "painless"
}
}
},
"docvalue_fields": [],
"_source": {
"excludes": []
},
"query": {
"bool": {
"must": [],
"filter": [
{
"match_all": {}
},
{
"range": {
"timeslot.startTime": {
"gte": 1621292400,
"lt": 1621428349
}
}
}
],
"should": [],
"must_not": []
}
}
},
"format": {"property": "aggregations.2.buckets"}
}
}
,
"scales": [
{
"name": "yscale",
"type": "linear",
"zero": true,
"domain": {"data": "vals", "field": "1.value"},
"range": "height"
},
{
"name": "xscale",
"type": "time",
"range": "width"
}
],
"axes": [
{"scale": "yscale", "orient": "left"},
{"scale": "xscale", "orient": "bottom"}
],
"marks": [
{
"type": "line",
"encode": {
"update": {
"x": {"scale": "xscale", "field": "key"},
"y": {"scale": "yscale", "field": "1.value"}
}
}
}
]
}
It gives me the following result set:
"took": 1,
"timed_out": false,
"_shards": {
"total": 4,
"successful": 4,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 401,
"max_score": null,
"hits": []
},
"aggregations": {
"2": {
"buckets": [
{
"1": {
"value": 86340
},
"key": 1621316000,
"doc_count": 7
},
{
"1": {
"value": 231592.92307692306
},
"key": 1621318000,
"doc_count": 13
},
{
"1": {
"value": 450529.23529411765
},
"key": 1621320000,
"doc_count": 17
},
{
"1": {
"value": 956080.0555555555
},
"key": 1621322000,
"doc_count": 18
},
{
"1": {
"value": 1199865.5714285714
},
"key": 1621324000,
"doc_count": 14
},
{
"1": {
"value": 875300.7368421053
},
"key": 1621326000,
"doc_count": 19
},
{
"1": {
"value": 926738.8
},
"key": 1621328000,
"doc_count": 20
},
{
"1": {
"value": 3239475.3333333335
},
"key": 1621330000,
"doc_count": 18
},
{
"1": {
"value": 3798063.714285714
},
"key": 1621332000,
"doc_count": 21
},
{
"1": {
"value": 482089.5
},
"key": 1621334000,
"doc_count": 4
},
{
"1": {
"value": 222952.33333333334
},
"key": 1621336000,
"doc_count": 12
},
{
"1": {
"value": 742225.75
},
"key": 1621338000,
"doc_count": 8
},
{
"1": {
"value": 204203.25
},
"key": 1621340000,
"doc_count": 4
},
{
"1": {
"value": 294886
},
"key": 1621342000,
"doc_count": 4
},
{
"1": {
"value": 284393.75
},
"key": 1621344000,
"doc_count": 4
},
{
"1": {
"value": 462800.5
},
"key": 1621346000,
"doc_count": 4
},
{
"1": {
"value": 233321.2
},
"key": 1621348000,
"doc_count": 5
},
{
"1": {
"value": 436757.8
},
"key": 1621350000,
"doc_count": 5
},
{
"1": {
"value": 4569021
},
"key": 1621352000,
"doc_count": 1
},
{
"1": {
"value": 368489.5
},
"key": 1621354000,
"doc_count": 4
},
{
"1": {
"value": 208359.4
},
"key": 1621356000,
"doc_count": 5
},
{
"1": {
"value": 7827146.375
},
"key": 1621358000,
"doc_count": 8
},
{
"1": {
"value": 63873.5
},
"key": 1621360000,
"doc_count": 6
},
{
"1": {
"value": 21300
},
"key": 1621364000,
"doc_count": 1
},
{
"1": {
"value": 138500
},
"key": 1621366000,
"doc_count": 2
},
{
"1": {
"value": 5872400
},
"key": 1621372000,
"doc_count": 1
},
{
"1": {
"value": 720200
},
"key": 1621374000,
"doc_count": 1
},
{
"1": {
"value": 208634.33333333334
},
"key": 1621402000,
"doc_count": 3
},
{
"1": {
"value": 306248.5
},
"key": 1621404000,
"doc_count": 10
},
{
"1": {
"value": 328983.77777777775
},
"key": 1621406000,
"doc_count": 18
},
{
"1": {
"value": 1081724
},
"key": 1621408000,
"doc_count": 10
},
{
"1": {
"value": 2451076.785714286
},
"key": 1621410000,
"doc_count": 14
},
{
"1": {
"value": 1952910.2857142857
},
"key": 1621412000,
"doc_count": 14
},
{
"1": {
"value": 2294818.1875
},
"key": 1621414000,
"doc_count": 16
},
{
"1": {
"value": 2841910.388888889
},
"key": 1621416000,
"doc_count": 18
},
{
"1": {
"value": 2401278.9523809524
},
"key": 1621418000,
"doc_count": 21
},
{
"1": {
"value": 4311845.4
},
"key": 1621420000,
"doc_count": 5
},
{
"1": {
"value": 617102.5333333333
},
"key": 1621422000,
"doc_count": 15
},
{
"1": {
"value": 590469.7142857143
},
"key": 1621424000,
"doc_count": 14
},
{
"1": {
"value": 391918.85714285716
},
"key": 1621426000,
"doc_count": 14
},
{
"1": {
"value": 202163.66666666666
},
"key": 1621428000,
"doc_count": 3
}
]
}
}
}
The problem is that I can't extract the "value" field from the "1" sub-aggregation. I've tried using a flatten transform, but it doesn't seem to work. If anyone can either:
a) Tell me how to solve this specific problem with Vega; or
b) Tell me another way to solve my original problem
I'd be much obliged!
Your DSL query is looking great. If I've read this correctly I believe what you are looking for is a project transform. This can make life a lot easier when dealing with nested variables, as there are certain instances where they just don't function as expected.
You also need to reference data within marks otherwise it will plot nothing.
Below is how to fix this, you'll just need to add your url parameter in.
{
$schema: https://vega.github.io/schema/vega/v3.json
data: [
{
name: vals
url: ... // fill this in
transform: [
{
type: project
fields: [
1.value
doc_count
key
]
as: [
val
doc_count
key
]
}
]
}
]
scales: [
{
name: yscale
type: linear
zero: true
domain: {
data: vals
field: val
}
range: height
}
{
name: xscale
type: time
domain: {
data: vals
field: key
}
range: width
}
]
axes: [
{
scale: yscale
orient: left
}
{
scale: xscale
orient: bottom
}
]
marks: [
{
type: line
from: {
data: vals
}
encode: {
update: {
x: {
scale: xscale
field: key
}
y: {
scale: yscale
field: val
}
}
}
}
]
}
In future if you are having issues, look at the examples found on the Vega Gallery. They also have extensive documentation. These two combined is all you need.
When I create a funnel chart with a lot of data, the labels are going outside of the chart div, like this
Is it possible to fix this or do I need to create another div with legends only ?
var userInfo = JSON.parse('#Html.Raw(DataJson)');
var chart = AmCharts.makeChart("chartdiv", {
"type": "funnel",
"theme": "light",
"dataProvider": userInfo,
"balloon": {
"fixedPosition": false
},
"valueField": "Quantidade",
"titleField": "Variac",
"marginRight": 250,
"marginLeft": 30,
"startX": 0,
"depth3D": 50,
"angle": 25,
"outlineAlpha": 1,
"outlineColor": "#FFFFFF",
"outlineThickness": 0.5,
"labelPosition": "right",
"balloonText": "[[Variac]]: [[Quantidade]]",
});
Here is a demo that illustrates the problem.
http://jsfiddle.net/abngzewr/3/
There isn't a way to prevent labels from leaving the chart div, but you can work around this by setting a hideLabelsPercent value that hides the smaller slices and then create a legend that lists all the slices.
AmCharts.makeChart("chartdiv", {
// ...
hideLabelsPercent: 2, //hide labels of slices that take up < 2% in size
// ...
});
Since you have a lot of data, you can create a legend in an external div using divId so you have room for both the chart and legend separately.
var chart = AmCharts.makeChart("chartdiv", {
"type": "funnel",
"theme": "light",
"dataProvider": [{
"title": "Website visits",
"value": 200
}, {
"title": "Downloads",
"value": 123
}, {
"title": "Requested price list",
"value": 98
}, {
"title": "Contaced for more info",
"value": 72
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Contacted for support",
"value": 35
}, {
"title": "Purchased additional products",
"value": 26
},
{
"title": "Downloads",
"value": 123
}, {
"title": "Requested price list",
"value": 98
}, {
"title": "Contaced for more info",
"value": 72
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Contacted for support",
"value": 35
},
{
"title": "Downloads",
"value": 123
}, {
"title": "Requested price list",
"value": 98
}, {
"title": "Contaced for more info",
"value": 72
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Contacted for support",
"value": 35
},
{
"title": "Downloads",
"value": 123
}, {
"title": "Requested price list",
"value": 98
}, {
"title": "Contaced for more info",
"value": 72
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Contacted for support",
"value": 35
},
{
"title": "Downloads",
"value": 123
}, {
"title": "Requested price list",
"value": 98
}, {
"title": "Contaced for more info",
"value": 72
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Contacted for support",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
}, {
"title": "Purchased",
"value": 35
},
],
"balloon": {
"fixedPosition": true
},
"valueField": "value",
"titleField": "title",
"marginRight": 250,
"marginLeft": 30,
"startX": 0,
"depth3D": 50,
"angle": 25,
"outlineAlpha": 1,
"outlineColor": "#FFFFFF",
"hideLabelsPercent": 2,
"outlineThickness": 2,
"labelPosition": "right",
"balloonText": "[[title]]: [[value]]n[[description]]",
"export": {
"enabled": true
},
"legend": {
"divId": "legenddiv"
}
});
#chartdiv {
width: 100%;
height: 500px;
}
#legenddiv {
position: relative;
}
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/funnel.js"></script>
<script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script>
<link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" />
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>
<div id="legenddiv"></div>
I'm very new with elastic search and kibana . I'm using vega plugin in kibana visualization.
But not able to create Bar Chart using elastic search aggs.
I'm getting proper result when I'm using kibana dev tools.
I'am attaching the following details with the sample code after run this I'm getting a blank page
Visualization Section:
{
"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"autosize": "fit",
"padding": 6,
"data": [
{
"name": "traffic-revenue",
"url": {
"index": "brnl_tms_plaza",
"body": {
"size": "0",
"aggs": {
"group_by_vehicle_subcat": {
"terms": {
"field": "VehicleSubCatCode.keyword"
}
}
}
},
"format": {
"property": "aggregations.group_by_vehicle_subcat.buckets"
}
}
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {
"data": "traffic-revenue",
"field": "key"
},
"range": "width",
"padding": 0.05,
"round": true
},
{
"name": "yscale",
"domain": {
"data": "traffic-revenue",
"field": "doc_count"
},
"nice": true,
"range": "height"
}
],
"axes": [
{
"orient": "bottom",
"scale": "xscale"
},
{"orient": "left", "scale": "yscale"}
],
"marks": [
{
"type": "rect",
"from": {
"data": "traffic-revenue"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "key",
"axis": {"title": "Vehicle category"}
},
"width": {
"scale": "xscale",
"band": 1
},
"y": {
"scale": "yscale",
"field": "doc_count",
"axis": {"title": "Vehicle Rate Count"}
},
"y2": {
"scale": "yscale",
"value": 0
}
},
"update": {
"fill": {"value": "steelblue"}
},
"hover": {"fill": {"value": "red"}}
}
}
]
}
Data Set
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 48,
"max_score": 0,
"hits": []
},
"aggregations": {
"group_by_vehicle_subcat": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "LMV",
"doc_count": 35
},
{
"key": "BUS",
"doc_count": 3
},
{
"key": "LCV",
"doc_count": 3
},
{
"key": "MAV-5",
"doc_count": 3
},
{
"key": "MAV-4 with trailer",
"doc_count": 2
},
{
"key": "MAV-3 without trailer",
"doc_count": 1
},
{
"key": "MINI-BUS",
"doc_count": 1
}
]
}
}
}
I would recommend debugging your vega code using static data to make sure it is defined properly.
I'm not sure why, but I was able to get your visualization to draw when I set the autosize property to none and set the height and width explicitly.
Here is a vega specification based off of the one you provided which should run in the online vega editor.
{
"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"autosize": "none",
"width": 400,
"height": 500,
"padding": 20,
"data": [
{
"name": "traffic-revenue",
"values": [
{"key": "a", "doc_count": 5},
{"key": "b", "doc_count": 22},
{"key": "c", "doc_count": 1},
{"key": "d", "doc_count": 7},
{"key": "e", "doc_count": 12},
{"key": "f", "doc_count": 2}
]
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {
"data": "traffic-revenue",
"field": "key"
},
"range": "width",
"padding": 0.05,
"round": true
},
{
"name": "yscale",
"domain": {
"data": "traffic-revenue",
"field": "doc_count"
},
"nice": true,
"range": "height"
}
],
"axes": [
{
"orient": "bottom",
"scale": "xscale"
},
{"orient": "left", "scale": "yscale"}
],
"marks": [
{
"type": "rect",
"from": {
"data": "traffic-revenue"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "key",
"axis": {"title": "Vehicle category"}
},
"width": {
"scale": "xscale",
"band": 1
},
"y": {
"scale": "yscale",
"field": "doc_count",
"axis": {"title": "Vehicle Rate Count"}
},
"y2": {
"scale": "yscale",
"value": 0
}
},
"update": {
"fill": {"value": "steelblue"}
},
"hover": {"fill": {"value": "red"}}
}
}
]
}
You may already know this since you have the format tag on your elasticsearch data, but if your visualization is working with statically defined data, and not when you pull data from an elasticsearch query, try looking at the data source directly using the vega debuggging functions described here https://vega.github.io/vega/docs/api/debugging/.
Running the following in the browser console should let you look at the data in the format vega is receiving it. VEGA_DEBUG.view.data("")