2016-08-29 2 views
1

Я использую множество таблиц визуализации Google для отображения разнообразных данных в одностраничном веб-приложении с несколькими вкладками. Некоторые из этих таблиц содержат столбцы, в которых используются форматированные значения. Когда пользователь нажимает на заголовок столбца для этих столбцов, данные сортируются в соответствии с порядком сортировки базовых значений, а не порядком сортировки отформатированных значений. Это приводит к тому, что в некоторых случаях данные не отображаются пользователю для сортировки.Как получить таблицу визуализации Google для сортировки по форматированным значениям ячеек, когда они есть?

Я ищу способ исправить это, которое можно использовать повторно во всех моих таблицах, предпочтительно, путем записи одного прослушивателя событий, который может быть прикреплен к каждой таблице, и будет обрабатывать все особенности независимо от типов данных, используемых в различные столбцы различных связанных таблиц данных и независимо от того, использует ли какой-либо данный столбец форматированные значения. У меня есть условие, что если какая-либо ячейка в столбце использует форматированное значение, то все ячейки в этом столбце имеют значение, но у меня нет условия, что каждый столбец использует форматированные значения. Если столбец не использует отформатированные значения, то я хочу, чтобы нормальная сортировка основывалась на типе данных в столбце (например, число, строка, дата и т. Д.).

В качестве примера у меня может быть DataTable, как показано ниже. (Эти данные не являются фактические данные, но зеркальные ситуации, которые являются проблематичными для меня.)

var dataTable = new google.visualization.DataTable({ 
    cols: [ 
     {type: 'number', label: 'ID'}, 
     {type: 'number', label: 'Places'}, 
     {type: 'string', label: 'Things'} 
    ], 
    rows: [ 
     {c:[{v:1},{v:102735,f:'Harbor Place'},{v:'pet',f:'Dalmation'}]}, 
     {c:[{v:2},{v:163848,f:'Alphaville'},{v:'my',f:'Top Favorites'}]}, 
     {c:[{v:3},{v:113787,f:'Beta City'},{v:'ten',f:'Best Things'}]} 
    ] 
}); 

Без моего делать какие-либо специальной настройки, эту таблицу, если отсортирован по возрастанию по столбцу ID, будет выглядеть так, как пользователь будет ожидать:

ID Places   Things 
---------------------------------- 
1 Harbor Place Dalmation 
2 Alphaville  Top Favorites 
3 Beta City  Best Things 

Если пользователь щелкает по заголовку столбца Places, таблица будет выглядеть так, потому что восходящая сортировка выполняется на основных числовых значений:

ID Places   Things 
---------------------------------- 
1 Harbor Place Dalmation 
3 Beta City  Best Things 
2 Alphaville  Top Favorites 

Пользователь, однако, ожидает, что таблица выглядеть следующим образом:

ID Places   Things 
---------------------------------- 
2 Alphaville  Top Favorites 
3 Beta City  Best Things 
1 Harbor Place Dalmation 

Если пользователь щелкает по заголовку столбца Things, таблица будет сортировать по возрастанию следующим образом, из-за порядка сортировки базового актива строковые значения:

ID Places   Things 
---------------------------------- 
2 Alphaville  Top Favorites 
1 Harbor Place Dalmation 
3 Beta City  Best Things 

пользователь ожидает, что это:

ID Places   Things 
---------------------------------- 
3 Beta City  Best Things 
1 Harbor Place Dalmation 
2 Alphaville  Top Favorites 

Я искал на StackOverflow и на Google и не нашли какого-либо обсуждения й это особая ситуация. Поэтому я работал над написанием своего собственного прослушивателя событий, но он быстро стал очень привлекательным, пытаясь написать его как нечто, которое можно использовать повторно для любого из моих таблиц. Так что я пропущу что-то простое? У кого-то еще была такая ситуация и она была решена; если да, что вы сделали?

ответ

1

вы можете использовать DataView Class установить порядок ROW

dataView.setRows([1, 2, 0]);

затем нарисовать диаграмму с DataView

table.draw(dataView, options);

получая порядок строк во время 'sort' события сложная часть,
, так как нет удобных методов для форматированных значений, например getDistinctValues

в следующем рабочем фрагменте, отформатированные значения извлекаются в массив,
сортируются, а затем getFilteredRows используется, чтобы получить индекс строки форматированного значения

google.charts.load('current', { 
 
    callback: function() { 
 
    var dataTable = new google.visualization.DataTable({ 
 
     cols: [ 
 
     {type: 'number', label: 'ID'}, 
 
     {type: 'number', label: 'Places'}, 
 
     {type: 'string', label: 'Things'} 
 
     ], 
 
     rows: [ 
 
     {c:[{v:1},{v:102735,f:'Harbor Place'},{v:'pet',f:'Dalmation'}]}, 
 
     {c:[{v:2},{v:163848,f:'Alphaville'},{v:'my',f:'Top Favorites'}]}, 
 
     {c:[{v:3},{v:113787,f:'Beta City'},{v:'ten',f:'Best Things'}]} 
 
     ] 
 
    }); 
 

 
    // use DataView to set order of rows 
 
    var dataView = new google.visualization.DataView(dataTable); 
 
    dataView.setRows([1, 2, 0]); 
 

 
    var table = new google.visualization.Table(document.getElementById('chart_div')); 
 
    var options = { 
 
     // use event to set order 
 
     sort: 'event', 
 

 
     // set column arrow 
 
     sortColumn: 1, 
 
     sortAscending: true 
 
    }; 
 

 
    google.visualization.events.addListener(table, 'sort', function(props) { 
 
     var sortValues = []; 
 
     var sortRows = []; 
 
     var sortDirection = (props.ascending) ? 1 : -1; 
 

 
     // load values into sortable array 
 
     for (var i = 0; i < dataTable.getNumberOfRows(); i++) { 
 
     sortValues.push({ 
 
      v: dataTable.getValue(i, props.column), 
 
      f: dataTable.getFormattedValue(i, props.column) 
 
     }); 
 
     } 
 
     sortValues.sort(function (row1, row2) { 
 
     return row1.f.localeCompare(row2.f) * sortDirection; 
 
     }); 
 

 
     // set row indexes 
 
     sortValues.forEach(function (sortValue) { 
 
     sortRows.push(dataTable.getFilteredRows([{column: props.column, value: sortValue.v}])[0]); 
 
     }); 
 

 
     // use DataView to set order of rows 
 
     dataView.setRows(sortRows); 
 

 
     // set column arrow 
 
     options.sortColumn = props.column; 
 
     options.sortAscending = props.ascending; 
 

 
     table.draw(dataView, options); 
 
    }); 
 

 
    table.draw(dataView, options); 
 
    }, 
 
    packages: ['table'] 
 
});
<script src="https://www.gstatic.com/charts/loader.js"></script> 
 
<div id="chart_div"></div>

+0

Действительно , это действительно помогает. Рассмотрев ваше решение, @WhiteHat, и, учитывая мои исследования, я не верю, что есть более простое решение, чем это. Я подтвердил ваш ответ, который появится однажды, когда я доберусь до 15 человек. Благодаря! –

+0

Примечание для тех, кто приходит после: это решение as-is не будет сортировать столбцы в соответствии с их естественным порядком сортировки, если вы не указали форматированное значение. Вызов getFormattedValue преобразует исходное значение в строку, а затем код переходит к выполнению строкового сортировки независимо от исходного типа данных. Мне еще нужно выяснить эту часть и, возможно, придется задать другой вопрос. –

+0

вы можете сохранить ссылку на 'rows', до создания' DataTable', а затем использовать ее вместо 'sortValues' выше - ссылки станут немного сложнее, но вся необходимая информация должна быть там ... – WhiteHat