Files
redash/client/app/visualizations/chart/chart-editor.html
2019-05-06 11:30:48 +03:00

478 lines
20 KiB
HTML

<div>
<ul class="tab-nav">
<li ng-class="{active: $ctrl.currentTab == 'general'}">
<a ng-click="$ctrl.setCurrentTab('general')">General</a>
</li>
<li ng-class="{active: $ctrl.currentTab == 'xAxis'}" ng-if="$ctrl.options.globalSeriesType != 'custom'">
<a ng-click="$ctrl.setCurrentTab('xAxis')">X Axis</a>
</li>
<li ng-class="{active: $ctrl.currentTab == 'yAxis'}" ng-if="$ctrl.options.globalSeriesType != 'custom'">
<a ng-click="$ctrl.setCurrentTab('yAxis')">Y Axis</a>
</li>
<li ng-class="{active: $ctrl.currentTab == 'series'}" ng-if="$ctrl.options.globalSeriesType != 'custom'">
<a ng-click="$ctrl.setCurrentTab('series')">Series</a>
</li>
<li ng-class="{active: $ctrl.currentTab == 'colors'}" ng-if="$ctrl.options.globalSeriesType != 'custom'">
<a ng-click="$ctrl.setCurrentTab('colors')">Colors</a>
</li>
<li ng-class="{active: $ctrl.currentTab == 'dataLabels'}" ng-if="$ctrl.options.globalSeriesType != 'custom'">
<a ng-click="$ctrl.setCurrentTab('dataLabels')">Data Labels</a>
</li>
</ul>
<div ng-if="$ctrl.currentTab == 'general'" class="m-t-10 m-b-10">
<div class="form-group">
<label class="control-label">Chart Type</label>
<div ng-if="$ctrl.chartTypes">
<!--the if is a weird workaround-->
<ui-select ng-model="$ctrl.options.globalSeriesType" on-select="$ctrl.chartTypeChanged()">
<ui-select-match placeholder="Choose chart type...">
<div>
<i class="fa fa-{{$select.selected.value.icon}}"></i>
{{$select.selected.value.name}}
</div>
</ui-select-match>
<ui-select-choices repeat="info.chartType as (chartType, info) in $ctrl.chartTypes">
<div>
<i class="fa fa-{{info.value.icon}}"></i>
<span> </span>
<span ng-bind-html="info.value.name | highlight: $select.search"></span>
</div>
</ui-select-choices>
</ui-select>
</div>
</div>
<div class="form-group" ng-class="{'has-error': chartEditor.xAxisColumn.$invalid}">
<label class="control-label">X Column</label>
<ui-select name="xAxisColumn" required ng-model="$ctrl.form.xAxisColumn">
<ui-select-match placeholder="Choose column...">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="column in $ctrl.columnNames | remove:$ctrl.form.yAxisColumns | remove:$ctrl.form.groupby">
<span ng-bind-html="column | highlight: $select.search"></span>
<span> </span>
<small class="text-muted" ng-bind="$ctrl.columns[column].type"></small>
</ui-select-choices>
</ui-select>
</div>
<!-- not using regular validation (chartEditor.yAxisColumns.$invalid) due to a bug in ui-select with multiple choices-->
<div class="form-group" ng-class="{'has-error': !$ctrl.form.yAxisColumns || $ctrl.form.yAxisColumns.length == 0}">
<label class="control-label">Y Columns</label>
<ui-select multiple name="yAxisColumns" required ng-model="$ctrl.form.yAxisColumns">
<ui-select-match placeholder="Choose columns...">{{$item}}</ui-select-match>
<ui-select-choices repeat="column in $ctrl.columnNames | remove:$ctrl.form.groupby | remove:$ctrl.form.xAxisColumn">
<span ng-bind-html="column | highlight: $select.search"></span>
<span> </span>
<small class="text-muted" ng-bind="$ctrl.columns[column].type"></small>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group" ng-if="['custom', 'heatmap'].indexOf($ctrl.options.globalSeriesType) == -1">
<label class="control-label">Group by</label>
<ui-select name="groupby" ng-model="$ctrl.form.groupby" class="clearable">
<ui-select-match allow-clear="true" placeholder="Choose column...">
{{$select.selected}}
</ui-select-match>
<ui-select-choices repeat="column in $ctrl.columnNames | remove:$ctrl.form.yAxisColumns | remove:$ctrl.form.xAxisColumn">
<span ng-bind-html="column | highlight: $select.search"></span>
<span> </span>
<small class="text-muted" ng-bind="$ctrl.columns[column].type"></small>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group" ng-if="$ctrl.showSizeColumnPicker()">
<label class="control-label">Bubble size column</label>
<ui-select name="sizeColumn" ng-model="$ctrl.form.sizeColumn">
<ui-select-match allow-clear="true" placeholder="Choose column...">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="column in $ctrl.columnNames | remove:$ctrl.form.yAxisColumns | remove:$ctrl.form.groupby">
<span ng-bind-html="column | highlight: $select.search"></span>
<span> </span>
<small class="text-muted" ng-bind="$ctrl.columns[column].type"></small>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group" ng-if="$ctrl.showZColumnPicker()">
<label class="control-label">Color Column</label>
<ui-select name="zValColumn" ng-model="$ctrl.form.zValColumn">
<ui-select-match allow-clear="true" placeholder="Choose column...">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="column in $ctrl.columnNames | remove:$ctrl.form.yAxisColumns | remove:$ctrl.form.groupby">
<span ng-bind-html="column | highlight: $select.search"></span><span> </span>
<small class="text-muted" ng-bind="$ctrl.columns[column].type"></small>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group" ng-if="['custom', 'heatmap'].indexOf($ctrl.options.globalSeriesType) == -1">
<label class="control-label">Errors column</label>
<ui-select name="errorColumn" ng-model="$ctrl.form.errorColumn">
<ui-select-match allow-clear="true" placeholder="Choose column...">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="column in $ctrl.columnNames | remove:$ctrl.form.yAxisColumns | remove:$ctrl.form.groupby">
<span ng-bind-html="column | highlight: $select.search"></span>
<span> </span>
<small class="text-muted" ng-bind="$ctrl.columns[column].type"></small>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group" ng-if="$ctrl.options.globalSeriesType === 'pie'">
<label class="control-label">Direction</label>
<ui-select ng-model="$ctrl.options.direction.type">
<ui-select-match placeholder="Choose Direction...">{{$select.selected.label}}</ui-select-match>
<ui-select-choices repeat="direction.value as direction in $ctrl.directions">
<div ng-bind-html="direction.label | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
<div class="checkbox" ng-if="['custom', 'heatmap'].indexOf($ctrl.options.globalSeriesType) == -1">
<label>
<input type="checkbox" ng-model="$ctrl.options.legend.enabled">
<i class="input-helper"></i> Show Legend
</label>
</div>
<div class="checkbox" ng-if="$ctrl.options.globalSeriesType == 'box'">
<label>
<input type="checkbox" ng-model="$ctrl.options.showpoints">
<i class="input-helper"></i> Show All Points
</label>
</div>
<div class="form-group" ng-if="['custom', 'heatmap'].indexOf($ctrl.options.globalSeriesType) == -1">
<label class="control-label">Stacking</label>
<div ng-if="$ctrl.stackingOptions">
<!--the if is a weird workaround-->
<ui-select
ng-model="$ctrl.options.series.stacking"
ng-disabled="['line', 'area', 'column'].indexOf($ctrl.options.globalSeriesType) == -1"
>
<ui-select-match placeholder="Choose stacking...">{{ $select.selected.key }}</ui-select-match>
<ui-select-choices repeat="value.value as (key, value) in $ctrl.stackingOptions">
<div ng-bind-html="value.key | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
<div ng-if="['line', 'area', 'column'].indexOf($ctrl.options.globalSeriesType) >= 0" class="checkbox">
<label class="control-label">
<input type="checkbox" ng-model="$ctrl.options.series.percentValues"> Normalize values to percentage
</label>
</div>
</div>
</div>
<div ng-if="$ctrl.options.globalSeriesType == 'custom'">
<div class="form-group">
<label class="control-label">Custom code</label>
<textarea ng-model="$ctrl.options.customCode" class="form-control v-resizable" rows="10">
</textarea>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="$ctrl.options.enableConsoleLogs">
<i class="input-helper"></i> Show errors in the console
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="$ctrl.options.autoRedraw">
<i class="input-helper"></i> Auto update graph
</label>
</div>
</div>
<div ng-if="$ctrl.currentTab == 'xAxis'" class="m-t-10 m-b-10">
<div class="form-group">
<label class="control-label">Scale</label>
<ui-select ng-model="$ctrl.options.xAxis.type">
<ui-select-match placeholder="Choose Scale...">{{$select.selected.label}}</ui-select-match>
<ui-select-choices repeat="scaleType.value as scaleType in $ctrl.xAxisScales">
<div ng-bind-html="scaleType.label | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group">
<label class="control-label">Name</label>
<input ng-model="$ctrl.options.xAxis.title.text" type="text" class="form-control">
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="$ctrl.options.sortX">
<i class="input-helper"></i> Sort Values
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="$ctrl.options.reverseX">
<i class="input-helper"></i> Reverse Order
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="$ctrl.options.xAxis.labels.enabled">
<i class="input-helper"></i> Show Labels
</label>
</div>
</div>
<div ng-if="$ctrl.currentTab == 'yAxis'" class="m-t-10 m-b-10">
<div ng-repeat="yAxis in $ctrl.options.yAxis">
<h4>{{$index == 0 ? 'Left' : 'Right'}} Y Axis</h4>
<div class="form-group">
<label class="control-label">Scale</label>
<ui-select ng-model="yAxis.type">
<ui-select-match placeholder="Choose Scale...">{{$select.selected | capitalize}}</ui-select-match>
<ui-select-choices repeat="scaleType in $ctrl.yAxisScales">
<div ng-bind-html="scaleType | capitalize | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
<div class="form-group">
<label class="control-label">Name</label>
<input ng-model="yAxis.title.text" type="text" class="form-control">
</div>
<div class="form-group">
<label class="control-label">Min Value</label>
<input ng-model="yAxis.rangeMin" type="number" step="any" placeholder="Auto" class="form-control">
</div>
<div class="form-group">
<label class="control-label">Max Value</label>
<input ng-model="yAxis.rangeMax" type="number" step="any" placeholder="Auto" class="form-control">
</div>
<div class="checkbox" ng-if="$ctrl.options.globalSeriesType == 'heatmap'">
<label>
<input type="checkbox" ng-model="$ctrl.options.sortY">
<i class="input-helper"></i> Sort Values
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="$ctrl.options.reverseY">
<i class="input-helper"></i> Reverse Order
</label>
</div>
</div>
</div>
<div ng-if="$ctrl.currentTab == 'series'" class="m-t-10 m-b-10">
<table class="table table-condensed col-table">
<thead>
<th style="width: 1%;">zIndex</th>
<th ng-if="$ctrl.options.globalSeriesType != 'pie'">Left Y Axis</th>
<th ng-if="$ctrl.options.globalSeriesType != 'pie'">Right Y Axis</th>
<th>Label</th>
<th ng-if="$ctrl.options.globalSeriesType != 'pie'">Type</th>
</thead>
<tbody ui-sortable ng-model="$ctrl.form.seriesList">
<tr ng-repeat="name in $ctrl.form.seriesList">
<td style="width: 1%; cursor: move;">
<i class="fa fa-arrows-v"></i>
<span ng-bind="$ctrl.options.seriesOptions[name].zIndex + 1"></span>
</td>
<td ng-if="$ctrl.options.globalSeriesType != 'pie'">
<input type="radio" ng-value="0" ng-model="$ctrl.options.seriesOptions[name].yAxis">
</td>
<td ng-if="$ctrl.options.globalSeriesType != 'pie'">
<input type="radio" ng-value="1" ng-model="$ctrl.options.seriesOptions[name].yAxis">
</td>
<td style="padding: 3px; width: 140px;">
<input
placeholder="{{name}}"
class="form-control input-sm super-small-input" type="text"
ng-model="$ctrl.options.seriesOptions[name].name"
>
</td>
<td ng-if="$ctrl.options.globalSeriesType != 'pie'" style="padding: 3px; width: 105px;">
<ui-select ng-model="$ctrl.options.seriesOptions[name].type">
<ui-select-match placeholder="Chart Type">
<div>
<i class="fa fa-{{$select.selected.value.icon}}"></i>
{{$select.selected.value.name}}
</div>
</ui-select-match>
<ui-select-choices repeat="info.chartType as (chartType, info) in $ctrl.chartTypes">
<div>
<i class="fa fa-{{info.value.icon}}"></i>
<span> </span>
<span ng-bind-html="info.value.name | highlight: $select.search"></span>
</div>
</ui-select-choices>
</ui-select>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-if="($ctrl.currentTab == 'colors') && (['pie', 'heatmap'].indexOf($ctrl.options.globalSeriesType) == -1)" class="m-t-10 m-b-10">
<table class="table table-condensed col-table">
<tbody>
<tr ng-repeat="name in $ctrl.form.seriesList">
<td style="padding: 3px; width: 140px;">
<div>{{ name }}</div>
</td>
<td style="padding: 3px; width: 35px;">
<ui-select ng-model="$ctrl.options.seriesOptions[name].color">
<ui-select-match>
<color-box color="$select.selected.value"></color-box>
</ui-select-match>
<ui-select-choices repeat="color.value as (key, color) in $ctrl.colors">
<color-box color="color.value"></color-box>
<span ng-bind-html="color.key | capitalize | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-if="($ctrl.currentTab == 'colors') && ($ctrl.options.globalSeriesType == 'heatmap')" class="m-t-10 m-b-10">
<div class="form-group" ng-if="$ctrl.options.globalSeriesType == 'heatmap'">
<label class="control-label">Color Scheme</label>
<ui-select ng-model="$ctrl.options.colorScheme">
<ui-select-match allow-clear="true" placeholder="Choose Color Scheme...">{{$select.selected | capitalize}}</ui-select-match>
<ui-select-choices repeat="value in $ctrl.colorScheme">
<div ng-bind-html="value | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group" ng-if="$ctrl.options.colorScheme == 'Custom...'">
<label class="control-label">Min Color</label>
<ui-select ng-model="$ctrl.options.heatMinColor">
<ui-select-match>
<color-box color="$select.selected.value"></color-box>
</ui-select-match>
<ui-select-choices repeat="color.value as (key, color) in $ctrl.colors">
<color-box color="color.value"></color-box>
<span ng-bind-html="color.key | capitalize | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
</div>
<div class="col-xs-6">
<div class="form-group" ng-if="$ctrl.options.colorScheme == 'Custom...'">
<label class="control-label">Max Color</label>
<ui-select ng-model="$ctrl.options.heatMaxColor">
<ui-select-match>
<color-box color="$select.selected.value"></color-box>
</ui-select-match>
<ui-select-choices repeat="color.value as (key, color) in $ctrl.colors">
<color-box color="color.value"></color-box>
<span ng-bind-html="color.key | capitalize | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
</div>
</div>
</div>
<div ng-if="($ctrl.currentTab == 'colors') && ($ctrl.options.globalSeriesType == 'pie')" class="m-t-10 m-b-10">
<table class="table table-condensed col-table">
<tbody>
<tr ng-repeat="name in $ctrl.form.valuesList">
<td style="padding: 3px; width: 140px;">
<div>{{ name }}</div>
</td>
<td style="padding: 3px; width: 35px;">
<ui-select ng-model="$ctrl.options.valuesOptions[name].color">
<ui-select-match>
<color-box color="$select.selected.value"></color-box>
</ui-select-match>
<ui-select-choices repeat="color.value as (key, color) in $ctrl.colors">
<color-box color="color.value"></color-box>
<span ng-bind-html="color.key | capitalize | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-if="$ctrl.currentTab == 'dataLabels'" class="m-t-10 m-b-10">
<div ng-if="['line', 'area', 'column', 'scatter', 'pie', 'heatmap'].indexOf($ctrl.options.globalSeriesType) >= 0" class="checkbox">
<label>
<input type="checkbox" ng-model="$ctrl.options.showDataLabels"> Show Data Labels</label>
</div>
<div class="form-group">
<label for="chart-editor-number-format">
Number Values Format
<span class="m-l-5" uib-popover-html="'Format <a href=&quot;https://redash.io/help/user-guide/visualizations/formatting-numbers&quot; target=&quot;_blank&quot;>specs.</a>'"
popover-trigger="'click outsideClick'">
<i class="fa fa-question-circle"></i>
</span>
</label>
<input
class="form-control" ng-model="$ctrl.options.numberFormat"
ng-model-options="{ allowInvalid: true, debounce: 200 }" id="chart-editor-number-format"
>
</div>
<div class="form-group">
<label for="chart-editor-percent-format">
Percent Values Format
<span class="m-l-5" uib-popover-html="'Format <a href=&quot;https://redash.io/help/user-guide/visualizations/formatting-numbers&quot; target=&quot;_blank&quot;>specs.</a>'"
popover-trigger="'click outsideClick'">
<i class="fa fa-question-circle"></i>
</span>
</label>
<input
class="form-control" ng-model="$ctrl.options.percentFormat"
ng-model-options="{ allowInvalid: true, debounce: 200 }" id="chart-editor-percent-format"
>
</div>
<div class="form-group">
<label for="chart-editor-datetime-format">
Date/Time Values Format
<span class="m-l-5" uib-popover-html="'Format <a href=&quot;https://momentjs.com/docs/#/displaying/format/&quot; target=&quot;_blank&quot;>specs.</a>'"
popover-trigger="'click outsideClick'">
<i class="fa fa-question-circle"></i>
</span>
</label>
<input
class="form-control" ng-model="$ctrl.options.dateTimeFormat"
ng-model-options="{ allowInvalid: true, debounce: 200 }" id="chart-editor-datetime-format"
>
</div>
<div class="form-group">
<label for="chart-editor-text">
Data Labels
<i class="fa fa-question-circle m-l-5" uib-popover-html="$ctrl.templateHint"
popover-trigger="'click outsideClick'" popover-placement="top-left"></i>
</label>
<input class="form-control" ng-model="$ctrl.options.textFormat"
ng-model-options="{ allowInvalid: true, debounce: 200 }" id="chart-editor-text"
placeholder="(auto)"
>
</div>
</div>
</div>