Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15421124
D20814.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D20814.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -141,7 +141,7 @@
'rsrc/css/phui/phui-big-info-view.css' => '362ad37b',
'rsrc/css/phui/phui-box.css' => '5ed3b8cb',
'rsrc/css/phui/phui-bulk-editor.css' => '374d5e30',
- 'rsrc/css/phui/phui-chart.css' => '10135a9d',
+ 'rsrc/css/phui/phui-chart.css' => '14df9ae3',
'rsrc/css/phui/phui-cms.css' => '8c05c41e',
'rsrc/css/phui/phui-comment-form.css' => '68a2d99a',
'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0',
@@ -390,7 +390,7 @@
'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'c715c123',
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => '6a85bc5a',
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '47a0728b',
- 'rsrc/js/application/fact/Chart.js' => 'eec96de0',
+ 'rsrc/js/application/fact/Chart.js' => 'ddb9dd1f',
'rsrc/js/application/fact/ChartCurtainView.js' => '86954222',
'rsrc/js/application/fact/ChartFunctionLabel.js' => '81de1dab',
'rsrc/js/application/files/behavior-document-engine.js' => '243d6c22',
@@ -699,7 +699,7 @@
'javelin-behavior-user-menu' => '60cd9241',
'javelin-behavior-view-placeholder' => 'a9942052',
'javelin-behavior-workflow' => '9623adc1',
- 'javelin-chart' => 'eec96de0',
+ 'javelin-chart' => 'ddb9dd1f',
'javelin-chart-curtain-view' => '86954222',
'javelin-chart-function-label' => '81de1dab',
'javelin-color' => '78f811c9',
@@ -828,7 +828,7 @@
'phui-calendar-day-css' => '9597d706',
'phui-calendar-list-css' => 'ccd7e4e2',
'phui-calendar-month-css' => 'cb758c42',
- 'phui-chart-css' => '10135a9d',
+ 'phui-chart-css' => '14df9ae3',
'phui-cms-css' => '8c05c41e',
'phui-comment-form-css' => '68a2d99a',
'phui-comment-panel-css' => 'ec4e31c0',
@@ -2066,6 +2066,12 @@
'javelin-uri',
'phabricator-notification',
),
+ 'ddb9dd1f' => array(
+ 'phui-chart-css',
+ 'd3',
+ 'javelin-chart-curtain-view',
+ 'javelin-chart-function-label',
+ ),
'dfa1d313' => array(
'javelin-behavior',
'javelin-dom',
@@ -2127,12 +2133,6 @@
'phabricator-keyboard-shortcut',
'javelin-stratcom',
),
- 'eec96de0' => array(
- 'phui-chart-css',
- 'd3',
- 'javelin-chart-curtain-view',
- 'javelin-chart-function-label',
- ),
'ef836bf2' => array(
'javelin-behavior',
'javelin-dom',
diff --git a/src/applications/fact/chart/PhabricatorChartStackedAreaDataset.php b/src/applications/fact/chart/PhabricatorChartStackedAreaDataset.php
--- a/src/applications/fact/chart/PhabricatorChartStackedAreaDataset.php
+++ b/src/applications/fact/chart/PhabricatorChartStackedAreaDataset.php
@@ -17,8 +17,8 @@
$datapoints = $function->newDatapoints($data_query);
foreach ($datapoints as $point) {
- $x = $point['x'];
- $function_points[$function_idx][$x] = $point;
+ $x_value = $point['x'];
+ $function_points[$function_idx][$x_value] = $point;
}
}
@@ -140,12 +140,67 @@
$series = array_reverse($series);
+ // We're going to group multiple events into a single point if they have
+ // X values that are very close to one another.
+ //
+ // If the Y values are also close to one another (these points are near
+ // one another in a horizontal line), it can be hard to select any
+ // individual point with the mouse.
+ //
+ // Even if the Y values are not close together (the points are on a
+ // fairly steep slope up or down), it's usually better to be able to
+ // mouse over a single point at the top or bottom of the slope and get
+ // a summary of what's going on.
+
+ $domain_max = $data_query->getMaximumValue();
+ $domain_min = $data_query->getMinimumValue();
+ $resolution = ($domain_max - $domain_min) / 100;
+
$events = array();
foreach ($raw_points as $function_idx => $points) {
$event_list = array();
+
+ $event_group = array();
+ $head_event = null;
foreach ($points as $point) {
- $event_list[] = $point;
+ $x = $point['x'];
+
+ if ($head_event === null) {
+ // We don't have any points yet, so start a new group.
+ $head_event = $x;
+ $event_group[] = $point;
+ } else if (($x - $head_event) <= $resolution) {
+ // This point is close to the first point in this group, so
+ // add it to the existing group.
+ $event_group[] = $point;
+ } else {
+ // This point is not close to the first point in the group,
+ // so create a new group.
+ $event_list[] = $event_group;
+ $head_event = $x;
+ $event_group = array($point);
+ }
}
+
+ if ($event_group) {
+ $event_list[] = $event_group;
+ }
+
+ $event_spec = array();
+ foreach ($event_list as $key => $event_points) {
+ // NOTE: We're using the last point as the representative point so
+ // that you can learn about a section of a chart by hovering over
+ // the point to right of the section, which is more intuitive than
+ // other points.
+ $event = last($event_points);
+
+ $event = $event + array(
+ 'n' => count($event_points),
+ );
+
+ $event_list[$key] = $event;
+ }
+
$events[] = $event_list;
}
diff --git a/webroot/rsrc/css/phui/phui-chart.css b/webroot/rsrc/css/phui/phui-chart.css
--- a/webroot/rsrc/css/phui/phui-chart.css
+++ b/webroot/rsrc/css/phui/phui-chart.css
@@ -36,16 +36,17 @@
}
.chart .point {
- fill: {$lightblue};
+ fill: #ffffff;
stroke: {$blue};
- stroke-width: 1px;
+ stroke-width: 2px;
+ position: relative;
+ cursor: pointer;
}
.chart-tooltip {
position: absolute;
text-align: center;
width: 120px;
- height: 16px;
overflow: hidden;
padding: 2px;
background: {$lightbluebackground};
diff --git a/webroot/rsrc/js/application/fact/Chart.js b/webroot/rsrc/js/application/fact/Chart.js
--- a/webroot/rsrc/js/application/fact/Chart.js
+++ b/webroot/rsrc/js/application/fact/Chart.js
@@ -133,6 +133,8 @@
},
_newStackedArea: function(g, dataset, x, y, div, curtain) {
+ var ii;
+
var to_date = JX.bind(this, this._newDate);
var area = d3.area()
@@ -144,7 +146,7 @@
.x(function(d) { return x(to_date(d.x)); })
.y(function(d) { return y(d.y1); });
- for (var ii = 0; ii < dataset.data.length; ii++) {
+ for (ii = 0; ii < dataset.data.length; ii++) {
var label = new JX.ChartFunctionLabel(dataset.labels[ii]);
var fill_color = label.getFillColor() || label.getColor();
@@ -160,6 +162,11 @@
.style('stroke', stroke_color)
.attr('d', line(dataset.data[ii]));
+ curtain.addFunctionLabel(label);
+ }
+
+ // Now that we've drawn all the areas and lines, draw the dots.
+ for (ii = 0; ii < dataset.data.length; ii++) {
g.selectAll('dot')
.data(dataset.events[ii])
.enter()
@@ -178,8 +185,16 @@
var d_d = dd.getDate();
+ var y = parseInt(d.y1);
+
+ var label = d.n + ' Points';
+
+ var view =
+ d_y + '-' + d_m + '-' + d_d + ': ' + y + '<br />' +
+ label;
+
div
- .html(d_y + '-' + d_m + '-' + d_d + ': ' + d.y1)
+ .html(view)
.style('opacity', 0.9)
.style('left', (d3.event.pageX - 60) + 'px')
.style('top', (d3.event.pageY - 38) + 'px');
@@ -187,9 +202,8 @@
.on('mouseout', function() {
div.style('opacity', 0);
});
-
- curtain.addFunctionLabel(label);
}
+
},
_newDate: function(epoch) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 22, 9:12 PM (2 d, 14 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7655263
Default Alt Text
D20814.diff (7 KB)
Attached To
Mode
D20814: In stacked area charts, group nearby points so they don't overlap
Attached
Detach File
Event Timeline
Log In to Comment