Page MenuHomePhabricator

D20500.id49000.diff
No OneTemporary

D20500.id49000.diff

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' => '7853a69b',
+ 'rsrc/css/phui/phui-chart.css' => '10135a9d',
'rsrc/css/phui/phui-cms.css' => '8c05c41e',
'rsrc/css/phui/phui-comment-form.css' => '68a2d99a',
'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0',
@@ -389,7 +389,8 @@
'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' => 'a3516cea',
+ 'rsrc/js/application/fact/Chart.js' => 'b88a227d',
+ 'rsrc/js/application/fact/ChartCurtainView.js' => 'd10a3c25',
'rsrc/js/application/files/behavior-document-engine.js' => '243d6c22',
'rsrc/js/application/files/behavior-icon-composer.js' => '38a6cedb',
'rsrc/js/application/files/behavior-launch-icon-composer.js' => 'a17b84f1',
@@ -696,7 +697,8 @@
'javelin-behavior-user-menu' => '60cd9241',
'javelin-behavior-view-placeholder' => 'a9942052',
'javelin-behavior-workflow' => '9623adc1',
- 'javelin-chart' => 'a3516cea',
+ 'javelin-chart' => 'b88a227d',
+ 'javelin-chart-curtain-view' => 'd10a3c25',
'javelin-color' => '78f811c9',
'javelin-cookie' => '05d290ef',
'javelin-diffusion-locate-file-source' => '94243d89',
@@ -823,7 +825,7 @@
'phui-calendar-day-css' => '9597d706',
'phui-calendar-list-css' => 'ccd7e4e2',
'phui-calendar-month-css' => 'cb758c42',
- 'phui-chart-css' => '7853a69b',
+ 'phui-chart-css' => '10135a9d',
'phui-cms-css' => '8c05c41e',
'phui-comment-form-css' => '68a2d99a',
'phui-comment-panel-css' => 'ec4e31c0',
@@ -1767,10 +1769,6 @@
'javelin-workflow',
'phabricator-draggable-list',
),
- 'a3516cea' => array(
- 'phui-chart-css',
- 'd3',
- ),
'a4356cde' => array(
'javelin-install',
'javelin-dom',
@@ -1935,6 +1933,11 @@
'javelin-dom',
'phabricator-draggable-list',
),
+ 'b88a227d' => array(
+ 'phui-chart-css',
+ 'd3',
+ 'javelin-chart-curtain-view',
+ ),
'b9109f8f' => array(
'javelin-behavior',
'javelin-uri',
diff --git a/src/applications/fact/engine/PhabricatorChartRenderingEngine.php b/src/applications/fact/engine/PhabricatorChartRenderingEngine.php
--- a/src/applications/fact/engine/PhabricatorChartRenderingEngine.php
+++ b/src/applications/fact/engine/PhabricatorChartRenderingEngine.php
@@ -94,10 +94,8 @@
'div',
array(
'id' => $chart_node_id,
- 'style' => 'background: #ffffff; '.
- 'height: 480px; ',
- ),
- '');
+ 'class' => 'chart-hardpoint',
+ ));
$data_uri = urisprintf('/fact/chart/%s/draw/', $chart_key);
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
@@ -10,6 +10,7 @@
}
.chart .axis text {
+ font: {$basefont};
fill: {$darkgreytext};
}
@@ -52,3 +53,43 @@
border-radius: 8px;
pointer-events: none;
}
+
+.chart-hardpoint {
+ min-height: 480px;
+ overflow: hidden;
+ position: relative;
+}
+
+.device-desktop .chart-container {
+ position: absolute;
+ bottom: 0;
+ top: 0;
+ left: 0;
+ right: 300px;
+}
+
+.device .chart-container {
+ min-height: 480px;
+}
+
+.device-desktop .chart-curtain {
+ width: 300px;
+ position: absolute;
+ bottom: 0;
+ top: 0;
+ right: 0;
+}
+
+.chart-function-label-list {
+ background: {$lightbluebackground};
+ border: 1px solid {$lightblueborder};
+ padding: 8px 12px;
+}
+
+.device-desktop .chart-function-label-list {
+ margin-top: 23px;
+}
+
+.chart-function-label-list-item .phui-icon-view {
+ margin-right: 8px;
+}
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
@@ -2,6 +2,7 @@
* @provides javelin-chart
* @requires phui-chart-css
* d3
+ * javelin-chart-curtain-view
*/
JX.install('Chart', {
@@ -14,6 +15,8 @@
members: {
_rootNode: null,
_data: null,
+ _chartContainerNode: null,
+ _curtain: null,
setData: function(blob) {
this._data = blob;
@@ -26,23 +29,42 @@
}
var hardpoint = this._rootNode;
+ var curtain = this._getCurtain();
+ var container_node = this._getChartContainerNode();
+
+ var content = [
+ container_node,
+ curtain.getNode(),
+ ];
+
+ JX.DOM.setContent(hardpoint, content);
// Remove the old chart (if one exists) before drawing the new chart.
- JX.DOM.setContent(hardpoint, []);
+ JX.DOM.setContent(container_node, []);
- var viewport = JX.Vector.getDim(hardpoint);
+ var viewport = JX.Vector.getDim(container_node);
var config = this._data;
function css_function(n) {
return n + '(' + JX.$A(arguments).slice(1).join(', ') + ')';
}
- var padding = {
- top: 24,
- left: 48,
- bottom: 48,
- right: 32
- };
+ var padding = {};
+ if (JX.Device.isDesktop()) {
+ padding = {
+ top: 24,
+ left: 48,
+ bottom: 48,
+ right: 12
+ };
+ } else {
+ padding = {
+ top: 12,
+ left: 36,
+ bottom: 24,
+ right: 4
+ };
+ }
var size = {
frameWidth: viewport.x,
@@ -61,20 +83,20 @@
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
- var svg = d3.select('#' + hardpoint.id).append('svg')
+ var svg = d3.select(container_node).append('svg')
.attr('width', size.frameWidth)
.attr('height', size.frameHeight)
.attr('class', 'chart');
var g = svg.append('g')
- .attr(
- 'transform',
- css_function('translate', padding.left, padding.top));
+ .attr(
+ 'transform',
+ css_function('translate', padding.left, padding.top));
g.append('rect')
- .attr('class', 'inner')
- .attr('width', size.width)
- .attr('height', size.height);
+ .attr('class', 'inner')
+ .attr('width', size.width)
+ .attr('height', size.height);
x.domain([this._newDate(config.xMin), this._newDate(config.xMax)]);
y.domain([config.yMin, config.yMax]);
@@ -84,16 +106,20 @@
.attr('class', 'chart-tooltip')
.style('opacity', 0);
+ curtain.reset();
+
for (var idx = 0; idx < config.datasets.length; idx++) {
var dataset = config.datasets[idx];
switch (dataset.type) {
case 'stacked-area':
- this._newStackedArea(g, dataset, x, y, div);
+ this._newStackedArea(g, dataset, x, y, div, curtain);
break;
}
}
+ curtain.redraw();
+
g.append('g')
.attr('class', 'x axis')
.attr('transform', css_function('translate', 0, size.height))
@@ -105,7 +131,7 @@
.call(yAxis);
},
- _newStackedArea: function(g, dataset, x, y, div) {
+ _newStackedArea: function(g, dataset, x, y, div, curtain) {
var to_date = JX.bind(this, this._newDate);
var area = d3.area()
@@ -155,11 +181,30 @@
div.style('opacity', 0);
});
+ curtain.addFunctionLabel('Important Data');
}
},
_newDate: function(epoch) {
return new Date(epoch * 1000);
+ },
+
+ _getCurtain: function() {
+ if (!this._curtain) {
+ this._curtain = new JX.ChartCurtainView();
+ }
+ return this._curtain;
+ },
+
+ _getChartContainerNode: function() {
+ if (!this._chartContainerNode) {
+ var attrs = {
+ className: 'chart-container'
+ };
+
+ this._chartContainerNode = JX.$N('div', attrs);
+ }
+ return this._chartContainerNode;
}
}
diff --git a/webroot/rsrc/js/application/fact/ChartCurtainView.js b/webroot/rsrc/js/application/fact/ChartCurtainView.js
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/js/application/fact/ChartCurtainView.js
@@ -0,0 +1,85 @@
+/**
+ * @provides javelin-chart-curtain-view
+ */
+JX.install('ChartCurtainView', {
+
+ construct: function() {
+ this._labels = [];
+ },
+
+ members: {
+ _node: null,
+ _labels: null,
+ _labelsNode: null,
+
+ getNode: function() {
+ if (!this._node) {
+ var attr = {
+ className: 'chart-curtain'
+ };
+
+ this._node = JX.$N('div', attr);
+ }
+ return this._node;
+ },
+
+ reset: function() {
+ this._labels = [];
+ },
+
+ addFunctionLabel: function(label) {
+ this._labels.push(label);
+ return this;
+ },
+
+ redraw: function() {
+ var content = [this._getFunctionLabelsNode()];
+
+ JX.DOM.setContent(this.getNode(), content);
+ return this;
+ },
+
+ _getFunctionLabelsNode: function() {
+ if (!this._labels.length) {
+ return null;
+ }
+
+ if (!this._labelsNode) {
+ var list_attrs = {
+ className: 'chart-function-label-list'
+ };
+
+ var labels = JX.$N('ul', list_attrs);
+
+ var items = [];
+ for (var ii = 0; ii < this._labels.length; ii++) {
+ items.push(this._newFunctionLabelItem(this._labels[ii]));
+ }
+
+ JX.DOM.setContent(labels, items);
+
+ this._labelsNode = labels;
+ }
+
+ return this._labelsNode;
+ },
+
+ _newFunctionLabelItem: function(item) {
+ var item_attrs = {
+ className: 'chart-function-label-list-item'
+ };
+
+ var icon = new JX.PHUIXIconView()
+ .setIcon('fa-circle');
+
+ var content = [
+ icon.getNode(),
+ item
+ ];
+
+ return JX.$N('li', item_attrs, content);
+ }
+
+ }
+
+});

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 20, 1:23 PM (6 d, 20 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7579841
Default Alt Text
D20500.id49000.diff (10 KB)

Event Timeline