diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -120,6 +120,7 @@ 'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59', 'rsrc/css/phui/calendar/phui-calendar-month.css' => 'a92e47d2', 'rsrc/css/phui/calendar/phui-calendar.css' => '8675968e', + 'rsrc/css/phui/datakit/phui-bar-chart.css' => '8fa2a563', 'rsrc/css/phui/phui-action-header-view.css' => '89c497e7', 'rsrc/css/phui/phui-action-list.css' => '9ee9910a', 'rsrc/css/phui/phui-action-panel.css' => 'd2e088bd', @@ -772,6 +773,7 @@ 'phriction-document-css' => '7d7f0071', 'phui-action-header-view-css' => '89c497e7', 'phui-action-panel-css' => 'd2e088bd', + 'phui-bar-chart-css' => '8fa2a563', 'phui-box-css' => '7b3a2eed', 'phui-button-css' => 'ffe12633', 'phui-calendar-css' => '8675968e', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1124,6 +1124,7 @@ 'PHUIActionHeaderView' => 'view/phui/PHUIActionHeaderView.php', 'PHUIActionPanelExample' => 'applications/uiexample/examples/PHUIActionPanelExample.php', 'PHUIActionPanelView' => 'view/phui/PHUIActionPanelView.php', + 'PHUIBarChartView' => 'view/phui/datakit/PHUIBarChartView.php', 'PHUIBoxExample' => 'applications/uiexample/examples/PHUIBoxExample.php', 'PHUIBoxView' => 'view/phui/PHUIBoxView.php', 'PHUIButtonBarExample' => 'applications/uiexample/examples/PHUIButtonBarExample.php', @@ -1136,6 +1137,7 @@ 'PHUIColorPalletteExample' => 'applications/uiexample/examples/PHUIColorPalletteExample.php', 'PHUICrumbView' => 'view/phui/PHUICrumbView.php', 'PHUICrumbsView' => 'view/phui/PHUICrumbsView.php', + 'PHUIDataKitExample' => 'applications/uiexample/examples/PHUIDataKitExample.php', 'PHUIDocumentExample' => 'applications/uiexample/examples/PHUIDocumentExample.php', 'PHUIDocumentView' => 'view/phui/PHUIDocumentView.php', 'PHUIDurableColumn' => 'view/phui/PHUIDurableColumn.php', @@ -4350,6 +4352,7 @@ 'PHUIActionHeaderView' => 'AphrontView', 'PHUIActionPanelExample' => 'PhabricatorUIExample', 'PHUIActionPanelView' => 'AphrontTagView', + 'PHUIBarChartView' => 'AphrontTagView', 'PHUIBoxExample' => 'PhabricatorUIExample', 'PHUIBoxView' => 'AphrontTagView', 'PHUIButtonBarExample' => 'PhabricatorUIExample', @@ -4362,6 +4365,7 @@ 'PHUIColorPalletteExample' => 'PhabricatorUIExample', 'PHUICrumbView' => 'AphrontView', 'PHUICrumbsView' => 'AphrontView', + 'PHUIDataKitExample' => 'PhabricatorUIExample', 'PHUIDocumentExample' => 'PhabricatorUIExample', 'PHUIDocumentView' => 'AphrontTagView', 'PHUIDurableColumn' => 'AphrontTagView', diff --git a/src/applications/uiexample/examples/PHUIDataKitExample.php b/src/applications/uiexample/examples/PHUIDataKitExample.php new file mode 100644 --- /dev/null +++ b/src/applications/uiexample/examples/PHUIDataKitExample.php @@ -0,0 +1,107 @@ +setFluidLayout(true) + ->setBorder(true); + + $users = array( + 'Jan 1, 2014' => 1, + 'Jan 2, 2014' => 2, + 'Jan 3, 2014' => 3, + 'Jan 4, 2014' => 4, + 'Jan 5, 2014' => 5, + 'Jan 6, 2014' => 6, + 'Jan 7, 2014' => 7,); + $chart1 = id(new PHUIBarChartView()) + ->setMinValue(0) + ->setMaxValue(20) + ->setUnit(pht('Users')) + ->setBars($users); + + $tasks = array( + 'Jan 1, 2014' => 21, + 'Jan 2, 2014' => 12, + 'Jan 3, 2014' => 8, + 'Jan 4, 2014' => 21, + 'Jan 5, 2014' => 0, + 'Jan 6, 2014' => 16, + 'Jan 7, 2014' => 70,); + $chart2 = id(new PHUIBarChartView()) + ->setMinValue(0) + ->setMaxValue(50) + ->setUnit(pht('Tasks')) + ->setBars($tasks); + + $commits = array( + 'Jan 1, 2014' => 1, + 'Jan 2, 2014' => 6, + 'Jan 3, 2014' => 8, + 'Jan 4, 2014' => 11, + 'Jan 5, 2014' => 6, + 'Jan 6, 2014' => 16, + 'Jan 7, 2014' => 20,); + $chart3 = id(new PHUIBarChartView()) + ->setMinValue(0) + ->setMaxValue(100) + ->setUnit(pht('Commits')) + ->setBars($commits); + + $funds = array( + 'Jan 1, 2014' => '0.00', + 'Jan 2, 2014' => '5.00', + 'Jan 3, 2014' => '0.00', + 'Jan 4, 2014' => '1.00', + 'Jan 5, 2014' => '11.00', + 'Jan 6, 2014' => '12.00', + 'Jan 7, 2014' => '5.00',); + $chart4 = id(new PHUIBarChartView()) + ->setMinValue(0) + ->setMaxValue(100) + ->setUnit(pht('Dollars')) + ->setBars($funds); + + + $panel1 = id(new PHUIActionPanelView()) + ->setChart($chart1) + ->setHeader(pht('Daily Active Users')) + ->setSubHeader( + pht('How many people come to work each day.')); + $view->addColumn($panel1); + + $panel2 = id(new PHUIActionPanelView()) + ->setChart($chart2) + ->setHeader(pht('Daily Task Creation')) + ->setSubHeader( + pht('How much are we over-extending ourselves.')); + $view->addColumn($panel2); + + $panel3 = id(new PHUIActionPanelView()) + ->setChart($chart3) + ->setHeader(pht('Daily Commits')) + ->setSubHeader( + pht('Obviously, the only correct metric for productivity.')); + $view->addColumn($panel3); + + $panel4 = id(new PHUIActionPanelView()) + ->setChart($chart4) + ->setHeader(pht('Daily Funding')) + ->setSubHeader( + pht('Can we afford health insurance at the end of the month.')); + $view->addColumn($panel4); + + + return phutil_tag_div('ml', $view); + } +} diff --git a/src/view/phui/PHUIActionPanelView.php b/src/view/phui/PHUIActionPanelView.php --- a/src/view/phui/PHUIActionPanelView.php +++ b/src/view/phui/PHUIActionPanelView.php @@ -9,6 +9,7 @@ private $bigText; private $state; private $status; + private $chart; const STATE_WARN = 'phui-action-panel-warn'; const STATE_INFO = 'phui-action-panel-info'; @@ -52,6 +53,11 @@ return $this; } + public function setChart(PHUIBarChartView $chart) { + $this->chart = $chart; + return $this; + } + protected function getStateIcon() { $icon = new PHUIIconView(); switch ($this->state) { @@ -85,7 +91,6 @@ if ($this->state) { $classes[] = 'phui-action-panel-has-state'; $classes[] = $this->state; - } return array( @@ -125,6 +130,11 @@ $fonticon); } + $chart = null; + if ($this->chart) { + $chart = $this->chart; + } + $header = null; if ($this->header) { $header = $this->header; @@ -165,7 +175,7 @@ array($state_icon, $this->status)); } - return array($icon, $header, $subheader, $status); + return array($icon, $chart, $header, $subheader, $status); } diff --git a/src/view/phui/datakit/PHUIBarChartView.php b/src/view/phui/datakit/PHUIBarChartView.php new file mode 100644 --- /dev/null +++ b/src/view/phui/datakit/PHUIBarChartView.php @@ -0,0 +1,125 @@ +href = $href; + return $this; + } + + public function setMinValue($value) { + $this->minValue = $value; + return $this; + } + + public function setMaxValue($value) { + $this->maxValue = $value; + return $this; + } + + public function setUnit($unit) { + $this->unit = $unit; + return $this; + } + + public function setContext($context) { + $this->context = $context; + return $this; + } + + public function setBars($bars) { + $this->bars = $bars; + return $this; + } + + protected function getTagAttributes() { + require_celerity_resource('phui-bar-chart-css'); + + $classes = array(); + $classes[] = 'phui-bar-chart'; + + return array( + 'class' => implode(' ', $classes), + ); + + } + + protected function getTagContent() { + Javelin::initBehavior('phabricator-tooltips'); + + $cells = array(); + $width = floor(100 / count($this->bars)); + foreach ($this->bars as $context => $data) { + $height = 0; + if (floor($data) > 0) { + $height = ceil(($data / ($this->maxValue - $this->minValue)) * 100); + } + if ($height > 100) { + $height = 100; + } else if ($height < 1) { + $height = 1; + } + + $text = pht('%s: %d %s', $context, $data, $this->unit); + + $bar = phutil_tag( + 'div', + array( + 'class' => 'phui-bar-chart-bar', + 'style' => 'height: '.$height.'%; ',), + null); + + $cells[] = javelin_tag( + 'div', + array( + 'class' => 'phui-bar-chart-cell', + 'style' => 'width: '.$width.'%;', + 'sigil' => 'has-tooltip', + 'meta' => array( + 'tip' => $text, + 'align' => 'S', + 'size' => '300', + ),), + $bar); + } + + $row = phutil_tag( + 'div', + array( + 'class' => 'phui-bar-chart-row', + ), + $cells); + + $table = phutil_tag( + 'div', + array( + 'class' => 'phui-bar-chart-table', + ), + $row); + + $min = phutil_tag( + 'div', + array( + 'class' => 'phui-bar-chart-min', + ), + $this->minValue); + + $max = phutil_tag( + 'div', + array( + 'class' => 'phui-bar-chart-max', + ), + $this->maxValue); + + return array($min, $max, $table); + + } + +} diff --git a/webroot/rsrc/css/phui/datakit/phui-bar-chart.css b/webroot/rsrc/css/phui/datakit/phui-bar-chart.css new file mode 100644 --- /dev/null +++ b/webroot/rsrc/css/phui/datakit/phui-bar-chart.css @@ -0,0 +1,45 @@ +/** + * @provides phui-bar-chart-css + */ + +.phui-bar-chart { + height: 128px; + position: relative; + margin-bottom: 8px; + border-bottom: 1px solid {$lightblueborder}; + padding-right: 28px; +} + +.phui-bar-chart-table { + display: table; + height: 100%; + width: 100%; +} + +.phui-bar-chart-row { + display: table-row; +} + +.phui-bar-chart-cell { + display: table-cell; + vertical-align: bottom; +} + +.phui-bar-chart-bar { + background-color: {$blue}; + margin: 0 3px; +} + +.phui-bar-chart-min { + position: absolute; + bottom: 4px; + right: 4px; + color: {$bluetext}; +} + +.phui-bar-chart-max { + position: absolute; + top: 0; + right: 4px; + color: {$bluetext}; +}